Mailbox support for texture layers.
[chromium-blink-merge.git] / ash / wm / session_state_controller_impl.cc
blobb31b29b600c96c857def855472cea98f0ecf2360
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
3 // found in the LICENSE file.
5 #include "ash/wm/session_state_controller_impl.h"
7 #include "ash/ash_switches.h"
8 #include "ash/shell.h"
9 #include "ash/shell_delegate.h"
10 #include "ash/shell_window_ids.h"
11 #include "ash/wm/session_state_animator.h"
12 #include "base/command_line.h"
13 #include "ui/aura/root_window.h"
14 #include "ui/views/corewm/compound_event_filter.h"
16 #if defined(OS_CHROMEOS)
17 #include "base/chromeos/chromeos_version.h"
18 #endif
20 namespace ash {
22 SessionStateControllerImpl::TestApi::TestApi(
23 SessionStateControllerImpl* controller)
24 : controller_(controller) {
27 SessionStateControllerImpl::TestApi::~TestApi() {
30 SessionStateControllerImpl::SessionStateControllerImpl()
31 : login_status_(user::LOGGED_IN_NONE),
32 system_is_locked_(false),
33 shutting_down_(false),
34 shutdown_after_lock_(false) {
35 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this);
38 SessionStateControllerImpl::~SessionStateControllerImpl() {
39 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this);
42 void SessionStateControllerImpl::OnLoginStateChanged(user::LoginStatus status) {
43 if (status != user::LOGGED_IN_LOCKED)
44 login_status_ = status;
45 system_is_locked_ = (status == user::LOGGED_IN_LOCKED);
48 void SessionStateControllerImpl::OnAppTerminating() {
49 // If we hear that Chrome is exiting but didn't request it ourselves, all we
50 // can really hope for is that we'll have time to clear the screen.
51 if (!shutting_down_) {
52 shutting_down_ = true;
53 Shell* shell = ash::Shell::GetInstance();
54 shell->env_filter()->set_cursor_hidden_by_filter(false);
55 shell->cursor_manager()->DisableMouseEvents();
56 animator_->StartAnimation(
57 internal::SessionStateAnimator::kAllContainersMask,
58 internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
59 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
63 void SessionStateControllerImpl::OnLockStateChanged(bool locked) {
64 if (shutting_down_ || (system_is_locked_ == locked))
65 return;
67 system_is_locked_ = locked;
69 if (locked) {
70 animator_->StartAnimation(
71 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
72 internal::SessionStateAnimator::ANIMATION_FADE_IN,
73 internal::SessionStateAnimator::ANIMATION_SPEED_SHOW_LOCK_SCREEN);
74 FOR_EACH_OBSERVER(SessionStateObserver, observers_,
75 OnSessionStateEvent(
76 SessionStateObserver::EVENT_LOCK_ANIMATION_STARTED));
77 lock_timer_.Stop();
78 lock_fail_timer_.Stop();
80 if (shutdown_after_lock_) {
81 shutdown_after_lock_ = false;
82 StartLockToShutdownTimer();
84 } else {
85 animator_->StartAnimation(
86 internal::SessionStateAnimator::DESKTOP_BACKGROUND |
87 internal::SessionStateAnimator::LAUNCHER |
88 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
89 internal::SessionStateAnimator::ANIMATION_RESTORE,
90 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
94 void SessionStateControllerImpl::OnStartingLock() {
95 if (shutting_down_ || system_is_locked_)
96 return;
98 animator_->StartAnimation(
99 internal::SessionStateAnimator::LAUNCHER,
100 internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
101 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
103 animator_->StartAnimation(
104 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
105 internal::SessionStateAnimator::ANIMATION_FULL_CLOSE,
106 internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
108 FOR_EACH_OBSERVER(SessionStateObserver, observers_,
109 OnSessionStateEvent(SessionStateObserver::EVENT_LOCK_ANIMATION_STARTED));
111 // Hide the screen locker containers so we can make them fade in later.
112 animator_->StartAnimation(
113 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
114 internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
115 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
118 void SessionStateControllerImpl::StartLockAnimationAndLockImmediately() {
119 animator_->StartAnimation(
120 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
121 internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE,
122 internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
123 FOR_EACH_OBSERVER(SessionStateObserver, observers_,
124 OnSessionStateEvent(SessionStateObserver::EVENT_LOCK_ANIMATION_STARTED));
125 OnLockTimeout();
128 void SessionStateControllerImpl::StartLockAnimation(bool shutdown_after_lock) {
129 shutdown_after_lock_ = shutdown_after_lock;
131 animator_->StartAnimation(
132 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
133 internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE,
134 internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
135 FOR_EACH_OBSERVER(SessionStateObserver, observers_,
136 OnSessionStateEvent(
137 SessionStateObserver::EVENT_PRELOCK_ANIMATION_STARTED));
138 StartLockTimer();
141 void SessionStateControllerImpl::StartShutdownAnimation() {
142 animator_->StartAnimation(
143 internal::SessionStateAnimator::kAllContainersMask,
144 internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE,
145 internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
147 StartPreShutdownAnimationTimer();
150 bool SessionStateControllerImpl::LockRequested() {
151 return lock_fail_timer_.IsRunning();
154 bool SessionStateControllerImpl::ShutdownRequested() {
155 return shutting_down_;
158 bool SessionStateControllerImpl::CanCancelLockAnimation() {
159 return lock_timer_.IsRunning();
162 void SessionStateControllerImpl::CancelLockAnimation() {
163 if (!CanCancelLockAnimation())
164 return;
165 shutdown_after_lock_ = false;
166 animator_->StartAnimation(
167 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
168 internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE,
169 internal::SessionStateAnimator::ANIMATION_SPEED_REVERT);
170 lock_timer_.Stop();
173 bool SessionStateControllerImpl::CanCancelShutdownAnimation() {
174 return pre_shutdown_timer_.IsRunning() ||
175 shutdown_after_lock_ ||
176 lock_to_shutdown_timer_.IsRunning();
179 void SessionStateControllerImpl::CancelShutdownAnimation() {
180 if (!CanCancelShutdownAnimation())
181 return;
182 if (lock_to_shutdown_timer_.IsRunning()) {
183 lock_to_shutdown_timer_.Stop();
184 return;
186 if (shutdown_after_lock_) {
187 shutdown_after_lock_ = false;
188 return;
191 if (system_is_locked_) {
192 // If we've already started shutdown transition at lock screen
193 // desktop background needs to be restored immediately.
194 animator_->StartAnimation(
195 internal::SessionStateAnimator::DESKTOP_BACKGROUND,
196 internal::SessionStateAnimator::ANIMATION_RESTORE,
197 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
198 animator_->StartAnimation(
199 internal::SessionStateAnimator::kAllLockScreenContainersMask,
200 internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE,
201 internal::SessionStateAnimator::ANIMATION_SPEED_REVERT);
202 } else {
203 animator_->StartAnimation(
204 internal::SessionStateAnimator::kAllContainersMask,
205 internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE,
206 internal::SessionStateAnimator::ANIMATION_SPEED_REVERT);
208 pre_shutdown_timer_.Stop();
211 void SessionStateControllerImpl::RequestShutdown() {
212 if (!shutting_down_)
213 RequestShutdownImpl();
216 void SessionStateControllerImpl::RequestShutdownImpl() {
217 DCHECK(!shutting_down_);
218 shutting_down_ = true;
220 Shell* shell = ash::Shell::GetInstance();
221 shell->env_filter()->set_cursor_hidden_by_filter(false);
222 shell->cursor_manager()->DisableMouseEvents();
224 if (login_status_ != user::LOGGED_IN_NONE) {
225 // Hide the other containers before starting the animation.
226 // ANIMATION_FULL_CLOSE will make the screen locker windows partially
227 // transparent, and we don't want the other windows to show through.
228 animator_->StartAnimation(
229 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
230 internal::SessionStateAnimator::LAUNCHER,
231 internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
232 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
233 animator_->StartAnimation(
234 internal::SessionStateAnimator::kAllLockScreenContainersMask,
235 internal::SessionStateAnimator::ANIMATION_FULL_CLOSE,
236 internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
237 } else {
238 animator_->StartAnimation(
239 internal::SessionStateAnimator::kAllContainersMask,
240 internal::SessionStateAnimator::ANIMATION_FULL_CLOSE,
241 internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
243 StartRealShutdownTimer();
246 void SessionStateControllerImpl::OnRootWindowHostCloseRequested(
247 const aura::RootWindow*) {
248 Shell::GetInstance()->delegate()->Exit();
251 void SessionStateControllerImpl::StartLockTimer() {
252 lock_timer_.Stop();
253 lock_timer_.Start(
254 FROM_HERE,
255 animator_->GetDuration(
256 internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE),
257 this, &SessionStateControllerImpl::OnLockTimeout);
260 void SessionStateControllerImpl::OnLockTimeout() {
261 delegate_->RequestLockScreen();
262 lock_fail_timer_.Start(
263 FROM_HERE,
264 base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs),
265 this, &SessionStateControllerImpl::OnLockFailTimeout);
268 void SessionStateControllerImpl::OnLockFailTimeout() {
269 DCHECK(!system_is_locked_);
270 // Undo lock animation.
271 animator_->StartAnimation(
272 internal::SessionStateAnimator::LAUNCHER |
273 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
274 internal::SessionStateAnimator::ANIMATION_RESTORE,
275 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
278 void SessionStateControllerImpl::StartLockToShutdownTimer() {
279 shutdown_after_lock_ = false;
280 lock_to_shutdown_timer_.Stop();
281 lock_to_shutdown_timer_.Start(
282 FROM_HERE,
283 base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs),
284 this, &SessionStateControllerImpl::OnLockToShutdownTimeout);
288 void SessionStateControllerImpl::OnLockToShutdownTimeout() {
289 DCHECK(system_is_locked_);
290 StartShutdownAnimation();
293 void SessionStateControllerImpl::StartPreShutdownAnimationTimer() {
294 pre_shutdown_timer_.Stop();
295 pre_shutdown_timer_.Start(
296 FROM_HERE,
297 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs),
298 this, &SessionStateControllerImpl::OnPreShutdownAnimationTimeout);
301 void SessionStateControllerImpl::OnPreShutdownAnimationTimeout() {
302 if (!shutting_down_)
303 RequestShutdownImpl();
306 void SessionStateControllerImpl::StartRealShutdownTimer() {
307 base::TimeDelta duration =
308 base::TimeDelta::FromMilliseconds(kShutdownRequestDelayMs);
309 duration += animator_->GetDuration(
310 internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
312 real_shutdown_timer_.Start(
313 FROM_HERE,
314 duration,
315 this, &SessionStateControllerImpl::OnRealShutdownTimeout);
318 void SessionStateControllerImpl::OnRealShutdownTimeout() {
319 DCHECK(shutting_down_);
320 #if defined(OS_CHROMEOS)
321 if (!base::chromeos::IsRunningOnChromeOS()) {
322 ShellDelegate* delegate = Shell::GetInstance()->delegate();
323 if (delegate) {
324 delegate->Exit();
325 return;
328 #endif
329 delegate_->RequestShutdown();
332 void SessionStateControllerImpl::OnLockScreenHide(base::Closure& callback) {
333 callback.Run();
336 void SessionStateControllerImpl::SetLockScreenDisplayedCallback(
337 base::Closure& callback) {
338 NOTIMPLEMENTED();
341 } // namespace ash