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

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

Issue 2504523002: [Reland-fixing asan failure] Tablet-like power button behavior on Convertible/Tablet ChromeOS devic… (Closed)
Patch Set: fix asan test failure 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 weak_ptr_factory_(this) {
71 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
72 this);
73 ui::InputDeviceManager::GetInstance()->AddObserver(this);
74 Shell::GetInstance()->PrependPreTargetHandler(this);
75
76 GetInitialBacklightsForcedOff();
77 }
78
79 TabletPowerButtonController::~TabletPowerButtonController() {
80 Shell::GetInstance()->RemovePreTargetHandler(this);
81 ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
82 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
83 this);
84 }
85
86 bool TabletPowerButtonController::ShouldHandlePowerButtonEvents() const {
87 return IsTabletModeSupported();
88 }
89
90 void TabletPowerButtonController::OnPowerButtonEvent(
91 bool down,
92 const base::TimeTicks& timestamp) {
93 // When the system resumes in response to the power button being pressed,
94 // Chrome receives powerd's SuspendDone signal and notification that the
95 // backlight has been turned back on before seeing the power button events
96 // that woke the system. Ignore events just after resuming to ensure that we
97 // don't turn the screen off in response to the events.
98 if (timestamp - last_resume_time_ <=
99 base::TimeDelta::FromMilliseconds(kIgnorePowerButtonAfterResumeMs)) {
100 return;
101 }
102
103 if (down) {
104 screen_off_when_power_button_down_ = brightness_level_is_zero_;
105 SetBacklightsForcedOff(false);
106 StartShutdownTimer();
107 } else {
108 if (shutdown_timer_.IsRunning()) {
109 shutdown_timer_.Stop();
110 if (!screen_off_when_power_button_down_) {
111 SetBacklightsForcedOff(true);
112 LockScreenIfRequired();
113 }
114 }
115 screen_off_when_power_button_down_ = false;
116
117 // When power button is released, cancel shutdown animation whenever it is
118 // still cancellable.
119 if (controller_->CanCancelShutdownAnimation())
120 controller_->CancelShutdownAnimation();
121 }
122 }
123
124 void TabletPowerButtonController::PowerManagerRestarted() {
125 chromeos::DBusThreadManager::Get()
126 ->GetPowerManagerClient()
127 ->SetBacklightsForcedOff(backlights_forced_off_);
128 }
129
130 void TabletPowerButtonController::BrightnessChanged(int level,
131 bool user_initiated) {
132 brightness_level_is_zero_ = level == 0;
133 }
134
135 void TabletPowerButtonController::SuspendDone(
136 const base::TimeDelta& sleep_duration) {
137 last_resume_time_ = tick_clock_->NowTicks();
138 }
139
140 void TabletPowerButtonController::OnKeyEvent(ui::KeyEvent* event) {
141 if (!IsTabletModeActive() && backlights_forced_off_)
142 SetBacklightsForcedOff(false);
143 }
144
145 void TabletPowerButtonController::OnMouseEvent(ui::MouseEvent* event) {
146 ui::EventPointerType pointer_type = event->pointer_details().pointer_type;
147 if (pointer_type != ui::EventPointerType::POINTER_TYPE_MOUSE &&
148 pointer_type != ui::EventPointerType::POINTER_TYPE_TOUCH) {
149 return;
150 }
151
152 if (!IsTabletModeActive() && backlights_forced_off_)
153 SetBacklightsForcedOff(false);
154 }
155
156 void TabletPowerButtonController::OnStylusStateChanged(ui::StylusState state) {
157 if (IsTabletModeSupported() && state == ui::StylusState::REMOVED &&
158 backlights_forced_off_) {
159 SetBacklightsForcedOff(false);
160 }
161 }
162
163 void TabletPowerButtonController::SetTickClockForTesting(
164 std::unique_ptr<base::TickClock> tick_clock) {
165 DCHECK(tick_clock);
166 tick_clock_ = std::move(tick_clock);
167 }
168
169 void TabletPowerButtonController::SetBacklightsForcedOff(bool forced_off) {
170 if (backlights_forced_off_ == forced_off)
171 return;
172
173 chromeos::DBusThreadManager::Get()
174 ->GetPowerManagerClient()
175 ->SetBacklightsForcedOff(forced_off);
176 backlights_forced_off_ = forced_off;
177 }
178
179 void TabletPowerButtonController::GetInitialBacklightsForcedOff() {
180 chromeos::DBusThreadManager::Get()
181 ->GetPowerManagerClient()
182 ->GetBacklightsForcedOff(base::Bind(
183 &TabletPowerButtonController::OnGotInitialBacklightsForcedOff,
184 weak_ptr_factory_.GetWeakPtr()));
185 }
186
187 void TabletPowerButtonController::OnGotInitialBacklightsForcedOff(
188 bool is_forced_off) {
189 backlights_forced_off_ = is_forced_off;
190 }
191
192 void TabletPowerButtonController::StartShutdownTimer() {
193 shutdown_timer_.Start(FROM_HERE,
194 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs),
195 this, &TabletPowerButtonController::OnShutdownTimeout);
196 }
197
198 void TabletPowerButtonController::OnShutdownTimeout() {
199 controller_->StartShutdownAnimation();
200 }
201
202 void TabletPowerButtonController::LockScreenIfRequired() {
203 SessionStateDelegate* session_state_delegate =
204 WmShell::Get()->GetSessionStateDelegate();
205 if (session_state_delegate->ShouldLockScreenAutomatically() &&
206 session_state_delegate->CanLockScreen() &&
207 !session_state_delegate->IsUserSessionBlocked() &&
208 !controller_->LockRequested()) {
209 session_state_delegate->LockScreen();
210 }
211 }
212
213 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698