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 "chromeos/dbus/dbus_thread_manager.h" | |
13 #include "ui/events/devices/input_device_manager.h" | |
14 #include "ui/events/devices/stylus_state.h" | |
15 #include "ui/events/event.h" | |
16 | |
17 namespace ash { | |
18 | |
19 namespace { | |
20 | |
21 // Amount of time the power button must be held to start the pre-shutdown | |
22 // animation when in tablet mode. | |
23 constexpr int kShutdownTimeoutMs = 1000; | |
24 | |
25 // Amount of time since last SuspendDone() that power button event needs to be | |
26 // ignored. | |
27 constexpr int kWaitSuspendDoneDurationMs = 2000; | |
Daniel Erat
2016/11/10 22:48:55
nit: kIgnorePowerButtonAfterResumeMs?
Qiang(Joe) Xu
2016/11/11 04:39:22
Done.
| |
28 | |
29 TabletPowerButtonController* instance = nullptr; | |
30 | |
31 // Returns true if device is a convertible/tablet device or has | |
32 // kAshEnableTouchViewTesting in test, otherwise false. | |
33 bool IsTabletModeSupported() { | |
34 MaximizeModeController* maximize_mode_controller = | |
35 WmShell::Get()->maximize_mode_controller(); | |
36 return maximize_mode_controller && | |
37 maximize_mode_controller->CanEnterMaximizeMode(); | |
38 } | |
39 | |
40 // Returns true if device is currently in tablet/maximize mode, otherwise false. | |
41 bool IsTabletModeActive() { | |
42 MaximizeModeController* maximize_mode_controller = | |
43 WmShell::Get()->maximize_mode_controller(); | |
44 return maximize_mode_controller && | |
45 maximize_mode_controller->IsMaximizeModeWindowManagerEnabled(); | |
46 } | |
47 | |
48 } // namespace | |
49 | |
50 TabletPowerButtonController::TestApi::TestApi( | |
51 TabletPowerButtonController* controller) | |
52 : controller_(controller) {} | |
53 | |
54 TabletPowerButtonController::TestApi::~TestApi() {} | |
55 | |
56 bool TabletPowerButtonController::TestApi::ShutdownTimerIsRunning() const { | |
57 return controller_->shutdown_timer_.IsRunning(); | |
58 } | |
59 | |
60 void TabletPowerButtonController::TestApi::TriggerShutdownTimeout() { | |
61 DCHECK(ShutdownTimerIsRunning()); | |
Daniel Erat
2016/11/10 22:48:54
how about making this method return false if the t
Qiang(Joe) Xu
2016/11/11 04:39:22
EXPECT_FALSE(TriggerShutdownTimeout) can represent
| |
62 controller_->OnShutdownTimeout(); | |
63 controller_->shutdown_timer_.Stop(); | |
64 } | |
65 | |
66 // static | |
67 TabletPowerButtonController* TabletPowerButtonController::GetInstance() { | |
68 DCHECK(instance); | |
69 return instance; | |
70 } | |
71 | |
72 TabletPowerButtonController::TabletPowerButtonController( | |
73 LockStateController* controller) | |
74 : controller_(controller) { | |
75 DCHECK(!instance); | |
76 instance = this; | |
77 | |
78 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( | |
79 this); | |
80 ui::InputDeviceManager::GetInstance()->AddObserver(this); | |
81 Shell::GetInstance()->PrependPreTargetHandler(this); | |
82 GetInitialBacklightsForcedOff(); | |
83 } | |
84 | |
85 TabletPowerButtonController::~TabletPowerButtonController() { | |
86 Shell::GetInstance()->RemovePreTargetHandler(this); | |
87 ui::InputDeviceManager::GetInstance()->RemoveObserver(this); | |
88 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( | |
89 this); | |
90 | |
91 DCHECK_EQ(instance, this); | |
92 instance = nullptr; | |
93 } | |
94 | |
95 bool TabletPowerButtonController::ShouldHandlePowerButtonEvents() const { | |
96 return IsTabletModeSupported(); | |
97 } | |
98 | |
99 void TabletPowerButtonController::OnPowerButtonEvent( | |
100 bool down, | |
101 const base::TimeTicks& timestamp) { | |
102 // When pressing power button causing SuspendDone, chrome side will first | |
Daniel Erat
2016/11/10 22:48:55
how about this?
// When the system resumes in res
Qiang(Joe) Xu
2016/11/11 04:39:22
It is much better. Thanks!
| |
103 // receive SuspendDone signal and then power button events. The resumed | |
104 // brightness could make chrome think it is pressed on brightness-on-state, | |
105 // but actually it is pressed on suspended-state (brightness-off-state). | |
106 if (!last_resume_time_.is_null() && | |
107 timestamp - last_resume_time_ <= | |
108 base::TimeDelta::FromMilliseconds(kWaitSuspendDoneDurationMs)) { | |
109 return; | |
110 } | |
111 | |
112 if (down) { | |
113 screen_off_when_power_button_down_ = brightness_level_is_zero_; | |
114 SetBacklightsForcedOff(false); | |
115 StartShutdownTimer(); | |
116 } else { | |
117 if (shutdown_timer_.IsRunning()) { | |
118 shutdown_timer_.Stop(); | |
119 if (!screen_off_when_power_button_down_) { | |
120 SetBacklightsForcedOff(true); | |
121 LockScreenIfRequired(); | |
122 } | |
123 } | |
124 screen_off_when_power_button_down_ = false; | |
125 | |
126 // When power button is released, cancel shutdown animation whenever it is | |
127 // still cancellable. | |
128 if (controller_->CanCancelShutdownAnimation()) | |
129 controller_->CancelShutdownAnimation(); | |
130 } | |
131 } | |
132 | |
133 void TabletPowerButtonController::PowerManagerRestarted() { | |
134 chromeos::DBusThreadManager::Get() | |
135 ->GetPowerManagerClient() | |
136 ->SetBacklightsForcedOff(backlights_forced_off_); | |
137 } | |
138 | |
139 void TabletPowerButtonController::BrightnessChanged(int level, | |
140 bool user_initiated) { | |
141 brightness_level_is_zero_ = level == 0; | |
142 } | |
143 | |
144 void TabletPowerButtonController::SuspendDone( | |
145 const base::TimeDelta& sleep_duration) { | |
146 last_resume_time_ = base::TimeTicks::Now(); | |
Daniel Erat
2016/11/10 22:48:54
i'd suggest using base::TickClock instead so you c
Qiang(Joe) Xu
2016/11/11 04:39:22
Done.
| |
147 } | |
148 | |
149 void TabletPowerButtonController::OnKeyEvent(ui::KeyEvent* event) { | |
150 if (!IsTabletModeActive() && backlights_forced_off_) | |
151 SetBacklightsForcedOff(false); | |
152 } | |
153 | |
154 void TabletPowerButtonController::OnMouseEvent(ui::MouseEvent* event) { | |
155 ui::EventPointerType pointer_type = event->pointer_details().pointer_type; | |
156 if (pointer_type != ui::EventPointerType::POINTER_TYPE_MOUSE && | |
157 pointer_type != ui::EventPointerType::POINTER_TYPE_TOUCH) { | |
158 return; | |
159 } | |
160 | |
161 if (!IsTabletModeActive() && backlights_forced_off_) | |
162 SetBacklightsForcedOff(false); | |
163 } | |
164 | |
165 void TabletPowerButtonController::OnStylusStateChanged(ui::StylusState state) { | |
166 if (IsTabletModeSupported() && state == ui::StylusState::REMOVED && | |
167 backlights_forced_off_) { | |
168 SetBacklightsForcedOff(false); | |
169 } | |
170 } | |
171 | |
172 void TabletPowerButtonController::SetBacklightsForcedOff(bool forced_off) { | |
173 if (backlights_forced_off_ == forced_off) | |
174 return; | |
175 | |
176 chromeos::DBusThreadManager::Get() | |
177 ->GetPowerManagerClient() | |
178 ->SetBacklightsForcedOff(forced_off); | |
179 backlights_forced_off_ = forced_off; | |
180 } | |
181 | |
182 void TabletPowerButtonController::GetInitialBacklightsForcedOff() { | |
183 chromeos::DBusThreadManager::Get() | |
184 ->GetPowerManagerClient() | |
185 ->GetBacklightsForcedOff(base::Bind( | |
186 &TabletPowerButtonController::OnGotInitialBacklightsForcedOff, | |
187 base::Unretained(this))); | |
188 } | |
189 | |
190 void TabletPowerButtonController::OnGotInitialBacklightsForcedOff( | |
191 bool is_forced_off) { | |
192 backlights_forced_off_ = is_forced_off; | |
193 } | |
194 | |
195 void TabletPowerButtonController::StartShutdownTimer() { | |
196 shutdown_timer_.Start(FROM_HERE, | |
197 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs), | |
198 this, &TabletPowerButtonController::OnShutdownTimeout); | |
199 } | |
200 | |
201 void TabletPowerButtonController::OnShutdownTimeout() { | |
202 controller_->StartShutdownAnimation(); | |
203 } | |
204 | |
205 void TabletPowerButtonController::LockScreenIfRequired() { | |
206 SessionStateDelegate* session_state_delegate = | |
207 WmShell::Get()->GetSessionStateDelegate(); | |
208 if (session_state_delegate->ShouldLockScreenAutomatically() && | |
209 session_state_delegate->CanLockScreen() && | |
210 !session_state_delegate->IsUserSessionBlocked() && | |
211 !controller_->LockRequested()) { | |
212 session_state_delegate->LockScreen(); | |
213 } | |
214 } | |
215 | |
216 } // namespace ash | |
OLD | NEW |