// Copyright 2017 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/rotator/screen_rotation_animator.h"

#include <memory>

#include "ash/display/display_configuration_controller_test_api.h"
#include "ash/display/screen_orientation_controller.h"
#include "ash/display/screen_orientation_controller_test_api.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/public/cpp/ash_switches.h"
#include "ash/rotator/screen_rotation_animator_observer.h"
#include "ash/rotator/screen_rotation_animator_test_api.h"
#include "ash/shell.h"
#include "ash/system/overview/overview_button_tray.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/status_area_widget_test_helper.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/ash_test_helper.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/callback_forward.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "ui/compositor/layer_tree_owner.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/display/display.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/screen.h"
#include "ui/display/test/display_manager_test_api.h"
#include "ui/wm/core/window_util.h"

namespace ash {

namespace {

display::Display::Rotation GetDisplayRotation(int64_t display_id) {
  return Shell::Get()
      ->display_manager()
      ->GetDisplayInfo(display_id)
      .GetActiveRotation();
}

void SetDisplayRotation(int64_t display_id,
                        display::Display::Rotation rotation) {
  Shell::Get()->display_manager()->SetDisplayRotation(
      display_id, rotation, display::Display::RotationSource::USER);
}

OverviewButtonTray* GetTray() {
  return StatusAreaWidgetTestHelper::GetStatusAreaWidget()
      ->overview_button_tray();
}

class AnimationObserver : public ScreenRotationAnimatorObserver {
 public:
  AnimationObserver() = default;

  bool notified() const { return notified_; }

  void OnScreenRotationAnimationFinished(
      ScreenRotationAnimator* animator) override {
    notified_ = true;
  }

 private:
  bool notified_ = false;

  DISALLOW_COPY_AND_ASSIGN(AnimationObserver);
};

class TestScreenRotationAnimator : public ScreenRotationAnimator {
 public:
  TestScreenRotationAnimator(aura::Window* root_window,
                             const base::Closure& before_callback,
                             const base::Closure& after_callback);
  ~TestScreenRotationAnimator() override = default;

 private:
  CopyCallback CreateAfterCopyCallbackBeforeRotation(
      std::unique_ptr<ScreenRotationRequest> rotation_request) override;
  CopyCallback CreateAfterCopyCallbackAfterRotation(
      std::unique_ptr<ScreenRotationRequest> rotation_request) override;

  void IntersectBefore(CopyCallback next_callback,
                       std::unique_ptr<viz::CopyOutputResult> result);
  void IntersectAfter(CopyCallback next_callback,
                      std::unique_ptr<viz::CopyOutputResult> result);

  base::Closure intersect_before_callback_;
  base::Closure intersect_after_callback_;

  DISALLOW_COPY_AND_ASSIGN(TestScreenRotationAnimator);
};

TestScreenRotationAnimator::TestScreenRotationAnimator(
    aura::Window* root_window,
    const base::Closure& before_callback,
    const base::Closure& after_callback)
    : ScreenRotationAnimator(root_window),
      intersect_before_callback_(before_callback),
      intersect_after_callback_(after_callback) {}

ScreenRotationAnimator::CopyCallback
TestScreenRotationAnimator::CreateAfterCopyCallbackBeforeRotation(
    std::unique_ptr<ScreenRotationRequest> rotation_request) {
  CopyCallback next_callback =
      ScreenRotationAnimator::CreateAfterCopyCallbackBeforeRotation(
          std::move(rotation_request));
  return base::BindOnce(&TestScreenRotationAnimator::IntersectBefore,
                        base::Unretained(this), std::move(next_callback));
}

ScreenRotationAnimator::CopyCallback
TestScreenRotationAnimator::CreateAfterCopyCallbackAfterRotation(
    std::unique_ptr<ScreenRotationRequest> rotation_request) {
  CopyCallback next_callback =
      ScreenRotationAnimator::CreateAfterCopyCallbackAfterRotation(
          std::move(rotation_request));
  return base::BindOnce(&TestScreenRotationAnimator::IntersectAfter,
                        base::Unretained(this), std::move(next_callback));
}

void TestScreenRotationAnimator::IntersectBefore(
    CopyCallback next_callback,
    std::unique_ptr<viz::CopyOutputResult> result) {
  intersect_before_callback_.Run();
  std::move(next_callback).Run(std::move(result));
}

void TestScreenRotationAnimator::IntersectAfter(
    CopyCallback next_callback,
    std::unique_ptr<viz::CopyOutputResult> result) {
  intersect_after_callback_.Run();
  std::move(next_callback).Run(std::move(result));
}

}  // namespace

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

  // AshTestBase:
  void SetUp() override;

 protected:
  int64_t display_id() const { return display_.id(); }

  ScreenRotationAnimator* animator() { return animator_.get(); }

  ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); }

 private:
  display::Display display_;

  std::unique_ptr<ScreenRotationAnimator> animator_;

  std::unique_ptr<ScreenRotationAnimatorTestApi> test_api_;

  std::unique_ptr<ui::ScopedAnimationDurationScaleMode> non_zero_duration_mode_;

  DISALLOW_COPY_AND_ASSIGN(ScreenRotationAnimatorSlowAnimationTest);
};

void ScreenRotationAnimatorSlowAnimationTest::SetUp() {
  AshTestBase::SetUp();

  display_ = display::Screen::GetScreen()->GetPrimaryDisplay();
  animator_ = std::make_unique<ScreenRotationAnimator>(
      Shell::GetRootWindowForDisplayId(display_.id()));
  test_api_ = std::make_unique<ScreenRotationAnimatorTestApi>(animator_.get());
  test_api()->DisableAnimationTimers();
  non_zero_duration_mode_ =
      std::make_unique<ui::ScopedAnimationDurationScaleMode>(
          ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
}

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

  // AshTestBase:
  void SetUp() override;

  void RemoveSecondaryDisplay(const std::string& specs);
  void QuitWaitForCopyCallback();

 protected:
  int64_t display_id() const { return display_.id(); }

  TestScreenRotationAnimator* animator() { return animator_.get(); }

  void SetScreenRotationAnimator(aura::Window* root_window,
                                 const base::Closure& before_callback,
                                 const base::Closure& after_callback);

  ScreenRotationAnimatorTestApi* test_api() { return test_api_.get(); }

  void WaitForCopyCallback();

  std::unique_ptr<base::RunLoop> run_loop_;

 protected:
  std::unique_ptr<TestScreenRotationAnimator> animator_;

 private:
  display::Display display_;

  std::unique_ptr<ScreenRotationAnimatorTestApi> test_api_;

  std::unique_ptr<ui::ScopedAnimationDurationScaleMode> non_zero_duration_mode_;

  DISALLOW_COPY_AND_ASSIGN(ScreenRotationAnimatorSmoothAnimationTest);
};

void ScreenRotationAnimatorSmoothAnimationTest::RemoveSecondaryDisplay(
    const std::string& specs) {
  UpdateDisplay(specs);
  QuitWaitForCopyCallback();
}

void ScreenRotationAnimatorSmoothAnimationTest::QuitWaitForCopyCallback() {
  run_loop_->QuitWhenIdle();
}

void ScreenRotationAnimatorSmoothAnimationTest::SetUp() {
  AshTestBase::SetUp();

  display_ = display::Screen::GetScreen()->GetPrimaryDisplay();
  run_loop_ = std::make_unique<base::RunLoop>();
  SetScreenRotationAnimator(Shell::GetRootWindowForDisplayId(display_.id()),
                            run_loop_->QuitWhenIdleClosure(),
                            run_loop_->QuitWhenIdleClosure());
  non_zero_duration_mode_ =
      std::make_unique<ui::ScopedAnimationDurationScaleMode>(
          ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
}

void ScreenRotationAnimatorSmoothAnimationTest::SetScreenRotationAnimator(
    aura::Window* root_window,
    const base::Closure& before_callback,
    const base::Closure& after_callback) {
  animator_ = std::make_unique<TestScreenRotationAnimator>(
      root_window, before_callback, after_callback);
  test_api_ = std::make_unique<ScreenRotationAnimatorTestApi>(animator_.get());
  test_api()->DisableAnimationTimers();
}

void ScreenRotationAnimatorSmoothAnimationTest::WaitForCopyCallback() {
  run_loop_.reset(new base::RunLoop());
  run_loop_->Run();
}

TEST_F(ScreenRotationAnimatorSlowAnimationTest, ShouldNotifyObserver) {
  SetDisplayRotation(display_id(), display::Display::ROTATE_0);
  AnimationObserver observer;
  animator()->AddScreenRotationAnimatorObserver(&observer);
  EXPECT_FALSE(observer.notified());

  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_FALSE(observer.notified());

  test_api()->CompleteAnimations();
  EXPECT_TRUE(observer.notified());
  EXPECT_FALSE(test_api()->HasActiveAnimations());
  animator()->RemoveScreenRotationAnimatorObserver(&observer);
}

TEST_F(ScreenRotationAnimatorSlowAnimationTest, ShouldNotifyObserverOnce) {
  SetDisplayRotation(display_id(), display::Display::ROTATE_0);
  AnimationObserver observer;
  animator()->AddScreenRotationAnimatorObserver(&observer);
  EXPECT_FALSE(observer.notified());

  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_FALSE(observer.notified());

  animator()->Rotate(display::Display::ROTATE_180,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_FALSE(observer.notified());

  test_api()->CompleteAnimations();
  EXPECT_TRUE(observer.notified());
  EXPECT_FALSE(test_api()->HasActiveAnimations());
  animator()->RemoveScreenRotationAnimatorObserver(&observer);
}

TEST_F(ScreenRotationAnimatorSlowAnimationTest, RotatesToDifferentRotation) {
  SetDisplayRotation(display_id(), display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_TRUE(test_api()->HasActiveAnimations());

  test_api()->CompleteAnimations();
  EXPECT_FALSE(test_api()->HasActiveAnimations());
}

TEST_F(ScreenRotationAnimatorSlowAnimationTest,
       ShouldNotRotateTheSameRotation) {
  SetDisplayRotation(display_id(), display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_0,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_FALSE(test_api()->HasActiveAnimations());
}

// Simulates the situation that if there is a new rotation request during
// animation, it should stop the animation immediately and add the new rotation
// request to the |last_pending_request_|.
TEST_F(ScreenRotationAnimatorSlowAnimationTest, RotatesDuringRotation) {
  SetDisplayRotation(display_id(), display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_TRUE(animator()->IsRotating());
  EXPECT_EQ(display::Display::ROTATE_90, animator()->GetTargetRotation());

  animator()->Rotate(display::Display::ROTATE_180,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_TRUE(test_api()->HasActiveAnimations());
  EXPECT_TRUE(animator()->IsRotating());
  EXPECT_EQ(display::Display::ROTATE_180, animator()->GetTargetRotation());

  test_api()->CompleteAnimations();
  EXPECT_FALSE(test_api()->HasActiveAnimations());
  EXPECT_FALSE(animator()->IsRotating());

  EXPECT_EQ(display::Display::ROTATE_180, GetDisplayRotation(display_id()));
}

// If there are multiple requests queued during animation, it should process the
// last request and finish the rotation animation.
TEST_F(ScreenRotationAnimatorSlowAnimationTest, ShouldCompleteAnimations) {
  SetDisplayRotation(display_id(), display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_TRUE(test_api()->HasActiveAnimations());

  animator()->Rotate(display::Display::ROTATE_180,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_TRUE(test_api()->HasActiveAnimations());

  animator()->Rotate(display::Display::ROTATE_270,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);
  EXPECT_TRUE(test_api()->HasActiveAnimations());

  test_api()->CompleteAnimations();
  EXPECT_FALSE(test_api()->HasActiveAnimations());
  EXPECT_EQ(display::Display::ROTATE_270, GetDisplayRotation(display_id()));
}

// Test that slow screen rotation animation will not interrupt hide animation.
// The OverviewButton should be hidden.
TEST_F(ScreenRotationAnimatorSlowAnimationTest,
       OverviewButtonTrayHideAnimationAlwaysCompletes) {
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);

  // Long duration for hide animation, to allow it to be interrupted.
  ui::ScopedAnimationDurationScaleMode hide_duration(
      ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
  GetTray()->SetVisible(false);

  // ScreenRotationAnimator copies the current layers, and deletes them upon
  // completion. Allow its animation to complete first.
  ui::ScopedAnimationDurationScaleMode rotate_duration(
      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
  SetDisplayRotation(display_id(), display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_SYNC);

  EXPECT_FALSE(GetTray()->visible());
}

// Test enable smooth screen rotation code path.
TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
       RotatesToDifferentRotationWithCopyCallback) {
  const int64_t display_id = display_manager()->GetDisplayAt(0).id();
  SetScreenRotationAnimator(
      Shell::GetRootWindowForDisplayId(display_id),
      run_loop_->QuitWhenIdleClosure(),
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::QuitWaitForCopyCallback,
          base::Unretained(this)));
  SetDisplayRotation(display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  EXPECT_TRUE(animator()->IsRotating());

  EXPECT_EQ(display::Display::ROTATE_90, animator()->GetTargetRotation());
  EXPECT_NE(display::Display::ROTATE_90, GetDisplayRotation(display_id));

  WaitForCopyCallback();
  EXPECT_TRUE(test_api()->HasActiveAnimations());
  EXPECT_EQ(display::Display::ROTATE_90, animator()->GetTargetRotation());
  // Once copy is made, the rotation is set to the target, with the
  // image that was rotated to the original orientation.
  EXPECT_EQ(display::Display::ROTATE_90, GetDisplayRotation(display_id));

  test_api()->CompleteAnimations();
  EXPECT_FALSE(test_api()->HasActiveAnimations());
  EXPECT_EQ(display::Display::ROTATE_90, GetDisplayRotation(display_id));
}

// If the rotating external secondary display is removed before the first copy
// request callback called, it should stop rotating.
TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
       RemoveExternalSecondaryDisplayBeforeFirstCopyCallback) {
  UpdateDisplay("640x480,800x600");
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());

  const int64_t primary_display_id = display_manager()->GetDisplayAt(0).id();
  const int64_t secondary_display_id = display_manager()->GetDisplayAt(1).id();

  SetScreenRotationAnimator(
      Shell::GetRootWindowForDisplayId(secondary_display_id),
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::RemoveSecondaryDisplay,
          base::Unretained(this), "640x480"),
      run_loop_->QuitWhenIdleClosure());
  SetDisplayRotation(secondary_display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  WaitForCopyCallback();
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(primary_display_id, display_manager()->GetDisplayAt(0).id());
}

// If the rotating external primary display is removed before the first copy
// request callback called, it should stop rotating.
TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
       RemoveExternalPrimaryDisplayBeforeFirstCopyCallback) {
  UpdateDisplay("640x480,800x600");
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());

  Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(
      display_manager()->GetDisplayAt(1).id());
  const int64_t primary_display_id = display_manager()->GetDisplayAt(1).id();
  const int64_t secondary_display_id = display_manager()->GetDisplayAt(0).id();
  SetScreenRotationAnimator(
      Shell::GetRootWindowForDisplayId(primary_display_id),
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::RemoveSecondaryDisplay,
          base::Unretained(this), "640x480"),
      run_loop_->QuitWhenIdleClosure());
  SetDisplayRotation(primary_display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  WaitForCopyCallback();
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(secondary_display_id, display_manager()->GetDisplayAt(0).id());
}

// If the rotating external secondary display is removed before the second copy
// request callback called, it should stop rotating.
TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
       RemoveExternalSecondaryDisplayBeforeSecondCopyCallback) {
  UpdateDisplay("640x480,800x600");
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());

  const int64_t primary_display_id = display_manager()->GetDisplayAt(0).id();
  const int64_t secondary_display_id = display_manager()->GetDisplayAt(1).id();
  SetScreenRotationAnimator(
      Shell::GetRootWindowForDisplayId(secondary_display_id),
      run_loop_->QuitWhenIdleClosure(),
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::RemoveSecondaryDisplay,
          base::Unretained(this), "640x480"));
  SetDisplayRotation(secondary_display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  WaitForCopyCallback();
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(primary_display_id, display_manager()->GetDisplayAt(0).id());
}

// If the rotating external primary display is removed before the second copy
// request callback called, it should stop rotating.
TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
       RemoveExternalPrimaryDisplayBeforeSecondCopyCallback) {
  UpdateDisplay("640x480,800x600");
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());

  Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(
      display_manager()->GetDisplayAt(1).id());
  const int64_t primary_display_id = display_manager()->GetDisplayAt(1).id();
  const int64_t secondary_display_id = display_manager()->GetDisplayAt(0).id();
  SetScreenRotationAnimator(
      Shell::GetRootWindowForDisplayId(primary_display_id),
      run_loop_->QuitWhenIdleClosure(),
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::RemoveSecondaryDisplay,
          base::Unretained(this), "640x480"));
  SetDisplayRotation(primary_display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  WaitForCopyCallback();
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(secondary_display_id, display_manager()->GetDisplayAt(0).id());
}

// If the external primary display is removed while rotating the secondary
// display. It should stop rotating the secondary display because the
// |root_window| changed.
TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
       RemoveExternalPrimaryDisplayDuringAnimationChangedRootWindow) {
  UpdateDisplay("640x480,800x600");
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());

  Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(
      display_manager()->GetDisplayAt(1).id());
  const int64_t secondary_display_id = display_manager()->GetDisplayAt(0).id();
  SetScreenRotationAnimator(
      Shell::GetRootWindowForDisplayId(secondary_display_id),
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::RemoveSecondaryDisplay,
          base::Unretained(this), "640x480"),
      run_loop_->QuitWhenIdleClosure());
  SetDisplayRotation(secondary_display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  WaitForCopyCallback();
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(secondary_display_id, display_manager()->GetDisplayAt(0).id());
  EXPECT_EQ(display::Display::ROTATE_0,
            GetDisplayRotation(secondary_display_id));
}

// Test that smooth screen rotation animation will not interrupt hide animation.
// The OverviewButton should be hidden.
TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
       OverviewButtonTrayHideAnimationAlwaysCompletes) {
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);

  // Long duration for hide animation, to allow it to be interrupted.
  ui::ScopedAnimationDurationScaleMode hide_duration(
      ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
  GetTray()->SetVisible(false);

  // Allow ScreenRotationAnimator animation to complete first.
  ui::ScopedAnimationDurationScaleMode rotate_duration(
      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
  int64_t display_id = display_manager()->GetDisplayAt(0).id();
  SetScreenRotationAnimator(
      Shell::GetRootWindowForDisplayId(display_id),
      run_loop_->QuitWhenIdleClosure(),
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::QuitWaitForCopyCallback,
          base::Unretained(this)));
  SetDisplayRotation(display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  WaitForCopyCallback();

  GetTray()->layer()->GetAnimator()->StopAnimating();
  EXPECT_FALSE(GetTray()->visible());
}

// Test that smooth screen rotation animation will work when |root_window|
// recreated.
TEST_F(ScreenRotationAnimatorSmoothAnimationTest,
       ShouldRotateAfterRecreateLayers) {
  const int64_t display_id = display_manager()->GetDisplayAt(0).id();
  aura::Window* root_window = Shell::GetRootWindowForDisplayId(display_id);
  SetScreenRotationAnimator(
      root_window, run_loop_->QuitWhenIdleClosure(),
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::QuitWaitForCopyCallback,
          base::Unretained(this)));
  SetDisplayRotation(display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  WaitForCopyCallback();
  EXPECT_TRUE(test_api()->HasActiveAnimations());

  test_api()->CompleteAnimations();
  EXPECT_FALSE(test_api()->HasActiveAnimations());
  EXPECT_EQ(display::Display::ROTATE_90, GetDisplayRotation(display_id));

  // Colone and delete the old layer tree.
  std::unique_ptr<ui::LayerTreeOwner> old_layer_tree_owner =
      ::wm::RecreateLayers(root_window);
  old_layer_tree_owner.reset();

  // Should work for another rotation.
  animator()->Rotate(display::Display::ROTATE_180,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  WaitForCopyCallback();
  EXPECT_TRUE(test_api()->HasActiveAnimations());

  test_api()->CompleteAnimations();
  EXPECT_FALSE(test_api()->HasActiveAnimations());
  EXPECT_EQ(display::Display::ROTATE_180, GetDisplayRotation(display_id));
}

TEST_F(ScreenRotationAnimatorSmoothAnimationTest, DisplayChangeDuringCopy) {
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);

  aura::Window* root_window =
      Shell::GetRootWindowForDisplayId(internal_display_id);
  SetScreenRotationAnimator(
      root_window,
      base::Bind(
          &ScreenRotationAnimatorSmoothAnimationTest::QuitWaitForCopyCallback,
          base::Unretained(this)),
      run_loop_->QuitWhenIdleClosure());

  TestScreenRotationAnimator* animator = animator_.get();
  DisplayConfigurationControllerTestApi testapi(
      Shell::Get()->display_configuration_controller());
  testapi.SetDisplayAnimator(true);
  testapi.SetScreenRotationAnimatorForDisplay(internal_display_id,
                                              std::move(animator_));
  ScreenOrientationControllerTestApi(
      Shell::Get()->screen_orientation_controller())
      .SetDisplayRotation(display::Display::ROTATE_90,
                          display::Display::RotationSource::ACCELEROMETER);

  EXPECT_TRUE(animator->IsRotating());
  display_manager()->UpdateDisplays();
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_FALSE(animator->IsRotating());

  WaitForCopyCallback();
  EXPECT_FALSE(animator->IsRotating());
  EXPECT_EQ(display::Display::ROTATE_0,
            GetDisplayRotation(internal_display_id));
}

TEST_F(ScreenRotationAnimatorSmoothAnimationTest, NewRequestShouldNotCancel) {
  const int64_t display_id = display_manager()->GetDisplayAt(0).id();
  aura::Window* root_window = Shell::GetRootWindowForDisplayId(display_id);
  SetScreenRotationAnimator(
      root_window, run_loop_->QuitWhenIdleClosure(),
      base::BindRepeating(
          &ScreenRotationAnimatorSmoothAnimationTest::QuitWaitForCopyCallback,
          base::Unretained(this)));
  SetDisplayRotation(display_id, display::Display::ROTATE_0);
  animator()->Rotate(display::Display::ROTATE_90,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  EXPECT_EQ(display::Display::ROTATE_0, GetDisplayRotation(display_id));

  // Requesting new orientation while waiting for copy should apply the previous
  // change immediately.
  animator()->Rotate(display::Display::ROTATE_180,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  EXPECT_EQ(display::Display::ROTATE_90, GetDisplayRotation(display_id));

  // Requesting yet another new orientation while waiting for copy should do the
  // same.
  animator()->Rotate(display::Display::ROTATE_270,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  EXPECT_EQ(display::Display::ROTATE_180, GetDisplayRotation(display_id));

  WaitForCopyCallback();
  // The display must be rotated once copy finishes.
  EXPECT_EQ(display::Display::ROTATE_270, GetDisplayRotation(display_id));
  EXPECT_TRUE(test_api()->HasActiveAnimations());

  // Requesting new orientation while animating will be queued.
  animator()->Rotate(display::Display::ROTATE_0,
                     display::Display::RotationSource::USER,
                     DisplayConfigurationController::ANIMATION_ASYNC);
  EXPECT_EQ(display::Display::ROTATE_270, GetDisplayRotation(display_id));
  EXPECT_FALSE(test_api()->HasActiveAnimations());

  // Finish current animation will start queued animation (from 270 to 0).
  test_api()->CompleteAnimations();
  EXPECT_TRUE(animator()->IsRotating());
  EXPECT_EQ(display::Display::ROTATE_270, GetDisplayRotation(display_id));
  EXPECT_FALSE(test_api()->HasActiveAnimations());

  WaitForCopyCallback();
  EXPECT_TRUE(test_api()->HasActiveAnimations());
  EXPECT_EQ(display::Display::ROTATE_0, GetDisplayRotation(display_id));

  test_api()->CompleteAnimations();
  EXPECT_FALSE(test_api()->HasActiveAnimations());
  EXPECT_EQ(display::Display::ROTATE_0, GetDisplayRotation(display_id));
}

}  // namespace ash
