blob: 6ad8e7c89c82e131c69935c1b80c87aa0bbed27e [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform/animation/CompositorAnimationPlayer.h"
#include "base/time/time.h"
#include "platform/animation/CompositorAnimation.h"
#include "platform/animation/CompositorAnimationDelegate.h"
#include "platform/animation/CompositorAnimationPlayerClient.h"
#include "platform/animation/CompositorAnimationTimeline.h"
#include "platform/animation/CompositorFloatAnimationCurve.h"
#include "platform/animation/CompositorTargetProperty.h"
#include "platform/testing/CompositorTest.h"
#include <memory>
namespace blink {
class CompositorAnimationDelegateForTesting
: public CompositorAnimationDelegate {
public:
CompositorAnimationDelegateForTesting() { ResetFlags(); }
void ResetFlags() {
started_ = false;
finished_ = false;
aborted_ = false;
}
void NotifyAnimationStarted(double, int) override { started_ = true; }
void NotifyAnimationFinished(double, int) override { finished_ = true; }
void NotifyAnimationAborted(double, int) override { aborted_ = true; }
bool started_;
bool finished_;
bool aborted_;
};
class CompositorAnimationPlayerTestClient
: public CompositorAnimationPlayerClient {
public:
CompositorAnimationPlayerTestClient()
: player_(CompositorAnimationPlayer::Create()) {}
CompositorAnimationPlayer* CompositorPlayer() const override {
return player_.get();
}
std::unique_ptr<CompositorAnimationPlayer> player_;
};
class CompositorAnimationPlayerTest : public CompositorTest {};
// Test that when the animation delegate is null, the animation player
// doesn't forward the finish notification.
TEST_F(CompositorAnimationPlayerTest, NullDelegate) {
std::unique_ptr<CompositorAnimationDelegateForTesting> delegate(
new CompositorAnimationDelegateForTesting);
std::unique_ptr<CompositorAnimationPlayer> player =
CompositorAnimationPlayer::Create();
cc::AnimationPlayer* cc_player = player->CcAnimationPlayer();
std::unique_ptr<CompositorAnimationCurve> curve =
CompositorFloatAnimationCurve::Create();
std::unique_ptr<CompositorAnimation> animation = CompositorAnimation::Create(
*curve, CompositorTargetProperty::TRANSFORM, 1, 0);
player->AddAnimation(std::move(animation));
player->SetAnimationDelegate(delegate.get());
EXPECT_FALSE(delegate->finished_);
cc_player->NotifyAnimationFinishedForTesting(
CompositorTargetProperty::TRANSFORM, 1);
EXPECT_TRUE(delegate->finished_);
delegate->ResetFlags();
player->SetAnimationDelegate(nullptr);
cc_player->NotifyAnimationFinishedForTesting(
CompositorTargetProperty::TRANSFORM, 1);
EXPECT_FALSE(delegate->finished_);
}
TEST_F(CompositorAnimationPlayerTest,
NotifyFromCCAfterCompositorPlayerDeletion) {
std::unique_ptr<CompositorAnimationDelegateForTesting> delegate(
new CompositorAnimationDelegateForTesting);
std::unique_ptr<CompositorAnimationPlayer> player =
CompositorAnimationPlayer::Create();
scoped_refptr<cc::AnimationPlayer> cc_player = player->CcAnimationPlayer();
std::unique_ptr<CompositorAnimationCurve> curve =
CompositorFloatAnimationCurve::Create();
std::unique_ptr<CompositorAnimation> animation = CompositorAnimation::Create(
*curve, CompositorTargetProperty::OPACITY, 1, 0);
player->AddAnimation(std::move(animation));
player->SetAnimationDelegate(delegate.get());
EXPECT_FALSE(delegate->finished_);
cc_player->NotifyAnimationFinishedForTesting(
CompositorTargetProperty::OPACITY, 1);
EXPECT_TRUE(delegate->finished_);
delegate->finished_ = false;
// Delete CompositorAnimationPlayer. ccPlayer stays alive.
player = nullptr;
// No notifications. Doesn't crash.
cc_player->NotifyAnimationFinishedForTesting(
CompositorTargetProperty::OPACITY, 1);
EXPECT_FALSE(delegate->finished_);
}
TEST_F(CompositorAnimationPlayerTest,
CompositorPlayerDeletionDetachesFromCCTimeline) {
std::unique_ptr<CompositorAnimationTimeline> timeline =
CompositorAnimationTimeline::Create();
std::unique_ptr<CompositorAnimationPlayerTestClient> client(
new CompositorAnimationPlayerTestClient);
scoped_refptr<cc::AnimationTimeline> cc_timeline =
timeline->GetAnimationTimeline();
scoped_refptr<cc::AnimationPlayer> cc_player =
client->player_->CcAnimationPlayer();
EXPECT_FALSE(cc_player->animation_timeline());
timeline->PlayerAttached(*client);
EXPECT_TRUE(cc_player->animation_timeline());
EXPECT_TRUE(cc_timeline->GetPlayerById(cc_player->id()));
// Delete client and CompositorAnimationPlayer while attached to timeline.
client = nullptr;
EXPECT_FALSE(cc_player->animation_timeline());
EXPECT_FALSE(cc_timeline->GetPlayerById(cc_player->id()));
}
} // namespace blink