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