15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/animation_container.h"
6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/animation_container_observer.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/linear_animation.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/test_animation_delegate.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace gfx {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class FakeAnimationContainerObserver : public AnimationContainerObserver {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeAnimationContainerObserver()
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : progressed_count_(0),
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        empty_(false) {
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int progressed_count() const { return progressed_count_; }
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool empty() const { return empty_; }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void AnimationContainerProgressed(
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      AnimationContainer* container) OVERRIDE {
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    progressed_count_++;
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Invoked when no more animations are being managed by this container.
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void AnimationContainerEmpty(AnimationContainer* container) OVERRIDE {
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    empty_ = true;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int progressed_count_;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool empty_;
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeAnimationContainerObserver);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestAnimation : public LinearAnimation {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestAnimation(AnimationDelegate* delegate)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : LinearAnimation(20, 20, delegate) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AnimateToState(double state) OVERRIDE {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestAnimation);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AnimationContainerTest: public testing::Test {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure the animation ups the ref count of the container and releases it
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// appropriately.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AnimationContainerTest, Ownership) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAnimationDelegate delegate;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AnimationContainer> container(new AnimationContainer());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Animation> animation(new TestAnimation(&delegate));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation->SetContainer(container.get());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setting the container should up the ref count.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(container->HasOneRef());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation.reset();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Releasing the animation should decrement the ref count.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(container->HasOneRef());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure multiple animations are managed correctly.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AnimationContainerTest, Multi) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAnimationDelegate delegate1;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAnimationDelegate delegate2;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AnimationContainer> container(new AnimationContainer());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAnimation animation1(&delegate1);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAnimation animation2(&delegate2);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation1.SetContainer(container.get());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation2.SetContainer(container.get());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start both animations.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation1.Start();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(container->is_running());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation2.Start();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(container->is_running());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the message loop the delegate quits the message loop when notified.
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Run();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both timers should have finished.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate1.finished());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate2.finished());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And the container should no longer be runnings.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(container->is_running());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure observer is notified appropriately.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AnimationContainerTest, Observer) {
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeAnimationContainerObserver observer;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAnimationDelegate delegate1;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AnimationContainer> container(new AnimationContainer());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->set_observer(&observer);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestAnimation animation1(&delegate1);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation1.SetContainer(container.get());
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the animation.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation1.Start();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(container->is_running());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the message loop. The delegate quits the message loop when notified.
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->Run();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, observer.progressed_count());
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timer should have finished.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(delegate1.finished());
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(observer.empty());
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And the container should no longer be running.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(container->is_running());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container->set_observer(NULL);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace gfx
139