1// Copyright 2013 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/ash_switches.h"
6#include "ash/session_state_delegate.h"
7#include "ash/shell.h"
8#include "ash/shell_window_ids.h"
9#include "ash/test/ash_test_base.h"
10#include "ash/test/test_shell_delegate.h"
11#include "ash/wm/lock_state_controller.h"
12#include "ash/wm/lock_state_controller_impl2.h"
13#include "ash/wm/power_button_controller.h"
14#include "ash/wm/session_state_animator.h"
15#include "base/command_line.h"
16#include "base/memory/scoped_ptr.h"
17#include "base/time/time.h"
18#include "ui/aura/env.h"
19#include "ui/aura/root_window.h"
20#include "ui/aura/test/event_generator.h"
21#include "ui/compositor/layer_animator.h"
22#include "ui/compositor/scoped_animation_duration_scale_mode.h"
23#include "ui/compositor/scoped_layer_animation_settings.h"
24#include "ui/gfx/rect.h"
25#include "ui/gfx/size.h"
26
27#if defined(OS_WIN)
28#include "base/win/windows_version.h"
29#endif
30
31namespace ash {
32
33using internal::SessionStateAnimator;
34
35namespace test {
36
37namespace {
38
39bool cursor_visible() {
40  return ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible();
41}
42
43void CheckCalledCallback(bool* flag) {
44  if (flag)
45    (*flag) = true;
46}
47
48aura::Window* GetContainer(int container ) {
49  aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
50  return Shell::GetContainer(root_window, container);
51}
52
53bool IsBackgroundHidden() {
54  return !GetContainer(internal::kShellWindowId_DesktopBackgroundContainer)->
55              IsVisible();
56}
57
58void ShowBackground() {
59  ui::ScopedLayerAnimationSettings settings(
60      GetContainer(internal::kShellWindowId_DesktopBackgroundContainer)->
61          layer()->GetAnimator());
62  settings.SetTransitionDuration(base::TimeDelta());
63  GetContainer(internal::kShellWindowId_DesktopBackgroundContainer)->Show();
64}
65
66void HideBackground() {
67  ui::ScopedLayerAnimationSettings settings(
68      GetContainer(internal::kShellWindowId_DesktopBackgroundContainer)->
69          layer()->GetAnimator());
70  settings.SetTransitionDuration(base::TimeDelta());
71  GetContainer(internal::kShellWindowId_DesktopBackgroundContainer)->Hide();
72}
73
74} // namespace
75
76// Fake implementation of PowerButtonControllerDelegate that just logs requests
77// to lock the screen and shut down the device.
78class TestLockStateControllerDelegate : public LockStateControllerDelegate {
79 public:
80  TestLockStateControllerDelegate()
81      : num_lock_requests_(0),
82        num_shutdown_requests_(0) {}
83
84  int num_lock_requests() const { return num_lock_requests_; }
85  int num_shutdown_requests() const { return num_shutdown_requests_; }
86
87  // LockStateControllerDelegate implementation.
88  virtual void RequestLockScreen() OVERRIDE {
89    num_lock_requests_++;
90  }
91  virtual void RequestShutdown() OVERRIDE {
92    num_shutdown_requests_++;
93  }
94
95 private:
96  int num_lock_requests_;
97  int num_shutdown_requests_;
98
99  DISALLOW_COPY_AND_ASSIGN(TestLockStateControllerDelegate);
100};
101
102class LockStateControllerImpl2Test : public AshTestBase {
103 public:
104  LockStateControllerImpl2Test() : controller_(NULL), delegate_(NULL) {}
105  virtual ~LockStateControllerImpl2Test() {}
106
107  virtual void SetUp() OVERRIDE {
108    CHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
109        ash::switches::kAshDisableNewLockAnimations));
110
111    AshTestBase::SetUp();
112
113    // We would control animations in a fine way:
114    animation_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
115        ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION));
116    // TODO(antrim) : restore
117    // animator_helper_ = ui::test::CreateLayerAnimatorHelperForTest();
118
119    // Temporary disable animations so that observer is always called, and
120    // no leaks happen during tests.
121    animation_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
122        ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
123    // TODO(antrim): once there is a way to mock time and run animations, make
124    // sure that animations are finished even in simple tests.
125
126    delegate_ = new TestLockStateControllerDelegate;
127    controller_ = Shell::GetInstance()->power_button_controller();
128    lock_state_controller_ = static_cast<LockStateControllerImpl2*>(
129        Shell::GetInstance()->lock_state_controller());
130    lock_state_controller_->SetDelegate(delegate_);  // transfers ownership
131    test_api_.reset(
132        new LockStateControllerImpl2::TestApi(lock_state_controller_));
133    animator_api_.reset(
134        new SessionStateAnimator::TestApi(lock_state_controller_->
135            animator_.get()));
136    shell_delegate_ = reinterpret_cast<TestShellDelegate*>(
137        ash::Shell::GetInstance()->delegate());
138    session_state_delegate_ = Shell::GetInstance()->session_state_delegate();
139  }
140
141  virtual void TearDown() {
142    // TODO(antrim) : restore
143    // animator_helper_->AdvanceUntilDone();
144    AshTestBase::TearDown();
145  }
146
147 protected:
148  void GenerateMouseMoveEvent() {
149    aura::test::EventGenerator generator(
150        Shell::GetPrimaryRootWindow());
151    generator.MoveMouseTo(10, 10);
152  }
153
154  int NumShutdownRequests() {
155    return delegate_->num_shutdown_requests() +
156           shell_delegate_->num_exit_requests();
157  }
158
159  void Advance(SessionStateAnimator::AnimationSpeed speed) {
160    // TODO (antrim) : restore
161    // animator_helper_->Advance(SessionStateAnimator::GetDuration(speed));
162  }
163
164  void AdvancePartially(SessionStateAnimator::AnimationSpeed speed,
165                        float factor) {
166// TODO (antrim) : restore
167//  base::TimeDelta duration = SessionStateAnimator::GetDuration(speed);
168//  base::TimeDelta partial_duration =
169//      base::TimeDelta::FromInternalValue(duration.ToInternalValue() * factor);
170//  animator_helper_->Advance(partial_duration);
171  }
172
173  void ExpectPreLockAnimationStarted() {
174    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
175    EXPECT_TRUE(
176        animator_api_->ContainersAreAnimated(
177            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
178            SessionStateAnimator::ANIMATION_LIFT));
179    EXPECT_TRUE(
180        animator_api_->ContainersAreAnimated(
181            SessionStateAnimator::LAUNCHER,
182            SessionStateAnimator::ANIMATION_FADE_OUT));
183    EXPECT_TRUE(
184        animator_api_->ContainersAreAnimated(
185            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
186            SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
187    EXPECT_TRUE(test_api_->is_animating_lock());
188  }
189
190  void ExpectPreLockAnimationCancel() {
191    EXPECT_TRUE(
192        animator_api_->ContainersAreAnimated(
193            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
194            SessionStateAnimator::ANIMATION_DROP));
195    EXPECT_TRUE(
196        animator_api_->ContainersAreAnimated(
197            SessionStateAnimator::LAUNCHER,
198            SessionStateAnimator::ANIMATION_FADE_IN));
199  }
200
201  void ExpectPreLockAnimationFinished() {
202    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
203    EXPECT_TRUE(
204        animator_api_->ContainersAreAnimated(
205            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
206            SessionStateAnimator::ANIMATION_LIFT));
207    EXPECT_TRUE(
208        animator_api_->ContainersAreAnimated(
209            SessionStateAnimator::LAUNCHER,
210            SessionStateAnimator::ANIMATION_FADE_OUT));
211    EXPECT_TRUE(
212        animator_api_->ContainersAreAnimated(
213            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
214            SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
215  }
216
217  void ExpectPostLockAnimationStarted() {
218    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
219    EXPECT_TRUE(
220        animator_api_->ContainersAreAnimated(
221            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
222            SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN));
223  }
224
225  void ExpectPastLockAnimationFinished() {
226    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
227    EXPECT_TRUE(
228        animator_api_->ContainersAreAnimated(
229            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
230            SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN));
231  }
232
233  void ExpectUnlockBeforeUIDestroyedAnimationStarted() {
234    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
235    EXPECT_TRUE(
236        animator_api_->ContainersAreAnimated(
237            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
238            SessionStateAnimator::ANIMATION_LIFT));
239  }
240
241  void ExpectUnlockBeforeUIDestroyedAnimationFinished() {
242    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
243    EXPECT_TRUE(
244        animator_api_->ContainersAreAnimated(
245            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
246            SessionStateAnimator::ANIMATION_LIFT));
247  }
248
249  void ExpectUnlockAfterUIDestroyedAnimationStarted() {
250    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
251    EXPECT_TRUE(
252        animator_api_->ContainersAreAnimated(
253            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
254            SessionStateAnimator::ANIMATION_DROP));
255    EXPECT_TRUE(
256        animator_api_->ContainersAreAnimated(
257            SessionStateAnimator::LAUNCHER,
258            SessionStateAnimator::ANIMATION_FADE_IN));
259  }
260
261  void ExpectUnlockAfterUIDestroyedAnimationFinished() {
262    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
263    EXPECT_TRUE(
264        animator_api_->ContainersAreAnimated(
265            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
266            SessionStateAnimator::ANIMATION_DROP));
267    EXPECT_TRUE(
268        animator_api_->ContainersAreAnimated(
269            SessionStateAnimator::LAUNCHER,
270            SessionStateAnimator::ANIMATION_FADE_IN));
271  }
272
273  void ExpectShutdownAnimationStarted() {
274    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
275    EXPECT_TRUE(
276        animator_api_->RootWindowIsAnimated(
277            SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS));
278  }
279
280  void ExpectShutdownAnimationFinished()  {
281    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
282    EXPECT_TRUE(
283        animator_api_->RootWindowIsAnimated(
284            SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS));
285  }
286
287  void ExpectShutdownAnimationCancel() {
288    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
289    EXPECT_TRUE(
290        animator_api_->RootWindowIsAnimated(
291            SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS));
292  }
293
294  void ExpectBackgroundIsShowing() {
295    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
296    EXPECT_TRUE(
297        animator_api_->ContainersAreAnimated(
298            SessionStateAnimator::DESKTOP_BACKGROUND,
299            SessionStateAnimator::ANIMATION_FADE_IN));
300  }
301
302  void ExpectBackgroundIsHiding() {
303    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
304    EXPECT_TRUE(
305        animator_api_->ContainersAreAnimated(
306            SessionStateAnimator::DESKTOP_BACKGROUND,
307            SessionStateAnimator::ANIMATION_FADE_OUT));
308  }
309
310  void ExpectUnlockedState() {
311    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
312    EXPECT_FALSE(session_state_delegate_->IsScreenLocked());
313
314    aura::Window::Windows containers;
315
316    SessionStateAnimator::GetContainers(
317        SessionStateAnimator::LAUNCHER |
318        SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
319        &containers);
320    for (aura::Window::Windows::const_iterator it = containers.begin();
321         it != containers.end(); ++it) {
322      aura::Window* window = *it;
323      ui::Layer* layer = window->layer();
324      EXPECT_EQ(1.0f, layer->opacity());
325      EXPECT_EQ(0.0f, layer->layer_brightness());
326      EXPECT_EQ(0.0f, layer->layer_saturation());
327      EXPECT_EQ(gfx::Transform(), layer->transform());
328    }
329  }
330
331  void ExpectLockedState() {
332    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
333    EXPECT_TRUE(session_state_delegate_->IsScreenLocked());
334
335    aura::Window::Windows containers;
336
337    SessionStateAnimator::GetContainers(
338        SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS |
339        SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
340        &containers);
341    for (aura::Window::Windows::const_iterator it = containers.begin();
342         it != containers.end(); ++it) {
343      aura::Window* window = *it;
344      ui::Layer* layer = window->layer();
345      EXPECT_EQ(1.0f, layer->opacity());
346      EXPECT_EQ(0.0f, layer->layer_brightness());
347      EXPECT_EQ(0.0f, layer->layer_saturation());
348      EXPECT_EQ(gfx::Transform(), layer->transform());
349    }
350  }
351
352  void PressPowerButton() {
353    controller_->OnPowerButtonEvent(true, base::TimeTicks::Now());
354    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
355  }
356
357  void ReleasePowerButton() {
358    controller_->OnPowerButtonEvent(false, base::TimeTicks::Now());
359    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
360  }
361
362  void PressLockButton() {
363    controller_->OnLockButtonEvent(true, base::TimeTicks::Now());
364  }
365
366  void ReleaseLockButton() {
367    controller_->OnLockButtonEvent(false, base::TimeTicks::Now());
368  }
369
370  void SystemLocks() {
371    lock_state_controller_->OnLockStateChanged(true);
372    session_state_delegate_->LockScreen();
373    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
374  }
375
376  void SuccessfulAuthentication(bool* call_flag) {
377    base::Closure closure = base::Bind(&CheckCalledCallback, call_flag);
378    lock_state_controller_->OnLockScreenHide(closure);
379    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
380  }
381
382  void SystemUnlocks() {
383    lock_state_controller_->OnLockStateChanged(false);
384    session_state_delegate_->UnlockScreen();
385    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
386  }
387
388  void Initialize(bool legacy_button, user::LoginStatus status) {
389    controller_->set_has_legacy_power_button_for_test(legacy_button);
390    lock_state_controller_->OnLoginStateChanged(status);
391    SetUserLoggedIn(status != user::LOGGED_IN_NONE);
392    if (status == user::LOGGED_IN_GUEST)
393      SetCanLockScreen(false);
394    lock_state_controller_->OnLockStateChanged(false);
395  }
396
397  PowerButtonController* controller_;  // not owned
398  LockStateControllerImpl2* lock_state_controller_;  // not owned
399  TestLockStateControllerDelegate* delegate_;  // not owned
400  TestShellDelegate* shell_delegate_;  // not owned
401  SessionStateDelegate* session_state_delegate_;  // not owned
402
403  scoped_ptr<ui::ScopedAnimationDurationScaleMode> animation_duration_mode_;
404  scoped_ptr<LockStateControllerImpl2::TestApi> test_api_;
405  scoped_ptr<SessionStateAnimator::TestApi> animator_api_;
406  // TODO(antrim) : restore
407//  scoped_ptr<ui::test::AnimationContainerTestHelper> animator_helper_;
408
409 private:
410  DISALLOW_COPY_AND_ASSIGN(LockStateControllerImpl2Test);
411};
412
413// Test the lock-to-shutdown flow for non-Chrome-OS hardware that doesn't
414// correctly report power button releases.  We should lock immediately the first
415// time the button is pressed and shut down when it's pressed from the locked
416// state.
417// TODO(antrim): Reenable this: http://crbug.com/167048
418TEST_F(LockStateControllerImpl2Test, DISABLED_LegacyLockAndShutDown) {
419  Initialize(true, user::LOGGED_IN_USER);
420
421  ExpectUnlockedState();
422
423  // We should request that the screen be locked immediately after seeing the
424  // power button get pressed.
425  PressPowerButton();
426
427  ExpectPreLockAnimationStarted();
428
429  EXPECT_FALSE(test_api_->is_lock_cancellable());
430
431  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
432
433  ExpectPreLockAnimationFinished();
434  EXPECT_EQ(1, delegate_->num_lock_requests());
435
436  // Notify that we locked successfully.
437  lock_state_controller_->OnStartingLock();
438  // We had that animation already.
439  //TODO (antrim) : restore
440  //  EXPECT_FALSE(animator_helper_->IsAnimating());
441
442  SystemLocks();
443
444  ExpectPostLockAnimationStarted();
445  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
446  ExpectPastLockAnimationFinished();
447
448  // We shouldn't progress towards the shutdown state, however.
449  EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
450  EXPECT_FALSE(test_api_->shutdown_timer_is_running());
451
452  ReleasePowerButton();
453
454  // Hold the button again and check that we start shutting down.
455  PressPowerButton();
456
457  ExpectShutdownAnimationStarted();
458
459  EXPECT_EQ(0, NumShutdownRequests());
460  // Make sure a mouse move event won't show the cursor.
461  GenerateMouseMoveEvent();
462  EXPECT_FALSE(cursor_visible());
463
464  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
465  test_api_->trigger_real_shutdown_timeout();
466  EXPECT_EQ(1, NumShutdownRequests());
467}
468
469// Test that we start shutting down immediately if the power button is pressed
470// while we're not logged in on an unofficial system.
471TEST_F(LockStateControllerImpl2Test, LegacyNotLoggedIn) {
472  Initialize(true, user::LOGGED_IN_NONE);
473
474  PressPowerButton();
475  ExpectShutdownAnimationStarted();
476
477  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
478}
479
480// Test that we start shutting down immediately if the power button is pressed
481// while we're logged in as a guest on an unofficial system.
482TEST_F(LockStateControllerImpl2Test, LegacyGuest) {
483  Initialize(true, user::LOGGED_IN_GUEST);
484
485  PressPowerButton();
486  ExpectShutdownAnimationStarted();
487
488  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
489}
490
491// When we hold the power button while the user isn't logged in, we should shut
492// down the machine directly.
493TEST_F(LockStateControllerImpl2Test, ShutdownWhenNotLoggedIn) {
494  Initialize(false, user::LOGGED_IN_NONE);
495
496  // Press the power button and check that we start the shutdown timer.
497  PressPowerButton();
498  EXPECT_FALSE(test_api_->is_animating_lock());
499  EXPECT_TRUE(test_api_->shutdown_timer_is_running());
500  ExpectShutdownAnimationStarted();
501
502  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN, 0.5f);
503
504  // Release the power button before the shutdown timer fires.
505  ReleasePowerButton();
506
507  EXPECT_FALSE(test_api_->shutdown_timer_is_running());
508  ExpectShutdownAnimationCancel();
509
510  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_REVERT, 0.5f);
511
512  // Press the button again and make the shutdown timeout fire this time.
513  // Check that we start the timer for actually requesting the shutdown.
514  PressPowerButton();
515
516  EXPECT_TRUE(test_api_->shutdown_timer_is_running());
517
518  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
519  ExpectShutdownAnimationFinished();
520  test_api_->trigger_shutdown_timeout();
521
522  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
523  EXPECT_EQ(0, NumShutdownRequests());
524
525  // When the timout fires, we should request a shutdown.
526  test_api_->trigger_real_shutdown_timeout();
527
528  EXPECT_EQ(1, NumShutdownRequests());
529}
530
531// Test that we lock the screen and deal with unlocking correctly.
532// TODO(antrim): Reenable this: http://crbug.com/167048
533TEST_F(LockStateControllerImpl2Test, DISABLED_LockAndUnlock) {
534  Initialize(false, user::LOGGED_IN_USER);
535
536  ExpectUnlockedState();
537
538  // Press the power button and check that the lock timer is started and that we
539  // start lifting the non-screen-locker containers.
540  PressPowerButton();
541
542  ExpectPreLockAnimationStarted();
543  EXPECT_TRUE(test_api_->is_lock_cancellable());
544  EXPECT_EQ(0, delegate_->num_lock_requests());
545
546  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
547  ExpectPreLockAnimationFinished();
548
549  EXPECT_EQ(1, delegate_->num_lock_requests());
550
551  // Notify that we locked successfully.
552  lock_state_controller_->OnStartingLock();
553  // We had that animation already.
554  //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
555
556  SystemLocks();
557
558  ExpectPostLockAnimationStarted();
559  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
560  ExpectPastLockAnimationFinished();
561
562  // When we release the power button, the lock-to-shutdown timer should be
563  // stopped.
564  ExpectLockedState();
565  EXPECT_TRUE(test_api_->lock_to_shutdown_timer_is_running());
566  ReleasePowerButton();
567  ExpectLockedState();
568  EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
569
570  // Notify that the screen has been unlocked.  We should show the
571  // non-screen-locker windows.
572  bool called = false;
573  SuccessfulAuthentication(&called);
574
575  ExpectUnlockBeforeUIDestroyedAnimationStarted();
576  EXPECT_FALSE(called);
577  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
578  ExpectUnlockBeforeUIDestroyedAnimationFinished();
579
580  EXPECT_TRUE(called);
581
582  SystemUnlocks();
583
584  ExpectUnlockAfterUIDestroyedAnimationStarted();
585  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
586  ExpectUnlockAfterUIDestroyedAnimationFinished();
587
588  ExpectUnlockedState();
589}
590
591// Test that we deal with cancelling lock correctly.
592// TODO(antrim): Reenable this: http://crbug.com/167048
593TEST_F(LockStateControllerImpl2Test, DISABLED_LockAndCancel) {
594  Initialize(false, user::LOGGED_IN_USER);
595
596  ExpectUnlockedState();
597
598  // Press the power button and check that the lock timer is started and that we
599  // start lifting the non-screen-locker containers.
600  PressPowerButton();
601
602  ExpectPreLockAnimationStarted();
603  EXPECT_TRUE(test_api_->is_lock_cancellable());
604
605  // forward only half way through
606  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
607
608  gfx::Transform transform_before_button_released =
609      GetContainer(internal::kShellWindowId_DefaultContainer)->
610          layer()->transform();
611
612  // Release the button before the lock timer fires.
613  ReleasePowerButton();
614
615  ExpectPreLockAnimationCancel();
616
617  gfx::Transform transform_after_button_released =
618      GetContainer(internal::kShellWindowId_DefaultContainer)->
619          layer()->transform();
620  // Expect no flickering, animation should proceed from mid-state.
621  EXPECT_EQ(transform_before_button_released, transform_after_button_released);
622
623  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
624  ExpectUnlockedState();
625  EXPECT_EQ(0, delegate_->num_lock_requests());
626}
627
628// Test that we deal with cancelling lock correctly.
629// TODO(antrim): Reenable this: http://crbug.com/167048
630TEST_F(LockStateControllerImpl2Test,
631       DISABLED_LockAndCancelAndLockAgain) {
632  Initialize(false, user::LOGGED_IN_USER);
633
634  ExpectUnlockedState();
635
636  // Press the power button and check that the lock timer is started and that we
637  // start lifting the non-screen-locker containers.
638  PressPowerButton();
639
640  ExpectPreLockAnimationStarted();
641  EXPECT_TRUE(test_api_->is_lock_cancellable());
642
643  // forward only half way through
644  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
645
646  // Release the button before the lock timer fires.
647  ReleasePowerButton();
648  ExpectPreLockAnimationCancel();
649
650  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, 0.5f);
651
652  PressPowerButton();
653  ExpectPreLockAnimationStarted();
654  EXPECT_TRUE(test_api_->is_lock_cancellable());
655
656  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.6f);
657
658  EXPECT_EQ(0, delegate_->num_lock_requests());
659  ExpectPreLockAnimationStarted();
660
661  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.6f);
662  ExpectPreLockAnimationFinished();
663  EXPECT_EQ(1, delegate_->num_lock_requests());
664}
665
666// Hold the power button down from the unlocked state to eventual shutdown.
667// TODO(antrim): Reenable this: http://crbug.com/167048
668TEST_F(LockStateControllerImpl2Test, DISABLED_LockToShutdown) {
669  Initialize(false, user::LOGGED_IN_USER);
670
671  // Hold the power button and lock the screen.
672  PressPowerButton();
673  EXPECT_TRUE(test_api_->is_animating_lock());
674
675  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
676  SystemLocks();
677  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
678
679  // When the lock-to-shutdown timeout fires, we should start the shutdown
680  // timer.
681  EXPECT_TRUE(test_api_->lock_to_shutdown_timer_is_running());
682
683  test_api_->trigger_lock_to_shutdown_timeout();
684
685  ExpectShutdownAnimationStarted();
686  EXPECT_TRUE(test_api_->shutdown_timer_is_running());
687
688  // Fire the shutdown timeout and check that we request shutdown.
689  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
690  ExpectShutdownAnimationFinished();
691  test_api_->trigger_shutdown_timeout();
692
693  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
694  EXPECT_EQ(0, NumShutdownRequests());
695  test_api_->trigger_real_shutdown_timeout();
696  EXPECT_EQ(1, NumShutdownRequests());
697}
698
699// Hold the power button down from the unlocked state to eventual shutdown,
700// then release the button while system does locking.
701TEST_F(LockStateControllerImpl2Test, CancelLockToShutdown) {
702  Initialize(false, user::LOGGED_IN_USER);
703
704  PressPowerButton();
705
706  // Hold the power button and lock the screen.
707  EXPECT_TRUE(test_api_->is_animating_lock());
708
709  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
710  SystemLocks();
711  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, 0.5f);
712
713  // Power button is released while system attempts to lock.
714  ReleasePowerButton();
715
716  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
717
718  EXPECT_FALSE(lock_state_controller_->ShutdownRequested());
719  EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
720  EXPECT_FALSE(test_api_->shutdown_timer_is_running());
721}
722
723// Test that we handle the case where lock requests are ignored.
724// TODO(antrim): Reenable this: http://crbug.com/167048
725TEST_F(LockStateControllerImpl2Test, DISABLED_Lock) {
726  // We require animations to have a duration for this test.
727  ui::ScopedAnimationDurationScaleMode normal_duration_mode(
728      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
729
730  Initialize(false, user::LOGGED_IN_USER);
731
732  // Hold the power button and lock the screen.
733  PressPowerButton();
734  ExpectPreLockAnimationStarted();
735
736  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
737
738  EXPECT_EQ(1, delegate_->num_lock_requests());
739  EXPECT_TRUE(test_api_->lock_fail_timer_is_running());
740  // We shouldn't start the lock-to-shutdown timer until the screen has actually
741  // been locked and this was animated.
742  EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
743
744  // Act as if the request timed out.  We should restore the windows.
745  test_api_->trigger_lock_fail_timeout();
746
747  ExpectUnlockAfterUIDestroyedAnimationStarted();
748  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
749  ExpectUnlockAfterUIDestroyedAnimationFinished();
750  ExpectUnlockedState();
751}
752
753// Test the basic operation of the lock button (not logged in).
754TEST_F(LockStateControllerImpl2Test, LockButtonBasicNotLoggedIn) {
755  // The lock button shouldn't do anything if we aren't logged in.
756  Initialize(false, user::LOGGED_IN_NONE);
757
758  PressLockButton();
759  EXPECT_FALSE(test_api_->is_animating_lock());
760  ReleaseLockButton();
761  EXPECT_EQ(0, delegate_->num_lock_requests());
762}
763
764// Test the basic operation of the lock button (guest).
765TEST_F(LockStateControllerImpl2Test, LockButtonBasicGuest) {
766  // The lock button shouldn't do anything when we're logged in as a guest.
767  Initialize(false, user::LOGGED_IN_GUEST);
768
769  PressLockButton();
770  EXPECT_FALSE(test_api_->is_animating_lock());
771  ReleaseLockButton();
772  EXPECT_EQ(0, delegate_->num_lock_requests());
773}
774
775// Test the basic operation of the lock button.
776// TODO(antrim): Reenable this: http://crbug.com/167048
777TEST_F(LockStateControllerImpl2Test, DISABLED_LockButtonBasic) {
778  // If we're logged in as a regular user, we should start the lock timer and
779  // the pre-lock animation.
780  Initialize(false, user::LOGGED_IN_USER);
781
782  PressLockButton();
783  ExpectPreLockAnimationStarted();
784  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
785
786  // If the button is released immediately, we shouldn't lock the screen.
787  ReleaseLockButton();
788  ExpectPreLockAnimationCancel();
789  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
790
791  ExpectUnlockedState();
792  EXPECT_EQ(0, delegate_->num_lock_requests());
793
794  // Press the button again and let the lock timeout fire.  We should request
795  // that the screen be locked.
796  PressLockButton();
797  ExpectPreLockAnimationStarted();
798  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
799  EXPECT_EQ(1, delegate_->num_lock_requests());
800
801  // Pressing the lock button while we have a pending lock request shouldn't do
802  // anything.
803  ReleaseLockButton();
804  PressLockButton();
805  ExpectPreLockAnimationFinished();
806  ReleaseLockButton();
807
808  // Pressing the button also shouldn't do anything after the screen is locked.
809  SystemLocks();
810  ExpectPostLockAnimationStarted();
811
812  PressLockButton();
813  ReleaseLockButton();
814  ExpectPostLockAnimationStarted();
815
816  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
817  ExpectPastLockAnimationFinished();
818
819  PressLockButton();
820  ReleaseLockButton();
821  ExpectPastLockAnimationFinished();
822}
823
824// Test that the power button takes priority over the lock button.
825// TODO(antrim): Reenable this: http://crbug.com/167048
826TEST_F(LockStateControllerImpl2Test,
827    DISABLED_PowerButtonPreemptsLockButton) {
828  Initialize(false, user::LOGGED_IN_USER);
829
830  // While the lock button is down, hold the power button.
831  PressLockButton();
832  ExpectPreLockAnimationStarted();
833  PressPowerButton();
834  ExpectPreLockAnimationStarted();
835
836  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
837
838  // The lock timer shouldn't be stopped when the lock button is released.
839  ReleaseLockButton();
840  ExpectPreLockAnimationStarted();
841  ReleasePowerButton();
842  ExpectPreLockAnimationCancel();
843
844  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
845  ExpectUnlockedState();
846
847  // Now press the power button first and then the lock button.
848  PressPowerButton();
849  ExpectPreLockAnimationStarted();
850  PressLockButton();
851  ExpectPreLockAnimationStarted();
852
853  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
854
855  // Releasing the power button should stop the lock timer.
856  ReleasePowerButton();
857  ExpectPreLockAnimationCancel();
858  ReleaseLockButton();
859  ExpectPreLockAnimationCancel();
860}
861
862// When the screen is locked without going through the usual power-button
863// slow-close path (e.g. via the wrench menu), test that we still show the
864// fast-close animation.
865TEST_F(LockStateControllerImpl2Test, LockWithoutButton) {
866  Initialize(false, user::LOGGED_IN_USER);
867  lock_state_controller_->OnStartingLock();
868
869  ExpectPreLockAnimationStarted();
870  EXPECT_FALSE(test_api_->is_lock_cancellable());
871
872  // TODO(antrim): After time-faking is fixed, let the pre-lock animation
873  // complete here and check that delegate_->num_lock_requests() is 0 to
874  // prevent http://crbug.com/172487 from regressing.
875}
876
877// When we hear that the process is exiting but we haven't had a chance to
878// display an animation, we should just blank the screen.
879TEST_F(LockStateControllerImpl2Test, ShutdownWithoutButton) {
880  Initialize(false, user::LOGGED_IN_USER);
881  lock_state_controller_->OnAppTerminating();
882
883  EXPECT_TRUE(
884      animator_api_->ContainersAreAnimated(
885          SessionStateAnimator::kAllContainersMask,
886          SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
887  GenerateMouseMoveEvent();
888  EXPECT_FALSE(cursor_visible());
889}
890
891// Test that we display the fast-close animation and shut down when we get an
892// outside request to shut down (e.g. from the login or lock screen).
893TEST_F(LockStateControllerImpl2Test, RequestShutdownFromLoginScreen) {
894  Initialize(false, user::LOGGED_IN_NONE);
895
896  lock_state_controller_->RequestShutdown();
897
898  ExpectShutdownAnimationStarted();
899  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
900
901  GenerateMouseMoveEvent();
902  EXPECT_FALSE(cursor_visible());
903
904  EXPECT_EQ(0, NumShutdownRequests());
905  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
906  test_api_->trigger_real_shutdown_timeout();
907  EXPECT_EQ(1, NumShutdownRequests());
908}
909
910TEST_F(LockStateControllerImpl2Test, RequestShutdownFromLockScreen) {
911  Initialize(false, user::LOGGED_IN_USER);
912
913  SystemLocks();
914  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
915  ExpectPastLockAnimationFinished();
916
917  lock_state_controller_->RequestShutdown();
918
919  ExpectShutdownAnimationStarted();
920  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
921
922  GenerateMouseMoveEvent();
923  EXPECT_FALSE(cursor_visible());
924
925  EXPECT_EQ(0, NumShutdownRequests());
926  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
927  test_api_->trigger_real_shutdown_timeout();
928  EXPECT_EQ(1, NumShutdownRequests());
929}
930
931// TODO(antrim): Reenable this: http://crbug.com/167048
932TEST_F(LockStateControllerImpl2Test,
933       DISABLED_RequestAndCancelShutdownFromLockScreen) {
934  Initialize(false, user::LOGGED_IN_USER);
935
936  SystemLocks();
937  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
938  ExpectLockedState();
939
940  // Press the power button and check that we start the shutdown timer.
941  PressPowerButton();
942  EXPECT_FALSE(test_api_->is_animating_lock());
943  EXPECT_TRUE(test_api_->shutdown_timer_is_running());
944
945  ExpectShutdownAnimationStarted();
946
947  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN, 0.5f);
948
949  float grayscale_before_button_release =
950      Shell::GetPrimaryRootWindow()->layer()->layer_grayscale();
951
952  // Release the power button before the shutdown timer fires.
953  ReleasePowerButton();
954
955  EXPECT_FALSE(test_api_->shutdown_timer_is_running());
956
957  ExpectShutdownAnimationCancel();
958
959  float grayscale_after_button_release =
960      Shell::GetPrimaryRootWindow()->layer()->layer_grayscale();
961  // Expect no flickering in undo animation.
962  EXPECT_EQ(grayscale_before_button_release, grayscale_after_button_release);
963
964  Advance(SessionStateAnimator::ANIMATION_SPEED_REVERT);
965  ExpectLockedState();
966}
967
968// Test that we ignore power button presses when the screen is turned off.
969TEST_F(LockStateControllerImpl2Test, IgnorePowerButtonIfScreenIsOff) {
970  Initialize(false, user::LOGGED_IN_USER);
971
972  // When the screen brightness is at 0%, we shouldn't do anything in response
973  // to power button presses.
974  controller_->OnScreenBrightnessChanged(0.0);
975
976  PressPowerButton();
977  EXPECT_FALSE(test_api_->is_animating_lock());
978  ReleasePowerButton();
979
980  // After increasing the brightness to 10%, we should start the timer like
981  // usual.
982  controller_->OnScreenBrightnessChanged(10.0);
983
984  PressPowerButton();
985  EXPECT_TRUE(test_api_->is_animating_lock());
986}
987
988// Test that hidden background appears and revers correctly on lock/cancel.
989// TODO(antrim): Reenable this: http://crbug.com/167048
990TEST_F(LockStateControllerImpl2Test,
991    DISABLED_TestHiddenBackgroundLockCancel) {
992  Initialize(false, user::LOGGED_IN_USER);
993  HideBackground();
994
995  EXPECT_TRUE(IsBackgroundHidden());
996  ExpectUnlockedState();
997  PressPowerButton();
998
999  ExpectPreLockAnimationStarted();
1000  EXPECT_FALSE(IsBackgroundHidden());
1001  ExpectBackgroundIsShowing();
1002
1003  // Forward only half way through.
1004  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
1005
1006  // Release the button before the lock timer fires.
1007  ReleasePowerButton();
1008  ExpectPreLockAnimationCancel();
1009  ExpectBackgroundIsHiding();
1010  EXPECT_FALSE(IsBackgroundHidden());
1011
1012  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
1013
1014  ExpectUnlockedState();
1015  EXPECT_TRUE(IsBackgroundHidden());
1016}
1017
1018// Test that hidden background appears and revers correctly on lock/unlock.
1019// TODO(antrim): Reenable this: http://crbug.com/167048
1020TEST_F(LockStateControllerImpl2Test,
1021    DISABLED_TestHiddenBackgroundLockUnlock) {
1022  Initialize(false, user::LOGGED_IN_USER);
1023  HideBackground();
1024
1025  EXPECT_TRUE(IsBackgroundHidden());
1026  ExpectUnlockedState();
1027
1028  // Press the power button and check that the lock timer is started and that we
1029  // start lifting the non-screen-locker containers.
1030  PressPowerButton();
1031
1032  ExpectPreLockAnimationStarted();
1033  EXPECT_FALSE(IsBackgroundHidden());
1034  ExpectBackgroundIsShowing();
1035
1036  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
1037
1038  ExpectPreLockAnimationFinished();
1039
1040  SystemLocks();
1041
1042  ReleasePowerButton();
1043
1044  ExpectPostLockAnimationStarted();
1045  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
1046  ExpectPastLockAnimationFinished();
1047
1048  ExpectLockedState();
1049
1050  SuccessfulAuthentication(NULL);
1051
1052  ExpectUnlockBeforeUIDestroyedAnimationStarted();
1053  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
1054  ExpectUnlockBeforeUIDestroyedAnimationFinished();
1055
1056  SystemUnlocks();
1057
1058  ExpectUnlockAfterUIDestroyedAnimationStarted();
1059  ExpectBackgroundIsHiding();
1060  EXPECT_FALSE(IsBackgroundHidden());
1061
1062  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
1063  ExpectUnlockAfterUIDestroyedAnimationFinished();
1064  EXPECT_TRUE(IsBackgroundHidden());
1065
1066  ExpectUnlockedState();
1067}
1068
1069}  // namespace test
1070}  // namespace ash
1071