OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "ash/wm/session_state_controller_impl.h" | |
6 | |
7 #include "ash/ash_switches.h" | |
8 #include "ash/cancel_mode.h" | |
9 #include "ash/shell.h" | |
10 #include "ash/shell_delegate.h" | |
11 #include "ash/shell_window_ids.h" | |
12 #include "ash/wm/session_state_animator.h" | |
13 #include "base/command_line.h" | |
14 #include "ui/aura/root_window.h" | |
15 #include "ui/views/corewm/compound_event_filter.h" | |
16 | |
17 #if defined(OS_CHROMEOS) | |
18 #include "base/chromeos/chromeos_version.h" | |
19 #endif | |
20 | |
21 namespace ash { | |
22 | |
23 SessionStateControllerImpl::TestApi::TestApi( | |
24 SessionStateControllerImpl* controller) | |
25 : controller_(controller) { | |
26 } | |
27 | |
28 SessionStateControllerImpl::TestApi::~TestApi() { | |
29 } | |
30 | |
31 SessionStateControllerImpl::SessionStateControllerImpl() | |
32 : login_status_(user::LOGGED_IN_NONE), | |
33 system_is_locked_(false), | |
34 shutting_down_(false), | |
35 shutdown_after_lock_(false) { | |
36 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this); | |
37 } | |
38 | |
39 SessionStateControllerImpl::~SessionStateControllerImpl() { | |
40 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this); | |
41 } | |
42 | |
43 void SessionStateControllerImpl::OnLoginStateChanged(user::LoginStatus status) { | |
44 if (status != user::LOGGED_IN_LOCKED) | |
45 login_status_ = status; | |
46 system_is_locked_ = (status == user::LOGGED_IN_LOCKED); | |
47 } | |
48 | |
49 void SessionStateControllerImpl::OnAppTerminating() { | |
50 // If we hear that Chrome is exiting but didn't request it ourselves, all we | |
51 // can really hope for is that we'll have time to clear the screen. | |
52 if (!shutting_down_) { | |
53 shutting_down_ = true; | |
54 Shell* shell = ash::Shell::GetInstance(); | |
55 shell->env_filter()->set_cursor_hidden_by_filter(false); | |
56 shell->cursor_manager()->HideCursor(); | |
57 animator_->StartAnimation( | |
58 internal::SessionStateAnimator::kAllContainersMask, | |
59 internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY, | |
60 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); | |
61 } | |
62 } | |
63 | |
64 void SessionStateControllerImpl::OnLockStateChanged(bool locked) { | |
65 if (shutting_down_ || (system_is_locked_ == locked)) | |
66 return; | |
67 | |
68 system_is_locked_ = locked; | |
69 | |
70 if (locked) { | |
71 animator_->StartAnimation( | |
72 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, | |
73 internal::SessionStateAnimator::ANIMATION_FADE_IN, | |
74 internal::SessionStateAnimator::ANIMATION_SPEED_SHOW_LOCK_SCREEN); | |
75 DispatchCancelMode(); | |
76 FOR_EACH_OBSERVER(LockStateObserver, observers_, | |
77 OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_STARTED)); | |
78 lock_timer_.Stop(); | |
79 lock_fail_timer_.Stop(); | |
80 | |
81 if (shutdown_after_lock_) { | |
82 shutdown_after_lock_ = false; | |
83 StartLockToShutdownTimer(); | |
84 } | |
85 } else { | |
86 animator_->StartAnimation( | |
87 internal::SessionStateAnimator::DESKTOP_BACKGROUND | | |
88 internal::SessionStateAnimator::LAUNCHER | | |
89 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
90 internal::SessionStateAnimator::ANIMATION_RESTORE, | |
91 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); | |
92 } | |
93 } | |
94 | |
95 void SessionStateControllerImpl::OnStartingLock() { | |
96 if (shutting_down_ || system_is_locked_) | |
97 return; | |
98 | |
99 animator_->StartAnimation( | |
100 internal::SessionStateAnimator::LAUNCHER, | |
101 internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY, | |
102 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); | |
103 | |
104 animator_->StartAnimation( | |
105 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
106 internal::SessionStateAnimator::ANIMATION_FULL_CLOSE, | |
107 internal::SessionStateAnimator::ANIMATION_SPEED_FAST); | |
108 | |
109 DispatchCancelMode(); | |
110 FOR_EACH_OBSERVER(LockStateObserver, observers_, | |
111 OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_STARTED)); | |
112 | |
113 // Hide the screen locker containers so we can make them fade in later. | |
114 animator_->StartAnimation( | |
115 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, | |
116 internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY, | |
117 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); | |
118 } | |
119 | |
120 void SessionStateControllerImpl::StartLockAnimationAndLockImmediately() { | |
121 animator_->StartAnimation( | |
122 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
123 internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE, | |
124 internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE); | |
125 DispatchCancelMode(); | |
126 FOR_EACH_OBSERVER(LockStateObserver, observers_, | |
127 OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_STARTED)); | |
128 OnLockTimeout(); | |
129 } | |
130 | |
131 void SessionStateControllerImpl::StartLockAnimation(bool shutdown_after_lock) { | |
132 shutdown_after_lock_ = shutdown_after_lock; | |
133 | |
134 animator_->StartAnimation( | |
135 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
136 internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE, | |
137 internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE); | |
138 DispatchCancelMode(); | |
139 FOR_EACH_OBSERVER(LockStateObserver, observers_, | |
140 OnLockStateEvent(LockStateObserver::EVENT_PRELOCK_ANIMATION_STARTED)); | |
141 StartLockTimer(); | |
142 } | |
143 | |
144 void SessionStateControllerImpl::StartShutdownAnimation() { | |
145 animator_->StartAnimation( | |
146 internal::SessionStateAnimator::kAllContainersMask, | |
147 internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE, | |
148 internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE); | |
149 | |
150 StartPreShutdownAnimationTimer(); | |
151 } | |
152 | |
153 bool SessionStateControllerImpl::LockRequested() { | |
154 return lock_fail_timer_.IsRunning(); | |
155 } | |
156 | |
157 bool SessionStateControllerImpl::ShutdownRequested() { | |
158 return shutting_down_; | |
159 } | |
160 | |
161 bool SessionStateControllerImpl::CanCancelLockAnimation() { | |
162 return lock_timer_.IsRunning(); | |
163 } | |
164 | |
165 void SessionStateControllerImpl::CancelLockAnimation() { | |
166 if (!CanCancelLockAnimation()) | |
167 return; | |
168 shutdown_after_lock_ = false; | |
169 animator_->StartAnimation( | |
170 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
171 internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE, | |
172 internal::SessionStateAnimator::ANIMATION_SPEED_REVERT); | |
173 lock_timer_.Stop(); | |
174 } | |
175 | |
176 bool SessionStateControllerImpl::CanCancelShutdownAnimation() { | |
177 return pre_shutdown_timer_.IsRunning() || | |
178 shutdown_after_lock_ || | |
179 lock_to_shutdown_timer_.IsRunning(); | |
180 } | |
181 | |
182 void SessionStateControllerImpl::CancelShutdownAnimation() { | |
183 if (!CanCancelShutdownAnimation()) | |
184 return; | |
185 if (lock_to_shutdown_timer_.IsRunning()) { | |
186 lock_to_shutdown_timer_.Stop(); | |
187 return; | |
188 } | |
189 if (shutdown_after_lock_) { | |
190 shutdown_after_lock_ = false; | |
191 return; | |
192 } | |
193 | |
194 if (system_is_locked_) { | |
195 // If we've already started shutdown transition at lock screen | |
196 // desktop background needs to be restored immediately. | |
197 animator_->StartAnimation( | |
198 internal::SessionStateAnimator::DESKTOP_BACKGROUND, | |
199 internal::SessionStateAnimator::ANIMATION_RESTORE, | |
200 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); | |
201 animator_->StartAnimation( | |
202 internal::SessionStateAnimator::kAllLockScreenContainersMask, | |
203 internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE, | |
204 internal::SessionStateAnimator::ANIMATION_SPEED_REVERT); | |
205 } else { | |
206 animator_->StartAnimation( | |
207 internal::SessionStateAnimator::kAllContainersMask, | |
208 internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE, | |
209 internal::SessionStateAnimator::ANIMATION_SPEED_REVERT); | |
210 } | |
211 pre_shutdown_timer_.Stop(); | |
212 } | |
213 | |
214 void SessionStateControllerImpl::RequestShutdown() { | |
215 if (!shutting_down_) | |
216 RequestShutdownImpl(); | |
217 } | |
218 | |
219 void SessionStateControllerImpl::RequestShutdownImpl() { | |
220 DCHECK(!shutting_down_); | |
221 shutting_down_ = true; | |
222 | |
223 Shell* shell = ash::Shell::GetInstance(); | |
224 shell->env_filter()->set_cursor_hidden_by_filter(false); | |
225 shell->cursor_manager()->HideCursor(); | |
226 | |
227 if (login_status_ != user::LOGGED_IN_NONE) { | |
228 // Hide the other containers before starting the animation. | |
229 // ANIMATION_FULL_CLOSE will make the screen locker windows partially | |
230 // transparent, and we don't want the other windows to show through. | |
231 animator_->StartAnimation( | |
232 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | | |
233 internal::SessionStateAnimator::LAUNCHER, | |
234 internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY, | |
235 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); | |
236 animator_->StartAnimation( | |
237 internal::SessionStateAnimator::kAllLockScreenContainersMask, | |
238 internal::SessionStateAnimator::ANIMATION_FULL_CLOSE, | |
239 internal::SessionStateAnimator::ANIMATION_SPEED_FAST); | |
240 } else { | |
241 animator_->StartAnimation( | |
242 internal::SessionStateAnimator::kAllContainersMask, | |
243 internal::SessionStateAnimator::ANIMATION_FULL_CLOSE, | |
244 internal::SessionStateAnimator::ANIMATION_SPEED_FAST); | |
245 } | |
246 StartRealShutdownTimer(); | |
247 } | |
248 | |
249 void SessionStateControllerImpl::OnRootWindowHostCloseRequested( | |
250 const aura::RootWindow*) { | |
251 Shell::GetInstance()->delegate()->Exit(); | |
252 } | |
253 | |
254 void SessionStateControllerImpl::StartLockTimer() { | |
255 lock_timer_.Stop(); | |
256 lock_timer_.Start( | |
257 FROM_HERE, | |
258 animator_->GetDuration( | |
259 internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE), | |
260 this, &SessionStateControllerImpl::OnLockTimeout); | |
261 } | |
262 | |
263 void SessionStateControllerImpl::OnLockTimeout() { | |
264 delegate_->RequestLockScreen(); | |
265 lock_fail_timer_.Start( | |
266 FROM_HERE, | |
267 base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs), | |
268 this, &SessionStateControllerImpl::OnLockFailTimeout); | |
269 } | |
270 | |
271 void SessionStateControllerImpl::OnLockFailTimeout() { | |
272 DCHECK(!system_is_locked_); | |
273 // Undo lock animation. | |
274 animator_->StartAnimation( | |
275 internal::SessionStateAnimator::LAUNCHER | | |
276 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
277 internal::SessionStateAnimator::ANIMATION_RESTORE, | |
278 internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); | |
279 } | |
280 | |
281 void SessionStateControllerImpl::StartLockToShutdownTimer() { | |
282 shutdown_after_lock_ = false; | |
283 lock_to_shutdown_timer_.Stop(); | |
284 lock_to_shutdown_timer_.Start( | |
285 FROM_HERE, | |
286 base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs), | |
287 this, &SessionStateControllerImpl::OnLockToShutdownTimeout); | |
288 } | |
289 | |
290 | |
291 void SessionStateControllerImpl::OnLockToShutdownTimeout() { | |
292 DCHECK(system_is_locked_); | |
293 StartShutdownAnimation(); | |
294 } | |
295 | |
296 void SessionStateControllerImpl::StartPreShutdownAnimationTimer() { | |
297 pre_shutdown_timer_.Stop(); | |
298 pre_shutdown_timer_.Start( | |
299 FROM_HERE, | |
300 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs), | |
301 this, &SessionStateControllerImpl::OnPreShutdownAnimationTimeout); | |
302 } | |
303 | |
304 void SessionStateControllerImpl::OnPreShutdownAnimationTimeout() { | |
305 if (!shutting_down_) | |
306 RequestShutdownImpl(); | |
307 } | |
308 | |
309 void SessionStateControllerImpl::StartRealShutdownTimer() { | |
310 base::TimeDelta duration = | |
311 base::TimeDelta::FromMilliseconds(kShutdownRequestDelayMs); | |
312 duration += animator_->GetDuration( | |
313 internal::SessionStateAnimator::ANIMATION_SPEED_FAST); | |
314 | |
315 real_shutdown_timer_.Start( | |
316 FROM_HERE, | |
317 duration, | |
318 this, &SessionStateControllerImpl::OnRealShutdownTimeout); | |
319 } | |
320 | |
321 void SessionStateControllerImpl::OnRealShutdownTimeout() { | |
322 DCHECK(shutting_down_); | |
323 #if defined(OS_CHROMEOS) | |
324 if (!base::chromeos::IsRunningOnChromeOS()) { | |
325 ShellDelegate* delegate = Shell::GetInstance()->delegate(); | |
326 if (delegate) { | |
327 delegate->Exit(); | |
328 return; | |
329 } | |
330 } | |
331 #endif | |
332 delegate_->RequestShutdown(); | |
333 } | |
334 | |
335 void SessionStateControllerImpl::OnLockScreenHide(base::Closure& callback) { | |
336 callback.Run(); | |
337 } | |
338 | |
339 void SessionStateControllerImpl::SetLockScreenDisplayedCallback( | |
340 base::Closure& callback) { | |
341 NOTIMPLEMENTED(); | |
342 } | |
343 | |
344 } // namespace ash | |
OLD | NEW |