123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- // Copyright (c) 2012 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/window_animations.h"
- #include "ash/public/cpp/keyboard/keyboard_switches.h"
- #include "ash/public/cpp/shelf_config.h"
- #include "ash/public/cpp/shell_window_ids.h"
- #include "ash/public/cpp/window_animation_types.h"
- #include "ash/shell.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/wm/window_state.h"
- #include "ash/wm/wm_event.h"
- #include "ash/wm/workspace_controller.h"
- #include "base/command_line.h"
- #include "base/time/time.h"
- #include "ui/aura/test/test_windows.h"
- #include "ui/aura/window.h"
- #include "ui/compositor/layer.h"
- #include "ui/compositor/layer_animation_observer.h"
- #include "ui/compositor/layer_animator.h"
- #include "ui/compositor/layer_tree_owner.h"
- #include "ui/compositor/scoped_animation_duration_scale_mode.h"
- #include "ui/compositor/scoped_layer_animation_settings.h"
- #include "ui/wm/core/window_util.h"
- using aura::Window;
- using ui::Layer;
- namespace ash {
- namespace {
- void WaitForMilliseconds(int ms) {
- base::RunLoop loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, loop.QuitClosure(), base::Milliseconds(ms));
- loop.Run();
- }
- } // namespace
- class WindowAnimationsTest : public AshTestBase {
- public:
- WindowAnimationsTest() = default;
- WindowAnimationsTest(const WindowAnimationsTest&) = delete;
- WindowAnimationsTest& operator=(const WindowAnimationsTest&) = delete;
- void SetUp() override {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- keyboard::switches::kEnableVirtualKeyboard);
- AshTestBase::SetUp();
- }
- };
- // Listens to animation scheduled notifications. Remembers the transition
- // duration of the first sequence.
- class MinimizeAnimationObserver : public ui::LayerAnimationObserver {
- public:
- explicit MinimizeAnimationObserver(ui::LayerAnimator* animator)
- : animator_(animator) {
- animator_->AddObserver(this);
- // RemoveObserver is called when the first animation is scheduled and so
- // there should be no need for now to remove it in destructor.
- }
- MinimizeAnimationObserver(const MinimizeAnimationObserver&) = delete;
- MinimizeAnimationObserver& operator=(const MinimizeAnimationObserver&) =
- delete;
- base::TimeDelta duration() { return duration_; }
- protected:
- // ui::LayerAnimationObserver:
- void OnLayerAnimationScheduled(
- ui::LayerAnimationSequence* sequence) override {
- duration_ = animator_->GetTransitionDuration();
- animator_->RemoveObserver(this);
- }
- void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {}
- void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {}
- private:
- ui::LayerAnimator* animator_;
- base::TimeDelta duration_;
- };
- // This is the class that simulates the behavior of
- // `FrameHeader::FrameAnimatorView` which may recreate the window layer in the
- // middle of setting the animation of the old and new layer.
- class FrameAnimator : public ui::ImplicitAnimationObserver {
- public:
- explicit FrameAnimator(aura::Window* window) : window_(window) {
- // Set up an animation which will be stopped before the old layer animation.
- SetOpacityAnimation(window_->layer());
- }
- FrameAnimator(const FrameAnimator&) = delete;
- FrameAnimator& operator=(const FrameAnimator&) = delete;
- ~FrameAnimator() override = default;
- // ui::ImplicitAnimationObserver:
- void OnImplicitAnimationsCompleted() override {
- // Once the initial animation is stopped by the old layer, start a new
- // opacity animation and recreate the window layer at the same time. The
- // opacity animation will be stopped when the layer set opacity and the
- // layer is destroyed.
- if (!animation_started_)
- StartAnimation();
- else
- layer_owner_.reset();
- }
- private:
- // Set an opacity animation which should last longer than the cross fade
- // animation.
- void SetOpacityAnimation(ui::Layer* layer) {
- layer->SetOpacity(1.f);
- ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
- settings.AddObserver(this);
- settings.SetTransitionDuration(base::Milliseconds(1000));
- layer->SetOpacity(0.f);
- }
- // Recreate the window layer and start a new opacity animation.
- void StartAnimation() {
- layer_owner_ =
- std::make_unique<ui::LayerTreeOwner>(window_->RecreateLayer());
- SetOpacityAnimation(layer_owner_->root());
- animation_started_ = true;
- }
- aura::Window* window_;
- std::unique_ptr<ui::LayerTreeOwner> layer_owner_;
- bool animation_started_ = false;
- };
- TEST_F(WindowAnimationsTest, HideShowBrightnessGrayscaleAnimation) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
- window->Show();
- EXPECT_TRUE(window->layer()->visible());
- // Hiding.
- wm::SetWindowVisibilityAnimationType(
- window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE);
- AnimateOnChildWindowVisibilityChanged(window.get(), false);
- EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
- EXPECT_FALSE(window->layer()->GetTargetVisibility());
- EXPECT_FALSE(window->layer()->visible());
- // Showing.
- wm::SetWindowVisibilityAnimationType(
- window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE);
- AnimateOnChildWindowVisibilityChanged(window.get(), true);
- EXPECT_EQ(0.0f, window->layer()->GetTargetBrightness());
- EXPECT_EQ(0.0f, window->layer()->GetTargetGrayscale());
- EXPECT_TRUE(window->layer()->visible());
- // Stays shown.
- window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
- base::Seconds(5));
- EXPECT_EQ(0.0f, window->layer()->GetTargetBrightness());
- EXPECT_EQ(0.0f, window->layer()->GetTargetGrayscale());
- EXPECT_TRUE(window->layer()->visible());
- }
- TEST_F(WindowAnimationsTest, LayerTargetVisibility) {
- std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
- // Layer target visibility changes according to Show/Hide.
- window->Show();
- EXPECT_TRUE(window->layer()->GetTargetVisibility());
- window->Hide();
- EXPECT_FALSE(window->layer()->GetTargetVisibility());
- window->Show();
- EXPECT_TRUE(window->layer()->GetTargetVisibility());
- }
- TEST_F(WindowAnimationsTest, CrossFadeToBounds) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
- window->SetBounds(gfx::Rect(5, 10, 320, 240));
- window->Show();
- Layer* old_layer = window->layer();
- EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
- // Cross fade to a larger size, as in a maximize animation.
- WindowState::Get(window.get())
- ->SetBoundsDirectCrossFade(gfx::Rect(0, 0, 640, 480));
- // Window's layer has been replaced.
- EXPECT_NE(old_layer, window->layer());
- // Original layer stays opaque and stretches to new size.
- EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
- EXPECT_EQ("5,10 320x240", old_layer->bounds().ToString());
- gfx::Transform grow_transform;
- grow_transform.Translate(-5.f, -10.f);
- grow_transform.Scale(640.f / 320.f, 480.f / 240.f);
- EXPECT_EQ(grow_transform, old_layer->GetTargetTransform());
- // New layer animates in to the identity transform.
- EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
- EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
- // Run the animations to completion.
- old_layer->GetAnimator()->Step(base::TimeTicks::Now() + base::Seconds(1));
- window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
- base::Seconds(1));
- // Cross fade to a smaller size, as in a restore animation.
- old_layer = window->layer();
- WindowState::Get(window.get())
- ->SetBoundsDirectCrossFade(gfx::Rect(5, 10, 320, 240));
- // Again, window layer has been replaced.
- EXPECT_NE(old_layer, window->layer());
- // Original layer fades out and stretches down to new size.
- EXPECT_EQ(0.0f, old_layer->GetTargetOpacity());
- EXPECT_EQ("0,0 640x480", old_layer->bounds().ToString());
- gfx::Transform shrink_transform;
- shrink_transform.Translate(5.f, 10.f);
- shrink_transform.Scale(320.f / 640.f, 240.f / 480.f);
- EXPECT_EQ(shrink_transform, old_layer->GetTargetTransform());
- // New layer animates in to the identity transform.
- EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
- EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
- old_layer->GetAnimator()->Step(base::TimeTicks::Now() + base::Seconds(1));
- window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
- base::Seconds(1));
- }
- // Tests that when crossfading from a window which has a transform, the cross
- // fading animation should be ignored and the window should set to its desired
- // bounds directly.
- TEST_F(WindowAnimationsTest, CrossFadeToBoundsFromTransform) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
- window->SetBounds(gfx::Rect(10, 10, 320, 240));
- gfx::Transform half_size;
- half_size.Translate(10, 10);
- half_size.Scale(0.5f, 0.5f);
- window->SetTransform(half_size);
- window->Show();
- Layer* old_layer = window->layer();
- EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
- // Cross fade to a larger size, as in a maximize animation.
- WindowState::Get(window.get())
- ->SetBoundsDirectCrossFade(gfx::Rect(0, 0, 640, 480));
- // Window's layer has not been replaced.
- EXPECT_EQ(old_layer, window->layer());
- // Original layer stays opaque and set to new size directly.
- EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
- EXPECT_EQ("0,0 640x480", old_layer->bounds().ToString());
- // Window still has its old transform before crossfading animation.
- EXPECT_EQ(half_size, old_layer->transform());
- }
- // Tests that if we recreate the window layers during a cross fade animation,
- // there is no crash.
- // Regression test for https://crbug.com/1088169.
- TEST_F(WindowAnimationsTest, CrossFadeThenRecreate) {
- auto window = CreateTestWindow(gfx::Rect(100, 100));
- // Use a bit more time than NON_ZERO_DURATION as its possible with non zero we
- // finish the animation instantly.
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
- WindowState* window_state = WindowState::Get(window.get());
- window_state->Maximize();
- ASSERT_TRUE(window->layer()->GetAnimator()->is_animating());
- // Recreate the layers and then delete |window|. There should be no crash when
- // stopping the old layers animation.
- std::unique_ptr<ui::LayerTreeOwner> tree = wm::RecreateLayers(window.get());
- window.reset();
- tree->root()->GetAnimator()->StopAnimating();
- }
- // Tests that if the window layer is recreated after setting the old layer's
- // animation (e.g., by `FrameHeader::FrameAnimatorView::StartAnimation`). There
- // should be no crash. Regression test for https://crbug.com/1313977.
- TEST_F(WindowAnimationsTest, RecreateWhenSettingCrossFade) {
- auto window = CreateTestWindow(gfx::Rect(100, 100));
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
- auto frame_animator = std::make_unique<FrameAnimator>(window.get());
- WindowState::Get(window.get())->Maximize();
- }
- TEST_F(WindowAnimationsTest, LockAnimationDuration) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
- Layer* layer = window->layer();
- window->SetBounds(gfx::Rect(5, 10, 320, 240));
- window->Show();
- // Test that it is possible to override transition duration when it is not
- // locked.
- {
- ui::ScopedLayerAnimationSettings settings1(layer->GetAnimator());
- settings1.SetTransitionDuration(base::Milliseconds(1000));
- {
- ui::ScopedLayerAnimationSettings settings2(layer->GetAnimator());
- // Duration is not locked so it gets overridden.
- settings2.SetTransitionDuration(base::Milliseconds(50));
- WindowState::Get(window.get())->Minimize();
- EXPECT_TRUE(layer->GetAnimator()->is_animating());
- // Expect duration from the inner scope
- EXPECT_EQ(50,
- layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
- }
- window->Show();
- layer->GetAnimator()->StopAnimating();
- }
- // Test that it is possible to lock transition duration
- {
- // Update layer as minimizing will replace the window's layer.
- layer = window->layer();
- ui::ScopedLayerAnimationSettings settings1(layer->GetAnimator());
- settings1.SetTransitionDuration(base::Milliseconds(1000));
- // Duration is locked in outer scope.
- settings1.LockTransitionDuration();
- {
- ui::ScopedLayerAnimationSettings settings2(layer->GetAnimator());
- // Transition duration setting is ignored.
- settings2.SetTransitionDuration(base::Milliseconds(50));
- WindowState::Get(window.get())->Minimize();
- EXPECT_TRUE(layer->GetAnimator()->is_animating());
- // Expect duration from the outer scope
- EXPECT_EQ(1000,
- layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
- }
- window->Show();
- layer->GetAnimator()->StopAnimating();
- }
- // Test that duration respects default.
- {
- layer = window->layer();
- // Query default duration.
- MinimizeAnimationObserver observer(layer->GetAnimator());
- WindowState::Get(window.get())->Minimize();
- EXPECT_TRUE(layer->GetAnimator()->is_animating());
- base::TimeDelta default_duration(observer.duration());
- window->Show();
- layer->GetAnimator()->StopAnimating();
- layer = window->layer();
- ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
- settings.LockTransitionDuration();
- // Setting transition duration is ignored since duration is locked
- settings.SetTransitionDuration(base::Milliseconds(1000));
- WindowState::Get(window.get())->Minimize();
- EXPECT_TRUE(layer->GetAnimator()->is_animating());
- // Expect default duration (200ms for stock ash minimizing animation).
- EXPECT_EQ(default_duration.InMilliseconds(),
- layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
- window->Show();
- layer->GetAnimator()->StopAnimating();
- }
- }
- // Test that a slide out animation slides the window off the screen while
- // modifying the opacity.
- TEST_F(WindowAnimationsTest, SlideOutAnimation) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
- std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
- window->SetBounds(gfx::Rect(0, 0, 100, 100));
- window->Show();
- EXPECT_TRUE(window->layer()->visible());
- ::wm::SetWindowVisibilityAnimationType(
- window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_FADE_IN_SLIDE_OUT);
- AnimateOnChildWindowVisibilityChanged(window.get(), false);
- EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
- EXPECT_FALSE(window->layer()->GetTargetVisibility());
- EXPECT_FALSE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(-150, 0, 100, 100), window->layer()->GetTargetBounds());
- }
- // Test that a fade in slide out animation fades in.
- TEST_F(WindowAnimationsTest, FadeInAnimation) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
- std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
- window->SetBounds(gfx::Rect(0, 0, 100, 100));
- window->Hide();
- EXPECT_FALSE(window->layer()->visible());
- ::wm::SetWindowVisibilityAnimationType(
- window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_FADE_IN_SLIDE_OUT);
- AnimateOnChildWindowVisibilityChanged(window.get(), true);
- EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
- EXPECT_TRUE(window->layer()->GetTargetVisibility());
- EXPECT_TRUE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(0, 0, 100, 100), window->layer()->GetTargetBounds());
- }
- TEST_F(WindowAnimationsTest, SlideOutAnimationPlaysTwiceForPipWindow) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
- std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
- window->SetBounds(gfx::Rect(8, 8, 100, 100));
- WindowState* window_state = WindowState::Get(window.get());
- const WMEvent enter_pip(WM_EVENT_PIP);
- window_state->OnWMEvent(&enter_pip);
- EXPECT_TRUE(window_state->IsPip());
- window->Show();
- EXPECT_TRUE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds());
- window->Hide();
- EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
- EXPECT_FALSE(window->layer()->GetTargetVisibility());
- EXPECT_FALSE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds());
- // Reset the position and try again.
- window->Show();
- window->SetBounds(gfx::Rect(8, 8, 100, 100));
- EXPECT_TRUE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds());
- window->Hide();
- EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
- EXPECT_FALSE(window->layer()->GetTargetVisibility());
- EXPECT_FALSE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds());
- }
- TEST_F(WindowAnimationsTest, ResetAnimationAfterDismissingArcPip) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
- std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
- window->SetBounds(gfx::Rect(8, 8, 100, 100));
- WindowState* window_state = WindowState::Get(window.get());
- const WMEvent enter_pip(WM_EVENT_PIP);
- window_state->OnWMEvent(&enter_pip);
- EXPECT_TRUE(window_state->IsPip());
- window->Show();
- EXPECT_TRUE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds());
- // Ensure the window is slided out.
- WindowState::Get(window.get())->Minimize();
- EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
- EXPECT_FALSE(window->layer()->GetTargetVisibility());
- EXPECT_FALSE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds());
- WindowState::Get(window.get())->Maximize();
- EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
- EXPECT_TRUE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(0, 0, 800, 600 - ShelfConfig::Get()->shelf_size()),
- window->layer()->GetTargetBounds());
- // Ensure the window is not slided out.
- window->Hide();
- EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
- EXPECT_FALSE(window->layer()->GetTargetVisibility());
- EXPECT_FALSE(window->layer()->visible());
- EXPECT_EQ(gfx::Rect(0, 0, 800, 600 - ShelfConfig::Get()->shelf_size()),
- window->layer()->GetTargetBounds());
- }
- // Tests a version of the cross fade animation which animates the transform and
- // opacity of the new layer, but only the opacity of the old layer. The old
- // layer transform is updated manually when the animation ticks so that it
- // has the same visible bounds as the new layer.
- // Flaky on Chrome OS. https://crbug.com/1113901
- TEST_F(WindowAnimationsTest, DISABLED_CrossFadeAnimateNewLayerOnly) {
- ui::ScopedAnimationDurationScaleMode test_duration_mode(
- ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
- std::unique_ptr<Window> window(CreateTestWindowInShellWithId(0));
- window->SetBounds(gfx::Rect(10, 10, 200, 200));
- window->Show();
- window->layer()->GetAnimator()->StopAnimating();
- Layer* old_layer = window->layer();
- EXPECT_EQ(1.f, old_layer->GetTargetOpacity());
- const gfx::Rect target_bounds(40, 40, 400, 400);
- CrossFadeAnimationAnimateNewLayerOnly(
- window.get(), target_bounds, base::Milliseconds(200), gfx::Tween::LINEAR,
- "test-histogram-name");
- // Window's layer has been replaced.
- EXPECT_NE(old_layer, window->layer());
- // Original layer fades away. Transform is updated as the animation steps.
- EXPECT_EQ(0.f, old_layer->GetTargetOpacity());
- EXPECT_EQ(gfx::Rect(10, 10, 200, 200), old_layer->bounds());
- EXPECT_EQ(gfx::Transform(), old_layer->GetTargetTransform());
- // New layer animates in to the identity transform.
- EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
- EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
- // Start the animations, then set the bounds of the new window during the
- // animation.
- WaitForMilliseconds(10);
- // Set the bounds halfway through the animation. The bounds of the old layer
- // remain the same, but the transform has updated to match the bounds of the
- // new layer.
- window->SetBounds(gfx::Rect(80, 80, 200, 200));
- WaitForMilliseconds(100);
- EXPECT_EQ(gfx::Rect(10, 10, 200, 200), old_layer->bounds());
- EXPECT_NE(gfx::Transform(), old_layer->GetTargetTransform());
- // New layer targets remain the same.
- EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
- EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
- WaitForMilliseconds(300);
- EXPECT_FALSE(window->layer()->GetAnimator()->is_animating());
- }
- } // namespace ash
|