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 group_id = 1;
     86     sequence.set_animation_group_id(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         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 group_id = 1;
    143     sequence.set_animation_group_id(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     sequence.OnThreadedAnimationStarted(cc::AnimationEvent(
    154         cc::AnimationEvent::Started,
    155         0,
    156         group_id,
    157         cc::Animation::Opacity,
    158         (opacity_effective_start - base::TimeTicks()).InSecondsF()));
    159     sequence.Progress(opacity_effective_start + delta/2, &delegate);
    160     EXPECT_FLOAT_EQ(0.5, sequence.last_progressed_fraction());
    161     sequence.Progress(opacity_effective_start + delta, &delegate);
    162     EXPECT_FLOAT_EQ(target_opacity, delegate.GetOpacityForAnimation());
    163 
    164     // Now at the start of the pause.
    165     EXPECT_FLOAT_EQ(0.0, sequence.last_progressed_fraction());
    166     TestLayerAnimationDelegate copy = delegate;
    167 
    168     // In the middle of the pause -- nothing should have changed.
    169     sequence.Progress(opacity_effective_start + delta + delta/2,
    170                       &delegate);
    171     CheckApproximatelyEqual(delegate.GetBoundsForAnimation(),
    172                             copy.GetBoundsForAnimation());
    173     CheckApproximatelyEqual(delegate.GetTransformForAnimation(),
    174                             copy.GetTransformForAnimation());
    175     EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(),
    176                     copy.GetOpacityForAnimation());
    177 
    178     sequence.Progress(opacity_effective_start + 2 * delta, &delegate);
    179     CheckApproximatelyEqual(start_transform,
    180                             delegate.GetTransformForAnimation());
    181     EXPECT_FLOAT_EQ(0.0, sequence.last_progressed_fraction());
    182     transform_effective_start = opacity_effective_start + 3 * delta;
    183     sequence.OnThreadedAnimationStarted(cc::AnimationEvent(
    184         cc::AnimationEvent::Started,
    185         0,
    186         group_id,
    187         cc::Animation::Transform,
    188         (transform_effective_start - base::TimeTicks()).InSecondsF()));
    189     sequence.Progress(transform_effective_start + delta/2, &delegate);
    190     EXPECT_FLOAT_EQ(0.5, sequence.last_progressed_fraction());
    191     EXPECT_TRUE(sequence.IsFinished(transform_effective_start + delta));
    192     sequence.Progress(transform_effective_start + delta, &delegate);
    193     CheckApproximatelyEqual(target_transform,
    194                             delegate.GetTransformForAnimation());
    195   }
    196 
    197   EXPECT_TRUE(sequence.properties().size() == 3);
    198   EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::OPACITY) !=
    199               sequence.properties().end());
    200   EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::TRANSFORM) !=
    201               sequence.properties().end());
    202   EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::BOUNDS) !=
    203               sequence.properties().end());
    204 }
    205 
    206 // Check that a sequence can still be aborted if it has cycled many times.
    207 TEST(LayerAnimationSequenceTest, AbortingCyclicSequence) {
    208   LayerAnimationSequence sequence;
    209   TestLayerAnimationDelegate delegate;
    210   float start_brightness = 0.0f;
    211   float target_brightness = 1.0f;
    212   base::TimeTicks start_time;
    213   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
    214   sequence.AddElement(
    215       LayerAnimationElement::CreateBrightnessElement(target_brightness, delta));
    216 
    217   sequence.AddElement(
    218       LayerAnimationElement::CreateBrightnessElement(start_brightness, delta));
    219 
    220   sequence.set_is_cyclic(true);
    221 
    222   delegate.SetBrightnessFromAnimation(start_brightness);
    223 
    224   start_time += delta;
    225   sequence.set_start_time(start_time);
    226   sequence.Start(&delegate);
    227   sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(101000),
    228                     &delegate);
    229   EXPECT_FLOAT_EQ(target_brightness, delegate.GetBrightnessForAnimation());
    230   sequence.Abort(&delegate);
    231 
    232   // Should be able to reuse the sequence after aborting.
    233   delegate.SetBrightnessFromAnimation(start_brightness);
    234   start_time += base::TimeDelta::FromMilliseconds(101000);
    235   sequence.set_start_time(start_time);
    236   sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(100000),
    237                     &delegate);
    238   EXPECT_FLOAT_EQ(start_brightness, delegate.GetBrightnessForAnimation());
    239 }
    240 
    241 // Check that a sequence can be 'fast-forwarded' to the end and the target set.
    242 // Also check that this has no effect if the sequence is cyclic.
    243 TEST(LayerAnimationSequenceTest, SetTarget) {
    244   LayerAnimationSequence sequence;
    245   TestLayerAnimationDelegate delegate;
    246   float start_opacity = 0.0f;
    247   float target_opacity = 1.0f;
    248   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
    249   sequence.AddElement(
    250       LayerAnimationElement::CreateOpacityElement(target_opacity, delta));
    251 
    252   LayerAnimationElement::TargetValue target_value(&delegate);
    253   target_value.opacity = start_opacity;
    254   sequence.GetTargetValue(&target_value);
    255   EXPECT_FLOAT_EQ(target_opacity, target_value.opacity);
    256 
    257   sequence.set_is_cyclic(true);
    258   target_value.opacity = start_opacity;
    259   sequence.GetTargetValue(&target_value);
    260   EXPECT_FLOAT_EQ(start_opacity, target_value.opacity);
    261 }
    262 
    263 TEST(LayerAnimationSequenceTest, AddObserver) {
    264   base::TimeTicks start_time;
    265   base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
    266   LayerAnimationSequence sequence;
    267   sequence.AddElement(
    268       LayerAnimationElement::CreateBrightnessElement(1.0f, delta));
    269   for (int i = 0; i < 2; ++i) {
    270     start_time += delta;
    271     sequence.set_start_time(start_time);
    272     TestLayerAnimationObserver observer;
    273     TestLayerAnimationDelegate delegate;
    274     sequence.AddObserver(&observer);
    275     EXPECT_TRUE(!observer.last_ended_sequence());
    276     sequence.Progress(start_time + delta, &delegate);
    277     EXPECT_EQ(observer.last_ended_sequence(), &sequence);
    278     sequence.RemoveObserver(&observer);
    279   }
    280 }
    281 
    282 } // namespace
    283 
    284 } // namespace ui
    285