// Copyright 2015 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 "ui/compositor/callback_layer_animation_observer.h"

#include <memory>

#include "base/bind.h"
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/test/layer_animation_observer_test_api.h"

namespace ui {
namespace test {

// Simple class that tracks whether callbacks were invoked and when.
class TestCallbacks {
 public:
  TestCallbacks();
  virtual ~TestCallbacks();

  void ResetCallbackObservations();

  void set_should_delete_observer_on_animations_ended(
      bool should_delete_observer_on_animations_ended) {
    should_delete_observer_on_animations_ended_ =
        should_delete_observer_on_animations_ended;
  }

  bool animations_started() const { return animations_started_; }

  bool animations_ended() const { return animations_ended_; }

  virtual void AnimationsStarted(const CallbackLayerAnimationObserver&);

  virtual bool AnimationsEnded(const CallbackLayerAnimationObserver&);

  testing::AssertionResult StartedEpochIsBeforeEndedEpoch();

 private:
  // Monotonic counter that tracks the next time snapshot.
  int next_epoch_ = 0;

  // Is true when AnimationsStarted() has been called.
  bool animations_started_ = false;

  // Relative time snapshot of when AnimationsStarted() was last called.
  int animations_started_epoch_ = -1;

  // Is true when AnimationsEnded() has been called.
  bool animations_ended_ = false;

  // Relative time snapshot of when AnimationsEnded() was last called.
  int animations_ended_epoch_ = -1;

  // The return value for AnimationsEnded().
  bool should_delete_observer_on_animations_ended_ = false;

  DISALLOW_COPY_AND_ASSIGN(TestCallbacks);
};

TestCallbacks::TestCallbacks() {}

TestCallbacks::~TestCallbacks() {}

void TestCallbacks::ResetCallbackObservations() {
  next_epoch_ = 0;
  animations_started_ = false;
  animations_started_epoch_ = -1;
  animations_ended_ = false;
  animations_ended_epoch_ = -1;
  should_delete_observer_on_animations_ended_ = false;
}

void TestCallbacks::AnimationsStarted(const CallbackLayerAnimationObserver&) {
  animations_started_ = true;
  animations_started_epoch_ = next_epoch_++;
}

bool TestCallbacks::AnimationsEnded(const CallbackLayerAnimationObserver&) {
  animations_ended_ = true;
  animations_ended_epoch_ = next_epoch_++;
  return should_delete_observer_on_animations_ended_;
}

testing::AssertionResult TestCallbacks::StartedEpochIsBeforeEndedEpoch() {
  if (animations_started_epoch_ < animations_ended_epoch_) {
    return testing::AssertionSuccess();
  } else {
    return testing::AssertionFailure()
           << "The started epoch=" << animations_started_epoch_
           << " is NOT before the ended epoch=" << animations_ended_epoch_;
  }
}

// A child of TestCallbacks that can explicitly delete a
// CallbackLayerAnimationObserver in the AnimationsStarted() or
// AnimationsEnded() callback.
class TestCallbacksThatExplicitlyDeletesObserver : public TestCallbacks {
 public:
  TestCallbacksThatExplicitlyDeletesObserver();

  void set_observer_to_delete_in_animation_started(
      CallbackLayerAnimationObserver* observer) {
    observer_to_delete_in_animation_started_ = observer;
  }

  void set_observer_to_delete_in_animation_ended(
      CallbackLayerAnimationObserver* observer) {
    observer_to_delete_in_animation_ended_ = observer;
  }

  // TestCallbacks:
  void AnimationsStarted(
      const CallbackLayerAnimationObserver& observer) override;
  bool AnimationsEnded(const CallbackLayerAnimationObserver& observer) override;

 private:
  // The observer to delete, if non-NULL, in AnimationsStarted().
  CallbackLayerAnimationObserver* observer_to_delete_in_animation_started_ =
      nullptr;

  // The observer to delete, if non-NULL, in AnimationsEnded().
  CallbackLayerAnimationObserver* observer_to_delete_in_animation_ended_ =
      nullptr;

  DISALLOW_COPY_AND_ASSIGN(TestCallbacksThatExplicitlyDeletesObserver);
};

TestCallbacksThatExplicitlyDeletesObserver::
    TestCallbacksThatExplicitlyDeletesObserver() {}

void TestCallbacksThatExplicitlyDeletesObserver::AnimationsStarted(
    const CallbackLayerAnimationObserver& observer) {
  if (observer_to_delete_in_animation_started_)
    delete observer_to_delete_in_animation_started_;
  TestCallbacks::AnimationsStarted(observer);
}

bool TestCallbacksThatExplicitlyDeletesObserver::AnimationsEnded(
    const CallbackLayerAnimationObserver& observer) {
  if (observer_to_delete_in_animation_ended_)
    delete observer_to_delete_in_animation_ended_;
  return TestCallbacks::AnimationsEnded(observer);
}

// A test specific CallbackLayerAnimationObserver that will set a bool when
// destroyed.
class TestCallbackLayerAnimationObserver
    : public CallbackLayerAnimationObserver {
 public:
  TestCallbackLayerAnimationObserver(
      AnimationStartedCallback animation_started_callback,
      AnimationEndedCallback animation_ended_callback,
      bool* destroyed);

  TestCallbackLayerAnimationObserver(
      AnimationStartedCallback animation_started_callback,
      bool should_delete_observer,
      bool* destroyed);

  TestCallbackLayerAnimationObserver(
      AnimationEndedCallback animation_ended_callback,
      bool* destroyed);

  ~TestCallbackLayerAnimationObserver() override;

 private:
  bool* destroyed_;

  DISALLOW_COPY_AND_ASSIGN(TestCallbackLayerAnimationObserver);
};

TestCallbackLayerAnimationObserver::TestCallbackLayerAnimationObserver(
    AnimationStartedCallback animation_started_callback,
    AnimationEndedCallback animation_ended_callback,
    bool* destroyed)
    : CallbackLayerAnimationObserver(animation_started_callback,
                                     animation_ended_callback),
      destroyed_(destroyed) {
  if (destroyed_)
    (*destroyed_) = false;
}

TestCallbackLayerAnimationObserver::TestCallbackLayerAnimationObserver(
    AnimationStartedCallback animation_started_callback,
    bool should_delete_observer,
    bool* destroyed)
    : CallbackLayerAnimationObserver(animation_started_callback,
                                     should_delete_observer),
      destroyed_(destroyed) {
  if (destroyed_)
    (*destroyed_) = false;
}

TestCallbackLayerAnimationObserver::TestCallbackLayerAnimationObserver(
    AnimationEndedCallback animation_ended_callback,
    bool* destroyed)
    : CallbackLayerAnimationObserver(animation_ended_callback),
      destroyed_(destroyed) {
  if (destroyed_)
    (*destroyed_) = false;
}

TestCallbackLayerAnimationObserver::~TestCallbackLayerAnimationObserver() {
  if (destroyed_)
    (*destroyed_) = true;
}

class CallbackLayerAnimationObserverTest : public testing::Test {
 public:
  CallbackLayerAnimationObserverTest();
  ~CallbackLayerAnimationObserverTest() override;

 protected:
  // Creates a LayerAnimationSequence.  The lifetime of the sequence will be
  // managed by this.
  LayerAnimationSequence* CreateLayerAnimationSequence();

  std::unique_ptr<TestCallbacks> callbacks_;

  std::unique_ptr<CallbackLayerAnimationObserver> observer_;

  std::unique_ptr<LayerAnimationObserverTestApi> observer_test_api_;

  // List of managaged sequences created by CreateLayerAnimationSequence() that
  // need to be destroyed.
  std::vector<std::unique_ptr<LayerAnimationSequence>> sequences_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CallbackLayerAnimationObserverTest);
};

CallbackLayerAnimationObserverTest::CallbackLayerAnimationObserverTest()
    : callbacks_(new TestCallbacks()),
      observer_(new CallbackLayerAnimationObserver(
          base::Bind(&TestCallbacks::AnimationsStarted,
                     base::Unretained(callbacks_.get())),
          base::Bind(&TestCallbacks::AnimationsEnded,
                     base::Unretained(callbacks_.get())))),
      observer_test_api_(new LayerAnimationObserverTestApi(observer_.get())) {}

CallbackLayerAnimationObserverTest::~CallbackLayerAnimationObserverTest() {
  observer_test_api_.reset();
  // The |observer_| will detach from all attached sequences upon destruction so
  // we need to explicitly delete the |observer_| before the |sequences_| and
  // |callbacks_|.
  observer_.reset();
}

LayerAnimationSequence*
CallbackLayerAnimationObserverTest::CreateLayerAnimationSequence() {
  sequences_.emplace_back(new LayerAnimationSequence);
  return sequences_.back().get();
}

TEST(CallbackLayerAnimationObserverDestructionTest, VerifyFalseAutoDelete) {
  TestCallbacks callbacks;
  callbacks.set_should_delete_observer_on_animations_ended(false);

  bool is_destroyed = false;

  TestCallbackLayerAnimationObserver* observer =
      new TestCallbackLayerAnimationObserver(
          base::Bind(&TestCallbacks::AnimationsStarted,
                     base::Unretained(&callbacks)),
          false, &is_destroyed);
  observer->SetActive();

  EXPECT_FALSE(is_destroyed);
  delete observer;
}

TEST(CallbackLayerAnimationObserverDestructionTest, VerifyTrueAutoDelete) {
  TestCallbacks callbacks;
  callbacks.set_should_delete_observer_on_animations_ended(false);

  bool is_destroyed = false;

  TestCallbackLayerAnimationObserver* observer =
      new TestCallbackLayerAnimationObserver(
          base::Bind(&TestCallbacks::AnimationsStarted,
                     base::Unretained(&callbacks)),
          true, &is_destroyed);
  observer->SetActive();

  EXPECT_TRUE(is_destroyed);
}

TEST(CallbackLayerAnimationObserverDestructionTest,
     AnimationEndedReturnsFalse) {
  TestCallbacks callbacks;
  callbacks.set_should_delete_observer_on_animations_ended(false);

  bool is_destroyed = false;

  TestCallbackLayerAnimationObserver* observer =
      new TestCallbackLayerAnimationObserver(
          base::Bind(&TestCallbacks::AnimationsStarted,
                     base::Unretained(&callbacks)),
          base::Bind(&TestCallbacks::AnimationsEnded,
                     base::Unretained(&callbacks)),
          &is_destroyed);
  observer->SetActive();

  EXPECT_FALSE(is_destroyed);
  delete observer;
}

TEST(CallbackLayerAnimationObserverDestructionTest, AnimationEndedReturnsTrue) {
  TestCallbacks callbacks;
  callbacks.set_should_delete_observer_on_animations_ended(true);

  bool is_destroyed = false;

  TestCallbackLayerAnimationObserver* observer =
      new TestCallbackLayerAnimationObserver(
          base::Bind(&TestCallbacks::AnimationsStarted,
                     base::Unretained(&callbacks)),
          base::Bind(&TestCallbacks::AnimationsEnded,
                     base::Unretained(&callbacks)),
          &is_destroyed);
  observer->SetActive();

  EXPECT_TRUE(is_destroyed);
}

TEST_F(CallbackLayerAnimationObserverTest, VerifyInitialState) {
  EXPECT_FALSE(observer_->active());
  EXPECT_EQ(0, observer_->aborted_count());
  EXPECT_EQ(0, observer_->successful_count());

  EXPECT_FALSE(callbacks_->animations_started());
  EXPECT_FALSE(callbacks_->animations_ended());
}

// Verifies that the CallbackLayerAnimationObserver is robust to explicit
// deletes caused as a side effect of calling the AnimationsStartedCallback()
// when there are no animation sequences attached. This test also guards against
// heap-use-after-free errors.
TEST_F(
    CallbackLayerAnimationObserverTest,
    ExplicitlyDeleteObserverInAnimationStartedCallbackWithNoSequencesAttached) {
  TestCallbacksThatExplicitlyDeletesObserver callbacks;
  callbacks.set_should_delete_observer_on_animations_ended(true);

  bool is_destroyed = false;

  TestCallbackLayerAnimationObserver* observer =
      new TestCallbackLayerAnimationObserver(
          base::Bind(&TestCallbacks::AnimationsStarted,
                     base::Unretained(&callbacks)),
          base::Bind(&TestCallbacks::AnimationsEnded,
                     base::Unretained(&callbacks)),
          &is_destroyed);

  callbacks.set_observer_to_delete_in_animation_started(observer);

  observer->SetActive();

  EXPECT_TRUE(is_destroyed);
}

// Verifies that the CallbackLayerAnimationObserver is robust to explicit
// deletes caused as a side effect of calling the AnimationsStartedCallback()
// when there are some animation sequences attached. This test also guards
// against heap-use-after-free errors.
TEST_F(
    CallbackLayerAnimationObserverTest,
    ExplicitlyDeleteObserverInAnimationStartedCallbackWithSomeSequencesAttached) {
  LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();

  TestCallbacksThatExplicitlyDeletesObserver callbacks;
  callbacks.set_should_delete_observer_on_animations_ended(true);

  bool is_destroyed = false;

  TestCallbackLayerAnimationObserver* observer =
      new TestCallbackLayerAnimationObserver(
          base::Bind(&TestCallbacks::AnimationsStarted,
                     base::Unretained(&callbacks)),
          base::Bind(&TestCallbacks::AnimationsEnded,
                     base::Unretained(&callbacks)),
          &is_destroyed);

  observer_test_api_->AttachedToSequence(sequence_1);
  observer_test_api_->AttachedToSequence(sequence_2);
  observer_->OnLayerAnimationStarted(sequence_1);
  observer_->OnLayerAnimationStarted(sequence_2);

  callbacks.set_observer_to_delete_in_animation_started(observer);

  observer->SetActive();

  EXPECT_TRUE(is_destroyed);
}

// Verifies that a 'true' return value for AnimationEndedCallback is ignored if
// the CallbackLayerAnimationObserver is explicitly deleted as a side effect of
// calling the AnimationEndedCallback. This test also guards against
// heap-use-after-free errors.
TEST_F(CallbackLayerAnimationObserverTest,
       IgnoreTrueReturnValueForAnimationEndedCallbackIfExplicitlyDeleted) {
  TestCallbacksThatExplicitlyDeletesObserver callbacks;
  callbacks.set_should_delete_observer_on_animations_ended(true);

  bool is_destroyed = false;

  TestCallbackLayerAnimationObserver* observer =
      new TestCallbackLayerAnimationObserver(
          base::Bind(&TestCallbacks::AnimationsStarted,
                     base::Unretained(&callbacks)),
          base::Bind(&TestCallbacks::AnimationsEnded,
                     base::Unretained(&callbacks)),
          &is_destroyed);

  callbacks.set_observer_to_delete_in_animation_ended(observer);

  observer->SetActive();

  EXPECT_TRUE(is_destroyed);
}

TEST_F(CallbackLayerAnimationObserverTest,
       SetActiveWhenNoSequencesWereAttached) {
  observer_->SetActive();

  EXPECT_FALSE(observer_->active());
  EXPECT_TRUE(callbacks_->animations_started());
  EXPECT_TRUE(callbacks_->animations_ended());
  EXPECT_TRUE(callbacks_->StartedEpochIsBeforeEndedEpoch());
}

TEST_F(CallbackLayerAnimationObserverTest,
       SetActiveWhenAllSequencesAreAttachedButNoneWereStarted) {
  LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();

  observer_test_api_->AttachedToSequence(sequence_1);
  observer_test_api_->AttachedToSequence(sequence_2);

  observer_->SetActive();

  EXPECT_TRUE(observer_->active());
  EXPECT_FALSE(callbacks_->animations_started());
  EXPECT_FALSE(callbacks_->animations_ended());
}

TEST_F(CallbackLayerAnimationObserverTest,
       SetActiveWhenAllSequencesAreAttachedAndOnlySomeWereStarted) {
  LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();

  observer_test_api_->AttachedToSequence(sequence_1);
  observer_test_api_->AttachedToSequence(sequence_2);
  observer_->OnLayerAnimationStarted(sequence_1);

  observer_->SetActive();

  EXPECT_TRUE(observer_->active());
  EXPECT_FALSE(callbacks_->animations_started());
  EXPECT_FALSE(callbacks_->animations_ended());
}

TEST_F(CallbackLayerAnimationObserverTest,
       SetActiveWhenAllSequencesAreAttachedAndOnlySomeWereCompleted) {
  LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();

  observer_test_api_->AttachedToSequence(sequence_1);
  observer_test_api_->AttachedToSequence(sequence_2);
  observer_->OnLayerAnimationStarted(sequence_1);
  observer_->OnLayerAnimationEnded(sequence_1);

  observer_->SetActive();

  EXPECT_TRUE(observer_->active());
  EXPECT_FALSE(callbacks_->animations_started());
  EXPECT_FALSE(callbacks_->animations_ended());
}

TEST_F(CallbackLayerAnimationObserverTest,
       SetActiveAfterAllSequencesWereStartedButNoneWereCompleted) {
  LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();

  observer_test_api_->AttachedToSequence(sequence_1);
  observer_test_api_->AttachedToSequence(sequence_2);
  observer_->OnLayerAnimationStarted(sequence_1);
  observer_->OnLayerAnimationStarted(sequence_2);

  observer_->SetActive();

  EXPECT_TRUE(observer_->active());
  EXPECT_TRUE(callbacks_->animations_started());
  EXPECT_FALSE(callbacks_->animations_ended());
}

TEST_F(CallbackLayerAnimationObserverTest,
       SetActiveWhenAllSequencesAreStartedAndOnlySomeWereCompleted) {
  LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();

  observer_test_api_->AttachedToSequence(sequence_1);
  observer_test_api_->AttachedToSequence(sequence_2);
  observer_->OnLayerAnimationStarted(sequence_1);
  observer_->OnLayerAnimationStarted(sequence_2);
  observer_->OnLayerAnimationEnded(sequence_1);

  observer_->SetActive();

  EXPECT_TRUE(observer_->active());
  EXPECT_TRUE(callbacks_->animations_started());
  EXPECT_FALSE(callbacks_->animations_ended());
}

TEST_F(CallbackLayerAnimationObserverTest,
       SetActiveWhenAllSequencesWereCompleted) {
  LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();

  observer_test_api_->AttachedToSequence(sequence_1);
  observer_test_api_->AttachedToSequence(sequence_2);
  observer_->OnLayerAnimationStarted(sequence_1);
  observer_->OnLayerAnimationStarted(sequence_2);
  observer_->OnLayerAnimationEnded(sequence_1);
  observer_->OnLayerAnimationEnded(sequence_2);

  observer_->SetActive();

  EXPECT_FALSE(observer_->active());
  EXPECT_TRUE(callbacks_->animations_started());
  EXPECT_TRUE(callbacks_->animations_ended());
}

TEST_F(CallbackLayerAnimationObserverTest,
       SetActiveAgainAfterAllSequencesWereCompleted) {
  LayerAnimationSequence* sequence_1 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_2 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_3 = CreateLayerAnimationSequence();
  LayerAnimationSequence* sequence_4 = CreateLayerAnimationSequence();

  observer_test_api_->AttachedToSequence(sequence_1);
  observer_test_api_->AttachedToSequence(sequence_2);
  observer_->OnLayerAnimationStarted(sequence_1);
  observer_->OnLayerAnimationStarted(sequence_2);
  observer_->OnLayerAnimationEnded(sequence_1);
  observer_->OnLayerAnimationEnded(sequence_2);

  observer_->SetActive();

  EXPECT_FALSE(observer_->active());

  observer_test_api_->AttachedToSequence(sequence_3);
  observer_test_api_->AttachedToSequence(sequence_4);

  callbacks_->ResetCallbackObservations();

  observer_->SetActive();

  EXPECT_TRUE(observer_->active());
  EXPECT_FALSE(callbacks_->animations_started());
  EXPECT_FALSE(callbacks_->animations_ended());
  EXPECT_EQ(2, observer_->successful_count());

  observer_->OnLayerAnimationStarted(sequence_3);
  observer_->OnLayerAnimationStarted(sequence_4);

  EXPECT_TRUE(observer_->active());
  EXPECT_TRUE(callbacks_->animations_started());
  EXPECT_FALSE(callbacks_->animations_ended());
  EXPECT_EQ(2, observer_->successful_count());

  observer_->OnLayerAnimationEnded(sequence_3);
  observer_->OnLayerAnimationEnded(sequence_4);

  EXPECT_FALSE(observer_->active());
  EXPECT_TRUE(callbacks_->animations_started());
  EXPECT_TRUE(callbacks_->animations_ended());
  EXPECT_EQ(4, observer_->successful_count());
}

}  // namespace test
}  // namespace ui
