// 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/system/power/power_event_observer.h"

#include <memory>

#include "ash/root_window_controller.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h"
#include "ash/system/power/power_event_observer_test_api.h"
#include "ash/test/ash_test_base.h"
#include "ash/wallpaper/wallpaper_widget_controller.h"
#include "ash/wm/lock_state_controller.h"
#include "ash/wm/lock_state_controller_test_api.h"
#include "ash/wm/test_session_state_animator.h"
#include "base/time/time.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager/suspend.pb.h"
#include "chromeos/dbus/power_manager_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"

namespace ash {

class PowerEventObserverTest : public AshTestBase {
 public:
  PowerEventObserverTest() = default;
  ~PowerEventObserverTest() override = default;

  // AshTestBase:
  void SetUp() override {
    chromeos::DBusThreadManager::Initialize();
    AshTestBase::SetUp();
    observer_.reset(new PowerEventObserver());
  }

  void TearDown() override {
    observer_.reset();
    AshTestBase::TearDown();
    chromeos::DBusThreadManager::Shutdown();
  }

 protected:
  int GetNumVisibleCompositors() {
    int result = 0;
    for (auto* window : Shell::GetAllRootWindows()) {
      if (window->GetHost()->compositor()->IsVisible())
        ++result;
    }

    return result;
  }

  bool GetLockedState() {
    // LockScreen is an async mojo call.
    SessionController* const session_controller =
        Shell::Get()->session_controller();
    session_controller->FlushMojoForTest();
    return session_controller->IsScreenLocked();
  }

  std::unique_ptr<PowerEventObserver> observer_;

 private:
  DISALLOW_COPY_AND_ASSIGN(PowerEventObserverTest);
};

TEST_F(PowerEventObserverTest, LockBeforeSuspend) {
  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  ASSERT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());

  // Check that the observer requests a suspend-readiness callback when it hears
  // that the system is about to suspend.
  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());

  // It should run the callback when it hears that the screen is locked and the
  // lock screen animations have completed.
  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);

  PowerEventObserverTestApi test_api(observer_.get());

  ui::Compositor* compositor =
      Shell::GetPrimaryRootWindow()->GetHost()->compositor();

  test_api.CompositingDidCommit(compositor);
  observer_->OnLockAnimationsComplete();

  // Verify that CompositingStarted and CompositingEnded observed before
  // CompositingDidCommit are ignored.
  test_api.CompositingStarted(compositor);
  test_api.CompositingEnded(compositor);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(1, GetNumVisibleCompositors());

  // Suspend should remain delayed after first compositing cycle ends.
  test_api.CompositeFrame(compositor);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(1, GetNumVisibleCompositors());

  test_api.CompositingDidCommit(compositor);
  test_api.CompositingStarted(compositor);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(1, GetNumVisibleCompositors());

  test_api.CompositingEnded(compositor);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());

  // If the system is already locked, no callback should be requested.
  observer_->SuspendDone(base::TimeDelta());
  EXPECT_EQ(1, GetNumVisibleCompositors());
  UnblockUserSession();
  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);

  // Notify that lock animation is complete.
  observer_->OnLockAnimationsComplete();

  // Wait for a compositing after lock animation completes before suspending.
  // In this case compositors should be made invisible immediately
  test_api.CompositeFrame(compositor);
  test_api.CompositeFrame(compositor);

  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());

  // It also shouldn't request a callback if it isn't instructed to lock the
  // screen.
  observer_->SuspendDone(base::TimeDelta());
  UnblockUserSession();
  SetShouldLockScreenAutomatically(false);
  EXPECT_EQ(1, GetNumVisibleCompositors());
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

TEST_F(PowerEventObserverTest, SetInvisibleBeforeSuspend) {
  // Tests that all the Compositors are marked invisible before a suspend
  // request when the screen is not supposed to be locked before a suspend.
  EXPECT_EQ(1, GetNumVisibleCompositors());

  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(0, GetNumVisibleCompositors());
  observer_->SuspendDone(base::TimeDelta());

  // Tests that all the Compositors are marked invisible _after_ the screen lock
  // animations have completed.
  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(1, GetNumVisibleCompositors());

  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
  EXPECT_EQ(1, GetNumVisibleCompositors());

  observer_->OnLockAnimationsComplete();

  EXPECT_EQ(1, GetNumVisibleCompositors());
  ASSERT_TRUE(PowerEventObserverTestApi(observer_.get())
                  .SimulateCompositorsReadyForSuspend());
  EXPECT_EQ(0, GetNumVisibleCompositors());

  observer_->SuspendDone(base::TimeDelta());
  EXPECT_EQ(1, GetNumVisibleCompositors());
}

TEST_F(PowerEventObserverTest, CanceledSuspend) {
  // Tests that the Compositors are not marked invisible if a suspend is
  // canceled or the system resumes before the lock screen is ready.
  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(1, GetNumVisibleCompositors());

  observer_->SuspendDone(base::TimeDelta());
  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
  observer_->OnLockAnimationsComplete();
  EXPECT_EQ(1, GetNumVisibleCompositors());
}

TEST_F(PowerEventObserverTest, DelayResuspendForLockAnimations) {
  // Tests that the following order of events is handled correctly:
  //
  // - A suspend request is started.
  // - The screen is locked.
  // - The suspend request is canceled.
  // - Another suspend request is started.
  // - The screen lock animations complete.
  // - The screen lock UI changes get composited
  //
  // In this case, the observer should block the second suspend request until
  // the screen lock compositing is done.
  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());

  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
  observer_->SuspendDone(base::TimeDelta());
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);

  // The expected number of suspend readiness callbacks is 2 because the
  // observer has not run the callback that it got from the first suspend
  // request.  The real PowerManagerClient would reset its internal counter in
  // this situation but the stub client is not that smart.
  EXPECT_EQ(2, client->GetNumPendingSuspendReadinessCallbacks());

  observer_->OnLockAnimationsComplete();
  EXPECT_EQ(2, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(1, GetNumVisibleCompositors());

  ASSERT_TRUE(PowerEventObserverTestApi(observer_.get())
                  .SimulateCompositorsReadyForSuspend());
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

// Tests that device suspend is delayed for screen lock until the screen lock
// changes are composited for all root windows.
TEST_F(PowerEventObserverTest, DelaySuspendForCompositing_MultiDisplay) {
  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  UpdateDisplay("100x100,200x200");

  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());

  aura::Window::Windows windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2u, windows.size());

  ui::Compositor* primary_compositor = windows[0]->GetHost()->compositor();
  ui::Compositor* secondary_compositor = windows[1]->GetHost()->compositor();
  ASSERT_EQ(2, GetNumVisibleCompositors());
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());

  PowerEventObserverTestApi test_api(observer_.get());

  // Simulate a commit before lock animations complete, and verify associated
  // compositing ends are ignored.
  test_api.CompositingDidCommit(secondary_compositor);
  observer_->OnLockAnimationsComplete();

  test_api.CompositingStarted(secondary_compositor);
  test_api.CompositingEnded(secondary_compositor);

  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(2, GetNumVisibleCompositors());

  test_api.CompositeFrame(primary_compositor);
  test_api.CompositeFrame(primary_compositor);

  test_api.CompositeFrame(secondary_compositor);

  // Even though compositing for one display is done, changes to compositor
  // visibility, and suspend readines state should be delayed until compositing
  // for the other display finishes.
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(2, GetNumVisibleCompositors());

  test_api.CompositeFrame(secondary_compositor);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

TEST_F(PowerEventObserverTest,
       DelaySuspendForCompositing_PendingDisplayRemoved) {
  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  UpdateDisplay("100x100,200x200");

  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());

  aura::Window::Windows windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2u, windows.size());

  ui::Compositor* primary_compositor = windows[0]->GetHost()->compositor();
  ASSERT_EQ(2, GetNumVisibleCompositors());
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  observer_->OnLockAnimationsComplete();

  PowerEventObserverTestApi test_api(observer_.get());

  test_api.CompositeFrame(primary_compositor);
  test_api.CompositeFrame(primary_compositor);

  // Even though compositing for one display is done, changes to compositor
  // visibility, and suspend readines state should be delayed until compositing
  // for the other display finishes.
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(2, GetNumVisibleCompositors());

  // Remove the second display, and verify the remaining compositor is hidden
  // at this point.
  UpdateDisplay("100x100");
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

TEST_F(PowerEventObserverTest, CompositorNotVisibleAtLockAnimationsComplete) {
  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());

  Shell::GetPrimaryRootWindow()->GetHost()->compositor()->SetVisible(false);

  observer_->OnLockAnimationsComplete();
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

// Tests that for suspend imminent induced locking screen, locking animations
// are immediate.
TEST_F(PowerEventObserverTest, ImmediateLockAnimations) {
  TestSessionStateAnimator* test_animator = new TestSessionStateAnimator;
  LockStateController* lock_state_controller =
      Shell::Get()->lock_state_controller();
  lock_state_controller->set_animator_for_test(test_animator);
  LockStateControllerTestApi lock_state_test_api(lock_state_controller);
  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);
  ASSERT_FALSE(GetLockedState());

  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  // Tests that locking animation starts.
  EXPECT_TRUE(lock_state_test_api.is_animating_lock());

  // Tests that we have two active animation containers for pre-lock animation,
  // which are non lock screen containers and shelf container.
  EXPECT_EQ(2u, test_animator->GetAnimationCount());
  test_animator->AreContainersAnimated(
      LockStateController::kPreLockContainersMask,
      SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY);
  // Tests that after finishing immediate animation, we have no active
  // animations left.
  test_animator->Advance(test_animator->GetDuration(
      SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE));
  EXPECT_EQ(0u, test_animator->GetAnimationCount());

  // Flushes locking screen async request to start post-lock animation.
  EXPECT_TRUE(GetLockedState());
  EXPECT_TRUE(lock_state_test_api.is_animating_lock());
  // Tests that we have two active animation container for post-lock animation,
  // which are lock screen containers and shelf container.
  EXPECT_EQ(2u, test_animator->GetAnimationCount());
  test_animator->AreContainersAnimated(
      SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
      SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN);
  test_animator->AreContainersAnimated(SessionStateAnimator::SHELF,
                                       SessionStateAnimator::ANIMATION_FADE_IN);
  // Tests that after finishing immediate animation, we have no active
  // animations left. Also checks that animation ends.
  test_animator->Advance(test_animator->GetDuration(
      SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE));
  EXPECT_EQ(0u, test_animator->GetAnimationCount());
  EXPECT_FALSE(lock_state_test_api.is_animating_lock());
}

// Tests that displays will not be considered ready to suspend until the
// animated wallpaper change finishes (if the wallpaper is being animated to
// another wallpaper after the screen is locked).
TEST_F(PowerEventObserverTest,
       DisplaysNotReadyForSuspendUntilWallpaperAnimationEnds) {
  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  ASSERT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());

  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  // Set up animation state so wallpaper widget animations are not ended on
  // their creation.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Lock screen - this is expected to start wallpaper change (e.g. to a
  // widget with a blurred wallpaper).
  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
  observer_->OnLockAnimationsComplete();

  WallpaperWidgetController* wallpaper_widget_controller =
      Shell::GetPrimaryRootWindowController()->wallpaper_widget_controller();
  // Assert that the wallpaper is being animated here - otherwise the test will
  // not work.
  ASSERT_TRUE(wallpaper_widget_controller->IsAnimating());

  ui::Compositor* compositor =
      Shell::GetPrimaryRootWindow()->GetHost()->compositor();
  PowerEventObserverTestApi test_api(observer_.get());

  // Simulate a single frame getting composited before the wallpaper animation
  // is done - this frame is expected to be ignored by power event observer's
  // compositing state observer.
  test_api.CompositeFrame(compositor);

  // Simulate wallpaper animation finishing - for the purpose of this test,
  // before suspend begins.
  wallpaper_widget_controller->EndPendingAnimation();

  // Expect that two compositing cycles are completed before suspend continues,
  // and displays get suspended.
  test_api.CompositeFrame(compositor);
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(1, GetNumVisibleCompositors());

  test_api.CompositeFrame(compositor);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

// Tests that animated wallpaper changes will be finished immediately when
// suspend starts (if the screen was locked when suspend started).
TEST_F(PowerEventObserverTest, EndWallpaperAnimationOnSuspendWhileLocked) {
  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  ASSERT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());

  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  // Set up animation state so wallpaper widget animations are not ended on
  // their creation.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Lock screen - this is expected to start wallpaper change (e.g. to a
  // widget with a blurred wallpaper).
  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
  observer_->OnLockAnimationsComplete();

  // Wallpaper animation should be stopped immediately on suspend.
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);

  WallpaperWidgetController* wallpaper_widget_controller =
      Shell::GetPrimaryRootWindowController()->wallpaper_widget_controller();
  EXPECT_FALSE(wallpaper_widget_controller->IsAnimating());

  ui::Compositor* compositor =
      Shell::GetPrimaryRootWindow()->GetHost()->compositor();
  PowerEventObserverTestApi test_api(observer_.get());

  // Expect that two compositing cycles are completed before suspend continues,
  // and displays get suspended.
  test_api.CompositeFrame(compositor);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(1, GetNumVisibleCompositors());

  test_api.CompositeFrame(compositor);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

// Tests that animated wallpaper changes will be finished immediately when
// suspend starts (if the screen lock started before suspend).
TEST_F(PowerEventObserverTest, EndWallpaperAnimationOnSuspendWhileLocking) {
  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  ASSERT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());

  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  // Set up animation state so wallpaper widget animations are not ended on
  // their creation.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Lock screen - this is expected to start wallpaper change (e.g. to a
  // widget with a blurred wallpaper).
  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);

  // If suspend starts, wallpaper animation should be stopped after screen lock
  // completes.
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  observer_->OnLockAnimationsComplete();

  WallpaperWidgetController* wallpaper_widget_controller =
      Shell::GetPrimaryRootWindowController()->wallpaper_widget_controller();
  EXPECT_FALSE(wallpaper_widget_controller->IsAnimating());

  ui::Compositor* compositor =
      Shell::GetPrimaryRootWindow()->GetHost()->compositor();
  PowerEventObserverTestApi test_api(observer_.get());

  // Expect that two compositing cycles are completed before suspend continues,
  // and displays get suspended.
  test_api.CompositeFrame(compositor);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(1, GetNumVisibleCompositors());

  test_api.CompositeFrame(compositor);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

// Tests that animated wallpaper changes will be finished immediately when
// suspend starts and causes a screen lock.
TEST_F(PowerEventObserverTest, EndWallpaperAnimationAfterLockDueToSuspend) {
  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  ASSERT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());

  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  // Set up animation state so wallpaper widget animations are not ended on
  // their creation.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Start suspend (which should start screen lock) - verify that wallpaper is
  // not animating after the screen lock animations are reported as complete.
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);
  observer_->OnLockAnimationsComplete();

  WallpaperWidgetController* wallpaper_widget_controller =
      Shell::GetPrimaryRootWindowController()->wallpaper_widget_controller();
  EXPECT_FALSE(wallpaper_widget_controller->IsAnimating());

  ui::Compositor* compositor =
      Shell::GetPrimaryRootWindow()->GetHost()->compositor();
  PowerEventObserverTestApi test_api(observer_.get());

  // Expect that two compositing cycles are completed before suspend continues,
  // and displays get suspended.
  test_api.CompositeFrame(compositor);
  EXPECT_EQ(1, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(1, GetNumVisibleCompositors());

  test_api.CompositeFrame(compositor);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

// Tests that removing a display while power event observer is waiting for the
// wallpaper animation does not cause suspend to hang.
TEST_F(PowerEventObserverTest, DisplayRemovedDuringWallpaperAnimation) {
  chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
  ASSERT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());

  SetCanLockScreen(true);
  SetShouldLockScreenAutomatically(true);

  UpdateDisplay("100x100,200x200");

  // Set up animation state so wallpaper widget animations are not ended on
  // their creation.
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Lock screen - this is expected to start wallpaper change (e.g. to a
  // widget with a blurred wallpaper).
  BlockUserSession(BLOCKED_BY_LOCK_SCREEN);
  observer_->OnLockAnimationsComplete();

  // Remove a display before wallpaper animation ends.
  UpdateDisplay("100x100");
  base::RunLoop().RunUntilIdle();

  // Start suspend and verify the suspend proceeds when the primary window's
  // compositors go throug two compositing cycles.
  observer_->SuspendImminent(power_manager::SuspendImminent_Reason_OTHER);

  ui::Compositor* compositor =
      Shell::GetPrimaryRootWindow()->GetHost()->compositor();
  PowerEventObserverTestApi test_api(observer_.get());

  // Expect that two compositing cycles are completed before suspend continues,
  // and displays get suspended.
  test_api.CompositeFrame(compositor);
  test_api.CompositeFrame(compositor);
  EXPECT_EQ(0, client->GetNumPendingSuspendReadinessCallbacks());
  EXPECT_EQ(0, GetNumVisibleCompositors());
}

}  // namespace ash
