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

Side by Side Diff: ui/compositor/callback_layer_animation_observer_unittest.cc

Issue 1369393002: Added a CallbackLayerAnimationObserver. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed concerns from patch set 8. Created 5 years, 2 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
« no previous file with comments | « ui/compositor/callback_layer_animation_observer.cc ('k') | ui/compositor/compositor.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 "ui/compositor/callback_layer_animation_observer.h"
6
7 #include "base/bind.h"
8 #include "base/macros.h"
9 #include "base/memory/scoped_vector.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/compositor/layer_animation_sequence.h"
12 #include "ui/compositor/test/layer_animation_observer_test_api.h"
13
14 namespace ui {
15 namespace test {
16
17 // Simple class that tracks whether callbacks were invoked and when.
18 class TestCallbacks {
19 public:
20 TestCallbacks();
21 virtual ~TestCallbacks();
22
23 void ResetCallbackObservations();
24
25 void set_should_delete_observer_on_animations_ended(
26 bool should_delete_observer_on_animations_ended) {
27 should_delete_observer_on_animations_ended_ =
28 should_delete_observer_on_animations_ended;
29 }
30
31 bool animations_started() const { return animations_started_; }
32
33 bool animations_ended() const { return animations_ended_; }
34
35 virtual void AnimationsStarted(const CallbackLayerAnimationObserver&);
36
37 virtual bool AnimationsEnded(const CallbackLayerAnimationObserver&);
38
39 testing::AssertionResult StartedEpochIsBeforeEndedEpoch();
40
41 private:
42 // Monotonic counter that tracks the next time snapshot.
43 int next_epoch_ = 0;
44
45 // Is true when AnimationsStarted() has been called.
46 bool animations_started_ = false;
47
48 // Relative time snapshot of when AnimationsStarted() was last called.
49 int animations_started_epoch_ = -1;
50
51 // Is true when AnimationsEnded() has been called.
52 bool animations_ended_ = false;
53
54 // Relative time snapshot of when AnimationsEnded() was last called.
55 int animations_ended_epoch_ = -1;
56
57 // The return value for AnimationsEnded().
58 bool should_delete_observer_on_animations_ended_ = false;
59
60 DISALLOW_COPY_AND_ASSIGN(TestCallbacks);
61 };
62
63 TestCallbacks::TestCallbacks() {}
64
65 TestCallbacks::~TestCallbacks() {}
66
67 void TestCallbacks::ResetCallbackObservations() {
68 next_epoch_ = 0;
69 animations_started_ = false;
70 animations_started_epoch_ = -1;
71 animations_ended_ = false;
72 animations_ended_epoch_ = -1;
73 should_delete_observer_on_animations_ended_ = false;
74 }
75
76 void TestCallbacks::AnimationsStarted(const CallbackLayerAnimationObserver&) {
77 animations_started_ = true;
78 animations_started_epoch_ = next_epoch_++;
79 }
80
81 bool TestCallbacks::AnimationsEnded(const CallbackLayerAnimationObserver&) {
82 animations_ended_ = true;
83 animations_ended_epoch_ = next_epoch_++;
84 return should_delete_observer_on_animations_ended_;
85 }
86
87 testing::AssertionResult TestCallbacks::StartedEpochIsBeforeEndedEpoch() {
88 if (animations_started_epoch_ < animations_ended_epoch_) {
89 return testing::AssertionSuccess();
90 } else {
91 return testing::AssertionFailure()
92 << "The started epoch=" << animations_started_epoch_
93 << " is NOT before the ended epoch=" << animations_ended_epoch_;
94 }
95 }
96
97 // A child of TestCallbacks that can explicitly delete a
98 // CallbackLayerAnimationObserver in the AnimationsStarted() or
99 // AnimationsEnded() callback.
100 class TestCallbacksThatExplicitlyDeletesObserver : public TestCallbacks {
101 public:
102 TestCallbacksThatExplicitlyDeletesObserver();
103
104 void set_observer_to_delete_in_animation_started(
105 CallbackLayerAnimationObserver* observer) {
106 observer_to_delete_in_animation_started_ = observer;
107 }
108
109 void set_observer_to_delete_in_animation_ended(
110 CallbackLayerAnimationObserver* observer) {
111 observer_to_delete_in_animation_ended_ = observer;
112 }
113
114 // TestCallbacks:
115 void AnimationsStarted(
116 const CallbackLayerAnimationObserver& observer) override;
117 bool AnimationsEnded(const CallbackLayerAnimationObserver& observer) override;
118
119 private:
120 // The observer to delete, if non-NULL, in AnimationsStarted().
121 CallbackLayerAnimationObserver* observer_to_delete_in_animation_started_ =
122 nullptr;
123
124 // The observer to delete, if non-NULL, in AnimationsEnded().
125 CallbackLayerAnimationObserver* observer_to_delete_in_animation_ended_ =
126 nullptr;
127
128 DISALLOW_COPY_AND_ASSIGN(TestCallbacksThatExplicitlyDeletesObserver);
129 };
130
131 TestCallbacksThatExplicitlyDeletesObserver::
132 TestCallbacksThatExplicitlyDeletesObserver() {}
133
134 void TestCallbacksThatExplicitlyDeletesObserver::AnimationsStarted(
135 const CallbackLayerAnimationObserver& observer) {
136 if (observer_to_delete_in_animation_started_)
137 delete observer_to_delete_in_animation_started_;
138 TestCallbacks::AnimationsStarted(observer);
139 }
140
141 bool TestCallbacksThatExplicitlyDeletesObserver::AnimationsEnded(
142 const CallbackLayerAnimationObserver& observer) {
143 if (observer_to_delete_in_animation_ended_)
144 delete observer_to_delete_in_animation_ended_;
145 return TestCallbacks::AnimationsEnded(observer);
146 }
147
148 // A test specific CallbackLayerAnimationObserver that will set a bool when
149 // destroyed.
150 class TestCallbackLayerAnimationObserver
151 : public CallbackLayerAnimationObserver {
152 public:
153 TestCallbackLayerAnimationObserver(
154 AnimationStartedCallback animation_started_callback,
155 AnimationEndedCallback animation_ended_callback,
156 bool* destroyed);
157 ~TestCallbackLayerAnimationObserver() override;
158
159 private:
160 bool* destroyed_;
161
162 DISALLOW_COPY_AND_ASSIGN(TestCallbackLayerAnimationObserver);
163 };
164
165 TestCallbackLayerAnimationObserver::TestCallbackLayerAnimationObserver(
166 AnimationStartedCallback animation_started_callback,
167 AnimationEndedCallback animation_ended_callback,
168 bool* destroyed)
169 : CallbackLayerAnimationObserver(animation_started_callback,
170 animation_ended_callback),
171 destroyed_(destroyed) {
172 (*destroyed_) = false;
173 }
174
175 TestCallbackLayerAnimationObserver::~TestCallbackLayerAnimationObserver() {
176 (*destroyed_) = true;
177 }
178
179 class CallbackLayerAnimationObserverTest : public testing::Test {
180 public:
181 CallbackLayerAnimationObserverTest();
182 ~CallbackLayerAnimationObserverTest() override;
183
184 protected:
185 // Creates a LayerAnimationSequence. The lifetime of the sequence will be
186 // managed by this.
187 LayerAnimationSequence* CreateLayerAnimationSequence();
188
189 scoped_ptr<TestCallbacks> callbacks_;
190
191 scoped_ptr<CallbackLayerAnimationObserver> observer_;
192
193 scoped_ptr<LayerAnimationObserverTestApi> observer_test_api_;
194
195 // List of managaged sequences created by CreateLayerAnimationSequence() that
196 // need to be destroyed.
197 ScopedVector<LayerAnimationSequence> sequences_;
198
199 private:
200 DISALLOW_COPY_AND_ASSIGN(CallbackLayerAnimationObserverTest);
201 };
202
203 CallbackLayerAnimationObserverTest::CallbackLayerAnimationObserverTest()
204 : callbacks_(new TestCallbacks()),
205 observer_(new CallbackLayerAnimationObserver(
206 base::Bind(&TestCallbacks::AnimationsStarted,
207 base::Unretained(callbacks_.get())),
208 base::Bind(&TestCallbacks::AnimationsEnded,
209 base::Unretained(callbacks_.get())))),
210 observer_test_api_(new LayerAnimationObserverTestApi(observer_.get())) {}
211
212 CallbackLayerAnimationObserverTest::~CallbackLayerAnimationObserverTest() {
213 observer_test_api_.reset();
214 // The |observer_| will detach from all attached sequences upon destruction so
215 // we need to explicitly delete the |observer_| before the |sequences_| and
216 // |callbacks_|.
217 observer_.reset();
218 }
219
220 LayerAnimationSequence*
221 CallbackLayerAnimationObserverTest::CreateLayerAnimationSequence() {
222 LayerAnimationSequence* sequence = new LayerAnimationSequence();
223 sequences_.push_back(sequence);
224 return sequence;
225 }
226
227 TEST_F(CallbackLayerAnimationObserverTest, VerifyInitialState) {
228 EXPECT_FALSE(observer_->active());
229 EXPECT_EQ(0, observer_->aborted_count());
230 EXPECT_EQ(0, observer_->successful_count());
231
232 EXPECT_FALSE(callbacks_->animations_started());
233 EXPECT_FALSE(callbacks_->animations_ended());
234 }
235
236 TEST(CallbackLayerAnimationObserverDestructionTest,
237 AnimationEndedReturnsFalse) {
238 TestCallbacks callbacks;
239 callbacks.set_should_delete_observer_on_animations_ended(false);
240
241 bool is_destroyed = false;
242
243 TestCallbackLayerAnimationObserver* observer =
244 new TestCallbackLayerAnimationObserver(
245 base::Bind(&TestCallbacks::AnimationsStarted,
246 base::Unretained(&callbacks)),
247 base::Bind(&TestCallbacks::AnimationsEnded,
248 base::Unretained(&callbacks)),
249 &is_destroyed);
250 observer->SetActive();
251
252 EXPECT_FALSE(is_destroyed);
253 delete observer;
254 }
255
256 TEST(CallbackLayerAnimationObserverDestructionTest, AnimationEndedReturnsTrue) {
257 TestCallbacks callbacks;
258 callbacks.set_should_delete_observer_on_animations_ended(true);
259
260 bool is_destroyed = false;
261
262 TestCallbackLayerAnimationObserver* observer =
263 new TestCallbackLayerAnimationObserver(
264 base::Bind(&TestCallbacks::AnimationsStarted,
265 base::Unretained(&callbacks)),
266 base::Bind(&TestCallbacks::AnimationsEnded,
267 base::Unretained(&callbacks)),
268 &is_destroyed);
269 observer->SetActive();
270
271 EXPECT_TRUE(is_destroyed);
272 }
273
274 // Verifies that the CallbackLayerAnimationObserver is robust to explicit
275 // deletes caused as a side effect of calling the AnimationsStartedCallback()
276 // when there are no animation sequences attached. This test also guards against
277 // heap-use-after-free errors.
278 TEST_F(
279 CallbackLayerAnimationObserverTest,
280 ExplicitlyDeleteObserverInAnimationStartedCallbackWithNoSequencesAttached) {
281 TestCallbacksThatExplicitlyDeletesObserver callbacks;
282 callbacks.set_should_delete_observer_on_animations_ended(true);
283
284 bool is_destroyed = false;
285
286 TestCallbackLayerAnimationObserver* observer =
287 new TestCallbackLayerAnimationObserver(
288 base::Bind(&TestCallbacks::AnimationsStarted,
289 base::Unretained(&callbacks)),
290 base::Bind(&TestCallbacks::AnimationsEnded,
291 base::Unretained(&callbacks)),
292 &is_destroyed);
293
294 callbacks.set_observer_to_delete_in_animation_started(observer);
295
296 observer->SetActive();
297
298 EXPECT_TRUE(is_destroyed);
299 }
300
301 // Verifies that the CallbackLayerAnimationObserver is robust to explicit
302 // deletes caused as a side effect of calling the AnimationsStartedCallback()
303 // when there are some animation sequences attached. This test also guards
304 // against heap-use-after-free errors.
305 TEST_F(
306 CallbackLayerAnimationObserverTest,
307 ExplicitlyDeleteObserverInAnimationStartedCallbackWithSomeSequencesAttached) {
308 LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
309 LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
310
311 TestCallbacksThatExplicitlyDeletesObserver callbacks;
312 callbacks.set_should_delete_observer_on_animations_ended(true);
313
314 bool is_destroyed = false;
315
316 TestCallbackLayerAnimationObserver* observer =
317 new TestCallbackLayerAnimationObserver(
318 base::Bind(&TestCallbacks::AnimationsStarted,
319 base::Unretained(&callbacks)),
320 base::Bind(&TestCallbacks::AnimationsEnded,
321 base::Unretained(&callbacks)),
322 &is_destroyed);
323
324 observer_test_api_->AttachedToSequence(sequence_1);
325 observer_test_api_->AttachedToSequence(sequence_2);
326 observer_->OnLayerAnimationStarted(sequence_1);
327 observer_->OnLayerAnimationStarted(sequence_2);
328
329 callbacks.set_observer_to_delete_in_animation_started(observer);
330
331 observer->SetActive();
332
333 EXPECT_TRUE(is_destroyed);
334 }
335
336 // Verifies that a 'true' return value for AnimationEndedCallback is ignored if
337 // the CallbackLayerAnimationObserver is explicitly deleted as a side effect of
338 // calling the AnimationEndedCallback. This test also guards against
339 // heap-use-after-free errors.
340 TEST_F(CallbackLayerAnimationObserverTest,
341 IgnoreTrueReturnValueForAnimationEndedCallbackIfExplicitlyDeleted) {
342 TestCallbacksThatExplicitlyDeletesObserver callbacks;
343 callbacks.set_should_delete_observer_on_animations_ended(true);
344
345 bool is_destroyed = false;
346
347 TestCallbackLayerAnimationObserver* observer =
348 new TestCallbackLayerAnimationObserver(
349 base::Bind(&TestCallbacks::AnimationsStarted,
350 base::Unretained(&callbacks)),
351 base::Bind(&TestCallbacks::AnimationsEnded,
352 base::Unretained(&callbacks)),
353 &is_destroyed);
354
355 callbacks.set_observer_to_delete_in_animation_ended(observer);
356
357 observer->SetActive();
358
359 EXPECT_TRUE(is_destroyed);
360 }
361
362 TEST_F(CallbackLayerAnimationObserverTest,
363 SetActiveWhenNoSequencesWereAttached) {
364 observer_->SetActive();
365
366 EXPECT_FALSE(observer_->active());
367 EXPECT_TRUE(callbacks_->animations_started());
368 EXPECT_TRUE(callbacks_->animations_ended());
369 EXPECT_TRUE(callbacks_->StartedEpochIsBeforeEndedEpoch());
370 }
371
372 TEST_F(CallbackLayerAnimationObserverTest,
373 SetActiveWhenAllSequencesAreAttachedButNoneWereStarted) {
374 LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
375 LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
376
377 observer_test_api_->AttachedToSequence(sequence_1);
378 observer_test_api_->AttachedToSequence(sequence_2);
379
380 observer_->SetActive();
381
382 EXPECT_TRUE(observer_->active());
383 EXPECT_FALSE(callbacks_->animations_started());
384 EXPECT_FALSE(callbacks_->animations_ended());
385 }
386
387 TEST_F(CallbackLayerAnimationObserverTest,
388 SetActiveWhenAllSequencesAreAttachedAndOnlySomeWereStarted) {
389 LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
390 LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
391
392 observer_test_api_->AttachedToSequence(sequence_1);
393 observer_test_api_->AttachedToSequence(sequence_2);
394 observer_->OnLayerAnimationStarted(sequence_1);
395
396 observer_->SetActive();
397
398 EXPECT_TRUE(observer_->active());
399 EXPECT_FALSE(callbacks_->animations_started());
400 EXPECT_FALSE(callbacks_->animations_ended());
401 }
402
403 TEST_F(CallbackLayerAnimationObserverTest,
404 SetActiveWhenAllSequencesAreAttachedAndOnlySomeWereCompleted) {
405 LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
406 LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
407
408 observer_test_api_->AttachedToSequence(sequence_1);
409 observer_test_api_->AttachedToSequence(sequence_2);
410 observer_->OnLayerAnimationStarted(sequence_1);
411 observer_->OnLayerAnimationEnded(sequence_1);
412
413 observer_->SetActive();
414
415 EXPECT_TRUE(observer_->active());
416 EXPECT_FALSE(callbacks_->animations_started());
417 EXPECT_FALSE(callbacks_->animations_ended());
418 }
419
420 TEST_F(CallbackLayerAnimationObserverTest,
421 SetActiveAfterAllSequencesWereStartedButNoneWereCompleted) {
422 LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
423 LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
424
425 observer_test_api_->AttachedToSequence(sequence_1);
426 observer_test_api_->AttachedToSequence(sequence_2);
427 observer_->OnLayerAnimationStarted(sequence_1);
428 observer_->OnLayerAnimationStarted(sequence_2);
429
430 observer_->SetActive();
431
432 EXPECT_TRUE(observer_->active());
433 EXPECT_TRUE(callbacks_->animations_started());
434 EXPECT_FALSE(callbacks_->animations_ended());
435 }
436
437 TEST_F(CallbackLayerAnimationObserverTest,
438 SetActiveWhenAllSequencesAreStartedAndOnlySomeWereCompleted) {
439 LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
440 LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
441
442 observer_test_api_->AttachedToSequence(sequence_1);
443 observer_test_api_->AttachedToSequence(sequence_2);
444 observer_->OnLayerAnimationStarted(sequence_1);
445 observer_->OnLayerAnimationStarted(sequence_2);
446 observer_->OnLayerAnimationEnded(sequence_1);
447
448 observer_->SetActive();
449
450 EXPECT_TRUE(observer_->active());
451 EXPECT_TRUE(callbacks_->animations_started());
452 EXPECT_FALSE(callbacks_->animations_ended());
453 }
454
455 TEST_F(CallbackLayerAnimationObserverTest,
456 SetActiveWhenAllSequencesWereCompleted) {
457 LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
458 LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
459
460 observer_test_api_->AttachedToSequence(sequence_1);
461 observer_test_api_->AttachedToSequence(sequence_2);
462 observer_->OnLayerAnimationStarted(sequence_1);
463 observer_->OnLayerAnimationStarted(sequence_2);
464 observer_->OnLayerAnimationEnded(sequence_1);
465 observer_->OnLayerAnimationEnded(sequence_2);
466
467 observer_->SetActive();
468
469 EXPECT_FALSE(observer_->active());
470 EXPECT_TRUE(callbacks_->animations_started());
471 EXPECT_TRUE(callbacks_->animations_ended());
472 }
473
474 TEST_F(CallbackLayerAnimationObserverTest,
475 SetActiveAgainAfterAllSequencesWereCompleted) {
476 LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
477 LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
478 LayerAnimationSequence* sequence_3 = CreateLayerAnimationSequence();
479 LayerAnimationSequence* sequence_4 = CreateLayerAnimationSequence();
480
481 observer_test_api_->AttachedToSequence(sequence_1);
482 observer_test_api_->AttachedToSequence(sequence_2);
483 observer_->OnLayerAnimationStarted(sequence_1);
484 observer_->OnLayerAnimationStarted(sequence_2);
485 observer_->OnLayerAnimationEnded(sequence_1);
486 observer_->OnLayerAnimationEnded(sequence_2);
487
488 observer_->SetActive();
489
490 EXPECT_FALSE(observer_->active());
491
492 observer_test_api_->AttachedToSequence(sequence_3);
493 observer_test_api_->AttachedToSequence(sequence_4);
494
495 callbacks_->ResetCallbackObservations();
496
497 observer_->SetActive();
498
499 EXPECT_TRUE(observer_->active());
500 EXPECT_FALSE(callbacks_->animations_started());
501 EXPECT_FALSE(callbacks_->animations_ended());
502 EXPECT_EQ(2, observer_->successful_count());
503
504 observer_->OnLayerAnimationStarted(sequence_3);
505 observer_->OnLayerAnimationStarted(sequence_4);
506
507 EXPECT_TRUE(observer_->active());
508 EXPECT_TRUE(callbacks_->animations_started());
509 EXPECT_FALSE(callbacks_->animations_ended());
510 EXPECT_EQ(2, observer_->successful_count());
511
512 observer_->OnLayerAnimationEnded(sequence_3);
513 observer_->OnLayerAnimationEnded(sequence_4);
514
515 EXPECT_FALSE(observer_->active());
516 EXPECT_TRUE(callbacks_->animations_started());
517 EXPECT_TRUE(callbacks_->animations_ended());
518 EXPECT_EQ(4, observer_->successful_count());
519 }
520
521 } // namespace test
522 } // namespace ui
OLDNEW
« no previous file with comments | « ui/compositor/callback_layer_animation_observer.cc ('k') | ui/compositor/compositor.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698