// Copyright 2011 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 "cc/layers/layer.h"

#include <stddef.h>

#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/base/math_util.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/picture_layer.h"
#include "cc/layers/solid_color_scrollbar_layer.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_impl_task_runner_provider.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_test_common.h"
#include "cc/test/stub_layer_tree_host_single_thread_client.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/single_thread_proxy.h"
#include "cc/trees/transform_node.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/transform.h"

using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Mock;
using ::testing::StrictMock;
using ::testing::_;

#define EXPECT_SET_NEEDS_FULL_TREE_SYNC(expect, code_to_test)               \
  do {                                                                      \
    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times((expect)); \
    code_to_test;                                                           \
    Mock::VerifyAndClearExpectations(layer_tree_host_.get());               \
  } while (false)

#define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test)                       \
  code_to_test;                                                                \
  root->layer_tree_host()->BuildPropertyTreesForTesting();                     \
  EXPECT_TRUE(root->subtree_property_changed());                               \
  EXPECT_TRUE(base::ContainsKey(                                               \
      root->layer_tree_host()->LayersThatShouldPushProperties(), root.get())); \
  EXPECT_TRUE(child->subtree_property_changed());                              \
  EXPECT_TRUE(base::ContainsKey(                                               \
      child->layer_tree_host()->LayersThatShouldPushProperties(),              \
      child.get()));                                                           \
  EXPECT_TRUE(grand_child->subtree_property_changed());                        \
  EXPECT_TRUE(base::ContainsKey(                                               \
      grand_child->layer_tree_host()->LayersThatShouldPushProperties(),        \
      grand_child.get()));

#define EXECUTE_AND_VERIFY_SUBTREE_NOT_CHANGED(code_to_test)                   \
  code_to_test;                                                                \
  root->layer_tree_host()->BuildPropertyTreesForTesting();                     \
  EXPECT_FALSE(root->subtree_property_changed());                              \
  EXPECT_FALSE(base::ContainsKey(                                              \
      root->layer_tree_host()->LayersThatShouldPushProperties(), root.get())); \
  EXPECT_FALSE(child->subtree_property_changed());                             \
  EXPECT_FALSE(base::ContainsKey(                                              \
      child->layer_tree_host()->LayersThatShouldPushProperties(),              \
      child.get()));                                                           \
  EXPECT_FALSE(grand_child->subtree_property_changed());                       \
  EXPECT_FALSE(base::ContainsKey(                                              \
      grand_child->layer_tree_host()->LayersThatShouldPushProperties(),        \
      grand_child.get()));

#define EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(code_to_test) \
  code_to_test;                                                \
  EXPECT_FALSE(root->subtree_property_changed());              \
  EXPECT_FALSE(child->subtree_property_changed());             \
  EXPECT_FALSE(grand_child->subtree_property_changed());

namespace cc {

namespace {

static auto kArbitrarySourceId1 =
    base::UnguessableToken::Deserialize(0xdead, 0xbeef);
static auto kArbitrarySourceId2 =
    base::UnguessableToken::Deserialize(0xdead, 0xbee0);

class MockLayerTreeHost : public LayerTreeHost {
 public:
  MockLayerTreeHost(LayerTreeHostSingleThreadClient* single_thread_client,
                    LayerTreeHost::InitParams params)
      : LayerTreeHost(std::move(params), CompositorMode::SINGLE_THREADED) {
    InitializeSingleThreaded(single_thread_client,
                             base::ThreadTaskRunnerHandle::Get());
  }

  MOCK_METHOD0(SetNeedsCommit, void());
  MOCK_METHOD0(SetNeedsUpdateLayers, void());
  MOCK_METHOD0(SetNeedsFullTreeSync, void());
};

bool LayerNeedsDisplay(Layer* layer) {
  return !layer->update_rect().IsEmpty();
}

class LayerTest : public testing::Test {
 public:
  LayerTest()
      : host_impl_(LayerTreeSettings(),
                   &task_runner_provider_,
                   &task_graph_runner_) {
    timeline_impl_ =
        AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
    timeline_impl_->set_is_impl_only(true);
    host_impl_.animation_host()->AddAnimationTimeline(timeline_impl_);
  }

  const LayerTreeSettings& settings() { return settings_; }
  scoped_refptr<AnimationTimeline> timeline_impl() { return timeline_impl_; }

 protected:
  void SetUp() override {
    animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);

    LayerTreeHost::InitParams params;
    params.client = &fake_client_;
    params.settings = &settings_;
    params.task_graph_runner = &task_graph_runner_;
    params.mutator_host = animation_host_.get();

    layer_tree_host_.reset(new StrictMock<MockLayerTreeHost>(
        &single_thread_client_, std::move(params)));
  }

  void TearDown() override {
    Mock::VerifyAndClearExpectations(layer_tree_host_.get());
    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
    parent_ = nullptr;
    child1_ = nullptr;
    child2_ = nullptr;
    child3_ = nullptr;
    grand_child1_ = nullptr;
    grand_child2_ = nullptr;
    grand_child3_ = nullptr;

    layer_tree_host_->SetRootLayer(nullptr);
    animation_host_->SetMutatorHostClient(nullptr);
    layer_tree_host_ = nullptr;
    animation_host_ = nullptr;
  }

  void SimulateCommitForLayer(Layer* layer) {
    layer->PushPropertiesTo(
        layer->CreateLayerImpl(host_impl_.active_tree()).get());
  }

  void VerifyTestTreeInitialState() const {
    ASSERT_EQ(3U, parent_->children().size());
    EXPECT_EQ(child1_, parent_->children()[0]);
    EXPECT_EQ(child2_, parent_->children()[1]);
    EXPECT_EQ(child3_, parent_->children()[2]);
    EXPECT_EQ(parent_.get(), child1_->parent());
    EXPECT_EQ(parent_.get(), child2_->parent());
    EXPECT_EQ(parent_.get(), child3_->parent());

    ASSERT_EQ(2U, child1_->children().size());
    EXPECT_EQ(grand_child1_, child1_->children()[0]);
    EXPECT_EQ(grand_child2_, child1_->children()[1]);
    EXPECT_EQ(child1_.get(), grand_child1_->parent());
    EXPECT_EQ(child1_.get(), grand_child2_->parent());

    ASSERT_EQ(1U, child2_->children().size());
    EXPECT_EQ(grand_child3_, child2_->children()[0]);
    EXPECT_EQ(child2_.get(), grand_child3_->parent());

    ASSERT_EQ(0U, child3_->children().size());
  }

  void CreateSimpleTestTree() {
    parent_ = Layer::Create();
    child1_ = Layer::Create();
    child2_ = Layer::Create();
    child3_ = Layer::Create();
    grand_child1_ = Layer::Create();
    grand_child2_ = Layer::Create();
    grand_child3_ = Layer::Create();

    EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());
    layer_tree_host_->SetRootLayer(parent_);

    parent_->AddChild(child1_);
    parent_->AddChild(child2_);
    parent_->AddChild(child3_);
    child1_->AddChild(grand_child1_);
    child1_->AddChild(grand_child2_);
    child2_->AddChild(grand_child3_);

    Mock::VerifyAndClearExpectations(layer_tree_host_.get());

    VerifyTestTreeInitialState();
  }

  FakeImplTaskRunnerProvider task_runner_provider_;
  TestTaskGraphRunner task_graph_runner_;
  FakeLayerTreeHostImpl host_impl_;

  StubLayerTreeHostSingleThreadClient single_thread_client_;
  FakeLayerTreeHostClient fake_client_;
  std::unique_ptr<StrictMock<MockLayerTreeHost>> layer_tree_host_;
  std::unique_ptr<AnimationHost> animation_host_;
  scoped_refptr<Layer> parent_;
  scoped_refptr<Layer> child1_;
  scoped_refptr<Layer> child2_;
  scoped_refptr<Layer> child3_;
  scoped_refptr<Layer> grand_child1_;
  scoped_refptr<Layer> grand_child2_;
  scoped_refptr<Layer> grand_child3_;

  scoped_refptr<AnimationTimeline> timeline_impl_;

  LayerTreeSettings settings_;
};

TEST_F(LayerTest, BasicCreateAndDestroy) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  ASSERT_TRUE(test_layer.get());

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
  test_layer->SetLayerTreeHost(layer_tree_host_.get());
  Mock::VerifyAndClearExpectations(layer_tree_host_.get());

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
  test_layer->SetLayerTreeHost(nullptr);
}

TEST_F(LayerTest, LayerPropertyChangedForSubtree) {
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask_layer1 = PictureLayer::Create(&client);

  layer_tree_host_->SetRootLayer(root);
  root->AddChild(child);
  root->AddChild(child2);
  child->AddChild(grand_child);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  child->SetForceRenderSurfaceForTesting(true);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
  child2->SetScrollParent(grand_child.get());

  // Resizing without a mask layer or masks_to_bounds, should only require a
  // regular commit. Note that a layer and its mask should match sizes, but
  // the mask isn't in the tree yet, so won't need its own commit.
  gfx::Size arbitrary_size = gfx::Size(1, 2);
  EXPECT_SET_NEEDS_COMMIT(1, root->SetBounds(arbitrary_size));
  EXPECT_SET_NEEDS_COMMIT(0, mask_layer1->SetBounds(arbitrary_size));
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMaskLayer(mask_layer1.get()));

  // Set up the impl layers after the full tree is constructed, including the
  // mask layer.
  SkBlendMode arbitrary_blend_mode = SkBlendMode::kMultiply;
  std::unique_ptr<LayerImpl> root_impl =
      LayerImpl::Create(host_impl_.active_tree(), root->id());
  std::unique_ptr<LayerImpl> child_impl =
      LayerImpl::Create(host_impl_.active_tree(), child->id());
  std::unique_ptr<LayerImpl> child2_impl =
      LayerImpl::Create(host_impl_.active_tree(), child2->id());
  std::unique_ptr<LayerImpl> grand_child_impl =
      LayerImpl::Create(host_impl_.active_tree(), grand_child->id());
  std::unique_ptr<LayerImpl> mask_layer1_impl =
      mask_layer1->CreateLayerImpl(host_impl_.active_tree());

  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get());
      mask_layer1->PushPropertiesTo(mask_layer1_impl.get()););

  // Once there is a mask layer, resizes require subtree properties to update.
  arbitrary_size = gfx::Size(11, 22);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(mask_layer1->SetBounds(arbitrary_size));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMasksToBounds(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetContentsOpaque(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetShouldFlattenTransform(false));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->Set3dSortingContextId(1));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetTrilinearFiltering(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetTrilinearFiltering(false));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetDoubleSided(false));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetHideLayerAndSubtree(true));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBlendMode(arbitrary_blend_mode));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  // Should be a different size than previous call, to ensure it marks tree
  // changed.
  arbitrary_size = gfx::Size(111, 222);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(mask_layer1->SetBounds(arbitrary_size));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  FilterOperations arbitrary_filters;
  arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(arbitrary_filters));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
      root->SetBackdropFilters(arbitrary_filters));
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get()));

  gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  root->SetPosition(arbitrary_point_f);
  TransformNode* node = layer_tree_host_->property_trees()->transform_tree.Node(
      root->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get());
      layer_tree_host_->property_trees()->ResetAllChangeTracking());
  EXPECT_FALSE(node->transform_changed);

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  child->SetPosition(arbitrary_point_f);
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      child->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
  // child2 is not in the subtree of child, but its scroll parent is. So, its
  // to_screen will be effected by change in position of child2.
  layer_tree_host_->property_trees()->transform_tree.UpdateTransforms(
      child2->transform_tree_index());
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      child2->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      child->PushPropertiesTo(child_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get());
      layer_tree_host_->property_trees()->ResetAllChangeTracking());
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      child->transform_tree_index());
  EXPECT_FALSE(node->transform_changed);

  gfx::Point3F arbitrary_point_3f = gfx::Point3F(0.125f, 0.25f, 0.f);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  root->SetTransformOrigin(arbitrary_point_3f);
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      root->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
  EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET(
      root->PushPropertiesTo(root_impl.get());
      child->PushPropertiesTo(child_impl.get());
      child2->PushPropertiesTo(child2_impl.get());
      grand_child->PushPropertiesTo(grand_child_impl.get());
      layer_tree_host_->property_trees()->ResetAllChangeTracking());

  gfx::Transform arbitrary_transform;
  arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  root->SetTransform(arbitrary_transform);
  node = layer_tree_host_->property_trees()->transform_tree.Node(
      root->transform_tree_index());
  EXPECT_TRUE(node->transform_changed);
}

TEST_F(LayerTest, AddAndRemoveChild) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();

  // Upon creation, layers should not have children or parent.
  ASSERT_EQ(0U, parent->children().size());
  EXPECT_FALSE(child->parent());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->AddChild(child));

  ASSERT_EQ(1U, parent->children().size());
  EXPECT_EQ(child.get(), parent->children()[0]);
  EXPECT_EQ(parent.get(), child->parent());
  EXPECT_EQ(parent.get(), child->RootLayer());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1), child->RemoveFromParent());
}

TEST_F(LayerTest, AddSameChildTwice) {
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1));

  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();

  layer_tree_host_->SetRootLayer(parent);

  ASSERT_EQ(0u, parent->children().size());

  parent->AddChild(child);
  ASSERT_EQ(1u, parent->children().size());
  EXPECT_EQ(parent.get(), child->parent());

  parent->AddChild(child);
  ASSERT_EQ(1u, parent->children().size());
  EXPECT_EQ(parent.get(), child->parent());
}

TEST_F(LayerTest, InsertChild) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();
  scoped_refptr<Layer> child3 = Layer::Create();
  scoped_refptr<Layer> child4 = Layer::Create();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));

  ASSERT_EQ(0U, parent->children().size());

  // Case 1: inserting to empty list.
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child3, 0));
  ASSERT_EQ(1U, parent->children().size());
  EXPECT_EQ(child3, parent->children()[0]);
  EXPECT_EQ(parent.get(), child3->parent());

  // Case 2: inserting to beginning of list
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child1, 0));
  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child3, parent->children()[1]);
  EXPECT_EQ(parent.get(), child1->parent());

  // Case 3: inserting to middle of list
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child2, 1));
  ASSERT_EQ(3U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);
  EXPECT_EQ(child3, parent->children()[2]);
  EXPECT_EQ(parent.get(), child2->parent());

  // Case 4: inserting to end of list
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child4, 3));

  ASSERT_EQ(4U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);
  EXPECT_EQ(child3, parent->children()[2]);
  EXPECT_EQ(child4, parent->children()[3]);
  EXPECT_EQ(parent.get(), child4->parent());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
}

TEST_F(LayerTest, InsertChildPastEndOfList) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();

  ASSERT_EQ(0U, parent->children().size());

  // insert to an out-of-bounds index
  parent->InsertChild(child1, 53);

  ASSERT_EQ(1U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);

  // insert another child to out-of-bounds, when list is not already empty.
  parent->InsertChild(child2, 2459);

  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);
}

TEST_F(LayerTest, InsertSameChildTwice) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));

  ASSERT_EQ(0U, parent->children().size());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child1, 0));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child2, 1));

  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);

  // Inserting the same child again should cause the child to be removed and
  // re-inserted at the new location.
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1), parent->InsertChild(child1, 1));

  // child1 should now be at the end of the list.
  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child2, parent->children()[0]);
  EXPECT_EQ(child1, parent->children()[1]);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
}

TEST_F(LayerTest, ReplaceChildWithNewChild) {
  CreateSimpleTestTree();
  scoped_refptr<Layer> child4 = Layer::Create();

  EXPECT_FALSE(child4->parent());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(
      AtLeast(1), parent_->ReplaceChild(child2_.get(), child4));
  EXPECT_FALSE(LayerNeedsDisplay(parent_.get()));
  EXPECT_FALSE(LayerNeedsDisplay(child1_.get()));
  EXPECT_FALSE(LayerNeedsDisplay(child2_.get()));
  EXPECT_FALSE(LayerNeedsDisplay(child3_.get()));
  EXPECT_FALSE(LayerNeedsDisplay(child4.get()));

  ASSERT_EQ(static_cast<size_t>(3), parent_->children().size());
  EXPECT_EQ(child1_, parent_->children()[0]);
  EXPECT_EQ(child4, parent_->children()[1]);
  EXPECT_EQ(child3_, parent_->children()[2]);
  EXPECT_EQ(parent_.get(), child4->parent());

  EXPECT_FALSE(child2_->parent());
}

TEST_F(LayerTest, ReplaceChildWithNewChildThatHasOtherParent) {
  CreateSimpleTestTree();

  // create another simple tree with test_layer and child4.
  scoped_refptr<Layer> test_layer = Layer::Create();
  scoped_refptr<Layer> child4 = Layer::Create();
  test_layer->AddChild(child4);
  ASSERT_EQ(1U, test_layer->children().size());
  EXPECT_EQ(child4, test_layer->children()[0]);
  EXPECT_EQ(test_layer.get(), child4->parent());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(
      AtLeast(1), parent_->ReplaceChild(child2_.get(), child4));

  ASSERT_EQ(3U, parent_->children().size());
  EXPECT_EQ(child1_, parent_->children()[0]);
  EXPECT_EQ(child4, parent_->children()[1]);
  EXPECT_EQ(child3_, parent_->children()[2]);
  EXPECT_EQ(parent_.get(), child4->parent());

  // test_layer should no longer have child4,
  // and child2 should no longer have a parent.
  ASSERT_EQ(0U, test_layer->children().size());
  EXPECT_FALSE(child2_->parent());
}

TEST_F(LayerTest, DeleteRemovedScrollParent) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));

  ASSERT_EQ(0U, parent->children().size());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child1, 0));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child2, 1));

  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);

  EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(child2.get()));

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, child2->RemoveFromParent());

  SimulateCommitForLayer(child1.get());

  EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(nullptr));
  EXPECT_TRUE(base::ContainsKey(
      layer_tree_host_->LayersThatShouldPushProperties(), child1.get()));

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
}

TEST_F(LayerTest, DeleteRemovedScrollChild) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child1 = Layer::Create();
  scoped_refptr<Layer> child2 = Layer::Create();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(parent));

  ASSERT_EQ(0U, parent->children().size());

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child1, 0));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, parent->InsertChild(child2, 1));

  ASSERT_EQ(2U, parent->children().size());
  EXPECT_EQ(child1, parent->children()[0]);
  EXPECT_EQ(child2, parent->children()[1]);

  EXPECT_SET_NEEDS_COMMIT(1, child1->SetScrollParent(child2.get()));

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, child1->RemoveFromParent());
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(nullptr));
}

TEST_F(LayerTest, ReplaceChildWithSameChild) {
  CreateSimpleTestTree();

  // SetNeedsFullTreeSync / SetNeedsCommit should not be called because its the
  // same child.
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(0);
  parent_->ReplaceChild(child2_.get(), child2_);

  VerifyTestTreeInitialState();
}

TEST_F(LayerTest, RemoveAllChildren) {
  CreateSimpleTestTree();

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(3), parent_->RemoveAllChildren());

  ASSERT_EQ(0U, parent_->children().size());
  EXPECT_FALSE(child1_->parent());
  EXPECT_FALSE(child2_->parent());
  EXPECT_FALSE(child3_->parent());
}

TEST_F(LayerTest, HasAncestor) {
  scoped_refptr<Layer> parent = Layer::Create();
  EXPECT_FALSE(parent->HasAncestor(parent.get()));

  scoped_refptr<Layer> child = Layer::Create();
  parent->AddChild(child);

  EXPECT_FALSE(child->HasAncestor(child.get()));
  EXPECT_TRUE(child->HasAncestor(parent.get()));
  EXPECT_FALSE(parent->HasAncestor(child.get()));

  scoped_refptr<Layer> child_child = Layer::Create();
  child->AddChild(child_child);

  EXPECT_FALSE(child_child->HasAncestor(child_child.get()));
  EXPECT_TRUE(child_child->HasAncestor(parent.get()));
  EXPECT_TRUE(child_child->HasAncestor(child.get()));
  EXPECT_FALSE(parent->HasAncestor(child.get()));
  EXPECT_FALSE(parent->HasAncestor(child_child.get()));
}

TEST_F(LayerTest, GetRootLayerAfterTreeManipulations) {
  CreateSimpleTestTree();

  // For this test we don't care about SetNeedsFullTreeSync calls.
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AnyNumber());

  scoped_refptr<Layer> child4 = Layer::Create();

  EXPECT_EQ(parent_.get(), parent_->RootLayer());
  EXPECT_EQ(parent_.get(), child1_->RootLayer());
  EXPECT_EQ(parent_.get(), child2_->RootLayer());
  EXPECT_EQ(parent_.get(), child3_->RootLayer());
  EXPECT_EQ(child4.get(),   child4->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child1_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child2_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child3_->RootLayer());

  child1_->RemoveFromParent();

  // |child1| and its children, grand_child1 and grand_child2 are now on a
  // separate subtree.
  EXPECT_EQ(parent_.get(), parent_->RootLayer());
  EXPECT_EQ(child1_.get(), child1_->RootLayer());
  EXPECT_EQ(parent_.get(), child2_->RootLayer());
  EXPECT_EQ(parent_.get(), child3_->RootLayer());
  EXPECT_EQ(child4.get(), child4->RootLayer());
  EXPECT_EQ(child1_.get(), grand_child1_->RootLayer());
  EXPECT_EQ(child1_.get(), grand_child2_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child3_->RootLayer());

  grand_child3_->AddChild(child4);

  EXPECT_EQ(parent_.get(), parent_->RootLayer());
  EXPECT_EQ(child1_.get(), child1_->RootLayer());
  EXPECT_EQ(parent_.get(), child2_->RootLayer());
  EXPECT_EQ(parent_.get(), child3_->RootLayer());
  EXPECT_EQ(parent_.get(), child4->RootLayer());
  EXPECT_EQ(child1_.get(), grand_child1_->RootLayer());
  EXPECT_EQ(child1_.get(), grand_child2_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child3_->RootLayer());

  child2_->ReplaceChild(grand_child3_.get(), child1_);

  // |grand_child3| gets orphaned and the child1 subtree gets planted back into
  // the tree under child2.
  EXPECT_EQ(parent_.get(), parent_->RootLayer());
  EXPECT_EQ(parent_.get(), child1_->RootLayer());
  EXPECT_EQ(parent_.get(), child2_->RootLayer());
  EXPECT_EQ(parent_.get(), child3_->RootLayer());
  EXPECT_EQ(grand_child3_.get(), child4->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child1_->RootLayer());
  EXPECT_EQ(parent_.get(), grand_child2_->RootLayer());
  EXPECT_EQ(grand_child3_.get(), grand_child3_->RootLayer());
}

TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) {
  // The semantics for SetNeedsDisplay which are tested here:
  //   1. sets NeedsDisplay flag appropriately.
  //   2. indirectly calls SetNeedsUpdate, exactly once for each call to
  //      SetNeedsDisplay.

  scoped_refptr<Layer> test_layer = Layer::Create();
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));

  gfx::Size test_bounds = gfx::Size(501, 508);

  gfx::Rect dirty_rect = gfx::Rect(10, 15, 1, 2);
  gfx::Rect out_of_bounds_dirty_rect = gfx::Rect(400, 405, 500, 502);

  // Before anything, test_layer should not be dirty.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // This is just initialization, but SetNeedsCommit behavior is verified anyway
  // to avoid warnings.
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBounds(test_bounds));
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // The real test begins here.
  SimulateCommitForLayer(test_layer.get());
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // Case 1: Layer should accept dirty rects that go beyond its bounds.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  EXPECT_SET_NEEDS_UPDATE(
      1, test_layer->SetNeedsDisplayRect(out_of_bounds_dirty_rect));
  EXPECT_TRUE(LayerNeedsDisplay(test_layer.get()));
  SimulateCommitForLayer(test_layer.get());

  // Case 2: SetNeedsDisplay() without the dirty rect arg.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  EXPECT_SET_NEEDS_UPDATE(1, test_layer->SetNeedsDisplay());
  EXPECT_TRUE(LayerNeedsDisplay(test_layer.get()));
  SimulateCommitForLayer(test_layer.get());

  // Case 3: SetNeedsDisplay() with an empty rect.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  EXPECT_SET_NEEDS_COMMIT(0, test_layer->SetNeedsDisplayRect(gfx::Rect()));
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  SimulateCommitForLayer(test_layer.get());

  // Case 4: SetNeedsDisplay() with a non-drawable layer
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(false));
  SimulateCommitForLayer(test_layer.get());
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));
  EXPECT_SET_NEEDS_UPDATE(0, test_layer->SetNeedsDisplayRect(dirty_rect));
  EXPECT_TRUE(LayerNeedsDisplay(test_layer.get()));
}

TEST_F(LayerTest, TestSettingMainThreadScrollingReason) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));

  // sanity check of initial test condition
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  uint32_t reasons = 0, reasons_to_clear = 0, reasons_after_clearing = 0;
  reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
  reasons |= MainThreadScrollingReason::kHandlingScrollFromMainThread;
  reasons |= MainThreadScrollingReason::kScrollbarScrolling;

  reasons_to_clear |= MainThreadScrollingReason::kHandlingScrollFromMainThread;
  reasons_to_clear |= MainThreadScrollingReason::kCustomScrollbarScrolling;

  reasons_after_clearing |=
      MainThreadScrollingReason::kThreadedScrollingDisabled;
  reasons_after_clearing |= MainThreadScrollingReason::kScrollbarScrolling;

  // Check that the reasons are added correctly.
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->AddMainThreadScrollingReasons(
             MainThreadScrollingReason::kThreadedScrollingDisabled));
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->AddMainThreadScrollingReasons(
             MainThreadScrollingReason::kHandlingScrollFromMainThread));
  EXPECT_SET_NEEDS_COMMIT(1,
                          test_layer->AddMainThreadScrollingReasons(
                              MainThreadScrollingReason::kScrollbarScrolling));
  EXPECT_EQ(reasons, test_layer->GetMainThreadScrollingReasons());

  // Check that the reasons can be selectively cleared.
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear));
  EXPECT_EQ(reasons_after_clearing,
            test_layer->GetMainThreadScrollingReasons());

  // Check that clearing non-set reasons doesn't set needs commit.
  reasons_to_clear = 0;
  reasons_to_clear |= MainThreadScrollingReason::kCustomScrollbarScrolling;
  reasons_to_clear |= MainThreadScrollingReason::kFrameOverlay;
  EXPECT_SET_NEEDS_COMMIT(
      0, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear));
  EXPECT_EQ(reasons_after_clearing,
            test_layer->GetMainThreadScrollingReasons());

  // Check that adding an existing condition doesn't set needs commit.
  EXPECT_SET_NEEDS_COMMIT(
      0, test_layer->AddMainThreadScrollingReasons(
             MainThreadScrollingReason::kThreadedScrollingDisabled));
}

TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true));

  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask_layer1 = PictureLayer::Create(&client);

  // sanity check of initial test condition
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // Next, test properties that should call SetNeedsCommit (but not
  // SetNeedsDisplay). All properties need to be set to new values in order for
  // SetNeedsCommit to be called.
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->SetTransformOrigin(gfx::Point3F(1.23f, 4.56f, 0.f)));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBackgroundColor(SK_ColorLTGRAY));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetMasksToBounds(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendMode(SkBlendMode::kHue));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsRootForIsolatedGroup(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetContentsOpaque(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPosition(gfx::PointF(4.f, 9.f)));
  // We can use any layer pointer here since we aren't syncing for real.
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollable(gfx::Size(1, 1)));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset(
      gfx::ScrollOffset(10, 10)));
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->AddMainThreadScrollingReasons(
             MainThreadScrollingReason::kThreadedScrollingDisabled));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNonFastScrollableRegion(
      Region(gfx::Rect(1, 1, 2, 2))));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(
      gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetDoubleSided(false));
  TouchActionRegion touch_action_region;
  touch_action_region.Union(kTouchActionNone, gfx::Rect(10, 10));
  EXPECT_SET_NEEDS_COMMIT(
      1, test_layer->SetTouchActionRegion(std::move(touch_action_region)));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetForceRenderSurfaceForTesting(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHideLayerAndSubtree(true));
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(ElementId(2)));

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  test_layer->SetMaskLayer(mask_layer1.get()));

  // The above tests should not have caused a change to the needs_display flag.
  EXPECT_FALSE(LayerNeedsDisplay(test_layer.get()));

  // As layers are removed from the tree, they will cause a tree sync.
  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times((AnyNumber()));
}

TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  host_impl_.active_tree()->SetRootLayerForTesting(std::move(impl_layer));
  host_impl_.active_tree()->BuildLayerListForTesting();
  LayerImpl* impl_layer_ptr = host_impl_.active_tree()->LayerById(1);
  test_layer->SetNeedsDisplayRect(gfx::Rect(5, 5));
  test_layer->PushPropertiesTo(impl_layer_ptr);
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 5.f, 5.f),
                       impl_layer_ptr->update_rect());

  // The LayerImpl's update_rect() should be accumulated here, since we did not
  // do anything to clear it.
  test_layer->SetNeedsDisplayRect(gfx::Rect(10, 10, 5, 5));
  test_layer->PushPropertiesTo(impl_layer_ptr);
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 15.f, 15.f),
                       impl_layer_ptr->update_rect());

  // If we do clear the LayerImpl side, then the next update_rect() should be
  // fresh without accumulation.
  host_impl_.active_tree()->ResetAllChangeTracking();
  test_layer->SetNeedsDisplayRect(gfx::Rect(10, 10, 5, 5));
  test_layer->PushPropertiesTo(impl_layer_ptr);
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(10.f, 10.f, 5.f, 5.f),
                       impl_layer_ptr->update_rect());
}

TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForTransform) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  gfx::Transform transform;
  transform.Rotate(45.0);
  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(transform));

  EXPECT_FALSE(impl_layer->LayerPropertyChanged());

  test_layer->PushPropertiesTo(impl_layer.get());

  EXPECT_TRUE(impl_layer->LayerPropertyChanged());
  EXPECT_FALSE(impl_layer->LayerPropertyChangedFromPropertyTrees());
  EXPECT_TRUE(impl_layer->LayerPropertyChangedNotFromPropertyTrees());
}

TEST_F(LayerTest, PushPropertiesCausesLayerPropertyChangedForOpacity) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f));

  EXPECT_FALSE(impl_layer->LayerPropertyChanged());

  test_layer->PushPropertiesTo(impl_layer.get());

  EXPECT_TRUE(impl_layer->LayerPropertyChanged());
  EXPECT_FALSE(impl_layer->LayerPropertyChangedFromPropertyTrees());
  EXPECT_TRUE(impl_layer->LayerPropertyChangedNotFromPropertyTrees());
}

TEST_F(LayerTest, MaskHasParent) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
  scoped_refptr<PictureLayer> mask_replacement = PictureLayer::Create(&client);

  parent->AddChild(child);
  child->SetMaskLayer(mask.get());

  EXPECT_EQ(parent.get(), child->parent());
  EXPECT_EQ(child.get(), mask->parent());

  child->SetMaskLayer(mask_replacement.get());
  EXPECT_EQ(nullptr, mask->parent());
  EXPECT_EQ(child.get(), mask_replacement->parent());
}

class LayerTreeHostFactory {
 public:
  std::unique_ptr<LayerTreeHost> Create(MutatorHost* mutator_host) {
    return Create(LayerTreeSettings(), mutator_host);
  }

  std::unique_ptr<LayerTreeHost> Create(LayerTreeSettings settings,
                                        MutatorHost* mutator_host) {
    LayerTreeHost::InitParams params;
    params.client = &client_;
    params.task_graph_runner = &task_graph_runner_;
    params.settings = &settings;
    params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
    params.mutator_host = mutator_host;

    return LayerTreeHost::CreateSingleThreaded(&single_thread_client_,
                                               std::move(params));
  }

 private:
  FakeLayerTreeHostClient client_;
  StubLayerTreeHostSingleThreadClient single_thread_client_;
  TestTaskGraphRunner task_graph_runner_;
};

void AssertLayerTreeHostMatchesForSubtree(Layer* layer, LayerTreeHost* host) {
  EXPECT_EQ(host, layer->layer_tree_host());

  for (size_t i = 0; i < layer->children().size(); ++i)
    AssertLayerTreeHostMatchesForSubtree(layer->children()[i].get(), host);

  if (layer->mask_layer())
    AssertLayerTreeHostMatchesForSubtree(layer->mask_layer(), host);
}

class LayerLayerTreeHostTest : public testing::Test {};

TEST_F(LayerLayerTreeHostTest, EnteringTree) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);

  // Set up a detached tree of layers. The host pointer should be nil for these
  // layers.
  parent->AddChild(child);
  child->SetMaskLayer(mask.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(), nullptr);

  LayerTreeHostFactory factory;

  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());
  // Setting the root layer should set the host pointer for all layers in the
  // tree.
  layer_tree_host->SetRootLayer(parent.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());

  // Clearing the root layer should also clear out the host pointers for all
  // layers in the tree.
  layer_tree_host->SetRootLayer(nullptr);

  AssertLayerTreeHostMatchesForSubtree(parent.get(), nullptr);
}

TEST_F(LayerLayerTreeHostTest, AddingLayerSubtree) {
  scoped_refptr<Layer> parent = Layer::Create();
  LayerTreeHostFactory factory;

  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());

  layer_tree_host->SetRootLayer(parent.get());

  EXPECT_EQ(parent->layer_tree_host(), layer_tree_host.get());

  // Adding a subtree to a layer already associated with a host should set the
  // host pointer on all layers in that subtree.
  scoped_refptr<Layer> child = Layer::Create();
  scoped_refptr<Layer> grand_child = Layer::Create();
  child->AddChild(grand_child);

  // Masks should pick up the new host too.
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> child_mask = PictureLayer::Create(&client);
  child->SetMaskLayer(child_mask.get());

  parent->AddChild(child);
  AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());

  layer_tree_host->SetRootLayer(nullptr);
}

TEST_F(LayerLayerTreeHostTest, ChangeHost) {
  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  FakeContentLayerClient client;
  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);

  // Same setup as the previous test.
  parent->AddChild(child);
  child->SetMaskLayer(mask.get());

  LayerTreeHostFactory factory;
  auto animation_host1 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> first_layer_tree_host =
      factory.Create(animation_host1.get());
  first_layer_tree_host->SetRootLayer(parent.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(),
                                       first_layer_tree_host.get());

  // Now re-root the tree to a new host (simulating what we do on a context lost
  // event). This should update the host pointers for all layers in the tree.
  auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> second_layer_tree_host =
      factory.Create(animation_host2.get());
  second_layer_tree_host->SetRootLayer(parent.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(),
                                       second_layer_tree_host.get());

  second_layer_tree_host->SetRootLayer(nullptr);
}

TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) {
  scoped_refptr<Layer> first_parent = Layer::Create();
  scoped_refptr<Layer> first_child = Layer::Create();
  scoped_refptr<Layer> second_parent = Layer::Create();
  scoped_refptr<Layer> second_child = Layer::Create();
  scoped_refptr<Layer> second_grand_child = Layer::Create();

  // First put all children under the first parent and set the first host.
  first_parent->AddChild(first_child);
  second_child->AddChild(second_grand_child);
  first_parent->AddChild(second_child);

  LayerTreeHostFactory factory;
  auto animation_host1 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> first_layer_tree_host =
      factory.Create(animation_host1.get());
  first_layer_tree_host->SetRootLayer(first_parent.get());

  AssertLayerTreeHostMatchesForSubtree(first_parent.get(),
                                       first_layer_tree_host.get());

  // Now reparent the subtree starting at second_child to a layer in a different
  // tree.
  auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> second_layer_tree_host =
      factory.Create(animation_host2.get());
  second_layer_tree_host->SetRootLayer(second_parent.get());

  second_parent->AddChild(second_child);

  // The moved layer and its children should point to the new host.
  EXPECT_EQ(second_layer_tree_host.get(), second_child->layer_tree_host());
  EXPECT_EQ(second_layer_tree_host.get(),
            second_grand_child->layer_tree_host());

  // Test over, cleanup time.
  first_layer_tree_host->SetRootLayer(nullptr);
  second_layer_tree_host->SetRootLayer(nullptr);
}

TEST_F(LayerLayerTreeHostTest, ReplaceMaskLayer) {
  FakeContentLayerClient client;

  scoped_refptr<Layer> parent = Layer::Create();
  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
  scoped_refptr<Layer> mask_child = Layer::Create();
  scoped_refptr<PictureLayer> mask_replacement = PictureLayer::Create(&client);

  parent->SetMaskLayer(mask.get());
  mask->AddChild(mask_child);

  LayerTreeHostFactory factory;
  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());
  layer_tree_host->SetRootLayer(parent.get());

  AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get());

  // Replacing the mask should clear out the old mask's subtree's host pointers.
  parent->SetMaskLayer(mask_replacement.get());
  EXPECT_EQ(nullptr, mask->layer_tree_host());
  EXPECT_EQ(nullptr, mask_child->layer_tree_host());

  // Test over, cleanup time.
  layer_tree_host->SetRootLayer(nullptr);
}

TEST_F(LayerLayerTreeHostTest, DestroyHostWithNonNullRootLayer) {
  scoped_refptr<Layer> root = Layer::Create();
  scoped_refptr<Layer> child = Layer::Create();
  root->AddChild(child);
  LayerTreeHostFactory factory;
  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());
  layer_tree_host->SetRootLayer(root);
}

TEST_F(LayerTest, SafeOpaqueBackgroundColor) {
  LayerTreeHostFactory factory;
  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<LayerTreeHost> layer_tree_host =
      factory.Create(animation_host.get());

  scoped_refptr<Layer> layer = Layer::Create();
  layer_tree_host->SetRootLayer(layer);

  for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) {
    for (int layer_opaque = 0; layer_opaque < 2; ++layer_opaque) {
      for (int host_opaque = 0; host_opaque < 2; ++host_opaque) {
        layer->SetContentsOpaque(!!contents_opaque);
        layer->SetBackgroundColor(layer_opaque ? SK_ColorRED
                                               : SK_ColorTRANSPARENT);
        layer_tree_host->set_background_color(
            host_opaque ? SK_ColorRED : SK_ColorTRANSPARENT);

        layer_tree_host->property_trees()->needs_rebuild = true;
        layer_tree_host->BuildPropertyTreesForTesting();
        SkColor safe_color = layer->SafeOpaqueBackgroundColor();
        if (contents_opaque) {
          EXPECT_EQ(SkColorGetA(safe_color), 255u)
              << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
              << host_opaque << "\n";
        } else {
          EXPECT_NE(SkColorGetA(safe_color), 255u)
              << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
              << host_opaque << "\n";
        }
      }
    }
  }
}

class DrawsContentChangeLayer : public Layer {
 public:
  static scoped_refptr<DrawsContentChangeLayer> Create() {
    return base::WrapRefCounted(new DrawsContentChangeLayer());
  }

  void SetLayerTreeHost(LayerTreeHost* host) override {
    Layer::SetLayerTreeHost(host);
    SetFakeDrawsContent(!fake_draws_content_);
  }

  bool HasDrawableContent() const override {
    return fake_draws_content_ && Layer::HasDrawableContent();
  }

  void SetFakeDrawsContent(bool fake_draws_content) {
    fake_draws_content_ = fake_draws_content;
    UpdateDrawsContent(HasDrawableContent());
  }

 private:
  DrawsContentChangeLayer() : fake_draws_content_(false) {}
  ~DrawsContentChangeLayer() override = default;

  bool fake_draws_content_;
};

TEST_F(LayerTest, DrawsContentChangedInSetLayerTreeHost) {
  scoped_refptr<Layer> root_layer = Layer::Create();
  scoped_refptr<DrawsContentChangeLayer> becomes_not_draws_content =
      DrawsContentChangeLayer::Create();
  scoped_refptr<DrawsContentChangeLayer> becomes_draws_content =
      DrawsContentChangeLayer::Create();
  root_layer->SetIsDrawable(true);
  becomes_not_draws_content->SetIsDrawable(true);
  becomes_not_draws_content->SetFakeDrawsContent(true);
  EXPECT_EQ(0, root_layer->NumDescendantsThatDrawContent());
  root_layer->AddChild(becomes_not_draws_content);
  EXPECT_EQ(0, root_layer->NumDescendantsThatDrawContent());

  becomes_draws_content->SetIsDrawable(true);
  root_layer->AddChild(becomes_draws_content);
  EXPECT_EQ(1, root_layer->NumDescendantsThatDrawContent());
}

TEST_F(LayerTest, PushUpdatesShouldHitTest) {
  scoped_refptr<Layer> root_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(root_layer));
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(3);

  // A layer that draws content should be hit testable.
  root_layer->SetIsDrawable(true);
  root_layer->PushPropertiesTo(impl_layer.get());
  EXPECT_TRUE(impl_layer->DrawsContent());
  EXPECT_FALSE(impl_layer->hit_testable_without_draws_content());
  EXPECT_TRUE(impl_layer->ShouldHitTest());

  // A layer that does not draw content and does not hit test without drawing
  // content should not be hit testable.
  root_layer->SetIsDrawable(false);
  root_layer->PushPropertiesTo(impl_layer.get());
  EXPECT_FALSE(impl_layer->DrawsContent());
  EXPECT_FALSE(impl_layer->hit_testable_without_draws_content());
  EXPECT_FALSE(impl_layer->ShouldHitTest());

  // |SetHitTestableWithoutDrawsContent| should cause a layer to become hit
  // testable even though it does not draw content.
  root_layer->SetHitTestableWithoutDrawsContent(true);
  root_layer->PushPropertiesTo(impl_layer.get());
  EXPECT_FALSE(impl_layer->DrawsContent());
  EXPECT_TRUE(impl_layer->hit_testable_without_draws_content());
  EXPECT_TRUE(impl_layer->ShouldHitTest());
}

void ReceiveCopyOutputResult(int* result_count,
                             std::unique_ptr<viz::CopyOutputResult> result) {
  ++(*result_count);
}

TEST_F(LayerTest, DedupesCopyOutputRequestsBySource) {
  scoped_refptr<Layer> layer = Layer::Create();
  int result_count = 0;

  // Create identical requests without the source being set, and expect the
  // layer does not abort either one.
  std::unique_ptr<viz::CopyOutputRequest> request =
      std::make_unique<viz::CopyOutputRequest>(
          viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
          base::BindOnce(&ReceiveCopyOutputResult, &result_count));
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, result_count);
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult, &result_count));
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, result_count);

  // When the layer is destroyed, expect both requests to be aborted.
  layer = nullptr;
  EXPECT_EQ(2, result_count);

  layer = Layer::Create();
  result_count = 0;

  // Create identical requests, but this time the source is being set.  Expect
  // the first request using |kArbitrarySourceId1| aborts immediately when
  // the second request using |kArbitrarySourceId1| is made.
  int did_receive_first_result_from_this_source = 0;
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult,
                     &did_receive_first_result_from_this_source));
  request->set_source(kArbitrarySourceId1);
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, did_receive_first_result_from_this_source);
  // Make a request from a different source.
  int did_receive_result_from_different_source = 0;
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult,
                     &did_receive_result_from_different_source));
  request->set_source(kArbitrarySourceId2);
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, did_receive_result_from_different_source);
  // Make a request without specifying the source.
  int did_receive_result_from_anonymous_source = 0;
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult,
                     &did_receive_result_from_anonymous_source));
  layer->RequestCopyOfOutput(std::move(request));
  EXPECT_EQ(0, did_receive_result_from_anonymous_source);
  // Make the second request from |kArbitrarySourceId1|.
  int did_receive_second_result_from_this_source = 0;
  request = std::make_unique<viz::CopyOutputRequest>(
      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
      base::BindOnce(&ReceiveCopyOutputResult,
                     &did_receive_second_result_from_this_source));
  request->set_source(kArbitrarySourceId1);
  layer->RequestCopyOfOutput(
      std::move(request));  // First request to be aborted.
  EXPECT_EQ(1, did_receive_first_result_from_this_source);
  EXPECT_EQ(0, did_receive_result_from_different_source);
  EXPECT_EQ(0, did_receive_result_from_anonymous_source);
  EXPECT_EQ(0, did_receive_second_result_from_this_source);

  // When the layer is destroyed, the other three requests should be aborted.
  layer = nullptr;
  EXPECT_EQ(1, did_receive_first_result_from_this_source);
  EXPECT_EQ(1, did_receive_result_from_different_source);
  EXPECT_EQ(1, did_receive_result_from_anonymous_source);
  EXPECT_EQ(1, did_receive_second_result_from_this_source);
}

TEST_F(LayerTest, AnimationSchedulesLayerUpdate) {
  // TODO(weiliangc): This is really a LayerTreeHost unittest by this point,
  // though currently there is no good place for this unittest to go. Move to
  // LayerTreeHost unittest when there is a good setup.
  scoped_refptr<Layer> layer = Layer::Create();
  layer->SetElementId(ElementId(2));
  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(layer));
  auto element_id = layer->element_id();

  EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
  layer_tree_host_->SetElementOpacityMutated(element_id,
                                             ElementListType::ACTIVE, 0.5f);
  Mock::VerifyAndClearExpectations(layer_tree_host_.get());

  EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
  gfx::Transform transform;
  transform.Rotate(45.0);
  layer_tree_host_->SetElementTransformMutated(
      element_id, ElementListType::ACTIVE, transform);
  Mock::VerifyAndClearExpectations(layer_tree_host_.get());

  // Scroll offset animation should not schedule a layer update since it is
  // handled similarly to normal compositor scroll updates.
  EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(0);
  layer_tree_host_->SetElementScrollOffsetMutated(
      element_id, ElementListType::ACTIVE, gfx::ScrollOffset(10, 10));
  Mock::VerifyAndClearExpectations(layer_tree_host_.get());
}

TEST_F(LayerTest, ElementIdIsPushed) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  std::unique_ptr<LayerImpl> impl_layer =
      LayerImpl::Create(host_impl_.active_tree(), 1);

  EXPECT_SET_NEEDS_FULL_TREE_SYNC(1,
                                  layer_tree_host_->SetRootLayer(test_layer));

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);

  test_layer->SetElementId(ElementId(2));

  EXPECT_FALSE(impl_layer->element_id());

  test_layer->PushPropertiesTo(impl_layer.get());

  EXPECT_EQ(ElementId(2), impl_layer->element_id());
}

TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  ElementId element_id = ElementId(2);
  test_layer->SetElementId(element_id);

  // Expect additional call due to has-animation check.
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
  scoped_refptr<AnimationTimeline> timeline =
      AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
  animation_host_->AddAnimationTimeline(timeline);

  AddOpacityTransitionToElementWithAnimation(element_id, timeline, 10.0, 1.f,
                                             0.f, false);
  EXPECT_TRUE(animation_host_->IsElementAnimating(element_id));

  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
  test_layer->SetLayerTreeHost(layer_tree_host_.get());
  // Layer should now be registered by element id.
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));

  test_layer->SetLayerTreeHost(nullptr);
  // Layer should have been un-registered.
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}

TEST_F(LayerTest, SetElementIdNotUsingLayerLists) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  test_layer->SetLayerTreeHost(layer_tree_host_.get());

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2);
  ElementId element_id = ElementId(2);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  test_layer->SetElementId(element_id);
  // Layer should now be registered by element id.
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));

  ElementId other_element_id = ElementId(3);
  test_layer->SetElementId(other_element_id);
  // The layer should have been unregistered from the original element
  // id and registered with the new one.
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(other_element_id));

  test_layer->SetLayerTreeHost(nullptr);
}

class LayerTestWithLayerLists : public LayerTest {
 protected:
  void SetUp() override {
    settings_.use_layer_lists = true;
    LayerTest::SetUp();
  }
};

TEST_F(LayerTestWithLayerLists, LayerTreeHostRegistersScrollingElementId) {
  scoped_refptr<Layer> normal_layer = Layer::Create();
  scoped_refptr<Layer> scrolling_layer = Layer::Create();
  scrolling_layer->SetScrollable(gfx::Size(1000, 1000));
  ElementId normal_element_id = ElementId(2);
  ElementId scrolling_element_id = ElementId(3);
  normal_layer->SetElementId(normal_element_id);
  scrolling_layer->SetElementId(scrolling_element_id);

  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(normal_element_id));
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(scrolling_element_id));
  normal_layer->SetLayerTreeHost(layer_tree_host_.get());
  scrolling_layer->SetLayerTreeHost(layer_tree_host_.get());
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(normal_element_id));
  EXPECT_EQ(scrolling_layer,
            layer_tree_host_->LayerByElementId(scrolling_element_id));

  normal_layer->SetLayerTreeHost(nullptr);
  scrolling_layer->SetLayerTreeHost(nullptr);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(scrolling_element_id));
}

TEST_F(LayerTestWithLayerLists, ChangingScrollableElementIdRegistersElement) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  test_layer->SetScrollable(gfx::Size(1000, 1000));
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  test_layer->SetLayerTreeHost(layer_tree_host_.get());

  ElementId element_id = ElementId(2);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  // Setting the element id should register the layer.
  test_layer->SetElementId(element_id);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));

  // Unsetting the element id should unregister the layer.
  test_layer->SetElementId(ElementId());
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  test_layer->SetLayerTreeHost(nullptr);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}

TEST_F(LayerTestWithLayerLists, ChangingScrollableRegistersElement) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  test_layer->SetLayerTreeHost(layer_tree_host_.get());

  ElementId element_id = ElementId(2);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  // Setting the element id commits the element id but should not register
  // the layer.
  test_layer->SetElementId(element_id);
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  // Making the layer scrollable should register it.
  test_layer->SetScrollable(gfx::Size(1000, 1000));
  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
  EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id));

  // Unsetting the element id should unregister the layer.
  test_layer->SetElementId(ElementId());
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));

  test_layer->SetLayerTreeHost(nullptr);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}

TEST_F(LayerTestWithLayerLists, SetElementIdUsingLayerLists) {
  scoped_refptr<Layer> test_layer = Layer::Create();
  ElementId element_id = ElementId(2);
  test_layer->SetElementId(element_id);

  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
  EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id));
}

}  // namespace
}  // namespace cc
