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

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: nits 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 "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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698