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

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

Issue 2474913004: Tablet-like power button behavior on Convertible/Tablet ChromeOS devices (Closed)
Patch Set: cr and additional changes Created 4 years, 1 month 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/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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698