Commit edee7a0b authored by loyso's avatar loyso Committed by Commit bot

Blink Compositor Animations: Add tests for resetting delegate in CC on Blink player deletion.

cc::AnimationPlayer is an RC object, so it may outsurvive blink::CompositorAnimationPlayer if attached to cc::AnimationTimeline.

We must clean-up animation delegate in cc::AnimationPlayer on blink::CompositorAnimationPlayer deletion.

This is tests for this CL: https://codereview.chromium.org/1747283004/

BUG=590803

Review URL: https://codereview.chromium.org/1810833002

Cr-Commit-Position: refs/heads/master@{#381621}
parent 838e5ce3
......@@ -7,44 +7,104 @@
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "platform/animation/CompositorAnimationDelegate.h"
#include "platform/animation/CompositorAnimationPlayerClient.h"
#include "platform/animation/CompositorAnimationTimeline.h"
#include "platform/animation/CompositorTargetProperty.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::TimeTicks;
using blink::CompositorAnimationDelegate;
using cc::Animation;
using testing::_;
namespace blink {
class MockCompositorAnimationDelegate : public CompositorAnimationDelegate {
class CompositorAnimationDelegateForTesting : public CompositorAnimationDelegate {
public:
MockCompositorAnimationDelegate() {}
CompositorAnimationDelegateForTesting() { resetFlags(); }
void resetFlags()
{
m_started = false;
m_finished = false;
m_aborted = false;
}
MOCK_METHOD2(notifyAnimationStarted, void(double, int));
MOCK_METHOD2(notifyAnimationFinished, void(double, int));
MOCK_METHOD2(notifyAnimationAborted, void(double, int));
void notifyAnimationStarted(double, int) override { m_started = true; }
void notifyAnimationFinished(double, int) override { m_finished = true; }
void notifyAnimationAborted(double, int) override { m_aborted = true; }
bool m_started;
bool m_finished;
bool m_aborted;
};
class CompositorAnimationPlayerTestClient : public CompositorAnimationPlayerClient {
public:
CompositorAnimationPlayerTestClient() : m_player(new CompositorAnimationPlayer) {}
CompositorAnimationPlayer* compositorPlayer() const override
{
return m_player.get();
}
scoped_ptr<CompositorAnimationPlayer> m_player;
};
// Test that when the animation delegate is null, the animation player
// doesn't forward the finish notification.
TEST(CompositorAnimationPlayerTest, NullDelegate)
{
scoped_ptr<CompositorAnimationDelegate> delegate(
new MockCompositorAnimationDelegate);
EXPECT_CALL(*static_cast<MockCompositorAnimationDelegate*>(delegate.get()),
notifyAnimationFinished(_, _))
.Times(1);
scoped_ptr<CompositorAnimationDelegateForTesting> delegate(new CompositorAnimationDelegateForTesting);
scoped_ptr<CompositorAnimationPlayer> player(new CompositorAnimationPlayer);
cc::AnimationPlayer* ccPlayer = player->animationPlayer();
player->setAnimationDelegate(delegate.get());
EXPECT_FALSE(delegate->m_finished);
ccPlayer->NotifyAnimationFinished(base::TimeTicks(), CompositorTargetProperty::SCROLL_OFFSET, 0);
EXPECT_TRUE(delegate->m_finished);
delegate->resetFlags();
player->setAnimationDelegate(nullptr);
ccPlayer->NotifyAnimationFinished(base::TimeTicks(), CompositorTargetProperty::SCROLL_OFFSET, 0);
EXPECT_FALSE(delegate->m_finished);
}
TEST(CompositorAnimationPlayerTest, NotifyFromCCAfterCompositorPlayerDeletion)
{
scoped_ptr<CompositorAnimationDelegateForTesting> delegate(new CompositorAnimationDelegateForTesting);
scoped_ptr<CompositorAnimationPlayer> player(new CompositorAnimationPlayer);
scoped_refptr<cc::AnimationPlayer> ccPlayer = player->animationPlayer();
player->setAnimationDelegate(delegate.get());
EXPECT_FALSE(delegate->m_finished);
// Delete CompositorAnimationPlayer. ccPlayer stays alive.
player = nullptr;
// No notifications. Doesn't crash.
ccPlayer->NotifyAnimationFinished(base::TimeTicks(), CompositorTargetProperty::OPACITY, 0);
EXPECT_FALSE(delegate->m_finished);
}
TEST(CompositorAnimationPlayerTest, CompositorPlayerDeletionDetachesFromCCTimeline)
{
scoped_ptr<CompositorAnimationTimeline> timeline(new CompositorAnimationTimeline);
scoped_ptr<CompositorAnimationPlayerTestClient> client(new CompositorAnimationPlayerTestClient);
scoped_refptr<cc::AnimationTimeline> ccTimeline = timeline->animationTimeline();
scoped_refptr<cc::AnimationPlayer> ccPlayer = client->m_player->animationPlayer();
EXPECT_FALSE(ccPlayer->animation_timeline());
scoped_ptr<CompositorAnimationPlayer> webPlayer(new CompositorAnimationPlayer);
cc::AnimationPlayer* player = webPlayer->animationPlayer();
timeline->playerAttached(*client);
EXPECT_TRUE(ccPlayer->animation_timeline());
EXPECT_TRUE(ccTimeline->GetPlayerById(ccPlayer->id()));
webPlayer->setAnimationDelegate(delegate.get());
player->NotifyAnimationFinished(TimeTicks(), CompositorTargetProperty::SCROLL_OFFSET, 0);
// Delete client and CompositorAnimationPlayer while attached to timeline.
client = nullptr;
webPlayer->setAnimationDelegate(nullptr);
player->NotifyAnimationFinished(TimeTicks(), CompositorTargetProperty::SCROLL_OFFSET, 0);
EXPECT_FALSE(ccPlayer->animation_timeline());
EXPECT_FALSE(ccTimeline->GetPlayerById(ccPlayer->id()));
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment