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

Side by Side Diff: ash/wm/power_button_controller.cc

Issue 11185006: Revert 162140 - ash : Decouple power button controller and session state controller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 2 months 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 | Annotate | Revision Log
« no previous file with comments | « ash/wm/power_button_controller.h ('k') | ash/wm/power_button_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/power_button_controller.h" 5 #include "ash/wm/power_button_controller.h"
6 6
7 #include "ash/ash_switches.h" 7 #include "ash/ash_switches.h"
8 #include "ash/shell.h" 8 #include "ash/shell.h"
9 #include "ash/shell_delegate.h" 9 #include "ash/shell_delegate.h"
10 #include "ash/shell_window_ids.h" 10 #include "ash/shell_window_ids.h"
11 #include "ash/wm/session_state_animator.h" 11 #include "ash/wm/session_state_animator.h"
12 #include "ash/wm/session_state_controller.h"
13 #include "base/command_line.h" 12 #include "base/command_line.h"
14 #include "ui/aura/root_window.h" 13 #include "ui/aura/root_window.h"
15 #include "ui/aura/shared/compound_event_filter.h" 14 #include "ui/aura/shared/compound_event_filter.h"
16 15
16 #if defined(OS_CHROMEOS)
17 #include "base/chromeos/chromeos_version.h"
18 #endif
19
17 namespace ash { 20 namespace ash {
18 21
19 PowerButtonController::PowerButtonController(SessionStateController* controller) 22 namespace {
20 : power_button_down_(false), 23
24 // Amount of time that the power button needs to be held before we lock the
25 // screen.
26 const int kLockTimeoutMs = 400;
27
28 // Amount of time that the power button needs to be held before we shut down.
29 const int kShutdownTimeoutMs = 400;
30
31 // Amount of time to wait for our lock requests to be honored before giving up.
32 const int kLockFailTimeoutMs = 4000;
33
34 // When the button has been held continuously from the unlocked state, amount of
35 // time that we wait after the screen locker window is shown before starting the
36 // pre-shutdown animation.
37 const int kLockToShutdownTimeoutMs = 150;
38
39 // Amount of time taken to scale the snapshot of the screen down to a
40 // slightly-smaller size once the user starts holding the power button. Used
41 // for both the pre-lock and pre-shutdown animations.
42 const int kSlowCloseAnimMs = 400;
43
44 // Amount of time taken to scale the snapshot of the screen back to its original
45 // size when the button is released.
46 const int kUndoSlowCloseAnimMs = 100;
47
48 // Amount of time taken to scale the snapshot down to a point in the center of
49 // the screen once the screen has been locked or we've been notified that the
50 // system is shutting down.
51 const int kFastCloseAnimMs = 150;
52
53 // Additional time (beyond kFastCloseAnimMs) to wait after starting the
54 // fast-close shutdown animation before actually requesting shutdown, to give
55 // the animation time to finish.
56 const int kShutdownRequestDelayMs = 50;
57
58 } // namespace
59
60 PowerButtonController::TestApi::TestApi(PowerButtonController* controller)
61 : controller_(controller),
62 animator_api_(new internal::SessionStateAnimator::TestApi(
63 controller->animator_.get())) {
64 }
65
66 PowerButtonController::TestApi::~TestApi() {
67 }
68
69 PowerButtonController::PowerButtonController()
70 : login_status_(user::LOGGED_IN_NONE),
71 unlocked_login_status_(user::LOGGED_IN_NONE),
72 power_button_down_(false),
21 lock_button_down_(false), 73 lock_button_down_(false),
22 screen_is_off_(false), 74 screen_is_off_(false),
75 shutting_down_(false),
23 has_legacy_power_button_( 76 has_legacy_power_button_(
24 CommandLine::ForCurrentProcess()->HasSwitch( 77 CommandLine::ForCurrentProcess()->HasSwitch(
25 switches::kAuraLegacyPowerButton)), 78 switches::kAuraLegacyPowerButton)),
26 controller_(controller) { 79 animator_(new internal::SessionStateAnimator()) {
80 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this);
27 } 81 }
28 82
29 PowerButtonController::~PowerButtonController() { 83 PowerButtonController::~PowerButtonController() {
84 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this);
85 }
86
87 void PowerButtonController::OnLoginStateChanged(user::LoginStatus status) {
88 login_status_ = status;
89 unlocked_login_status_ = user::LOGGED_IN_NONE;
90 }
91
92 void PowerButtonController::OnAppTerminating() {
93 // If we hear that Chrome is exiting but didn't request it ourselves, all we
94 // can really hope for is that we'll have time to clear the screen.
95 if (!shutting_down_) {
96 shutting_down_ = true;
97 Shell* shell = ash::Shell::GetInstance();
98 shell->env_filter()->set_cursor_hidden_by_filter(false);
99 shell->cursor_manager()->ShowCursor(false);
100 animator_->ShowBlackLayer();
101 animator_->StartAnimation(
102 internal::SessionStateAnimator::kAllContainersMask,
103 internal::SessionStateAnimator::ANIMATION_HIDE);
104 }
105 }
106
107 void PowerButtonController::OnLockStateChanged(bool locked) {
108 if (shutting_down_ || (login_status_ == user::LOGGED_IN_LOCKED) == locked)
109 return;
110
111 if (!locked && login_status_ == user::LOGGED_IN_LOCKED) {
112 login_status_ = unlocked_login_status_;
113 unlocked_login_status_ = user::LOGGED_IN_NONE;
114 } else {
115 unlocked_login_status_ = login_status_;
116 login_status_ = user::LOGGED_IN_LOCKED;
117 }
118
119 if (locked) {
120 animator_->StartAnimation(
121 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
122 internal::SessionStateAnimator::ANIMATION_FADE_IN);
123 lock_timer_.Stop();
124 lock_fail_timer_.Stop();
125
126 if (!has_legacy_power_button_ && power_button_down_) {
127 lock_to_shutdown_timer_.Stop();
128 lock_to_shutdown_timer_.Start(
129 FROM_HERE,
130 base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs),
131 this, &PowerButtonController::OnLockToShutdownTimeout);
132 }
133 } else {
134 animator_->StartAnimation(
135 internal::SessionStateAnimator::DESKTOP_BACKGROUND |
136 internal::SessionStateAnimator::LAUNCHER |
137 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
138 internal::SessionStateAnimator::ANIMATION_RESTORE);
139 animator_->DropBlackLayer();
140 }
30 } 141 }
31 142
32 void PowerButtonController::OnScreenBrightnessChanged(double percent) { 143 void PowerButtonController::OnScreenBrightnessChanged(double percent) {
33 screen_is_off_ = percent <= 0.001; 144 screen_is_off_ = percent <= 0.001;
34 } 145 }
35 146
147 void PowerButtonController::OnStartingLock() {
148 if (shutting_down_ || login_status_ == user::LOGGED_IN_LOCKED)
149 return;
150
151 // Ensure that the black layer is visible -- if the screen was locked via
152 // the wrench menu, we won't have already shown the black background
153 // as part of the slow-close animation.
154 animator_->ShowBlackLayer();
155
156 animator_->StartAnimation(
157 internal::SessionStateAnimator::LAUNCHER,
158 internal::SessionStateAnimator::ANIMATION_HIDE);
159
160 animator_->StartAnimation(
161 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
162 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE);
163
164 // Hide the screen locker containers so we can make them fade in later.
165 animator_->StartAnimation(
166 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
167 internal::SessionStateAnimator::ANIMATION_HIDE);
168 }
169
36 void PowerButtonController::OnPowerButtonEvent( 170 void PowerButtonController::OnPowerButtonEvent(
37 bool down, const base::TimeTicks& timestamp) { 171 bool down, const base::TimeTicks& timestamp) {
38 power_button_down_ = down; 172 power_button_down_ = down;
39 173
40 if (controller_->ShutdownRequested()) 174 if (shutting_down_)
41 return; 175 return;
42 176
43 // Avoid starting the lock/shutdown sequence if the power button is pressed 177 // Avoid starting the lock/shutdown sequence if the power button is pressed
44 // while the screen is off (http://crbug.com/128451). 178 // while the screen is off (http://crbug.com/128451).
45 if (screen_is_off_) 179 if (screen_is_off_)
46 return; 180 return;
47 181
48 if (has_legacy_power_button_) { 182 if (has_legacy_power_button_) {
49 // If power button releases won't get reported correctly because we're not 183 // If power button releases won't get reported correctly because we're not
50 // running on official hardware, just lock the screen or shut down 184 // running on official hardware, just lock the screen or shut down
51 // immediately. 185 // immediately.
52 if (down) { 186 if (down) {
53 if (controller_->IsEligibleForLock()) 187 animator_->ShowBlackLayer();
54 controller_->StartLockAnimationAndLockImmediately(); 188 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) {
55 else 189 animator_->StartAnimation(
56 controller_->RequestShutdown(); 190 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
191 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE);
192 OnLockTimeout();
193 } else {
194 OnShutdownTimeout();
195 }
57 } 196 }
58 } else { // !has_legacy_power_button_ 197 } else { // !has_legacy_power_button_
59 if (down) { 198 if (down) {
60 // If we already have a pending request to lock the screen, wait. 199 // If we already have a pending request to lock the screen, wait.
61 if (controller_->LockRequested()) 200 if (lock_fail_timer_.IsRunning())
62 return; 201 return;
63 202
64 if (controller_->IsEligibleForLock()) 203 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED)
65 controller_->StartLockAnimation(); 204 StartLockTimer();
66 else 205 else
67 controller_->StartShutdownAnimation(); 206 StartShutdownTimer();
68 } else { // Button is up. 207 } else { // Button is up.
69 if (controller_->CanCancelLockAnimation()) 208 if (lock_timer_.IsRunning() || shutdown_timer_.IsRunning()) {
70 controller_->CancelLockAnimation(); 209 if (login_status_ == user::LOGGED_IN_LOCKED) {
71 else if (controller_->CanCancelShutdownAnimation()) 210 // If we've already started shutdown transition at lock screen
72 controller_->CancelShutdownAnimation(); 211 // desktop background needs to be restored immediately.
212 animator_->StartAnimation(
213 internal::SessionStateAnimator::DESKTOP_BACKGROUND,
214 internal::SessionStateAnimator::ANIMATION_RESTORE);
215 }
216 animator_->StartAnimation(
217 (login_status_ == user::LOGGED_IN_LOCKED) ?
218 internal::SessionStateAnimator::kAllLockScreenContainersMask :
219 internal::SessionStateAnimator::kAllContainersMask,
220 internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE);
221 }
222
223 // Drop the black layer after the undo animation finishes.
224 if (lock_timer_.IsRunning() ||
225 (shutdown_timer_.IsRunning() && !LoggedInAsNonGuest())) {
226 animator_->ScheduleDropBlackLayer();
227 }
228
229 lock_timer_.Stop();
230 shutdown_timer_.Stop();
231 lock_to_shutdown_timer_.Stop();
73 } 232 }
74 } 233 }
75 } 234 }
76 235
77 void PowerButtonController::OnLockButtonEvent( 236 void PowerButtonController::OnLockButtonEvent(
78 bool down, const base::TimeTicks& timestamp) { 237 bool down, const base::TimeTicks& timestamp) {
79 lock_button_down_ = down; 238 lock_button_down_ = down;
80 239
81 if (controller_->ShutdownRequested() || !controller_->IsEligibleForLock()) 240 if (shutting_down_ || !LoggedInAsNonGuest())
82 return; 241 return;
83 242
84 // Bail if we're already locked or are in the process of locking. Also give 243 // Bail if we're already locked or are in the process of locking. Also give
85 // the power button precedence over the lock button (we don't expect both 244 // the power button precedence over the lock button (we don't expect both
86 // buttons to be present, so this is just making sure that we don't do 245 // buttons to be present, so this is just making sure that we don't do
87 // something completely stupid if that assumption changes later). 246 // something completely stupid if that assumption changes later).
88 if (power_button_down_) 247 if (login_status_ == user::LOGGED_IN_LOCKED ||
248 lock_fail_timer_.IsRunning() || power_button_down_)
89 return; 249 return;
90 250
91 if (controller_->IsLocked() || controller_->LockRequested()) 251 if (down) {
92 return; 252 StartLockTimer();
253 } else {
254 if (lock_timer_.IsRunning()) {
255 animator_->StartAnimation(
256 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
257 internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE);
258 animator_->ScheduleDropBlackLayer();
259 lock_timer_.Stop();
260 }
261 }
262 }
93 263
94 if (down) 264 void PowerButtonController::RequestShutdown() {
95 controller_->StartLockAnimation(); 265 if (!shutting_down_)
96 else 266 StartShutdownAnimationAndRequestShutdown();
97 controller_->CancelLockWithOtherAnimation(); 267 }
268
269 void PowerButtonController::OnRootWindowHostCloseRequested(
270 const aura::RootWindow*) {
271 if(Shell::GetInstance() && Shell::GetInstance()->delegate())
272 Shell::GetInstance()->delegate()->Exit();
273 }
274
275 bool PowerButtonController::LoggedInAsNonGuest() const {
276 if (login_status_ == user::LOGGED_IN_NONE)
277 return false;
278 if (login_status_ == user::LOGGED_IN_GUEST)
279 return false;
280 // TODO(mukai): think about kiosk mode.
281 return true;
282 }
283
284 void PowerButtonController::OnLockTimeout() {
285 delegate_->RequestLockScreen();
286 lock_fail_timer_.Start(
287 FROM_HERE,
288 base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs),
289 this, &PowerButtonController::OnLockFailTimeout);
290 }
291
292 void PowerButtonController::OnLockFailTimeout() {
293 DCHECK_NE(login_status_, user::LOGGED_IN_LOCKED);
294 LOG(ERROR) << "Screen lock request timed out";
295 animator_->StartAnimation(
296 internal::SessionStateAnimator::LAUNCHER |
297 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
298 internal::SessionStateAnimator::ANIMATION_RESTORE);
299 animator_->DropBlackLayer();
300 }
301
302 void PowerButtonController::OnLockToShutdownTimeout() {
303 DCHECK_EQ(login_status_, user::LOGGED_IN_LOCKED);
304 StartShutdownTimer();
305 }
306
307 void PowerButtonController::OnShutdownTimeout() {
308 if (!shutting_down_)
309 StartShutdownAnimationAndRequestShutdown();
310 }
311
312 void PowerButtonController::OnRealShutdownTimeout() {
313 DCHECK(shutting_down_);
314 #if defined(OS_CHROMEOS)
315 if (!base::chromeos::IsRunningOnChromeOS()) {
316 ShellDelegate* delegate = Shell::GetInstance()->delegate();
317 if (delegate)
318 delegate->Exit();
319 }
320 #endif
321 delegate_->RequestShutdown();
322 }
323
324 void PowerButtonController::StartLockTimer() {
325 animator_->ShowBlackLayer();
326 animator_->StartAnimation(
327 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
328 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE);
329 lock_timer_.Stop();
330 lock_timer_.Start(FROM_HERE,
331 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs),
332 this, &PowerButtonController::OnLockTimeout);
333 }
334
335 void PowerButtonController::StartShutdownTimer() {
336 animator_->ShowBlackLayer();
337 animator_->StartAnimation(
338 internal::SessionStateAnimator::kAllContainersMask,
339 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE);
340 shutdown_timer_.Stop();
341 shutdown_timer_.Start(
342 FROM_HERE,
343 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs),
344 this, &PowerButtonController::OnShutdownTimeout);
345 }
346
347 void PowerButtonController::StartShutdownAnimationAndRequestShutdown() {
348 DCHECK(!shutting_down_);
349 shutting_down_ = true;
350
351 Shell* shell = ash::Shell::GetInstance();
352 shell->env_filter()->set_cursor_hidden_by_filter(false);
353 shell->cursor_manager()->ShowCursor(false);
354
355 animator_->ShowBlackLayer();
356 if (login_status_ != user::LOGGED_IN_NONE) {
357 // Hide the other containers before starting the animation.
358 // ANIMATION_FAST_CLOSE will make the screen locker windows partially
359 // transparent, and we don't want the other windows to show through.
360 animator_->StartAnimation(
361 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
362 internal::SessionStateAnimator::LAUNCHER,
363 internal::SessionStateAnimator::ANIMATION_HIDE);
364 animator_->StartAnimation(
365 internal::SessionStateAnimator::kAllLockScreenContainersMask,
366 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE);
367 } else {
368 animator_->StartAnimation(
369 internal::SessionStateAnimator::kAllContainersMask,
370 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE);
371 }
372
373 real_shutdown_timer_.Start(
374 FROM_HERE,
375 base::TimeDelta::FromMilliseconds(
376 kFastCloseAnimMs + kShutdownRequestDelayMs),
377 this, &PowerButtonController::OnRealShutdownTimeout);
98 } 378 }
99 379
100 } // namespace ash 380 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/power_button_controller.h ('k') | ash/wm/power_button_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698