OLD | NEW |
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/cursor_manager.h" | 11 #include "ash/wm/session_state_animator.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/logging.h" | |
14 #include "base/time.h" | |
15 #include "third_party/skia/include/core/SkColor.h" | |
16 #include "ui/aura/env.h" | |
17 #include "ui/aura/root_window.h" | 13 #include "ui/aura/root_window.h" |
18 #include "ui/aura/shared/compound_event_filter.h" | 14 #include "ui/aura/shared/compound_event_filter.h" |
19 #include "ui/aura/window.h" | |
20 #include "ui/compositor/layer.h" | |
21 #include "ui/compositor/layer_animation_element.h" | |
22 #include "ui/compositor/layer_animation_sequence.h" | |
23 #include "ui/compositor/layer_animator.h" | |
24 #include "ui/gfx/canvas.h" | |
25 #include "ui/gfx/rect.h" | |
26 #include "ui/gfx/size.h" | |
27 #include "ui/gfx/transform.h" | |
28 | 15 |
29 namespace ash { | 16 namespace ash { |
30 | 17 |
31 namespace { | 18 namespace { |
32 | 19 |
33 // Amount of time that the power button needs to be held before we lock the | 20 // Amount of time that the power button needs to be held before we lock the |
34 // screen. | 21 // screen. |
35 const int kLockTimeoutMs = 400; | 22 const int kLockTimeoutMs = 400; |
36 | 23 |
37 // Amount of time that the power button needs to be held before we shut down. | 24 // Amount of time that the power button needs to be held before we shut down. |
(...skipping 14 matching lines...) Expand all Loading... |
52 | 39 |
53 // Amount of time taken to scale the snapshot of the screen back to its original | 40 // Amount of time taken to scale the snapshot of the screen back to its original |
54 // size when the button is released. | 41 // size when the button is released. |
55 const int kUndoSlowCloseAnimMs = 100; | 42 const int kUndoSlowCloseAnimMs = 100; |
56 | 43 |
57 // Amount of time taken to scale the snapshot down to a point in the center of | 44 // Amount of time taken to scale the snapshot down to a point in the center of |
58 // the screen once the screen has been locked or we've been notified that the | 45 // the screen once the screen has been locked or we've been notified that the |
59 // system is shutting down. | 46 // system is shutting down. |
60 const int kFastCloseAnimMs = 150; | 47 const int kFastCloseAnimMs = 150; |
61 | 48 |
62 // Amount of time taken to make the lock window fade in when the screen is | |
63 // locked. | |
64 const int kLockFadeInAnimMs = 200; | |
65 | |
66 // Additional time (beyond kFastCloseAnimMs) to wait after starting the | 49 // Additional time (beyond kFastCloseAnimMs) to wait after starting the |
67 // fast-close shutdown animation before actually requesting shutdown, to give | 50 // fast-close shutdown animation before actually requesting shutdown, to give |
68 // the animation time to finish. | 51 // the animation time to finish. |
69 const int kShutdownRequestDelayMs = 50; | 52 const int kShutdownRequestDelayMs = 50; |
70 | 53 |
71 // Slightly-smaller size that we scale the screen down to for the pre-lock and | 54 } // namespace |
72 // pre-shutdown states. | |
73 const float kSlowCloseSizeRatio = 0.95f; | |
74 | 55 |
75 // Returns the transform that should be applied to containers for the slow-close | 56 PowerButtonController::TestApi::TestApi(PowerButtonController* controller) |
76 // animation. | 57 : controller_(controller), |
77 ui::Transform GetSlowCloseTransform() { | 58 animator_api_(new internal::SessionStateAnimator::TestApi( |
78 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size(); | 59 controller->animator_.get())) { |
79 ui::Transform transform; | |
80 transform.SetScale(kSlowCloseSizeRatio, kSlowCloseSizeRatio); | |
81 transform.ConcatTranslate( | |
82 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5), | |
83 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5)); | |
84 return transform; | |
85 } | 60 } |
86 | 61 |
87 // Returns the transform that should be applied to containers for the fast-close | 62 PowerButtonController::TestApi::~TestApi() { |
88 // animation. | |
89 ui::Transform GetFastCloseTransform() { | |
90 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size(); | |
91 ui::Transform transform; | |
92 transform.SetScale(0.0, 0.0); | |
93 transform.ConcatTranslate(floor(0.5 * root_size.width() + 0.5), | |
94 floor(0.5 * root_size.height() + 0.5)); | |
95 return transform; | |
96 } | |
97 | |
98 // Slowly shrinks |window| to a slightly-smaller size. | |
99 void StartSlowCloseAnimationForWindow(aura::Window* window) { | |
100 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | |
101 animator->set_preemption_strategy( | |
102 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
103 animator->StartAnimation( | |
104 new ui::LayerAnimationSequence( | |
105 ui::LayerAnimationElement::CreateTransformElement( | |
106 GetSlowCloseTransform(), | |
107 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs)))); | |
108 } | |
109 | |
110 // Quickly undoes the effects of the slow-close animation on |window|. | |
111 void StartUndoSlowCloseAnimationForWindow(aura::Window* window) { | |
112 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | |
113 animator->set_preemption_strategy( | |
114 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
115 animator->StartAnimation( | |
116 new ui::LayerAnimationSequence( | |
117 ui::LayerAnimationElement::CreateTransformElement( | |
118 ui::Transform(), | |
119 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs)))); | |
120 } | |
121 | |
122 // Quickly shrinks |window| down to a point in the center of the screen and | |
123 // fades it out to 0 opacity. | |
124 void StartFastCloseAnimationForWindow(aura::Window* window) { | |
125 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | |
126 animator->set_preemption_strategy( | |
127 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
128 animator->StartAnimation( | |
129 new ui::LayerAnimationSequence( | |
130 ui::LayerAnimationElement::CreateTransformElement( | |
131 GetFastCloseTransform(), | |
132 base::TimeDelta::FromMilliseconds(kFastCloseAnimMs)))); | |
133 animator->StartAnimation( | |
134 new ui::LayerAnimationSequence( | |
135 ui::LayerAnimationElement::CreateOpacityElement( | |
136 0.0, base::TimeDelta::FromMilliseconds(kFastCloseAnimMs)))); | |
137 } | |
138 | |
139 // Fades |window| in to full opacity. | |
140 void FadeInWindow(aura::Window* window) { | |
141 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | |
142 animator->set_preemption_strategy( | |
143 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
144 animator->StartAnimation( | |
145 new ui::LayerAnimationSequence( | |
146 ui::LayerAnimationElement::CreateOpacityElement( | |
147 1.0, base::TimeDelta::FromMilliseconds(kLockFadeInAnimMs)))); | |
148 } | |
149 | |
150 // Makes |window| fully transparent instantaneously. | |
151 void HideWindow(aura::Window* window) { | |
152 window->layer()->SetOpacity(0.0); | |
153 } | |
154 | |
155 // Restores |window| to its original position and scale and full opacity | |
156 // instantaneously. | |
157 void RestoreWindow(aura::Window* window) { | |
158 window->layer()->SetTransform(ui::Transform()); | |
159 window->layer()->SetOpacity(1.0); | |
160 } | |
161 | |
162 // Fills |containers| with the containers described by |container_mask|. | |
163 void GetContainers(int container_mask, aura::Window::Windows* containers) { | |
164 aura::RootWindow* root_window = Shell::GetPrimaryRootWindow(); | |
165 containers->clear(); | |
166 | |
167 if (container_mask & PowerButtonController::DESKTOP_BACKGROUND) { | |
168 containers->push_back(Shell::GetContainer( | |
169 root_window, | |
170 internal::kShellWindowId_DesktopBackgroundContainer)); | |
171 } | |
172 if (container_mask & PowerButtonController::LAUNCHER) { | |
173 containers->push_back(Shell::GetContainer( | |
174 root_window, | |
175 internal::kShellWindowId_LauncherContainer)); | |
176 } | |
177 if (container_mask & PowerButtonController::NON_LOCK_SCREEN_CONTAINERS) { | |
178 // TODO(antrim): Figure out a way to eliminate a need to exclude launcher | |
179 // in such way. | |
180 aura::Window* non_lock_screen_containers = Shell::GetContainer( | |
181 root_window, | |
182 internal::kShellWindowId_NonLockScreenContainersContainer); | |
183 aura::Window::Windows children = non_lock_screen_containers->children(); | |
184 | |
185 for (aura::Window::Windows::const_iterator it = children.begin(); | |
186 it != children.end(); ++it) { | |
187 aura::Window* window = *it; | |
188 if (window->id() == internal::kShellWindowId_LauncherContainer) | |
189 continue; | |
190 containers->push_back(window); | |
191 } | |
192 } | |
193 if (container_mask & PowerButtonController::LOCK_SCREEN_BACKGROUND) { | |
194 containers->push_back(Shell::GetContainer( | |
195 root_window, | |
196 internal::kShellWindowId_LockScreenBackgroundContainer)); | |
197 } | |
198 if (container_mask & PowerButtonController::LOCK_SCREEN_CONTAINERS) { | |
199 containers->push_back(Shell::GetContainer( | |
200 root_window, | |
201 internal::kShellWindowId_LockScreenContainersContainer)); | |
202 } | |
203 if (container_mask & PowerButtonController::LOCK_SCREEN_RELATED_CONTAINERS) { | |
204 containers->push_back(Shell::GetContainer( | |
205 root_window, | |
206 internal::kShellWindowId_LockScreenRelatedContainersContainer)); | |
207 } | |
208 } | |
209 | |
210 // Apply animation |type| to all containers described by |container_mask|. | |
211 void StartAnimation(int container_mask, | |
212 PowerButtonController::AnimationType type) { | |
213 aura::Window::Windows containers; | |
214 GetContainers(container_mask, &containers); | |
215 | |
216 for (aura::Window::Windows::const_iterator it = containers.begin(); | |
217 it != containers.end(); ++it) { | |
218 aura::Window* window = *it; | |
219 switch (type) { | |
220 case PowerButtonController::ANIMATION_SLOW_CLOSE: | |
221 StartSlowCloseAnimationForWindow(window); | |
222 break; | |
223 case PowerButtonController::ANIMATION_UNDO_SLOW_CLOSE: | |
224 StartUndoSlowCloseAnimationForWindow(window); | |
225 break; | |
226 case PowerButtonController::ANIMATION_FAST_CLOSE: | |
227 StartFastCloseAnimationForWindow(window); | |
228 break; | |
229 case PowerButtonController::ANIMATION_FADE_IN: | |
230 FadeInWindow(window); | |
231 break; | |
232 case PowerButtonController::ANIMATION_HIDE: | |
233 HideWindow(window); | |
234 break; | |
235 case PowerButtonController::ANIMATION_RESTORE: | |
236 RestoreWindow(window); | |
237 break; | |
238 default: | |
239 NOTREACHED() << "Unhandled animation type " << type; | |
240 } | |
241 } | |
242 } | |
243 | |
244 } // namespace | |
245 | |
246 bool PowerButtonController::TestApi::ContainersAreAnimated( | |
247 int container_mask, AnimationType type) const { | |
248 aura::Window::Windows containers; | |
249 GetContainers(container_mask, &containers); | |
250 for (aura::Window::Windows::const_iterator it = containers.begin(); | |
251 it != containers.end(); ++it) { | |
252 aura::Window* window = *it; | |
253 ui::Layer* layer = window->layer(); | |
254 | |
255 switch (type) { | |
256 case PowerButtonController::ANIMATION_SLOW_CLOSE: | |
257 if (layer->GetTargetTransform() != GetSlowCloseTransform()) | |
258 return false; | |
259 break; | |
260 case PowerButtonController::ANIMATION_UNDO_SLOW_CLOSE: | |
261 if (layer->GetTargetTransform() != ui::Transform()) | |
262 return false; | |
263 break; | |
264 case PowerButtonController::ANIMATION_FAST_CLOSE: | |
265 if (layer->GetTargetTransform() != GetFastCloseTransform() || | |
266 layer->GetTargetOpacity() > 0.0001) | |
267 return false; | |
268 break; | |
269 case PowerButtonController::ANIMATION_FADE_IN: | |
270 if (layer->GetTargetOpacity() < 0.9999) | |
271 return false; | |
272 break; | |
273 case PowerButtonController::ANIMATION_HIDE: | |
274 if (layer->GetTargetOpacity() > 0.0001) | |
275 return false; | |
276 break; | |
277 case PowerButtonController::ANIMATION_RESTORE: | |
278 if (layer->opacity() < 0.9999 || layer->transform() != ui::Transform()) | |
279 return false; | |
280 break; | |
281 default: | |
282 NOTREACHED() << "Unhandled animation type " << type; | |
283 return false; | |
284 } | |
285 } | |
286 return true; | |
287 } | |
288 | |
289 bool PowerButtonController::TestApi::BlackLayerIsVisible() const { | |
290 return controller_->black_layer_.get() && | |
291 controller_->black_layer_->visible(); | |
292 } | |
293 | |
294 gfx::Rect PowerButtonController::TestApi::GetBlackLayerBounds() const { | |
295 ui::Layer* layer = controller_->black_layer_.get(); | |
296 return layer ? layer->bounds() : gfx::Rect(); | |
297 } | |
298 | |
299 // static | |
300 int PowerButtonController::GetAllContainersMask() { | |
301 return PowerButtonController::DESKTOP_BACKGROUND | | |
302 PowerButtonController::LAUNCHER | | |
303 PowerButtonController::NON_LOCK_SCREEN_CONTAINERS | | |
304 GetAllLockScreenContainersMask(); | |
305 } | |
306 | |
307 // static | |
308 int PowerButtonController::GetAllLockScreenContainersMask() { | |
309 return PowerButtonController::LOCK_SCREEN_BACKGROUND | | |
310 PowerButtonController::LOCK_SCREEN_CONTAINERS | | |
311 PowerButtonController::LOCK_SCREEN_RELATED_CONTAINERS; | |
312 } | 63 } |
313 | 64 |
314 PowerButtonController::PowerButtonController() | 65 PowerButtonController::PowerButtonController() |
315 : login_status_(user::LOGGED_IN_NONE), | 66 : login_status_(user::LOGGED_IN_NONE), |
316 unlocked_login_status_(user::LOGGED_IN_NONE), | 67 unlocked_login_status_(user::LOGGED_IN_NONE), |
317 power_button_down_(false), | 68 power_button_down_(false), |
318 lock_button_down_(false), | 69 lock_button_down_(false), |
319 screen_is_off_(false), | 70 screen_is_off_(false), |
320 shutting_down_(false), | 71 shutting_down_(false), |
321 has_legacy_power_button_( | 72 has_legacy_power_button_( |
322 CommandLine::ForCurrentProcess()->HasSwitch( | 73 CommandLine::ForCurrentProcess()->HasSwitch( |
323 switches::kAuraLegacyPowerButton)) { | 74 switches::kAuraLegacyPowerButton)), |
| 75 animator_(new internal::SessionStateAnimator()) { |
324 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this); | 76 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this); |
325 } | 77 } |
326 | 78 |
327 PowerButtonController::~PowerButtonController() { | 79 PowerButtonController::~PowerButtonController() { |
328 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this); | 80 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this); |
329 } | 81 } |
330 | 82 |
331 void PowerButtonController::OnLoginStateChanged(user::LoginStatus status) { | 83 void PowerButtonController::OnLoginStateChanged(user::LoginStatus status) { |
332 login_status_ = status; | 84 login_status_ = status; |
333 unlocked_login_status_ = user::LOGGED_IN_NONE; | 85 unlocked_login_status_ = user::LOGGED_IN_NONE; |
334 } | 86 } |
335 | 87 |
336 void PowerButtonController::OnAppTerminating() { | 88 void PowerButtonController::OnAppTerminating() { |
337 // If we hear that Chrome is exiting but didn't request it ourselves, all we | 89 // If we hear that Chrome is exiting but didn't request it ourselves, all we |
338 // can really hope for is that we'll have time to clear the screen. | 90 // can really hope for is that we'll have time to clear the screen. |
339 if (!shutting_down_) { | 91 if (!shutting_down_) { |
340 shutting_down_ = true; | 92 shutting_down_ = true; |
341 Shell* shell = ash::Shell::GetInstance(); | 93 Shell* shell = ash::Shell::GetInstance(); |
342 shell->env_filter()->set_cursor_hidden_by_filter(false); | 94 shell->env_filter()->set_cursor_hidden_by_filter(false); |
343 shell->cursor_manager()->ShowCursor(false); | 95 shell->cursor_manager()->ShowCursor(false); |
344 ShowBlackLayer(); | 96 animator_->ShowBlackLayer(); |
345 StartAnimation(GetAllContainersMask(), ANIMATION_HIDE); | 97 animator_->StartAnimation( |
| 98 internal::SessionStateAnimator::kAllContainersMask, |
| 99 internal::SessionStateAnimator::ANIMATION_HIDE); |
346 } | 100 } |
347 } | 101 } |
348 | 102 |
349 void PowerButtonController::OnLockStateChanged(bool locked) { | 103 void PowerButtonController::OnLockStateChanged(bool locked) { |
350 if (shutting_down_ || (login_status_ == user::LOGGED_IN_LOCKED) == locked) | 104 if (shutting_down_ || (login_status_ == user::LOGGED_IN_LOCKED) == locked) |
351 return; | 105 return; |
352 | 106 |
353 if (!locked && login_status_ == user::LOGGED_IN_LOCKED) { | 107 if (!locked && login_status_ == user::LOGGED_IN_LOCKED) { |
354 login_status_ = unlocked_login_status_; | 108 login_status_ = unlocked_login_status_; |
355 unlocked_login_status_ = user::LOGGED_IN_NONE; | 109 unlocked_login_status_ = user::LOGGED_IN_NONE; |
356 } else { | 110 } else { |
357 unlocked_login_status_ = login_status_; | 111 unlocked_login_status_ = login_status_; |
358 login_status_ = user::LOGGED_IN_LOCKED; | 112 login_status_ = user::LOGGED_IN_LOCKED; |
359 } | 113 } |
360 | 114 |
361 if (locked) { | 115 if (locked) { |
362 StartAnimation(LOCK_SCREEN_CONTAINERS, ANIMATION_FADE_IN); | 116 animator_->StartAnimation( |
| 117 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
| 118 internal::SessionStateAnimator::ANIMATION_FADE_IN); |
363 lock_timer_.Stop(); | 119 lock_timer_.Stop(); |
364 lock_fail_timer_.Stop(); | 120 lock_fail_timer_.Stop(); |
365 | 121 |
366 if (!has_legacy_power_button_ && power_button_down_) { | 122 if (!has_legacy_power_button_ && power_button_down_) { |
367 lock_to_shutdown_timer_.Stop(); | 123 lock_to_shutdown_timer_.Stop(); |
368 lock_to_shutdown_timer_.Start( | 124 lock_to_shutdown_timer_.Start( |
369 FROM_HERE, | 125 FROM_HERE, |
370 base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs), | 126 base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs), |
371 this, &PowerButtonController::OnLockToShutdownTimeout); | 127 this, &PowerButtonController::OnLockToShutdownTimeout); |
372 } | 128 } |
373 } else { | 129 } else { |
374 StartAnimation(DESKTOP_BACKGROUND | LAUNCHER | NON_LOCK_SCREEN_CONTAINERS, | 130 animator_->StartAnimation( |
375 ANIMATION_RESTORE); | 131 internal::SessionStateAnimator::DESKTOP_BACKGROUND | |
376 HideBlackLayer(); | 132 internal::SessionStateAnimator::LAUNCHER | |
| 133 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 134 internal::SessionStateAnimator::ANIMATION_RESTORE); |
| 135 animator_->DropBlackLayer(); |
377 } | 136 } |
378 } | 137 } |
379 | 138 |
380 void PowerButtonController::OnScreenBrightnessChanged(double percent) { | 139 void PowerButtonController::OnScreenBrightnessChanged(double percent) { |
381 screen_is_off_ = percent <= 0.001; | 140 screen_is_off_ = percent <= 0.001; |
382 } | 141 } |
383 | 142 |
384 void PowerButtonController::OnStartingLock() { | 143 void PowerButtonController::OnStartingLock() { |
385 if (shutting_down_ || login_status_ == user::LOGGED_IN_LOCKED) | 144 if (shutting_down_ || login_status_ == user::LOGGED_IN_LOCKED) |
386 return; | 145 return; |
387 | 146 |
388 // Ensure that the black layer is visible -- if the screen was locked via | 147 // Ensure that the black layer is visible -- if the screen was locked via |
389 // the wrench menu, we won't have already shown the black background | 148 // the wrench menu, we won't have already shown the black background |
390 // as part of the slow-close animation. | 149 // as part of the slow-close animation. |
391 ShowBlackLayer(); | 150 animator_->ShowBlackLayer(); |
392 | 151 |
393 StartAnimation(LAUNCHER, ANIMATION_HIDE); | 152 animator_->StartAnimation( |
| 153 internal::SessionStateAnimator::LAUNCHER, |
| 154 internal::SessionStateAnimator::ANIMATION_HIDE); |
394 | 155 |
395 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_FAST_CLOSE); | 156 animator_->StartAnimation( |
| 157 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 158 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); |
396 | 159 |
397 // Hide the screen locker containers so we can make them fade in later. | 160 // Hide the screen locker containers so we can make them fade in later. |
398 StartAnimation(LOCK_SCREEN_CONTAINERS, ANIMATION_HIDE); | 161 animator_->StartAnimation( |
| 162 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
| 163 internal::SessionStateAnimator::ANIMATION_HIDE); |
399 } | 164 } |
400 | 165 |
401 void PowerButtonController::OnPowerButtonEvent( | 166 void PowerButtonController::OnPowerButtonEvent( |
402 bool down, const base::TimeTicks& timestamp) { | 167 bool down, const base::TimeTicks& timestamp) { |
403 power_button_down_ = down; | 168 power_button_down_ = down; |
404 | 169 |
405 if (shutting_down_) | 170 if (shutting_down_) |
406 return; | 171 return; |
407 | 172 |
408 // Avoid starting the lock/shutdown sequence if the power button is pressed | 173 // Avoid starting the lock/shutdown sequence if the power button is pressed |
409 // while the screen is off (http://crbug.com/128451). | 174 // while the screen is off (http://crbug.com/128451). |
410 if (screen_is_off_) | 175 if (screen_is_off_) |
411 return; | 176 return; |
412 | 177 |
413 if (has_legacy_power_button_) { | 178 if (has_legacy_power_button_) { |
414 // If power button releases won't get reported correctly because we're not | 179 // If power button releases won't get reported correctly because we're not |
415 // running on official hardware, just lock the screen or shut down | 180 // running on official hardware, just lock the screen or shut down |
416 // immediately. | 181 // immediately. |
417 if (down) { | 182 if (down) { |
418 ShowBlackLayer(); | 183 animator_->ShowBlackLayer(); |
419 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) { | 184 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) { |
420 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_SLOW_CLOSE); | 185 animator_->StartAnimation( |
| 186 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 187 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
421 OnLockTimeout(); | 188 OnLockTimeout(); |
422 } else { | 189 } else { |
423 OnShutdownTimeout(); | 190 OnShutdownTimeout(); |
424 } | 191 } |
425 } | 192 } |
426 } else { // !has_legacy_power_button_ | 193 } else { // !has_legacy_power_button_ |
427 if (down) { | 194 if (down) { |
428 // If we already have a pending request to lock the screen, wait. | 195 // If we already have a pending request to lock the screen, wait. |
429 if (lock_fail_timer_.IsRunning()) | 196 if (lock_fail_timer_.IsRunning()) |
430 return; | 197 return; |
431 | 198 |
432 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) | 199 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) |
433 StartLockTimer(); | 200 StartLockTimer(); |
434 else | 201 else |
435 StartShutdownTimer(); | 202 StartShutdownTimer(); |
436 } else { // Button is up. | 203 } else { // Button is up. |
437 if (lock_timer_.IsRunning() || shutdown_timer_.IsRunning()) { | 204 if (lock_timer_.IsRunning() || shutdown_timer_.IsRunning()) { |
438 if (login_status_ == user::LOGGED_IN_LOCKED) { | 205 if (login_status_ == user::LOGGED_IN_LOCKED) { |
439 // If we've already started shutdown transition at lock screen | 206 // If we've already started shutdown transition at lock screen |
440 // desktop background needs to be restored immediately. | 207 // desktop background needs to be restored immediately. |
441 StartAnimation(DESKTOP_BACKGROUND, ANIMATION_RESTORE); | 208 animator_->StartAnimation( |
| 209 internal::SessionStateAnimator::DESKTOP_BACKGROUND, |
| 210 internal::SessionStateAnimator::ANIMATION_RESTORE); |
442 } | 211 } |
443 StartAnimation( | 212 animator_->StartAnimation( |
444 (login_status_ == user::LOGGED_IN_LOCKED) ? | 213 (login_status_ == user::LOGGED_IN_LOCKED) ? |
445 GetAllLockScreenContainersMask() : GetAllContainersMask(), | 214 internal::SessionStateAnimator::kAllLockScreenContainersMask : |
446 ANIMATION_UNDO_SLOW_CLOSE); | 215 internal::SessionStateAnimator::kAllContainersMask, |
| 216 internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); |
447 } | 217 } |
448 | 218 |
449 // Drop the black layer after the undo animation finishes. | 219 // Drop the black layer after the undo animation finishes. |
450 if (lock_timer_.IsRunning() || | 220 if (lock_timer_.IsRunning() || |
451 (shutdown_timer_.IsRunning() && !LoggedInAsNonGuest())) { | 221 (shutdown_timer_.IsRunning() && !LoggedInAsNonGuest())) { |
452 hide_black_layer_timer_.Stop(); | 222 animator_->ScheduleDropBlackLayer(); |
453 hide_black_layer_timer_.Start( | |
454 FROM_HERE, | |
455 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs), | |
456 this, &PowerButtonController::HideBlackLayer); | |
457 } | 223 } |
458 | 224 |
459 lock_timer_.Stop(); | 225 lock_timer_.Stop(); |
460 shutdown_timer_.Stop(); | 226 shutdown_timer_.Stop(); |
461 lock_to_shutdown_timer_.Stop(); | 227 lock_to_shutdown_timer_.Stop(); |
462 } | 228 } |
463 } | 229 } |
464 } | 230 } |
465 | 231 |
466 void PowerButtonController::OnLockButtonEvent( | 232 void PowerButtonController::OnLockButtonEvent( |
467 bool down, const base::TimeTicks& timestamp) { | 233 bool down, const base::TimeTicks& timestamp) { |
468 lock_button_down_ = down; | 234 lock_button_down_ = down; |
469 | 235 |
470 if (shutting_down_ || !LoggedInAsNonGuest()) | 236 if (shutting_down_ || !LoggedInAsNonGuest()) |
471 return; | 237 return; |
472 | 238 |
473 // Bail if we're already locked or are in the process of locking. Also give | 239 // Bail if we're already locked or are in the process of locking. Also give |
474 // the power button precedence over the lock button (we don't expect both | 240 // the power button precedence over the lock button (we don't expect both |
475 // buttons to be present, so this is just making sure that we don't do | 241 // buttons to be present, so this is just making sure that we don't do |
476 // something completely stupid if that assumption changes later). | 242 // something completely stupid if that assumption changes later). |
477 if (login_status_ == user::LOGGED_IN_LOCKED || | 243 if (login_status_ == user::LOGGED_IN_LOCKED || |
478 lock_fail_timer_.IsRunning() || power_button_down_) | 244 lock_fail_timer_.IsRunning() || power_button_down_) |
479 return; | 245 return; |
480 | 246 |
481 if (down) { | 247 if (down) { |
482 StartLockTimer(); | 248 StartLockTimer(); |
483 } else { | 249 } else { |
484 if (lock_timer_.IsRunning()) { | 250 if (lock_timer_.IsRunning()) { |
485 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_UNDO_SLOW_CLOSE); | 251 animator_->StartAnimation( |
486 hide_black_layer_timer_.Stop(); | 252 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
487 hide_black_layer_timer_.Start( | 253 internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); |
488 FROM_HERE, | 254 animator_->ScheduleDropBlackLayer(); |
489 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs), | |
490 this, &PowerButtonController::HideBlackLayer); | |
491 lock_timer_.Stop(); | 255 lock_timer_.Stop(); |
492 } | 256 } |
493 } | 257 } |
494 } | 258 } |
495 | 259 |
496 void PowerButtonController::RequestShutdown() { | 260 void PowerButtonController::RequestShutdown() { |
497 if (!shutting_down_) | 261 if (!shutting_down_) |
498 StartShutdownAnimationAndRequestShutdown(); | 262 StartShutdownAnimationAndRequestShutdown(); |
499 } | 263 } |
500 | 264 |
501 void PowerButtonController::OnRootWindowResized(const aura::RootWindow* root, | |
502 const gfx::Size& new_size) { | |
503 if (black_layer_.get()) | |
504 black_layer_->SetBounds(gfx::Rect(root->bounds().size())); | |
505 } | |
506 | |
507 void PowerButtonController::OnRootWindowHostCloseRequested( | 265 void PowerButtonController::OnRootWindowHostCloseRequested( |
508 const aura::RootWindow*) { | 266 const aura::RootWindow*) { |
509 if(Shell::GetInstance() && Shell::GetInstance()->delegate()) | 267 if(Shell::GetInstance() && Shell::GetInstance()->delegate()) |
510 Shell::GetInstance()->delegate()->Exit(); | 268 Shell::GetInstance()->delegate()->Exit(); |
511 } | 269 } |
512 | 270 |
513 bool PowerButtonController::LoggedInAsNonGuest() const { | 271 bool PowerButtonController::LoggedInAsNonGuest() const { |
514 if (login_status_ == user::LOGGED_IN_NONE) | 272 if (login_status_ == user::LOGGED_IN_NONE) |
515 return false; | 273 return false; |
516 if (login_status_ == user::LOGGED_IN_GUEST) | 274 if (login_status_ == user::LOGGED_IN_GUEST) |
517 return false; | 275 return false; |
518 // TODO(mukai): think about kiosk mode. | 276 // TODO(mukai): think about kiosk mode. |
519 return true; | 277 return true; |
520 } | 278 } |
521 | 279 |
522 void PowerButtonController::OnLockTimeout() { | 280 void PowerButtonController::OnLockTimeout() { |
523 delegate_->RequestLockScreen(); | 281 delegate_->RequestLockScreen(); |
524 lock_fail_timer_.Start( | 282 lock_fail_timer_.Start( |
525 FROM_HERE, | 283 FROM_HERE, |
526 base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs), | 284 base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs), |
527 this, &PowerButtonController::OnLockFailTimeout); | 285 this, &PowerButtonController::OnLockFailTimeout); |
528 } | 286 } |
529 | 287 |
530 void PowerButtonController::OnLockFailTimeout() { | 288 void PowerButtonController::OnLockFailTimeout() { |
531 DCHECK_NE(login_status_, user::LOGGED_IN_LOCKED); | 289 DCHECK_NE(login_status_, user::LOGGED_IN_LOCKED); |
532 LOG(ERROR) << "Screen lock request timed out"; | 290 LOG(ERROR) << "Screen lock request timed out"; |
533 StartAnimation(LAUNCHER | NON_LOCK_SCREEN_CONTAINERS, ANIMATION_RESTORE); | 291 animator_->StartAnimation( |
534 HideBlackLayer(); | 292 internal::SessionStateAnimator::LAUNCHER | |
| 293 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 294 internal::SessionStateAnimator::ANIMATION_RESTORE); |
| 295 animator_->DropBlackLayer(); |
535 } | 296 } |
536 | 297 |
537 void PowerButtonController::OnLockToShutdownTimeout() { | 298 void PowerButtonController::OnLockToShutdownTimeout() { |
538 DCHECK_EQ(login_status_, user::LOGGED_IN_LOCKED); | 299 DCHECK_EQ(login_status_, user::LOGGED_IN_LOCKED); |
539 StartShutdownTimer(); | 300 StartShutdownTimer(); |
540 } | 301 } |
541 | 302 |
542 void PowerButtonController::OnShutdownTimeout() { | 303 void PowerButtonController::OnShutdownTimeout() { |
543 if (!shutting_down_) | 304 if (!shutting_down_) |
544 StartShutdownAnimationAndRequestShutdown(); | 305 StartShutdownAnimationAndRequestShutdown(); |
545 } | 306 } |
546 | 307 |
547 void PowerButtonController::OnRealShutdownTimeout() { | 308 void PowerButtonController::OnRealShutdownTimeout() { |
548 DCHECK(shutting_down_); | 309 DCHECK(shutting_down_); |
549 delegate_->RequestShutdown(); | 310 delegate_->RequestShutdown(); |
550 } | 311 } |
551 | 312 |
552 void PowerButtonController::StartLockTimer() { | 313 void PowerButtonController::StartLockTimer() { |
553 ShowBlackLayer(); | 314 animator_->ShowBlackLayer(); |
554 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_SLOW_CLOSE); | 315 animator_->StartAnimation( |
| 316 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 317 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
555 lock_timer_.Stop(); | 318 lock_timer_.Stop(); |
556 lock_timer_.Start(FROM_HERE, | 319 lock_timer_.Start(FROM_HERE, |
557 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs), | 320 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs), |
558 this, &PowerButtonController::OnLockTimeout); | 321 this, &PowerButtonController::OnLockTimeout); |
559 } | 322 } |
560 | 323 |
561 void PowerButtonController::StartShutdownTimer() { | 324 void PowerButtonController::StartShutdownTimer() { |
562 ShowBlackLayer(); | 325 animator_->ShowBlackLayer(); |
563 StartAnimation(GetAllContainersMask(), ANIMATION_SLOW_CLOSE); | 326 animator_->StartAnimation( |
| 327 internal::SessionStateAnimator::kAllContainersMask, |
| 328 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
564 shutdown_timer_.Stop(); | 329 shutdown_timer_.Stop(); |
565 shutdown_timer_.Start( | 330 shutdown_timer_.Start( |
566 FROM_HERE, | 331 FROM_HERE, |
567 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs), | 332 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs), |
568 this, &PowerButtonController::OnShutdownTimeout); | 333 this, &PowerButtonController::OnShutdownTimeout); |
569 } | 334 } |
570 | 335 |
571 void PowerButtonController::StartShutdownAnimationAndRequestShutdown() { | 336 void PowerButtonController::StartShutdownAnimationAndRequestShutdown() { |
572 DCHECK(!shutting_down_); | 337 DCHECK(!shutting_down_); |
573 shutting_down_ = true; | 338 shutting_down_ = true; |
574 | 339 |
575 Shell* shell = ash::Shell::GetInstance(); | 340 Shell* shell = ash::Shell::GetInstance(); |
576 shell->env_filter()->set_cursor_hidden_by_filter(false); | 341 shell->env_filter()->set_cursor_hidden_by_filter(false); |
577 shell->cursor_manager()->ShowCursor(false); | 342 shell->cursor_manager()->ShowCursor(false); |
578 | 343 |
579 ShowBlackLayer(); | 344 animator_->ShowBlackLayer(); |
580 if (login_status_ != user::LOGGED_IN_NONE) { | 345 if (login_status_ != user::LOGGED_IN_NONE) { |
581 // Hide the other containers before starting the animation. | 346 // Hide the other containers before starting the animation. |
582 // ANIMATION_FAST_CLOSE will make the screen locker windows partially | 347 // ANIMATION_FAST_CLOSE will make the screen locker windows partially |
583 // transparent, and we don't want the other windows to show through. | 348 // transparent, and we don't want the other windows to show through. |
584 StartAnimation(LAUNCHER | NON_LOCK_SCREEN_CONTAINERS, ANIMATION_HIDE); | 349 animator_->StartAnimation( |
585 StartAnimation(GetAllLockScreenContainersMask(), ANIMATION_FAST_CLOSE); | 350 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | |
| 351 internal::SessionStateAnimator::LAUNCHER, |
| 352 internal::SessionStateAnimator::ANIMATION_HIDE); |
| 353 animator_->StartAnimation( |
| 354 internal::SessionStateAnimator::kAllLockScreenContainersMask, |
| 355 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); |
586 } else { | 356 } else { |
587 StartAnimation(GetAllContainersMask(), ANIMATION_FAST_CLOSE); | 357 animator_->StartAnimation( |
| 358 internal::SessionStateAnimator::kAllContainersMask, |
| 359 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); |
588 } | 360 } |
589 | 361 |
590 real_shutdown_timer_.Start( | 362 real_shutdown_timer_.Start( |
591 FROM_HERE, | 363 FROM_HERE, |
592 base::TimeDelta::FromMilliseconds( | 364 base::TimeDelta::FromMilliseconds( |
593 kFastCloseAnimMs + kShutdownRequestDelayMs), | 365 kFastCloseAnimMs + kShutdownRequestDelayMs), |
594 this, &PowerButtonController::OnRealShutdownTimeout); | 366 this, &PowerButtonController::OnRealShutdownTimeout); |
595 } | 367 } |
596 | 368 |
597 void PowerButtonController::ShowBlackLayer() { | |
598 if (hide_black_layer_timer_.IsRunning()) | |
599 hide_black_layer_timer_.Stop(); | |
600 | |
601 if (!black_layer_.get()) { | |
602 black_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); | |
603 black_layer_->SetColor(SK_ColorBLACK); | |
604 | |
605 ui::Layer* root_layer = Shell::GetPrimaryRootWindow()->layer(); | |
606 black_layer_->SetBounds(root_layer->bounds()); | |
607 root_layer->Add(black_layer_.get()); | |
608 root_layer->StackAtBottom(black_layer_.get()); | |
609 } | |
610 black_layer_->SetVisible(true); | |
611 } | |
612 | |
613 void PowerButtonController::HideBlackLayer() { | |
614 black_layer_.reset(); | |
615 } | |
616 | |
617 } // namespace ash | 369 } // namespace ash |
OLD | NEW |