OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/animation/element_animations.h" | 5 #include "cc/animation/element_animations.h" |
6 | 6 |
7 #include "cc/animation/animation_delegate.h" | 7 #include "cc/animation/animation_delegate.h" |
8 #include "cc/animation/animation_host.h" | 8 #include "cc/animation/animation_host.h" |
9 #include "cc/animation/animation_id_provider.h" | 9 #include "cc/animation/animation_id_provider.h" |
10 #include "cc/animation/animation_player.h" | 10 #include "cc/animation/animation_player.h" |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 EXPECT_EQ(element_animations, player2->element_animations()); | 184 EXPECT_EQ(element_animations, player2->element_animations()); |
185 | 185 |
186 host_->PushPropertiesTo(host_impl_); | 186 host_->PushPropertiesTo(host_impl_); |
187 GetImplTimelineAndPlayerByID(); | 187 GetImplTimelineAndPlayerByID(); |
188 | 188 |
189 scoped_refptr<ElementAnimations> element_animations_impl = | 189 scoped_refptr<ElementAnimations> element_animations_impl = |
190 player_impl_->element_animations(); | 190 player_impl_->element_animations(); |
191 EXPECT_TRUE(element_animations_impl); | 191 EXPECT_TRUE(element_animations_impl); |
192 | 192 |
193 int list_size_before = 0; | 193 int list_size_before = 0; |
194 for (const ElementAnimations::PlayersListNode* node = | 194 ElementAnimations::PlayersList::Iterator it( |
195 element_animations_impl->players_list().head(); | 195 &element_animations_impl->players_list()); |
196 node != element_animations_impl->players_list().end(); | 196 AnimationPlayer* player; |
197 node = node->next()) { | 197 while ((player = it.GetNext()) != nullptr) { |
198 const AnimationPlayer* player_impl = node->value(); | 198 EXPECT_TRUE(timeline_->GetPlayerById(player->id())); |
199 EXPECT_TRUE(timeline_->GetPlayerById(player_impl->id())); | |
200 ++list_size_before; | 199 ++list_size_before; |
201 } | 200 } |
202 EXPECT_EQ(3, list_size_before); | 201 EXPECT_EQ(3, list_size_before); |
203 | 202 |
204 player2->DetachElement(); | 203 player2->DetachElement(); |
205 EXPECT_FALSE(player2->element_animations()); | 204 EXPECT_FALSE(player2->element_animations()); |
206 EXPECT_EQ(element_animations, player_->element_animations()); | 205 EXPECT_EQ(element_animations, player_->element_animations()); |
207 EXPECT_EQ(element_animations, player1->element_animations()); | 206 EXPECT_EQ(element_animations, player1->element_animations()); |
208 | 207 |
209 host_->PushPropertiesTo(host_impl_); | 208 host_->PushPropertiesTo(host_impl_); |
210 EXPECT_EQ(element_animations_impl, player_impl_->element_animations()); | 209 EXPECT_EQ(element_animations_impl, player_impl_->element_animations()); |
211 | 210 |
212 int list_size_after = 0; | 211 int list_size_after = 0; |
213 for (const ElementAnimations::PlayersListNode* node = | 212 it = ElementAnimations::PlayersList::Iterator( |
214 element_animations_impl->players_list().head(); | 213 &element_animations_impl->players_list()); |
215 node != element_animations_impl->players_list().end(); | 214 while ((player = it.GetNext()) != nullptr) { |
216 node = node->next()) { | 215 EXPECT_TRUE(timeline_->GetPlayerById(player->id())); |
217 const AnimationPlayer* player_impl = node->value(); | |
218 EXPECT_TRUE(timeline_->GetPlayerById(player_impl->id())); | |
219 ++list_size_after; | 216 ++list_size_after; |
220 } | 217 } |
221 EXPECT_EQ(2, list_size_after); | 218 EXPECT_EQ(2, list_size_after); |
222 } | 219 } |
223 | 220 |
224 TEST_F(ElementAnimationsTest, SyncNewAnimation) { | 221 TEST_F(ElementAnimationsTest, SyncNewAnimation) { |
225 auto animations_impl = ElementAnimations::Create(); | 222 auto animations_impl = ElementAnimations::Create(); |
226 animations_impl->set_has_element_in_active_list(true); | 223 animations_impl->set_has_element_in_active_list(true); |
227 | 224 |
228 auto animations = ElementAnimations::Create(); | 225 auto animations = ElementAnimations::Create(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 std::move(curve), animation2_id, 0, TargetProperty::SCROLL_OFFSET)); | 290 std::move(curve), animation2_id, 0, TargetProperty::SCROLL_OFFSET)); |
294 animations->AddAnimation(std::move(animation)); | 291 animations->AddAnimation(std::move(animation)); |
295 animations->PushPropertiesTo(animations_impl.get()); | 292 animations->PushPropertiesTo(animations_impl.get()); |
296 EXPECT_VECTOR2DF_EQ(provider_initial_value, | 293 EXPECT_VECTOR2DF_EQ(provider_initial_value, |
297 animations_impl->GetAnimationById(animation2_id) | 294 animations_impl->GetAnimationById(animation2_id) |
298 ->curve() | 295 ->curve() |
299 ->ToScrollOffsetAnimationCurve() | 296 ->ToScrollOffsetAnimationCurve() |
300 ->GetValue(base::TimeDelta())); | 297 ->GetValue(base::TimeDelta())); |
301 } | 298 } |
302 | 299 |
| 300 class TestAnimationDelegateThatDestroysPlayer : public TestAnimationDelegate { |
| 301 public: |
| 302 TestAnimationDelegateThatDestroysPlayer() {} |
| 303 |
| 304 void NotifyAnimationStarted(base::TimeTicks monotonic_time, |
| 305 TargetProperty::Type target_property, |
| 306 int group) override { |
| 307 TestAnimationDelegate::NotifyAnimationStarted(monotonic_time, |
| 308 target_property, group); |
| 309 // Detaching player from the timeline ensures that the timeline doesn't hold |
| 310 // a reference to the player and the player is destroyed. |
| 311 timeline_->DetachPlayer(player_); |
| 312 }; |
| 313 |
| 314 void setTimelineAndPlayer(scoped_refptr<AnimationTimeline> timeline, |
| 315 scoped_refptr<AnimationPlayer> player) { |
| 316 timeline_ = timeline; |
| 317 player_ = player; |
| 318 } |
| 319 |
| 320 private: |
| 321 scoped_refptr<AnimationTimeline> timeline_; |
| 322 scoped_refptr<AnimationPlayer> player_; |
| 323 }; |
| 324 |
| 325 // Test that we don't crash if a player is deleted while ElementAnimations is |
| 326 // iterating through the list of players (see crbug.com/631052). This test |
| 327 // passes if it doesn't crash. |
| 328 TEST_F(ElementAnimationsTest, AddedPlayerIsDestroyed) { |
| 329 CreateTestLayer(true, false); |
| 330 AttachTimelinePlayerLayer(); |
| 331 CreateImplTimelineAndPlayer(); |
| 332 |
| 333 scoped_refptr<ElementAnimations> animations = element_animations(); |
| 334 scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); |
| 335 |
| 336 TestAnimationDelegateThatDestroysPlayer delegate; |
| 337 { |
| 338 scoped_refptr<AnimationPlayer> player = |
| 339 AnimationPlayer::Create(AnimationIdProvider::NextPlayerId()); |
| 340 delegate.setTimelineAndPlayer(timeline_, player); |
| 341 |
| 342 timeline_->AttachPlayer(player); |
| 343 player->AttachElement(element_id_); |
| 344 player->set_animation_delegate(&delegate); |
| 345 } |
| 346 |
| 347 int animation_id = AddOpacityTransitionToElementAnimations( |
| 348 animations.get(), 1.0, 0.f, 1.f, false); |
| 349 |
| 350 animations->PushPropertiesTo(animations_impl.get()); |
| 351 animations_impl->ActivateAnimations(); |
| 352 EXPECT_TRUE(animations_impl->GetAnimationById(animation_id)); |
| 353 |
| 354 animations_impl->Animate(kInitialTickTime); |
| 355 |
| 356 auto events = host_impl_->CreateEvents(); |
| 357 animations_impl->UpdateState(true, events.get()); |
| 358 EXPECT_EQ(1u, events->events_.size()); |
| 359 EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); |
| 360 |
| 361 // The actual detachment happens here, inside the callback |
| 362 animations->NotifyAnimationStarted(events->events_[0]); |
| 363 EXPECT_TRUE(delegate.started()); |
| 364 } |
| 365 |
303 // If an animation is started on the impl thread before it is ticked on the main | 366 // If an animation is started on the impl thread before it is ticked on the main |
304 // thread, we must be sure to respect the synchronized start time. | 367 // thread, we must be sure to respect the synchronized start time. |
305 TEST_F(ElementAnimationsTest, DoNotClobberStartTimes) { | 368 TEST_F(ElementAnimationsTest, DoNotClobberStartTimes) { |
306 CreateTestLayer(true, false); | 369 CreateTestLayer(true, false); |
307 AttachTimelinePlayerLayer(); | 370 AttachTimelinePlayerLayer(); |
308 CreateImplTimelineAndPlayer(); | 371 CreateImplTimelineAndPlayer(); |
309 | 372 |
310 scoped_refptr<ElementAnimations> animations = element_animations(); | 373 scoped_refptr<ElementAnimations> animations = element_animations(); |
311 scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); | 374 scoped_refptr<ElementAnimations> animations_impl = element_animations_impl(); |
312 | 375 |
(...skipping 3302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3615 EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( | 3678 EXPECT_FALSE(animations->IsPotentiallyAnimatingProperty( |
3616 TargetProperty::OPACITY, ElementListType::ACTIVE)); | 3679 TargetProperty::OPACITY, ElementListType::ACTIVE)); |
3617 EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( | 3680 EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( |
3618 TargetProperty::OPACITY, ElementListType::PENDING)); | 3681 TargetProperty::OPACITY, ElementListType::PENDING)); |
3619 EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( | 3682 EXPECT_FALSE(animations->IsCurrentlyAnimatingProperty( |
3620 TargetProperty::OPACITY, ElementListType::ACTIVE)); | 3683 TargetProperty::OPACITY, ElementListType::ACTIVE)); |
3621 } | 3684 } |
3622 | 3685 |
3623 } // namespace | 3686 } // namespace |
3624 } // namespace cc | 3687 } // namespace cc |
OLD | NEW |