1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/wm/overview/delayed_animation_observer_impl.h"
6
7 #include <memory>
8 #include <utility>
9 #include <vector>
10
11 #include "ash/test/ash_test_base.h"
12 #include "ash/wm/overview/overview_delegate.h"
13 #include "base/containers/unique_ptr_adapters.h"
14 #include "base/test/task_environment.h"
15 #include "ui/aura/window.h"
16 #include "ui/compositor/scoped_layer_animation_settings.h"
17 #include "ui/gfx/transform.h"
18
19 namespace ash {
20
21 namespace {
22
23 class TestOverviewDelegate : public OverviewDelegate {
24 public:
25 TestOverviewDelegate() = default;
26
27 ~TestOverviewDelegate() override = default;
28
29 // OverviewDelegate:
AddExitAnimationObserver(std::unique_ptr<DelayedAnimationObserver> animation_observer)30 void AddExitAnimationObserver(
31 std::unique_ptr<DelayedAnimationObserver> animation_observer) override {
32 animation_observer->SetOwner(this);
33 exit_observers_.push_back(std::move(animation_observer));
34 }
RemoveAndDestroyExitAnimationObserver(DelayedAnimationObserver * animation_observer)35 void RemoveAndDestroyExitAnimationObserver(
36 DelayedAnimationObserver* animation_observer) override {
37 base::EraseIf(exit_observers_, base::MatchesUniquePtr(animation_observer));
38 }
AddEnterAnimationObserver(std::unique_ptr<DelayedAnimationObserver> animation_observer)39 void AddEnterAnimationObserver(
40 std::unique_ptr<DelayedAnimationObserver> animation_observer) override {
41 animation_observer->SetOwner(this);
42 enter_observers_.push_back(std::move(animation_observer));
43 }
RemoveAndDestroyEnterAnimationObserver(DelayedAnimationObserver * animation_observer)44 void RemoveAndDestroyEnterAnimationObserver(
45 DelayedAnimationObserver* animation_observer) override {
46 base::EraseIf(enter_observers_, base::MatchesUniquePtr(animation_observer));
47 }
48
num_exit_observers() const49 size_t num_exit_observers() const { return exit_observers_.size(); }
num_enter_observers() const50 size_t num_enter_observers() const { return enter_observers_.size(); }
51
52 private:
53 std::vector<std::unique_ptr<DelayedAnimationObserver>> exit_observers_;
54 std::vector<std::unique_ptr<DelayedAnimationObserver>> enter_observers_;
55
56 DISALLOW_COPY_AND_ASSIGN(TestOverviewDelegate);
57 };
58
59 } // namespace
60
61 class ForceDelayObserverTest : public AshTestBase {
62 public:
ForceDelayObserverTest()63 ForceDelayObserverTest()
64 : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
65 ~ForceDelayObserverTest() override = default;
66
67 private:
68 DISALLOW_COPY_AND_ASSIGN(ForceDelayObserverTest);
69 };
70
TEST_F(ForceDelayObserverTest,Basic)71 TEST_F(ForceDelayObserverTest, Basic) {
72 TestOverviewDelegate delegate;
73
74 auto observer = std::make_unique<ForceDelayObserver>(
75 base::TimeDelta::FromMilliseconds(100));
76 delegate.AddEnterAnimationObserver(std::move(observer));
77 EXPECT_EQ(1u, delegate.num_enter_observers());
78
79 task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(50));
80 base::RunLoop().RunUntilIdle();
81 EXPECT_EQ(1u, delegate.num_enter_observers());
82 task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(55));
83 base::RunLoop().RunUntilIdle();
84 EXPECT_EQ(0u, delegate.num_enter_observers());
85 }
86
87 using EnterAnimationObserverTest = AshTestBase;
88
89 // Tests that adding a EnterAnimationObserver works as intended.
TEST_F(EnterAnimationObserverTest,Basic)90 TEST_F(EnterAnimationObserverTest, Basic) {
91 TestOverviewDelegate delegate;
92 std::unique_ptr<aura::Window> window = CreateTestWindow();
93
94 {
95 ui::ScopedLayerAnimationSettings animation_settings(
96 window->layer()->GetAnimator());
97 animation_settings.SetTransitionDuration(
98 base::TimeDelta::FromMilliseconds(1000));
99 animation_settings.SetPreemptionStrategy(
100 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
101
102 auto observer = std::make_unique<EnterAnimationObserver>();
103 animation_settings.AddObserver(observer.get());
104 delegate.AddEnterAnimationObserver(std::move(observer));
105 window->SetTransform(gfx::Transform(1.f, 0.f, 0.f, 1.f, 100.f, 0.f));
106 EXPECT_EQ(0u, delegate.num_exit_observers());
107 EXPECT_EQ(1u, delegate.num_enter_observers());
108 }
109
110 // Tests that when done animating, the observer count is zero.
111 window->layer()->GetAnimator()->StopAnimating();
112 EXPECT_EQ(0u, delegate.num_enter_observers());
113 }
114
115 using ExitAnimationObserverTest = AshTestBase;
116
117 // Tests that adding a ExitAnimationObserver works as intended.
TEST_F(ExitAnimationObserverTest,Basic)118 TEST_F(ExitAnimationObserverTest, Basic) {
119 TestOverviewDelegate delegate;
120 std::unique_ptr<aura::Window> window = CreateTestWindow();
121
122 {
123 ui::ScopedLayerAnimationSettings animation_settings(
124 window->layer()->GetAnimator());
125 animation_settings.SetTransitionDuration(
126 base::TimeDelta::FromMilliseconds(1000));
127 animation_settings.SetPreemptionStrategy(
128 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
129
130 auto observer = std::make_unique<ExitAnimationObserver>();
131 animation_settings.AddObserver(observer.get());
132 delegate.AddExitAnimationObserver(std::move(observer));
133 window->SetTransform(gfx::Transform(1.f, 0.f, 0.f, 1.f, 100.f, 0.f));
134 EXPECT_EQ(1u, delegate.num_exit_observers());
135 EXPECT_EQ(0u, delegate.num_enter_observers());
136 }
137
138 // Tests that when done animating, the observer count is zero.
139 window->layer()->GetAnimator()->StopAnimating();
140 EXPECT_EQ(0u, delegate.num_exit_observers());
141 }
142
143 } // namespace ash
144