Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: ash/common/wm/overview/cleanup_animation_observer_unittest.cc

Issue 2141133002: [ash-md] Animates overview shield in and out (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: [ash-md] Completes shield opacity animation after overview closes (nits) Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 <vector>
6
7 #include "ash/common/wm/overview/cleanup_animation_observer.h"
8
9 #include "ash/common/wm/overview/window_selector_delegate.h"
10 #include "ash/common/wm_lookup.h"
11 #include "ash/common/wm_window.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ui/compositor/layer_animation_observer.h"
14 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
15 #include "ui/compositor/scoped_layer_animation_settings.h"
16 #include "ui/gfx/geometry/rect.h"
17 #include "ui/views/widget/widget.h"
18 #include "ui/views/widget/widget_observer.h"
19
20 namespace ash {
21 namespace {
22
23 class TestWindowSelectorDelegate : public WindowSelectorDelegate {
24 public:
25 TestWindowSelectorDelegate() = default;
26
27 ~TestWindowSelectorDelegate() override {
28 // Destroy widgets that may be still animating if shell shuts down soon
29 // after exiting overview mode.
30 for (std::unique_ptr<DelayedAnimationObserver>& observer : observers_)
31 observer->Shutdown();
32 }
33
34 // WindowSelectorDelegate:
35 void OnSelectionEnded() override {}
36
37 void AddDelayedAnimationObserver(
38 std::unique_ptr<DelayedAnimationObserver> animation_observer) override {
39 animation_observer->SetOwner(this);
40 observers_.push_back(std::move(animation_observer));
41 }
42
43 void RemoveAndDestroyAnimationObserver(
44 DelayedAnimationObserver* animation_observer) override {
45 class IsEqual {
46 public:
47 explicit IsEqual(DelayedAnimationObserver* animation_observer)
48 : animation_observer_(animation_observer) {}
49 bool operator()(const std::unique_ptr<DelayedAnimationObserver>& other) {
50 return (other.get() == animation_observer_);
51 }
52
53 private:
54 const DelayedAnimationObserver* animation_observer_;
55 };
56 observers_.erase(std::remove_if(observers_.begin(), observers_.end(),
57 IsEqual(animation_observer)),
58 observers_.end());
59 }
60
61 private:
62 std::vector<std::unique_ptr<DelayedAnimationObserver>> observers_;
63
64 DISALLOW_COPY_AND_ASSIGN(TestWindowSelectorDelegate);
65 };
66
67 class CleanupAnimationObserverTest : public test::AshTestBase,
68 public views::WidgetObserver {
69 public:
70 CleanupAnimationObserverTest() = default;
71
72 ~CleanupAnimationObserverTest() override {
73 if (widget_)
74 widget_->RemoveObserver(this);
75 }
76
77 // Creates a Widget containing a Window with the given |bounds|. This should
78 // be used when the test requires a Widget. For example any test that will
79 // cause a window to be closed via
80 // views::Widget::GetWidgetForNativeView(window)->Close().
81 std::unique_ptr<views::Widget> CreateWindowWidget(const gfx::Rect& bounds) {
82 std::unique_ptr<views::Widget> widget(new views::Widget);
83 views::Widget::InitParams params;
84 params.bounds = bounds;
85 params.type = views::Widget::InitParams::TYPE_WINDOW;
86 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
87 widget->Init(params);
88 widget->Show();
89 ParentWindowInPrimaryRootWindow(widget->GetNativeWindow());
90 widget->AddObserver(this);
91 widget_ = widget.get();
92 return widget;
93 }
94
95 protected:
96 bool widget_destroyed() { return !widget_; }
97
98 private:
99 void OnWidgetDestroyed(views::Widget* widget) override {
100 if (widget_ == widget)
101 widget_ = nullptr;
102 }
103
104 views::Widget* widget_ = nullptr;
105
106 DISALLOW_COPY_AND_ASSIGN(CleanupAnimationObserverTest);
107 };
108
109 } // namespace
110
111 // Tests that basic create-destroy sequence does not crash.
112 TEST_F(CleanupAnimationObserverTest, CreateDestroy) {
113 TestWindowSelectorDelegate delegate;
114 std::unique_ptr<views::Widget> widget(
115 CreateWindowWidget(gfx::Rect(0, 0, 40, 40)));
116 std::unique_ptr<CleanupAnimationObserver> observer(
117 new CleanupAnimationObserver(std::move(widget)));
118 delegate.AddDelayedAnimationObserver(std::move(observer));
119 }
120
121 // Tests that completing animation deletes the animation observer and the
122 // test widget and that deleting the WindowSelectorDelegate instance which
123 // owns the observer does not crash.
124 TEST_F(CleanupAnimationObserverTest, CreateAnimateComplete) {
125 TestWindowSelectorDelegate delegate;
126 std::unique_ptr<views::Widget> widget(
127 CreateWindowWidget(gfx::Rect(0, 0, 40, 40)));
128 WmWindow* widget_window = WmLookup::Get()->GetWindowForWidget(widget.get());
129 {
130 ui::ScopedLayerAnimationSettings animation_settings(
131 widget_window->GetLayer()->GetAnimator());
132 animation_settings.SetTransitionDuration(
133 base::TimeDelta::FromMilliseconds(1000));
134 animation_settings.SetPreemptionStrategy(
135 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
136
137 std::unique_ptr<CleanupAnimationObserver> observer(
138 new CleanupAnimationObserver(std::move(widget)));
139 animation_settings.AddObserver(observer.get());
140 delegate.AddDelayedAnimationObserver(std::move(observer));
141
142 widget_window->SetBounds(gfx::Rect(50, 50, 60, 60));
143 }
144 // The widget should be destroyed when |animation_settings| gets out of scope
145 // which in absence of NON_ZERO_DURATION animation duration mode completes
146 // the animation and calls OnImplicitAnimationsCompleted() on the cleanup
147 // observer and auto-deletes the owned widget.
148 EXPECT_TRUE(widget_destroyed());
149 // TestWindowSelectorDelegate going out of scope should not crash.
150 }
151
152 // Tests that starting an animation and exiting doesn't crash. If not for
153 // TestWindowSelectorDelegate calling Shutdown() on a CleanupAnimationObserver
154 // instance in destructor, this test would have crashed.
155 TEST_F(CleanupAnimationObserverTest, CreateAnimateShutdown) {
156 TestWindowSelectorDelegate delegate;
157 std::unique_ptr<views::Widget> widget(
158 CreateWindowWidget(gfx::Rect(0, 0, 40, 40)));
159 WmWindow* widget_window = WmLookup::Get()->GetWindowForWidget(widget.get());
160 {
161 // Normal animations for tests have ZERO_DURATION, make sure we are actually
162 // animating the movement.
163 ui::ScopedAnimationDurationScaleMode animation_scale_mode(
164 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
165 ui::ScopedLayerAnimationSettings animation_settings(
166 widget_window->GetLayer()->GetAnimator());
167 animation_settings.SetTransitionDuration(
168 base::TimeDelta::FromMilliseconds(1000));
169 animation_settings.SetPreemptionStrategy(
170 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
171
172 std::unique_ptr<CleanupAnimationObserver> observer(
173 new CleanupAnimationObserver(std::move(widget)));
174 animation_settings.AddObserver(observer.get());
175 delegate.AddDelayedAnimationObserver(std::move(observer));
176
177 widget_window->SetBounds(gfx::Rect(50, 50, 60, 60));
178 }
179 // The widget still exists.
180 EXPECT_FALSE(widget_destroyed());
181 // The test widget is auto-deleted when |delegate| that owns it goes out of
182 // scope. The animation is still active when this happens which should not
183 // crash.
184 }
185
186 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/wm/overview/cleanup_animation_observer.cc ('k') | ash/common/wm/overview/window_grid.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698