OLD | NEW |
| (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/session/session_state_delegate.h" | |
8 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" | |
9 #include "ash/common/wm_shell.h" | |
10 #include "ash/shell.h" | |
11 #include "ash/wm/lock_state_controller.h" | |
12 #include "base/time/default_tick_clock.h" | |
13 #include "chromeos/dbus/dbus_thread_manager.h" | |
14 #include "ui/events/devices/input_device_manager.h" | |
15 #include "ui/events/devices/stylus_state.h" | |
16 #include "ui/events/event.h" | |
17 | |
18 namespace ash { | |
19 | |
20 namespace { | |
21 | |
22 // Amount of time the power button must be held to start the pre-shutdown | |
23 // animation when in tablet mode. | |
24 constexpr int kShutdownTimeoutMs = 1000; | |
25 | |
26 // Amount of time since last SuspendDone() that power button event needs to be | |
27 // ignored. | |
28 constexpr int kIgnorePowerButtonAfterResumeMs = 2000; | |
29 | |
30 // Returns true if device is a convertible/tablet device or has | |
31 // kAshEnableTouchViewTesting in test, otherwise false. | |
32 bool IsTabletModeSupported() { | |
33 MaximizeModeController* maximize_mode_controller = | |
34 WmShell::Get()->maximize_mode_controller(); | |
35 return maximize_mode_controller && | |
36 maximize_mode_controller->CanEnterMaximizeMode(); | |
37 } | |
38 | |
39 // Returns true if device is currently in tablet/maximize mode, otherwise false. | |
40 bool IsTabletModeActive() { | |
41 MaximizeModeController* maximize_mode_controller = | |
42 WmShell::Get()->maximize_mode_controller(); | |
43 return maximize_mode_controller && | |
44 maximize_mode_controller->IsMaximizeModeWindowManagerEnabled(); | |
45 } | |
46 | |
47 } // namespace | |
48 | |
49 TabletPowerButtonController::TestApi::TestApi( | |
50 TabletPowerButtonController* controller) | |
51 : controller_(controller) {} | |
52 | |
53 TabletPowerButtonController::TestApi::~TestApi() {} | |
54 | |
55 bool TabletPowerButtonController::TestApi::ShutdownTimerIsRunning() const { | |
56 return controller_->shutdown_timer_.IsRunning(); | |
57 } | |
58 | |
59 void TabletPowerButtonController::TestApi::TriggerShutdownTimeout() { | |
60 DCHECK(ShutdownTimerIsRunning()); | |
61 controller_->OnShutdownTimeout(); | |
62 controller_->shutdown_timer_.Stop(); | |
63 } | |
64 | |
65 TabletPowerButtonController::TabletPowerButtonController( | |
66 LockStateController* controller) | |
67 : tick_clock_(new base::DefaultTickClock()), | |
68 last_resume_time_(base::TimeTicks()), | |
69 controller_(controller) { | |
70 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( | |
71 this); | |
72 ui::InputDeviceManager::GetInstance()->AddObserver(this); | |
73 Shell::GetInstance()->PrependPreTargetHandler(this); | |
74 | |
75 GetInitialBacklightsForcedOff(); | |
76 } | |
77 | |
78 TabletPowerButtonController::~TabletPowerButtonController() { | |
79 Shell::GetInstance()->RemovePreTargetHandler(this); | |
80 ui::InputDeviceManager::GetInstance()->RemoveObserver(this); | |
81 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( | |
82 this); | |
83 } | |
84 | |
85 bool TabletPowerButtonController::ShouldHandlePowerButtonEvents() const { | |
86 return IsTabletModeSupported(); | |
87 } | |
88 | |
89 void TabletPowerButtonController::OnPowerButtonEvent( | |
90 bool down, | |
91 const base::TimeTicks& timestamp) { | |
92 // When the system resumes in response to the power button being pressed, | |
93 // Chrome receives powerd's SuspendDone signal and notification that the | |
94 // backlight has been turned back on before seeing the power button events | |
95 // that woke the system. Ignore events just after resuming to ensure that we | |
96 // don't turn the screen off in response to the events. | |
97 if (timestamp - last_resume_time_ <= | |
98 base::TimeDelta::FromMilliseconds(kIgnorePowerButtonAfterResumeMs)) { | |
99 return; | |
100 } | |
101 | |
102 if (down) { | |
103 screen_off_when_power_button_down_ = brightness_level_is_zero_; | |
104 SetBacklightsForcedOff(false); | |
105 StartShutdownTimer(); | |
106 } else { | |
107 if (shutdown_timer_.IsRunning()) { | |
108 shutdown_timer_.Stop(); | |
109 if (!screen_off_when_power_button_down_) { | |
110 SetBacklightsForcedOff(true); | |
111 LockScreenIfRequired(); | |
112 } | |
113 } | |
114 screen_off_when_power_button_down_ = false; | |
115 | |
116 // When power button is released, cancel shutdown animation whenever it is | |
117 // still cancellable. | |
118 if (controller_->CanCancelShutdownAnimation()) | |
119 controller_->CancelShutdownAnimation(); | |
120 } | |
121 } | |
122 | |
123 void TabletPowerButtonController::PowerManagerRestarted() { | |
124 chromeos::DBusThreadManager::Get() | |
125 ->GetPowerManagerClient() | |
126 ->SetBacklightsForcedOff(backlights_forced_off_); | |
127 } | |
128 | |
129 void TabletPowerButtonController::BrightnessChanged(int level, | |
130 bool user_initiated) { | |
131 brightness_level_is_zero_ = level == 0; | |
132 } | |
133 | |
134 void TabletPowerButtonController::SuspendDone( | |
135 const base::TimeDelta& sleep_duration) { | |
136 last_resume_time_ = tick_clock_->NowTicks(); | |
137 } | |
138 | |
139 void TabletPowerButtonController::OnKeyEvent(ui::KeyEvent* event) { | |
140 if (!IsTabletModeActive() && backlights_forced_off_) | |
141 SetBacklightsForcedOff(false); | |
142 } | |
143 | |
144 void TabletPowerButtonController::OnMouseEvent(ui::MouseEvent* event) { | |
145 ui::EventPointerType pointer_type = event->pointer_details().pointer_type; | |
146 if (pointer_type != ui::EventPointerType::POINTER_TYPE_MOUSE && | |
147 pointer_type != ui::EventPointerType::POINTER_TYPE_TOUCH) { | |
148 return; | |
149 } | |
150 | |
151 if (!IsTabletModeActive() && backlights_forced_off_) | |
152 SetBacklightsForcedOff(false); | |
153 } | |
154 | |
155 void TabletPowerButtonController::OnStylusStateChanged(ui::StylusState state) { | |
156 if (IsTabletModeSupported() && state == ui::StylusState::REMOVED && | |
157 backlights_forced_off_) { | |
158 SetBacklightsForcedOff(false); | |
159 } | |
160 } | |
161 | |
162 void TabletPowerButtonController::SetTickClockForTesting( | |
163 std::unique_ptr<base::TickClock> tick_clock) { | |
164 DCHECK(tick_clock); | |
165 tick_clock_ = std::move(tick_clock); | |
166 } | |
167 | |
168 void TabletPowerButtonController::SetBacklightsForcedOff(bool forced_off) { | |
169 if (backlights_forced_off_ == forced_off) | |
170 return; | |
171 | |
172 chromeos::DBusThreadManager::Get() | |
173 ->GetPowerManagerClient() | |
174 ->SetBacklightsForcedOff(forced_off); | |
175 backlights_forced_off_ = forced_off; | |
176 } | |
177 | |
178 void TabletPowerButtonController::GetInitialBacklightsForcedOff() { | |
179 chromeos::DBusThreadManager::Get() | |
180 ->GetPowerManagerClient() | |
181 ->GetBacklightsForcedOff(base::Bind( | |
182 &TabletPowerButtonController::OnGotInitialBacklightsForcedOff, | |
183 base::Unretained(this))); | |
184 } | |
185 | |
186 void TabletPowerButtonController::OnGotInitialBacklightsForcedOff( | |
187 bool is_forced_off) { | |
188 backlights_forced_off_ = is_forced_off; | |
189 } | |
190 | |
191 void TabletPowerButtonController::StartShutdownTimer() { | |
192 shutdown_timer_.Start(FROM_HERE, | |
193 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs), | |
194 this, &TabletPowerButtonController::OnShutdownTimeout); | |
195 } | |
196 | |
197 void TabletPowerButtonController::OnShutdownTimeout() { | |
198 controller_->StartShutdownAnimation(); | |
199 } | |
200 | |
201 void TabletPowerButtonController::LockScreenIfRequired() { | |
202 SessionStateDelegate* session_state_delegate = | |
203 WmShell::Get()->GetSessionStateDelegate(); | |
204 if (session_state_delegate->ShouldLockScreenAutomatically() && | |
205 session_state_delegate->CanLockScreen() && | |
206 !session_state_delegate->IsUserSessionBlocked() && | |
207 !controller_->LockRequested()) { | |
208 session_state_delegate->LockScreen(); | |
209 } | |
210 } | |
211 | |
212 } // namespace ash | |
OLD | NEW |