Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: ash/system/chromeos/power/tablet_power_button_controller.cc

Issue 2732813002: chromeos: Move files in //ash/common to //ash, part 1 (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/system/chromeos/power/tablet_power_button_controller.h"
6
7 #include "ash/common/accessibility_delegate.h"
8 #include "ash/common/session/session_state_delegate.h"
9 #include "ash/common/shell_delegate.h"
10 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h"
11 #include "ash/common/wm_shell.h"
12 #include "ash/shell.h"
13 #include "ash/wm/lock_state_controller.h"
14 #include "base/time/default_tick_clock.h"
15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "ui/events/devices/input_device_manager.h"
17 #include "ui/events/devices/stylus_state.h"
18 #include "ui/events/event.h"
19
20 namespace ash {
21
22 namespace {
23
24 // Amount of time the power button must be held to start the pre-shutdown
25 // animation when in tablet mode. This differs depending on whether the screen
26 // is on or off when the power button is initially pressed.
27 constexpr int kShutdownWhenScreenOnTimeoutMs = 500;
28 // TODO(derat): This is currently set to a high value to work around delays in
29 // powerd's reports of button-up events when the preceding button-down event
30 // turns the display on. Set it to a lower value once powerd no longer blocks on
31 // asking Chrome to turn the display on: http://crbug.com/685734
32 constexpr int kShutdownWhenScreenOffTimeoutMs = 2000;
33
34 // Amount of time since last SuspendDone() that power button event needs to be
35 // ignored.
36 constexpr int kIgnorePowerButtonAfterResumeMs = 2000;
37
38 // Ignore button-up events occurring within this many milliseconds of the
39 // previous button-up event. This prevents us from falling behind if the power
40 // button is pressed repeatedly.
41 constexpr int kIgnoreRepeatedButtonUpMs = 500;
42
43 // Returns true if device is a convertible/tablet device, otherwise false.
44 bool IsTabletModeSupported() {
45 MaximizeModeController* maximize_mode_controller =
46 WmShell::Get()->maximize_mode_controller();
47 return maximize_mode_controller &&
48 maximize_mode_controller->CanEnterMaximizeMode();
49 }
50
51 // Returns true if device is currently in tablet/maximize mode, otherwise false.
52 bool IsTabletModeActive() {
53 MaximizeModeController* maximize_mode_controller =
54 WmShell::Get()->maximize_mode_controller();
55 return maximize_mode_controller &&
56 maximize_mode_controller->IsMaximizeModeWindowManagerEnabled();
57 }
58
59 } // namespace
60
61 TabletPowerButtonController::TestApi::TestApi(
62 TabletPowerButtonController* controller)
63 : controller_(controller) {}
64
65 TabletPowerButtonController::TestApi::~TestApi() {}
66
67 bool TabletPowerButtonController::TestApi::ShutdownTimerIsRunning() const {
68 return controller_->shutdown_timer_.IsRunning();
69 }
70
71 void TabletPowerButtonController::TestApi::TriggerShutdownTimeout() {
72 DCHECK(ShutdownTimerIsRunning());
73 controller_->OnShutdownTimeout();
74 controller_->shutdown_timer_.Stop();
75 }
76
77 TabletPowerButtonController::TabletPowerButtonController(
78 LockStateController* controller)
79 : tick_clock_(new base::DefaultTickClock()),
80 force_off_on_button_up_(true),
81 controller_(controller),
82 weak_ptr_factory_(this) {
83 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
84 this);
85 WmShell::Get()->AddShellObserver(this);
86 // TODO(mash): Provide a way for this class to observe stylus events:
87 // http://crbug.com/682460
88 if (ui::InputDeviceManager::HasInstance())
89 ui::InputDeviceManager::GetInstance()->AddObserver(this);
90 Shell::GetInstance()->PrependPreTargetHandler(this);
91
92 GetInitialBacklightsForcedOff();
93 }
94
95 TabletPowerButtonController::~TabletPowerButtonController() {
96 Shell::GetInstance()->RemovePreTargetHandler(this);
97 if (ui::InputDeviceManager::HasInstance())
98 ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
99 WmShell::Get()->RemoveShellObserver(this);
100 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
101 this);
102 }
103
104 bool TabletPowerButtonController::ShouldHandlePowerButtonEvents() const {
105 return IsTabletModeSupported();
106 }
107
108 void TabletPowerButtonController::OnPowerButtonEvent(
109 bool down,
110 const base::TimeTicks& timestamp) {
111 if (down) {
112 force_off_on_button_up_ = true;
113 // When the system resumes in response to the power button being pressed,
114 // Chrome receives powerd's SuspendDone signal and notification that the
115 // backlight has been turned back on before seeing the power button events
116 // that woke the system. Avoid forcing off display just after resuming to
117 // ensure that we don't turn the display off in response to the events.
118 if (timestamp - last_resume_time_ <=
119 base::TimeDelta::FromMilliseconds(kIgnorePowerButtonAfterResumeMs)) {
120 force_off_on_button_up_ = false;
121 }
122 screen_off_when_power_button_down_ = brightness_level_is_zero_;
123 SetDisplayForcedOff(false);
124 StartShutdownTimer();
125 } else {
126 // When power button is released, cancel shutdown animation whenever it is
127 // still cancellable.
128 if (controller_->CanCancelShutdownAnimation())
129 controller_->CancelShutdownAnimation();
130
131 const base::TimeTicks previous_up_time = last_button_up_time_;
132 last_button_up_time_ = tick_clock_->NowTicks();
133 // Ignore the event if it comes too soon after the last one.
134 if (timestamp - previous_up_time <=
135 base::TimeDelta::FromMilliseconds(kIgnoreRepeatedButtonUpMs)) {
136 shutdown_timer_.Stop();
137 return;
138 }
139
140 if (shutdown_timer_.IsRunning()) {
141 shutdown_timer_.Stop();
142 if (!screen_off_when_power_button_down_ && force_off_on_button_up_) {
143 SetDisplayForcedOff(true);
144 LockScreenIfRequired();
145 }
146 }
147 }
148 }
149
150 void TabletPowerButtonController::PowerManagerRestarted() {
151 chromeos::DBusThreadManager::Get()
152 ->GetPowerManagerClient()
153 ->SetBacklightsForcedOff(backlights_forced_off_);
154 }
155
156 void TabletPowerButtonController::BrightnessChanged(int level,
157 bool user_initiated) {
158 brightness_level_is_zero_ = level == 0;
159 }
160
161 void TabletPowerButtonController::SuspendDone(
162 const base::TimeDelta& sleep_duration) {
163 last_resume_time_ = tick_clock_->NowTicks();
164 }
165
166 void TabletPowerButtonController::OnMaximizeModeStarted() {
167 shutdown_timer_.Stop();
168 if (controller_->CanCancelShutdownAnimation())
169 controller_->CancelShutdownAnimation();
170 }
171
172 void TabletPowerButtonController::OnMaximizeModeEnded() {
173 shutdown_timer_.Stop();
174 if (controller_->CanCancelShutdownAnimation())
175 controller_->CancelShutdownAnimation();
176 }
177
178 void TabletPowerButtonController::OnKeyEvent(ui::KeyEvent* event) {
179 // Ignore key events generated by the power button since power button activity
180 // is already handled by OnPowerButtonEvent().
181 if (event->key_code() == ui::VKEY_POWER)
182 return;
183
184 if (!IsTabletModeActive() && backlights_forced_off_)
185 SetDisplayForcedOff(false);
186 }
187
188 void TabletPowerButtonController::OnMouseEvent(ui::MouseEvent* event) {
189 if (event->flags() & ui::EF_IS_SYNTHESIZED)
190 return;
191
192 if (!IsTabletModeActive() && backlights_forced_off_)
193 SetDisplayForcedOff(false);
194 }
195
196 void TabletPowerButtonController::OnStylusStateChanged(ui::StylusState state) {
197 if (IsTabletModeSupported() && state == ui::StylusState::REMOVED &&
198 backlights_forced_off_) {
199 SetDisplayForcedOff(false);
200 }
201 }
202
203 void TabletPowerButtonController::SetTickClockForTesting(
204 std::unique_ptr<base::TickClock> tick_clock) {
205 DCHECK(tick_clock);
206 tick_clock_ = std::move(tick_clock);
207 }
208
209 void TabletPowerButtonController::SetDisplayForcedOff(bool forced_off) {
210 if (backlights_forced_off_ == forced_off)
211 return;
212
213 // Set the display and keyboard backlights (if present) to |forced_off|.
214 chromeos::DBusThreadManager::Get()
215 ->GetPowerManagerClient()
216 ->SetBacklightsForcedOff(forced_off);
217 backlights_forced_off_ = forced_off;
218
219 ShellDelegate* delegate = WmShell::Get()->delegate();
220 delegate->SetTouchscreenEnabledInPrefs(!forced_off,
221 true /* use_local_state */);
222 delegate->UpdateTouchscreenStatusFromPrefs();
223
224 // Send an a11y alert.
225 WmShell::Get()->accessibility_delegate()->TriggerAccessibilityAlert(
226 forced_off ? A11Y_ALERT_SCREEN_OFF : A11Y_ALERT_SCREEN_ON);
227 }
228
229 void TabletPowerButtonController::GetInitialBacklightsForcedOff() {
230 chromeos::DBusThreadManager::Get()
231 ->GetPowerManagerClient()
232 ->GetBacklightsForcedOff(base::Bind(
233 &TabletPowerButtonController::OnGotInitialBacklightsForcedOff,
234 weak_ptr_factory_.GetWeakPtr()));
235 }
236
237 void TabletPowerButtonController::OnGotInitialBacklightsForcedOff(
238 bool is_forced_off) {
239 backlights_forced_off_ = is_forced_off;
240 }
241
242 void TabletPowerButtonController::StartShutdownTimer() {
243 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(
244 screen_off_when_power_button_down_ ? kShutdownWhenScreenOffTimeoutMs
245 : kShutdownWhenScreenOnTimeoutMs);
246 shutdown_timer_.Start(FROM_HERE, timeout, this,
247 &TabletPowerButtonController::OnShutdownTimeout);
248 }
249
250 void TabletPowerButtonController::OnShutdownTimeout() {
251 controller_->StartShutdownAnimation();
252 }
253
254 void TabletPowerButtonController::LockScreenIfRequired() {
255 SessionStateDelegate* session_state_delegate =
256 WmShell::Get()->GetSessionStateDelegate();
257 if (session_state_delegate->ShouldLockScreenAutomatically() &&
258 session_state_delegate->CanLockScreen() &&
259 !session_state_delegate->IsUserSessionBlocked() &&
260 !controller_->LockRequested()) {
261 session_state_delegate->LockScreen();
262 }
263 }
264
265 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698