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_element.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/test/test_layer_animation_delegate.h" 14#include "ui/compositor/test/test_utils.h" 15#include "ui/gfx/rect.h" 16#include "ui/gfx/transform.h" 17 18namespace ui { 19 20namespace { 21 22// Check that the transformation element progresses the delegate as expected and 23// that the element can be reused after it completes. 24TEST(LayerAnimationElementTest, TransformElement) { 25 TestLayerAnimationDelegate delegate; 26 gfx::Transform start_transform, target_transform, middle_transform; 27 start_transform.Rotate(-30.0); 28 target_transform.Rotate(30.0); 29 base::TimeTicks start_time; 30 base::TimeTicks effective_start_time; 31 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 32 33 scoped_ptr<LayerAnimationElement> element( 34 LayerAnimationElement::CreateTransformElement(target_transform, delta)); 35 element->set_animation_group_id(1); 36 37 for (int i = 0; i < 2; ++i) { 38 start_time = effective_start_time + delta; 39 element->set_requested_start_time(start_time); 40 delegate.SetTransformFromAnimation(start_transform); 41 element->Start(&delegate, 1); 42 element->Progress(start_time, &delegate); 43 CheckApproximatelyEqual(start_transform, 44 delegate.GetTransformForAnimation()); 45 effective_start_time = start_time + delta; 46 element->set_effective_start_time(effective_start_time); 47 element->Progress(effective_start_time, &delegate); 48 EXPECT_FLOAT_EQ(0.0, element->last_progressed_fraction()); 49 element->Progress(effective_start_time + delta/2, &delegate); 50 EXPECT_FLOAT_EQ(0.5, element->last_progressed_fraction()); 51 52 base::TimeDelta element_duration; 53 EXPECT_TRUE(element->IsFinished(effective_start_time + delta, 54 &element_duration)); 55 EXPECT_EQ(2 * delta, element_duration); 56 57 element->Progress(effective_start_time + delta, &delegate); 58 EXPECT_FLOAT_EQ(1.0, element->last_progressed_fraction()); 59 CheckApproximatelyEqual(target_transform, 60 delegate.GetTransformForAnimation()); 61 } 62 63 LayerAnimationElement::TargetValue target_value(&delegate); 64 element->GetTargetValue(&target_value); 65 CheckApproximatelyEqual(target_transform, target_value.transform); 66} 67 68// Check that the bounds element progresses the delegate as expected and 69// that the element can be reused after it completes. 70TEST(LayerAnimationElementTest, BoundsElement) { 71 TestLayerAnimationDelegate delegate; 72 gfx::Rect start, target, middle; 73 start = target = middle = gfx::Rect(0, 0, 50, 50); 74 start.set_x(-90); 75 target.set_x(90); 76 base::TimeTicks start_time; 77 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 78 79 scoped_ptr<LayerAnimationElement> element( 80 LayerAnimationElement::CreateBoundsElement(target, delta)); 81 82 for (int i = 0; i < 2; ++i) { 83 start_time += delta; 84 element->set_requested_start_time(start_time); 85 delegate.SetBoundsFromAnimation(start); 86 element->Start(&delegate, 1); 87 element->Progress(start_time, &delegate); 88 CheckApproximatelyEqual(start, delegate.GetBoundsForAnimation()); 89 element->Progress(start_time + delta/2, &delegate); 90 CheckApproximatelyEqual(middle, delegate.GetBoundsForAnimation()); 91 92 base::TimeDelta element_duration; 93 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); 94 EXPECT_EQ(delta, element_duration); 95 96 element->Progress(start_time + delta, &delegate); 97 CheckApproximatelyEqual(target, delegate.GetBoundsForAnimation()); 98 } 99 100 LayerAnimationElement::TargetValue target_value(&delegate); 101 element->GetTargetValue(&target_value); 102 CheckApproximatelyEqual(target, target_value.bounds); 103} 104 105// Check that the opacity element progresses the delegate as expected and 106// that the element can be reused after it completes. 107TEST(LayerAnimationElementTest, OpacityElement) { 108 TestLayerAnimationDelegate delegate; 109 float start = 0.0; 110 float middle = 0.5; 111 float target = 1.0; 112 base::TimeTicks start_time; 113 base::TimeTicks effective_start_time; 114 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 115 scoped_ptr<LayerAnimationElement> element( 116 LayerAnimationElement::CreateOpacityElement(target, delta)); 117 118 for (int i = 0; i < 2; ++i) { 119 start_time = effective_start_time + delta; 120 element->set_requested_start_time(start_time); 121 delegate.SetOpacityFromAnimation(start); 122 element->Start(&delegate, 1); 123 element->Progress(start_time, &delegate); 124 EXPECT_FLOAT_EQ(start, element->last_progressed_fraction()); 125 effective_start_time = start_time + delta; 126 element->set_effective_start_time(effective_start_time); 127 element->Progress(effective_start_time, &delegate); 128 EXPECT_FLOAT_EQ(start, element->last_progressed_fraction()); 129 element->Progress(effective_start_time + delta/2, &delegate); 130 EXPECT_FLOAT_EQ(middle, element->last_progressed_fraction()); 131 132 base::TimeDelta element_duration; 133 EXPECT_TRUE(element->IsFinished(effective_start_time + delta, 134 &element_duration)); 135 EXPECT_EQ(2 * delta, element_duration); 136 137 element->Progress(effective_start_time + delta, &delegate); 138 EXPECT_FLOAT_EQ(target, element->last_progressed_fraction()); 139 EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation()); 140 } 141 142 LayerAnimationElement::TargetValue target_value(&delegate); 143 element->GetTargetValue(&target_value); 144 EXPECT_FLOAT_EQ(target, target_value.opacity); 145} 146 147// Check that the visibility element progresses the delegate as expected and 148// that the element can be reused after it completes. 149TEST(LayerAnimationElementTest, VisibilityElement) { 150 TestLayerAnimationDelegate delegate; 151 bool start = true; 152 bool target = false; 153 base::TimeTicks start_time; 154 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 155 scoped_ptr<LayerAnimationElement> element( 156 LayerAnimationElement::CreateVisibilityElement(target, delta)); 157 158 for (int i = 0; i < 2; ++i) { 159 start_time += delta; 160 element->set_requested_start_time(start_time); 161 delegate.SetVisibilityFromAnimation(start); 162 element->Start(&delegate, 1); 163 element->Progress(start_time, &delegate); 164 EXPECT_TRUE(delegate.GetVisibilityForAnimation()); 165 element->Progress(start_time + delta/2, &delegate); 166 EXPECT_TRUE(delegate.GetVisibilityForAnimation()); 167 168 base::TimeDelta element_duration; 169 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); 170 EXPECT_EQ(delta, element_duration); 171 172 element->Progress(start_time + delta, &delegate); 173 EXPECT_FALSE(delegate.GetVisibilityForAnimation()); 174 } 175 176 LayerAnimationElement::TargetValue target_value(&delegate); 177 element->GetTargetValue(&target_value); 178 EXPECT_FALSE(target_value.visibility); 179} 180 181// Check that the Brightness element progresses the delegate as expected and 182// that the element can be reused after it completes. 183TEST(LayerAnimationElementTest, BrightnessElement) { 184 TestLayerAnimationDelegate delegate; 185 float start = 0.0; 186 float middle = 0.5; 187 float target = 1.0; 188 base::TimeTicks start_time; 189 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 190 scoped_ptr<LayerAnimationElement> element( 191 LayerAnimationElement::CreateBrightnessElement(target, delta)); 192 193 for (int i = 0; i < 2; ++i) { 194 start_time += delta; 195 element->set_requested_start_time(start_time); 196 delegate.SetBrightnessFromAnimation(start); 197 element->Start(&delegate, 1); 198 element->Progress(start_time, &delegate); 199 EXPECT_FLOAT_EQ(start, delegate.GetBrightnessForAnimation()); 200 element->Progress(start_time + delta/2, &delegate); 201 EXPECT_FLOAT_EQ(middle, delegate.GetBrightnessForAnimation()); 202 203 base::TimeDelta element_duration; 204 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); 205 EXPECT_EQ(delta, element_duration); 206 207 element->Progress(start_time + delta, &delegate); 208 EXPECT_FLOAT_EQ(target, delegate.GetBrightnessForAnimation()); 209 } 210 211 LayerAnimationElement::TargetValue target_value(&delegate); 212 element->GetTargetValue(&target_value); 213 EXPECT_FLOAT_EQ(target, target_value.brightness); 214} 215 216// Check that the Grayscale element progresses the delegate as expected and 217// that the element can be reused after it completes. 218TEST(LayerAnimationElementTest, GrayscaleElement) { 219 TestLayerAnimationDelegate delegate; 220 float start = 0.0; 221 float middle = 0.5; 222 float target = 1.0; 223 base::TimeTicks start_time; 224 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 225 scoped_ptr<LayerAnimationElement> element( 226 LayerAnimationElement::CreateGrayscaleElement(target, delta)); 227 228 for (int i = 0; i < 2; ++i) { 229 start_time += delta; 230 element->set_requested_start_time(start_time); 231 delegate.SetGrayscaleFromAnimation(start); 232 element->Start(&delegate, 1); 233 element->Progress(start_time, &delegate); 234 EXPECT_FLOAT_EQ(start, delegate.GetGrayscaleForAnimation()); 235 element->Progress(start_time + delta/2, &delegate); 236 EXPECT_FLOAT_EQ(middle, delegate.GetGrayscaleForAnimation()); 237 238 base::TimeDelta element_duration; 239 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); 240 EXPECT_EQ(delta, element_duration); 241 242 element->Progress(start_time + delta, &delegate); 243 EXPECT_FLOAT_EQ(target, delegate.GetGrayscaleForAnimation()); 244 } 245 246 LayerAnimationElement::TargetValue target_value(&delegate); 247 element->GetTargetValue(&target_value); 248 EXPECT_FLOAT_EQ(target, target_value.grayscale); 249} 250 251// Check that the pause element progresses the delegate as expected and 252// that the element can be reused after it completes. 253TEST(LayerAnimationElementTest, PauseElement) { 254 LayerAnimationElement::AnimatableProperties properties; 255 properties.insert(LayerAnimationElement::TRANSFORM); 256 properties.insert(LayerAnimationElement::BOUNDS); 257 properties.insert(LayerAnimationElement::OPACITY); 258 properties.insert(LayerAnimationElement::BRIGHTNESS); 259 properties.insert(LayerAnimationElement::GRAYSCALE); 260 base::TimeTicks start_time; 261 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 262 263 scoped_ptr<LayerAnimationElement> element( 264 LayerAnimationElement::CreatePauseElement(properties, delta)); 265 266 TestLayerAnimationDelegate delegate; 267 TestLayerAnimationDelegate copy = delegate; 268 269 start_time += delta; 270 element->set_requested_start_time(start_time); 271 element->Start(&delegate, 1); 272 273 // Pause should last for |delta|. 274 base::TimeDelta element_duration; 275 EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); 276 EXPECT_EQ(delta, element_duration); 277 278 element->Progress(start_time + delta, &delegate); 279 280 // Nothing should have changed. 281 CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), 282 copy.GetBoundsForAnimation()); 283 CheckApproximatelyEqual(delegate.GetTransformForAnimation(), 284 copy.GetTransformForAnimation()); 285 EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), 286 copy.GetOpacityForAnimation()); 287 EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), 288 copy.GetBrightnessForAnimation()); 289 EXPECT_FLOAT_EQ(delegate.GetGrayscaleForAnimation(), 290 copy.GetGrayscaleForAnimation()); 291} 292 293// Check that a threaded opacity element updates the delegate as expected when 294// aborted. 295TEST(LayerAnimationElementTest, AbortOpacityElement) { 296 TestLayerAnimationDelegate delegate; 297 float start = 0.0; 298 float target = 1.0; 299 base::TimeTicks start_time; 300 base::TimeTicks effective_start_time; 301 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 302 scoped_ptr<LayerAnimationElement> element( 303 LayerAnimationElement::CreateOpacityElement(target, delta)); 304 305 // Choose a non-linear Tween type. 306 Tween::Type tween_type = Tween::EASE_IN; 307 element->set_tween_type(tween_type); 308 309 delegate.SetOpacityFromAnimation(start); 310 311 // Aborting the element before it has started should not update the delegate. 312 element->Abort(&delegate); 313 EXPECT_FLOAT_EQ(start, delegate.GetOpacityForAnimation()); 314 315 start_time += delta; 316 element->set_requested_start_time(start_time); 317 element->Start(&delegate, 1); 318 element->Progress(start_time, &delegate); 319 effective_start_time = start_time + delta; 320 element->set_effective_start_time(effective_start_time); 321 element->Progress(effective_start_time, &delegate); 322 element->Progress(effective_start_time + delta/2, &delegate); 323 324 // Since the element has started, it should update the delegate when 325 // aborted. 326 element->Abort(&delegate); 327 EXPECT_FLOAT_EQ(Tween::CalculateValue(tween_type, 0.5), 328 delegate.GetOpacityForAnimation()); 329} 330 331// Check that a threaded transform element updates the delegate as expected when 332// aborted. 333TEST(LayerAnimationElementTest, AbortTransformElement) { 334 TestLayerAnimationDelegate delegate; 335 gfx::Transform start_transform, target_transform; 336 start_transform.Rotate(-30.0); 337 target_transform.Rotate(30.0); 338 base::TimeTicks start_time; 339 base::TimeTicks effective_start_time; 340 base::TimeDelta delta = base::TimeDelta::FromSeconds(1); 341 scoped_ptr<LayerAnimationElement> element( 342 LayerAnimationElement::CreateTransformElement(target_transform, delta)); 343 344 // Choose a non-linear Tween type. 345 Tween::Type tween_type = Tween::EASE_IN; 346 element->set_tween_type(tween_type); 347 348 delegate.SetTransformFromAnimation(start_transform); 349 350 // Aborting the element before it has started should not update the delegate. 351 element->Abort(&delegate); 352 CheckApproximatelyEqual(start_transform, delegate.GetTransformForAnimation()); 353 354 start_time += delta; 355 element->set_requested_start_time(start_time); 356 element->Start(&delegate, 1); 357 element->Progress(start_time, &delegate); 358 effective_start_time = start_time + delta; 359 element->set_effective_start_time(effective_start_time); 360 element->Progress(effective_start_time, &delegate); 361 element->Progress(effective_start_time + delta/2, &delegate); 362 363 // Since the element has started, it should update the delegate when 364 // aborted. 365 element->Abort(&delegate); 366 target_transform.Blend(start_transform, 367 Tween::CalculateValue(tween_type, 0.5)); 368 CheckApproximatelyEqual(target_transform, 369 delegate.GetTransformForAnimation()); 370} 371 372} // namespace 373 374} // namespace ui 375