Home | History | Annotate | Download | only in compositor
      1 // Copyright (c) 2012 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/layer_animation_sequence.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/compiler_specific.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/time/time.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #include "ui/compositor/layer_animation_delegate.h"
     13 #include "ui/compositor/layer_animation_element.h"
     14 #include "ui/compositor/test/test_layer_animation_delegate.h"
     15 #include "ui/compositor/test/test_layer_animation_observer.h"
     16 #include "ui/compositor/test/test_utils.h"
     17 #include "ui/gfx/rect.h"
     18 #include "ui/gfx/transform.h"
     19 
     20 namespace ui {
     21 
     22 namespace {
     23 
     24 // Check that the sequence behaves sanely when it contains no elements.
     25 TEST(LayerAnimationSequenceTest, NoElement) {
     26   LayerAnimationSequence sequence;
     27   base::TimeTicks start_time;
     28   start_time += base::TimeDelta::FromSeconds(1);
     29   sequence.set_start_time(start_time);
     30   EXPECT_TRUE(sequence.IsFinished(start_time));
     31   EXPECT_TRUE(sequence.properties().size() == 0);
     32   LayerAnimationElement::AnimatableProperties properties;
     33   EXPECT_FALSE(sequence.HasConflictingProperty(properties));
     34 }
     35 
     36 // Check that the sequences progresses the delegate as expected when it contains
     37 // a single non-threaded element.
     38 TEST(LayerAnimationSequenceTest, SingleElement) {
     39   LayerAnimationSequence sequence;
     40   TestLayerAnimationDelegate delegate;
     41   float start = 0.0f;
     42   float middle = 0.5f;
     43   float target = 1.0f;
     44   base::TimeTicks start_time;
     45   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
     46   sequence.AddElement(
     47       LayerAnimationElement::CreateBrightnessElement(target, delta));
     48 
     49   for (int i = 0; i < 2; ++i) {
     50     start_time += delta;
     51     sequence.set_start_time(start_time);
     52     delegate.SetBrightnessFromAnimation(start);
     53     sequence.Start(&delegate);
     54     sequence.Progress(start_time, &delegate);
     55     EXPECT_FLOAT_EQ(start, delegate.GetBrightnessForAnimation());
     56     sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(500),
     57                       &delegate);
     58     EXPECT_FLOAT_EQ(middle, delegate.GetBrightnessForAnimation());
     59     EXPECT_TRUE(sequence.IsFinished(start_time + delta));
     60     sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(1000),
     61                       &delegate);
     62     EXPECT_FLOAT_EQ(target, delegate.GetBrightnessForAnimation());
     63   }
     64 
     65   EXPECT_TRUE(sequence.properties().size() == 1);
     66   EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::BRIGHTNESS) !=
     67               sequence.properties().end());
     68 }
     69 
     70 // Check that the sequences progresses the delegate as expected when it contains
     71 // a single threaded element.
     72 TEST(LayerAnimationSequenceTest, SingleThreadedElement) {
     73   LayerAnimationSequence sequence;
     74   TestLayerAnimationDelegate delegate;
     75   float start = 0.0f;
     76   float middle = 0.5f;
     77   float target = 1.0f;
     78   base::TimeTicks start_time;
     79   base::TimeTicks effective_start;
     80   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
     81   sequence.AddElement(
     82       LayerAnimationElement::CreateOpacityElement(target, delta));
     83 
     84   for (int i = 0; i < 2; ++i) {
     85     int starting_group_id = 1;
     86     sequence.set_animation_group_id(starting_group_id);
     87     start_time = effective_start + delta;
     88     sequence.set_start_time(start_time);
     89     delegate.SetOpacityFromAnimation(start);
     90     sequence.Start(&delegate);
     91     sequence.Progress(start_time, &delegate);
     92     EXPECT_FLOAT_EQ(start, sequence.last_progressed_fraction());
     93     effective_start = start_time + delta;
     94     sequence.OnThreadedAnimationStarted(cc::AnimationEvent(
     95         cc::AnimationEvent::Started,
     96         0,
     97         sequence.animation_group_id(),
     98         cc::Animation::Opacity,
     99         (effective_start - base::TimeTicks()).InSecondsF()));
    100     sequence.Progress(effective_start + delta/2, &delegate);
    101     EXPECT_FLOAT_EQ(middle, sequence.last_progressed_fraction());
    102     EXPECT_TRUE(sequence.IsFinished(effective_start + delta));
    103     sequence.Progress(effective_start + delta, &delegate);
    104     EXPECT_FLOAT_EQ(target, sequence.last_progressed_fraction());
    105     EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation());
    106   }
    107 
    108   EXPECT_TRUE(sequence.properties().size() == 1);
    109   EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::OPACITY) !=
    110               sequence.properties().end());
    111 }
    112 
    113 // Check that the sequences progresses the delegate as expected when it contains
    114 // multiple elements. Note, see the layer animator tests for cyclic sequences.
    115 TEST(LayerAnimationSequenceTest, MultipleElement) {
    116   LayerAnimationSequence sequence;
    117   TestLayerAnimationDelegate delegate;
    118   float start_opacity = 0.0f;
    119   float target_opacity = 1.0f;
    120   base::TimeTicks start_time;
    121   base::TimeTicks opacity_effective_start;
    122   base::TimeTicks transform_effective_start;
    123   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
    124   sequence.AddElement(
    125       LayerAnimationElement::CreateOpacityElement(target_opacity, delta));
    126 
    127   // Pause bounds for a second.
    128   LayerAnimationElement::AnimatableProperties properties;
    129   properties.insert(LayerAnimationElement::BOUNDS);
    130 
    131   sequence.AddElement(
    132       LayerAnimationElement::CreatePauseElement(properties, delta));
    133 
    134   gfx::Transform start_transform, target_transform, middle_transform;
    135   start_transform.Rotate(-30.0);
    136   target_transform.Rotate(30.0);
    137 
    138   sequence.AddElement(
    139       LayerAnimationElement::CreateTransformElement(target_transform, delta));
    140 
    141   for (int i = 0; i < 2; ++i) {
    142     int starting_group_id = 1;
    143     sequence.set_animation_group_id(starting_group_id);
    144     start_time = opacity_effective_start + 4 * delta;
    145     sequence.set_start_time(start_time);
    146     delegate.SetOpacityFromAnimation(start_opacity);
    147     delegate.SetTransformFromAnimation(start_transform);
    148 
    149     sequence.Start(&delegate);
    150     sequence.Progress(start_time, &delegate);
    151     EXPECT_FLOAT_EQ(0.0, sequence.last_progressed_fraction());
    152     opacity_effective_start = start_time + delta;
    153     EXPECT_EQ(starting_group_id, sequence.animation_group_id());
    154     sequence.OnThreadedAnimationStarted(cc::AnimationEvent(
    155         cc::AnimationEvent::Started,
    156         0,
    157         sequence.animation_group_id(),
    158         cc::Animation::Opacity,
    159         (opacity_effective_start - base::TimeTicks()).InSecondsF()));
    160     sequence.Progress(opacity_effective_start + delta/2, &delegate);
    161     EXPECT_FLOAT_EQ(0.5, sequence.last_progressed_fraction());
    162     sequence.Progress(opacity_effective_start + delta, &delegate);
    163     EXPECT_FLOAT_EQ(target_opacity, delegate.GetOpacityForAnimation());
    164 
    165     // Now at the start of the pause.
    166     EXPECT_FLOAT_EQ(0.0, sequence.last_progressed_fraction());
    167     TestLayerAnimationDelegate copy = delegate;
    168 
    169     // In the middle of the pause -- nothing should have changed.
    170     sequence.Progress(opacity_effective_start + delta + delta/2,
    171                       &delegate);
    172     CheckApproximatelyEqual(delegate.GetBoundsForAnimation(),
    173                             copy.GetBoundsForAnimation());
    174     CheckApproximatelyEqual(delegate.GetTransformForAnimation(),
    175                             copy.GetTransformForAnimation());
    176     EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(),
    177                     copy.GetOpacityForAnimation());
    178 
    179     sequence.Progress(opacity_effective_start + 2 * delta, &delegate);
    180     CheckApproximatelyEqual(start_transform,
    181                             delegate.GetTransformForAnimation());
    182     EXPECT_FLOAT_EQ(0.0, sequence.last_progressed_fraction());
    183     transform_effective_start = opacity_effective_start + 3 * delta;
    184     EXPECT_NE(starting_group_id, sequence.animation_group_id());
    185     sequence.OnThreadedAnimationStarted(cc::AnimationEvent(
    186         cc::AnimationEvent::Started,
    187         0,
    188         sequence.animation_group_id(),
    189         cc::Animation::Transform,
    190         (transform_effective_start - base::TimeTicks()).InSecondsF()));
    191     sequence.Progress(transform_effective_start + delta/2, &delegate);
    192     EXPECT_FLOAT_EQ(0.5, sequence.last_progressed_fraction());
    193     EXPECT_TRUE(sequence.IsFinished(transform_effective_start + delta));
    194     sequence.Progress(transform_effective_start + delta, &delegate);
    195     CheckApproximatelyEqual(target_transform,
    196                             delegate.GetTransformForAnimation());
    197   }
    198 
    199   EXPECT_TRUE(sequence.properties().size() == 3);
    200   EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::OPACITY) !=
    201               sequence.properties().end());
    202   EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::TRANSFORM) !=
    203               sequence.properties().end());
    204   EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::BOUNDS) !=
    205               sequence.properties().end());
    206 }
    207 
    208 // Check that a sequence can still be aborted if it has cycled many times.
    209 TEST(LayerAnimationSequenceTest, AbortingCyclicSequence) {
    210   LayerAnimationSequence sequence;
    211   TestLayerAnimationDelegate delegate;
    212   float start_brightness = 0.0f;
    213   float target_brightness = 1.0f;
    214   base::TimeTicks start_time;
    215   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
    216   sequence.AddElement(
    217       LayerAnimationElement::CreateBrightnessElement(target_brightness, delta));
    218 
    219   sequence.AddElement(
    220       LayerAnimationElement::CreateBrightnessElement(start_brightness, delta));
    221 
    222   sequence.set_is_cyclic(true);
    223 
    224   delegate.SetBrightnessFromAnimation(start_brightness);
    225 
    226   start_time += delta;
    227   sequence.set_start_time(start_time);
    228   sequence.Start(&delegate);
    229   sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(101000),
    230                     &delegate);
    231   EXPECT_FLOAT_EQ(target_brightness, delegate.GetBrightnessForAnimation());
    232   sequence.Abort(&delegate);
    233 
    234   // Should be able to reuse the sequence after aborting.
    235   delegate.SetBrightnessFromAnimation(start_brightness);
    236   start_time += base::TimeDelta::FromMilliseconds(101000);
    237   sequence.set_start_time(start_time);
    238   sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(100000),
    239                     &delegate);
    240   EXPECT_FLOAT_EQ(start_brightness, delegate.GetBrightnessForAnimation());
    241 }
    242 
    243 // Check that a sequence can be 'fast-forwarded' to the end and the target set.
    244 // Also check that this has no effect if the sequence is cyclic.
    245 TEST(LayerAnimationSequenceTest, SetTarget) {
    246   LayerAnimationSequence sequence;
    247   TestLayerAnimationDelegate delegate;
    248   float start_opacity = 0.0f;
    249   float target_opacity = 1.0f;
    250   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
    251   sequence.AddElement(
    252       LayerAnimationElement::CreateOpacityElement(target_opacity, delta));
    253 
    254   LayerAnimationElement::TargetValue target_value(&delegate);
    255   target_value.opacity = start_opacity;
    256   sequence.GetTargetValue(&target_value);
    257   EXPECT_FLOAT_EQ(target_opacity, target_value.opacity);
    258 
    259   sequence.set_is_cyclic(true);
    260   target_value.opacity = start_opacity;
    261   sequence.GetTargetValue(&target_value);
    262   EXPECT_FLOAT_EQ(start_opacity, target_value.opacity);
    263 }
    264 
    265 TEST(LayerAnimationSequenceTest, AddObserver) {
    266   base::TimeTicks start_time;
    267   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
    268   LayerAnimationSequence sequence;
    269   sequence.AddElement(
    270       LayerAnimationElement::CreateBrightnessElement(1.0f, delta));
    271   for (int i = 0; i < 2; ++i) {
    272     start_time += delta;
    273     sequence.set_start_time(start_time);
    274     TestLayerAnimationObserver observer;
    275     TestLayerAnimationDelegate delegate;
    276     sequence.AddObserver(&observer);
    277     EXPECT_TRUE(!observer.last_ended_sequence());
    278     sequence.Progress(start_time + delta, &delegate);
    279     EXPECT_EQ(observer.last_ended_sequence(), &sequence);
    280     sequence.RemoveObserver(&observer);
    281   }
    282 }
    283 
    284 } // namespace
    285 
    286 } // namespace ui
    287