// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/lock_state_controller.h"

#include "ash/ash_switches.h"
#include "ash/session/session_state_delegate.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/test_lock_state_controller_delegate.h"
#include "ash/test/test_shell_delegate.h"
#include "ash/wm/power_button_controller.h"
#include "ash/wm/session_state_animator.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "ui/aura/env.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"

#if defined(OS_CHROMEOS)
#include "ui/display/chromeos/display_configurator.h"
#include "ui/display/chromeos/test/test_display_snapshot.h"
#include "ui/display/types/display_constants.h"
#endif

#if defined(OS_WIN)
#include "base/win/windows_version.h"
#endif

namespace ash {
namespace test {
namespace {

bool cursor_visible() {
  return ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible();
}

void CheckCalledCallback(bool* flag) {
  if (flag)
    (*flag) = true;
}

aura::Window* GetContainer(int container ) {
  aura::Window* root_window = Shell::GetPrimaryRootWindow();
  return Shell::GetContainer(root_window, container);
}

bool IsBackgroundHidden() {
  return !GetContainer(kShellWindowId_DesktopBackgroundContainer)->IsVisible();
}

void HideBackground() {
  ui::ScopedLayerAnimationSettings settings(
      GetContainer(kShellWindowId_DesktopBackgroundContainer)
          ->layer()
          ->GetAnimator());
  settings.SetTransitionDuration(base::TimeDelta());
  GetContainer(kShellWindowId_DesktopBackgroundContainer)->Hide();
}

} // namespace

class LockStateControllerTest : public AshTestBase {
 public:
  LockStateControllerTest() : controller_(NULL), delegate_(NULL) {}
  virtual ~LockStateControllerTest() {}

  virtual void SetUp() OVERRIDE {
    AshTestBase::SetUp();

    // We would control animations in a fine way:
    animation_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
        ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION));
    // TODO(antrim) : restore
    // animator_helper_ = ui::test::CreateLayerAnimatorHelperForTest();

    // Temporary disable animations so that observer is always called, and
    // no leaks happen during tests.
    animation_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
        ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
    // TODO(antrim): once there is a way to mock time and run animations, make
    // sure that animations are finished even in simple tests.

    delegate_ = new TestLockStateControllerDelegate;
    controller_ = Shell::GetInstance()->power_button_controller();
    lock_state_controller_ = static_cast<LockStateController*>(
        Shell::GetInstance()->lock_state_controller());
    lock_state_controller_->SetDelegate(delegate_);  // transfers ownership
    test_api_.reset(new LockStateController::TestApi(lock_state_controller_));
    animator_api_.reset(
        new SessionStateAnimator::TestApi(lock_state_controller_->
            animator_.get()));
    shell_delegate_ = reinterpret_cast<TestShellDelegate*>(
        ash::Shell::GetInstance()->delegate());
    session_state_delegate_ = Shell::GetInstance()->session_state_delegate();
  }

  virtual void TearDown() {
    // TODO(antrim) : restore
    // animator_helper_->AdvanceUntilDone();
    window_.reset();
    AshTestBase::TearDown();
  }

 protected:
  void GenerateMouseMoveEvent() {
    aura::test::EventGenerator generator(
        Shell::GetPrimaryRootWindow());
    generator.MoveMouseTo(10, 10);
  }

  int NumShutdownRequests() {
    return delegate_->num_shutdown_requests() +
           shell_delegate_->num_exit_requests();
  }

  void Advance(SessionStateAnimator::AnimationSpeed speed) {
    // TODO (antrim) : restore
    // animator_helper_->Advance(SessionStateAnimator::GetDuration(speed));
  }

  void AdvancePartially(SessionStateAnimator::AnimationSpeed speed,
                        float factor) {
// TODO (antrim) : restore
//  base::TimeDelta duration = SessionStateAnimator::GetDuration(speed);
//  base::TimeDelta partial_duration =
//      base::TimeDelta::FromInternalValue(duration.ToInternalValue() * factor);
//  animator_helper_->Advance(partial_duration);
  }

  void ExpectPreLockAnimationStarted() {
    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_LIFT));
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LAUNCHER,
            SessionStateAnimator::ANIMATION_FADE_OUT));
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
    EXPECT_TRUE(test_api_->is_animating_lock());
  }

  void ExpectPreLockAnimationCancel() {
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_DROP));
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LAUNCHER,
            SessionStateAnimator::ANIMATION_FADE_IN));
  }

  void ExpectPreLockAnimationFinished() {
    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_LIFT));
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LAUNCHER,
            SessionStateAnimator::ANIMATION_FADE_OUT));
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
  }

  void ExpectPostLockAnimationStarted() {
    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN));
  }

  void ExpectPastLockAnimationFinished() {
    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN));
  }

  void ExpectUnlockBeforeUIDestroyedAnimationStarted() {
    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_LIFT));
  }

  void ExpectUnlockBeforeUIDestroyedAnimationFinished() {
    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_LIFT));
  }

  void ExpectUnlockAfterUIDestroyedAnimationStarted() {
    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_DROP));
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LAUNCHER,
            SessionStateAnimator::ANIMATION_FADE_IN));
  }

  void ExpectUnlockAfterUIDestroyedAnimationFinished() {
    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
            SessionStateAnimator::ANIMATION_DROP));
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::LAUNCHER,
            SessionStateAnimator::ANIMATION_FADE_IN));
  }

  void ExpectShutdownAnimationStarted() {
    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->RootWindowIsAnimated(
            SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS));
  }

  void ExpectShutdownAnimationFinished()  {
    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->RootWindowIsAnimated(
            SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS));
  }

  void ExpectShutdownAnimationCancel() {
    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->RootWindowIsAnimated(
            SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS));
  }

  void ExpectBackgroundIsShowing() {
    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::DESKTOP_BACKGROUND,
            SessionStateAnimator::ANIMATION_FADE_IN));
  }

  void ExpectBackgroundIsHiding() {
    //TODO (antrim) : restore EXPECT_TRUE(animator_helper_->IsAnimating());
    EXPECT_TRUE(
        animator_api_->ContainersAreAnimated(
            SessionStateAnimator::DESKTOP_BACKGROUND,
            SessionStateAnimator::ANIMATION_FADE_OUT));
  }

  void ExpectUnlockedState() {
    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
    EXPECT_FALSE(session_state_delegate_->IsScreenLocked());

    aura::Window::Windows containers;

    SessionStateAnimator::GetContainers(
        SessionStateAnimator::LAUNCHER |
        SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
        &containers);
    for (aura::Window::Windows::const_iterator it = containers.begin();
         it != containers.end(); ++it) {
      aura::Window* window = *it;
      ui::Layer* layer = window->layer();
      EXPECT_EQ(1.0f, layer->opacity());
      EXPECT_EQ(0.0f, layer->layer_brightness());
      EXPECT_EQ(0.0f, layer->layer_saturation());
      EXPECT_EQ(gfx::Transform(), layer->transform());
    }
  }

  void ExpectLockedState() {
    //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());
    EXPECT_TRUE(session_state_delegate_->IsScreenLocked());

    aura::Window::Windows containers;

    SessionStateAnimator::GetContainers(
        SessionStateAnimator::LOCK_SCREEN_RELATED_CONTAINERS |
        SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
        &containers);
    for (aura::Window::Windows::const_iterator it = containers.begin();
         it != containers.end(); ++it) {
      aura::Window* window = *it;
      ui::Layer* layer = window->layer();
      EXPECT_EQ(1.0f, layer->opacity());
      EXPECT_EQ(0.0f, layer->layer_brightness());
      EXPECT_EQ(0.0f, layer->layer_saturation());
      EXPECT_EQ(gfx::Transform(), layer->transform());
    }
  }

  void PressPowerButton() {
    controller_->OnPowerButtonEvent(true, base::TimeTicks::Now());
    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
  }

  void ReleasePowerButton() {
    controller_->OnPowerButtonEvent(false, base::TimeTicks::Now());
    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
  }

  void PressLockButton() {
    controller_->OnLockButtonEvent(true, base::TimeTicks::Now());
  }

  void ReleaseLockButton() {
    controller_->OnLockButtonEvent(false, base::TimeTicks::Now());
  }

  void SystemLocks() {
    lock_state_controller_->OnLockStateChanged(true);
    session_state_delegate_->LockScreen();
    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
  }

  void SuccessfulAuthentication(bool* call_flag) {
    base::Closure closure = base::Bind(&CheckCalledCallback, call_flag);
    lock_state_controller_->OnLockScreenHide(closure);
    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
  }

  void SystemUnlocks() {
    lock_state_controller_->OnLockStateChanged(false);
    session_state_delegate_->UnlockScreen();
    //TODO (antrim) : restore animator_helper_->Advance(base::TimeDelta());
  }

  void Initialize(bool legacy_button, user::LoginStatus status) {
    controller_->set_has_legacy_power_button_for_test(legacy_button);
    lock_state_controller_->OnLoginStateChanged(status);
    SetUserLoggedIn(status != user::LOGGED_IN_NONE);
    if (status == user::LOGGED_IN_GUEST)
      SetCanLockScreen(false);
    lock_state_controller_->OnLockStateChanged(false);
  }

  void CreateWindowForLockscreen() {
    window_.reset(new aura::Window(&window_delegate_));
    window_->SetBounds(gfx::Rect(0, 0, 100, 100));
    window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
    window_->Init(aura::WINDOW_LAYER_TEXTURED);
    window_->SetName("WINDOW");
    aura::Window* container = Shell::GetContainer(
        Shell::GetPrimaryRootWindow(), kShellWindowId_LockScreenContainer);
    ASSERT_TRUE(container);
    container->AddChild(window_.get());
    window_->Show();
  }

  PowerButtonController* controller_;  // not owned
  LockStateController* lock_state_controller_;  // not owned
  TestLockStateControllerDelegate* delegate_;  // not owned
  TestShellDelegate* shell_delegate_;  // not owned
  SessionStateDelegate* session_state_delegate_;  // not owned

  aura::test::TestWindowDelegate window_delegate_;
  scoped_ptr<aura::Window> window_;
  scoped_ptr<ui::ScopedAnimationDurationScaleMode> animation_duration_mode_;
  scoped_ptr<LockStateController::TestApi> test_api_;
  scoped_ptr<SessionStateAnimator::TestApi> animator_api_;
  // TODO(antrim) : restore
//  scoped_ptr<ui::test::AnimationContainerTestHelper> animator_helper_;

 private:
  DISALLOW_COPY_AND_ASSIGN(LockStateControllerTest);
};

// Test the lock-to-shutdown flow for non-Chrome-OS hardware that doesn't
// correctly report power button releases.  We should lock immediately the first
// time the button is pressed and shut down when it's pressed from the locked
// state.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest, DISABLED_LegacyLockAndShutDown) {
  Initialize(true, user::LOGGED_IN_USER);

  ExpectUnlockedState();

  // We should request that the screen be locked immediately after seeing the
  // power button get pressed.
  PressPowerButton();

  ExpectPreLockAnimationStarted();

  EXPECT_FALSE(test_api_->is_lock_cancellable());

  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);

  ExpectPreLockAnimationFinished();
  EXPECT_EQ(1, delegate_->num_lock_requests());

  // Notify that we locked successfully.
  lock_state_controller_->OnStartingLock();
  // We had that animation already.
  //TODO (antrim) : restore
  //  EXPECT_FALSE(animator_helper_->IsAnimating());

  SystemLocks();

  ExpectPostLockAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectPastLockAnimationFinished();

  // We shouldn't progress towards the shutdown state, however.
  EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
  EXPECT_FALSE(test_api_->shutdown_timer_is_running());

  ReleasePowerButton();

  // Hold the button again and check that we start shutting down.
  PressPowerButton();

  ExpectShutdownAnimationStarted();

  EXPECT_EQ(0, NumShutdownRequests());
  // Make sure a mouse move event won't show the cursor.
  GenerateMouseMoveEvent();
  EXPECT_FALSE(cursor_visible());

  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
  test_api_->trigger_real_shutdown_timeout();
  EXPECT_EQ(1, NumShutdownRequests());
}

// Test that we start shutting down immediately if the power button is pressed
// while we're not logged in on an unofficial system.
TEST_F(LockStateControllerTest, LegacyNotLoggedIn) {
  Initialize(true, user::LOGGED_IN_NONE);

  PressPowerButton();
  ExpectShutdownAnimationStarted();

  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
}

// Test that we start shutting down immediately if the power button is pressed
// while we're logged in as a guest on an unofficial system.
TEST_F(LockStateControllerTest, LegacyGuest) {
  Initialize(true, user::LOGGED_IN_GUEST);

  PressPowerButton();
  ExpectShutdownAnimationStarted();

  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
}

// When we hold the power button while the user isn't logged in, we should shut
// down the machine directly.
TEST_F(LockStateControllerTest, ShutdownWhenNotLoggedIn) {
  Initialize(false, user::LOGGED_IN_NONE);

  // Press the power button and check that we start the shutdown timer.
  PressPowerButton();
  EXPECT_FALSE(test_api_->is_animating_lock());
  EXPECT_TRUE(test_api_->shutdown_timer_is_running());
  ExpectShutdownAnimationStarted();

  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN, 0.5f);

  // Release the power button before the shutdown timer fires.
  ReleasePowerButton();

  EXPECT_FALSE(test_api_->shutdown_timer_is_running());
  ExpectShutdownAnimationCancel();

  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_REVERT, 0.5f);

  // Press the button again and make the shutdown timeout fire this time.
  // Check that we start the timer for actually requesting the shutdown.
  PressPowerButton();

  EXPECT_TRUE(test_api_->shutdown_timer_is_running());

  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
  ExpectShutdownAnimationFinished();
  test_api_->trigger_shutdown_timeout();

  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
  EXPECT_EQ(0, NumShutdownRequests());

  // When the timout fires, we should request a shutdown.
  test_api_->trigger_real_shutdown_timeout();

  EXPECT_EQ(1, NumShutdownRequests());
}

// Test that we lock the screen and deal with unlocking correctly.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest, DISABLED_LockAndUnlock) {
  Initialize(false, user::LOGGED_IN_USER);

  ExpectUnlockedState();

  // Press the power button and check that the lock timer is started and that we
  // start lifting the non-screen-locker containers.
  PressPowerButton();

  ExpectPreLockAnimationStarted();
  EXPECT_TRUE(test_api_->is_lock_cancellable());
  EXPECT_EQ(0, delegate_->num_lock_requests());

  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
  ExpectPreLockAnimationFinished();

  EXPECT_EQ(1, delegate_->num_lock_requests());

  // Notify that we locked successfully.
  lock_state_controller_->OnStartingLock();
  // We had that animation already.
  //TODO (antrim) : restore EXPECT_FALSE(animator_helper_->IsAnimating());

  SystemLocks();

  ExpectPostLockAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectPastLockAnimationFinished();

  // When we release the power button, the lock-to-shutdown timer should be
  // stopped.
  ExpectLockedState();
  EXPECT_TRUE(test_api_->lock_to_shutdown_timer_is_running());
  ReleasePowerButton();
  ExpectLockedState();
  EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());

  // Notify that the screen has been unlocked.  We should show the
  // non-screen-locker windows.
  bool called = false;
  SuccessfulAuthentication(&called);

  ExpectUnlockBeforeUIDestroyedAnimationStarted();
  EXPECT_FALSE(called);
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectUnlockBeforeUIDestroyedAnimationFinished();

  EXPECT_TRUE(called);

  SystemUnlocks();

  ExpectUnlockAfterUIDestroyedAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectUnlockAfterUIDestroyedAnimationFinished();

  ExpectUnlockedState();
}

// Test that we deal with cancelling lock correctly.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest, DISABLED_LockAndCancel) {
  Initialize(false, user::LOGGED_IN_USER);

  ExpectUnlockedState();

  // Press the power button and check that the lock timer is started and that we
  // start lifting the non-screen-locker containers.
  PressPowerButton();

  ExpectPreLockAnimationStarted();
  EXPECT_TRUE(test_api_->is_lock_cancellable());

  // forward only half way through
  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);

  gfx::Transform transform_before_button_released =
      GetContainer(kShellWindowId_DefaultContainer)->layer()->transform();

  // Release the button before the lock timer fires.
  ReleasePowerButton();

  ExpectPreLockAnimationCancel();

  gfx::Transform transform_after_button_released =
      GetContainer(kShellWindowId_DefaultContainer)->layer()->transform();
  // Expect no flickering, animation should proceed from mid-state.
  EXPECT_EQ(transform_before_button_released, transform_after_button_released);

  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectUnlockedState();
  EXPECT_EQ(0, delegate_->num_lock_requests());
}

// Test that we deal with cancelling lock correctly.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest,
       DISABLED_LockAndCancelAndLockAgain) {
  Initialize(false, user::LOGGED_IN_USER);

  ExpectUnlockedState();

  // Press the power button and check that the lock timer is started and that we
  // start lifting the non-screen-locker containers.
  PressPowerButton();

  ExpectPreLockAnimationStarted();
  EXPECT_TRUE(test_api_->is_lock_cancellable());

  // forward only half way through
  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);

  // Release the button before the lock timer fires.
  ReleasePowerButton();
  ExpectPreLockAnimationCancel();

  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, 0.5f);

  PressPowerButton();
  ExpectPreLockAnimationStarted();
  EXPECT_TRUE(test_api_->is_lock_cancellable());

  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.6f);

  EXPECT_EQ(0, delegate_->num_lock_requests());
  ExpectPreLockAnimationStarted();

  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.6f);
  ExpectPreLockAnimationFinished();
  EXPECT_EQ(1, delegate_->num_lock_requests());
}

// Hold the power button down from the unlocked state to eventual shutdown.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest, DISABLED_LockToShutdown) {
  Initialize(false, user::LOGGED_IN_USER);

  // Hold the power button and lock the screen.
  PressPowerButton();
  EXPECT_TRUE(test_api_->is_animating_lock());

  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
  SystemLocks();
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);

  // When the lock-to-shutdown timeout fires, we should start the shutdown
  // timer.
  EXPECT_TRUE(test_api_->lock_to_shutdown_timer_is_running());

  test_api_->trigger_lock_to_shutdown_timeout();

  ExpectShutdownAnimationStarted();
  EXPECT_TRUE(test_api_->shutdown_timer_is_running());

  // Fire the shutdown timeout and check that we request shutdown.
  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
  ExpectShutdownAnimationFinished();
  test_api_->trigger_shutdown_timeout();

  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
  EXPECT_EQ(0, NumShutdownRequests());
  test_api_->trigger_real_shutdown_timeout();
  EXPECT_EQ(1, NumShutdownRequests());
}

// Hold the power button down from the unlocked state to eventual shutdown,
// then release the button while system does locking.
TEST_F(LockStateControllerTest, CancelLockToShutdown) {
  Initialize(false, user::LOGGED_IN_USER);

  PressPowerButton();

  // Hold the power button and lock the screen.
  EXPECT_TRUE(test_api_->is_animating_lock());

  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
  SystemLocks();
  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, 0.5f);

  // Power button is released while system attempts to lock.
  ReleasePowerButton();

  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);

  EXPECT_FALSE(lock_state_controller_->ShutdownRequested());
  EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());
  EXPECT_FALSE(test_api_->shutdown_timer_is_running());
}

// Test that we handle the case where lock requests are ignored.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest, DISABLED_Lock) {
  // We require animations to have a duration for this test.
  ui::ScopedAnimationDurationScaleMode normal_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);

  Initialize(false, user::LOGGED_IN_USER);

  // Hold the power button and lock the screen.
  PressPowerButton();
  ExpectPreLockAnimationStarted();

  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);

  EXPECT_EQ(1, delegate_->num_lock_requests());
  EXPECT_TRUE(test_api_->lock_fail_timer_is_running());
  // We shouldn't start the lock-to-shutdown timer until the screen has actually
  // been locked and this was animated.
  EXPECT_FALSE(test_api_->lock_to_shutdown_timer_is_running());

  // Act as if the request timed out.  We should restore the windows.
  test_api_->trigger_lock_fail_timeout();

  ExpectUnlockAfterUIDestroyedAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectUnlockAfterUIDestroyedAnimationFinished();
  ExpectUnlockedState();
}

// Test the basic operation of the lock button (not logged in).
TEST_F(LockStateControllerTest, LockButtonBasicNotLoggedIn) {
  // The lock button shouldn't do anything if we aren't logged in.
  Initialize(false, user::LOGGED_IN_NONE);

  PressLockButton();
  EXPECT_FALSE(test_api_->is_animating_lock());
  ReleaseLockButton();
  EXPECT_EQ(0, delegate_->num_lock_requests());
}

// Test the basic operation of the lock button (guest).
TEST_F(LockStateControllerTest, LockButtonBasicGuest) {
  // The lock button shouldn't do anything when we're logged in as a guest.
  Initialize(false, user::LOGGED_IN_GUEST);

  PressLockButton();
  EXPECT_FALSE(test_api_->is_animating_lock());
  ReleaseLockButton();
  EXPECT_EQ(0, delegate_->num_lock_requests());
}

// Test the basic operation of the lock button.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest, DISABLED_LockButtonBasic) {
  // If we're logged in as a regular user, we should start the lock timer and
  // the pre-lock animation.
  Initialize(false, user::LOGGED_IN_USER);

  PressLockButton();
  ExpectPreLockAnimationStarted();
  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);

  // If the button is released immediately, we shouldn't lock the screen.
  ReleaseLockButton();
  ExpectPreLockAnimationCancel();
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);

  ExpectUnlockedState();
  EXPECT_EQ(0, delegate_->num_lock_requests());

  // Press the button again and let the lock timeout fire.  We should request
  // that the screen be locked.
  PressLockButton();
  ExpectPreLockAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
  EXPECT_EQ(1, delegate_->num_lock_requests());

  // Pressing the lock button while we have a pending lock request shouldn't do
  // anything.
  ReleaseLockButton();
  PressLockButton();
  ExpectPreLockAnimationFinished();
  ReleaseLockButton();

  // Pressing the button also shouldn't do anything after the screen is locked.
  SystemLocks();
  ExpectPostLockAnimationStarted();

  PressLockButton();
  ReleaseLockButton();
  ExpectPostLockAnimationStarted();

  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectPastLockAnimationFinished();

  PressLockButton();
  ReleaseLockButton();
  ExpectPastLockAnimationFinished();
}

// Test that the power button takes priority over the lock button.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest,
    DISABLED_PowerButtonPreemptsLockButton) {
  Initialize(false, user::LOGGED_IN_USER);

  // While the lock button is down, hold the power button.
  PressLockButton();
  ExpectPreLockAnimationStarted();
  PressPowerButton();
  ExpectPreLockAnimationStarted();

  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);

  // The lock timer shouldn't be stopped when the lock button is released.
  ReleaseLockButton();
  ExpectPreLockAnimationStarted();
  ReleasePowerButton();
  ExpectPreLockAnimationCancel();

  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectUnlockedState();

  // Now press the power button first and then the lock button.
  PressPowerButton();
  ExpectPreLockAnimationStarted();
  PressLockButton();
  ExpectPreLockAnimationStarted();

  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);

  // Releasing the power button should stop the lock timer.
  ReleasePowerButton();
  ExpectPreLockAnimationCancel();
  ReleaseLockButton();
  ExpectPreLockAnimationCancel();
}

// When the screen is locked without going through the usual power-button
// slow-close path (e.g. via the wrench menu), test that we still show the
// fast-close animation.
TEST_F(LockStateControllerTest, LockWithoutButton) {
  Initialize(false, user::LOGGED_IN_USER);
  lock_state_controller_->OnStartingLock();

  ExpectPreLockAnimationStarted();
  EXPECT_FALSE(test_api_->is_lock_cancellable());

  // TODO(antrim): After time-faking is fixed, let the pre-lock animation
  // complete here and check that delegate_->num_lock_requests() is 0 to
  // prevent http://crbug.com/172487 from regressing.
}

// When we hear that the process is exiting but we haven't had a chance to
// display an animation, we should just blank the screen.
TEST_F(LockStateControllerTest, ShutdownWithoutButton) {
  Initialize(false, user::LOGGED_IN_USER);
  lock_state_controller_->OnAppTerminating();

  EXPECT_TRUE(
      animator_api_->ContainersAreAnimated(
          SessionStateAnimator::kAllContainersMask,
          SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
  GenerateMouseMoveEvent();
  EXPECT_FALSE(cursor_visible());
}

// Test that we display the fast-close animation and shut down when we get an
// outside request to shut down (e.g. from the login or lock screen).
TEST_F(LockStateControllerTest, RequestShutdownFromLoginScreen) {
  Initialize(false, user::LOGGED_IN_NONE);
  CreateWindowForLockscreen();

  lock_state_controller_->RequestShutdown();

  ExpectShutdownAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);

  GenerateMouseMoveEvent();
  EXPECT_FALSE(cursor_visible());

  EXPECT_EQ(0, NumShutdownRequests());
  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
  test_api_->trigger_real_shutdown_timeout();
  EXPECT_EQ(1, NumShutdownRequests());
}

TEST_F(LockStateControllerTest, RequestShutdownFromLockScreen) {
  Initialize(false, user::LOGGED_IN_USER);

  SystemLocks();
  CreateWindowForLockscreen();
  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
  ExpectPastLockAnimationFinished();

  lock_state_controller_->RequestShutdown();

  ExpectShutdownAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);

  GenerateMouseMoveEvent();
  EXPECT_FALSE(cursor_visible());

  EXPECT_EQ(0, NumShutdownRequests());
  EXPECT_TRUE(test_api_->real_shutdown_timer_is_running());
  test_api_->trigger_real_shutdown_timeout();
  EXPECT_EQ(1, NumShutdownRequests());
}

// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest,
       DISABLED_RequestAndCancelShutdownFromLockScreen) {
  Initialize(false, user::LOGGED_IN_USER);

  SystemLocks();
  Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
  ExpectLockedState();

  // Press the power button and check that we start the shutdown timer.
  PressPowerButton();
  EXPECT_FALSE(test_api_->is_animating_lock());
  EXPECT_TRUE(test_api_->shutdown_timer_is_running());

  ExpectShutdownAnimationStarted();

  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN, 0.5f);

  float grayscale_before_button_release =
      Shell::GetPrimaryRootWindow()->layer()->layer_grayscale();

  // Release the power button before the shutdown timer fires.
  ReleasePowerButton();

  EXPECT_FALSE(test_api_->shutdown_timer_is_running());

  ExpectShutdownAnimationCancel();

  float grayscale_after_button_release =
      Shell::GetPrimaryRootWindow()->layer()->layer_grayscale();
  // Expect no flickering in undo animation.
  EXPECT_EQ(grayscale_before_button_release, grayscale_after_button_release);

  Advance(SessionStateAnimator::ANIMATION_SPEED_REVERT);
  ExpectLockedState();
}

// Test that we ignore power button presses when the screen is turned off.
TEST_F(LockStateControllerTest, IgnorePowerButtonIfScreenIsOff) {
  Initialize(false, user::LOGGED_IN_USER);

  // When the screen brightness is at 0%, we shouldn't do anything in response
  // to power button presses.
  controller_->OnScreenBrightnessChanged(0.0);
  PressPowerButton();
  EXPECT_FALSE(test_api_->is_animating_lock());
  ReleasePowerButton();

  // After increasing the brightness to 10%, we should start the timer like
  // usual.
  controller_->OnScreenBrightnessChanged(10.0);
  PressPowerButton();
  EXPECT_TRUE(test_api_->is_animating_lock());
  ReleasePowerButton();
}

#if defined(OS_CHROMEOS) && defined(USE_X11)
TEST_F(LockStateControllerTest, HonorPowerButtonInDockedMode) {
  ScopedVector<const ui::DisplayMode> modes;
  modes.push_back(new ui::DisplayMode(gfx::Size(1, 1), false, 60.0f));

  // Create two outputs, the first internal and the second external.
  ui::DisplayConfigurator::DisplayStateList outputs;
  ui::DisplayConfigurator::DisplayState internal_output;
  ui::TestDisplaySnapshot internal_display;
  internal_display.set_type(ui::DISPLAY_CONNECTION_TYPE_INTERNAL);
  internal_display.set_modes(modes.get());
  internal_output.display = &internal_display;
  outputs.push_back(internal_output);

  ui::DisplayConfigurator::DisplayState external_output;
  ui::TestDisplaySnapshot external_display;
  external_display.set_type(ui::DISPLAY_CONNECTION_TYPE_HDMI);
  external_display.set_modes(modes.get());
  external_output.display = &external_display;
  outputs.push_back(external_output);

  // When all of the displays are turned off (e.g. due to user inactivity), the
  // power button should be ignored.
  controller_->OnScreenBrightnessChanged(0.0);
  static_cast<ui::TestDisplaySnapshot*>(outputs[0].display)
      ->set_current_mode(NULL);
  static_cast<ui::TestDisplaySnapshot*>(outputs[1].display)
      ->set_current_mode(NULL);
  controller_->OnDisplayModeChanged(outputs);
  PressPowerButton();
  EXPECT_FALSE(test_api_->is_animating_lock());
  ReleasePowerButton();

  // When the screen brightness is 0% but the external display is still turned
  // on (indicating either docked mode or the user having manually decreased the
  // brightness to 0%), the power button should still be handled.
  static_cast<ui::TestDisplaySnapshot*>(outputs[1].display)
      ->set_current_mode(modes[0]);
  controller_->OnDisplayModeChanged(outputs);
  PressPowerButton();
  EXPECT_TRUE(test_api_->is_animating_lock());
  ReleasePowerButton();
}
#endif

// Test that hidden background appears and revers correctly on lock/cancel.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest, DISABLED_TestHiddenBackgroundLockCancel) {
  Initialize(false, user::LOGGED_IN_USER);
  HideBackground();

  EXPECT_TRUE(IsBackgroundHidden());
  ExpectUnlockedState();
  PressPowerButton();

  ExpectPreLockAnimationStarted();
  EXPECT_FALSE(IsBackgroundHidden());
  ExpectBackgroundIsShowing();

  // Forward only half way through.
  AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);

  // Release the button before the lock timer fires.
  ReleasePowerButton();
  ExpectPreLockAnimationCancel();
  ExpectBackgroundIsHiding();
  EXPECT_FALSE(IsBackgroundHidden());

  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);

  ExpectUnlockedState();
  EXPECT_TRUE(IsBackgroundHidden());
}

// Test that hidden background appears and revers correctly on lock/unlock.
// TODO(antrim): Reenable this: http://crbug.com/167048
TEST_F(LockStateControllerTest, DISABLED_TestHiddenBackgroundLockUnlock) {
  Initialize(false, user::LOGGED_IN_USER);
  HideBackground();

  EXPECT_TRUE(IsBackgroundHidden());
  ExpectUnlockedState();

  // Press the power button and check that the lock timer is started and that we
  // start lifting the non-screen-locker containers.
  PressPowerButton();

  ExpectPreLockAnimationStarted();
  EXPECT_FALSE(IsBackgroundHidden());
  ExpectBackgroundIsShowing();

  Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);

  ExpectPreLockAnimationFinished();

  SystemLocks();

  ReleasePowerButton();

  ExpectPostLockAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectPastLockAnimationFinished();

  ExpectLockedState();

  SuccessfulAuthentication(NULL);

  ExpectUnlockBeforeUIDestroyedAnimationStarted();
  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectUnlockBeforeUIDestroyedAnimationFinished();

  SystemUnlocks();

  ExpectUnlockAfterUIDestroyedAnimationStarted();
  ExpectBackgroundIsHiding();
  EXPECT_FALSE(IsBackgroundHidden());

  Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  ExpectUnlockAfterUIDestroyedAnimationFinished();
  EXPECT_TRUE(IsBackgroundHidden());

  ExpectUnlockedState();
}

}  // namespace test
}  // namespace ash
