// Copyright 2012 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/trees/layer_tree_host.h"

#include "base/memory/weak_ptr.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/picture_layer.h"
#include "cc/scheduler/begin_frame_source.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/trees/layer_tree_impl.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/vector2d_conversions.h"

namespace cc {
namespace {

class LayerTreeHostScrollTest : public LayerTreeTest {};

class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
 public:
  LayerTreeHostScrollTestScrollSimple()
      : initial_scroll_(10, 20),
        second_scroll_(40, 5),
        scroll_amount_(2, -1),
        num_scrolls_(0) {}

  void BeginTest() override {
    Layer* root_layer = layer_tree_host()->root_layer();
    scoped_refptr<Layer> scroll_layer = Layer::Create();
    root_layer->AddChild(scroll_layer);
    // Create an effective max_scroll_offset of (100, 100).
    scroll_layer->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
                                      root_layer->bounds().height() + 100));
    scroll_layer->SetIsDrawable(true);
    scroll_layer->SetIsContainerForFixedPositionLayers(true);
    scroll_layer->SetScrollClipLayerId(root_layer->id());
    scroll_layer->SetScrollOffset(initial_scroll_);
    layer_tree_host()->RegisterViewportLayers(NULL, root_layer, scroll_layer,
                                              NULL);
    PostSetNeedsCommitToMainThread();
  }

  void Layout() override {
    Layer* root = layer_tree_host()->root_layer();
    Layer* scroll_layer = root->children()[0].get();
    if (!layer_tree_host()->source_frame_number()) {
      EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
    } else {
      EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_,
                                                  scroll_amount_),
                       scroll_layer->scroll_offset());

      // Pretend like Javascript updated the scroll position itself.
      scroll_layer->SetScrollOffset(second_scroll_);
    }
  }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root = impl->active_tree()->root_layer();
    LayerImpl* scroll_layer = root->children()[0];
    EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta());

    scroll_layer->SetScrollClipLayer(root->id());
    scroll_layer->SetBounds(
        gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
    scroll_layer->ScrollBy(scroll_amount_);

    switch (impl->active_tree()->source_frame_number()) {
      case 0:
        EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset());
        EXPECT_VECTOR_EQ(scroll_amount_, scroll_layer->ScrollDelta());
        PostSetNeedsCommitToMainThread();
        break;
      case 1:
        EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), second_scroll_);
        EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
        EndTest();
        break;
    }
  }

  void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
                           float scale,
                           float top_controls_delta) override {
    num_scrolls_++;
  }

  void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }

 private:
  gfx::ScrollOffset initial_scroll_;
  gfx::ScrollOffset second_scroll_;
  gfx::Vector2dF scroll_amount_;
  int num_scrolls_;
};

MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple);

class LayerTreeHostScrollTestScrollMultipleRedraw
    : public LayerTreeHostScrollTest {
 public:
  LayerTreeHostScrollTestScrollMultipleRedraw()
      : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {}

  void BeginTest() override {
    Layer* root_layer = layer_tree_host()->root_layer();
    scroll_layer_ = Layer::Create();
    root_layer->AddChild(scroll_layer_);
    // Create an effective max_scroll_offset of (100, 100).
    scroll_layer_->SetBounds(gfx::Size(root_layer->bounds().width() + 100,
                                       root_layer->bounds().height() + 100));
    scroll_layer_->SetIsDrawable(true);
    scroll_layer_->SetIsContainerForFixedPositionLayers(true);
    scroll_layer_->SetScrollClipLayerId(root_layer->id());
    scroll_layer_->SetScrollOffset(initial_scroll_);
    layer_tree_host()->RegisterViewportLayers(NULL, root_layer, scroll_layer_,
                                              NULL);
    PostSetNeedsCommitToMainThread();
  }

  void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
    switch (layer_tree_host()->source_frame_number()) {
      case 0:
        EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
        break;
      case 1:
        EXPECT_VECTOR_EQ(
            scroll_layer_->scroll_offset(),
            gfx::ScrollOffsetWithDelta(initial_scroll_,
                                       scroll_amount_ + scroll_amount_));
      case 2:
        EXPECT_VECTOR_EQ(
            scroll_layer_->scroll_offset(),
            gfx::ScrollOffsetWithDelta(initial_scroll_,
                                       scroll_amount_ + scroll_amount_));
        break;
    }
  }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* scroll_layer =
        impl->active_tree()->LayerById(scroll_layer_->id());
    if (impl->active_tree()->source_frame_number() == 0 &&
        impl->SourceAnimationFrameNumber() == 1) {
      // First draw after first commit.
      EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
      scroll_layer->ScrollBy(scroll_amount_);
      EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), scroll_amount_);

      EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
      PostSetNeedsRedrawToMainThread();
    } else if (impl->active_tree()->source_frame_number() == 0 &&
               impl->SourceAnimationFrameNumber() == 2) {
      // Second draw after first commit.
      EXPECT_EQ(scroll_layer->ScrollDelta(), scroll_amount_);
      scroll_layer->ScrollBy(scroll_amount_);
      EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
                       scroll_amount_ + scroll_amount_);

      EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_);
      PostSetNeedsCommitToMainThread();
    } else if (impl->active_tree()->source_frame_number() == 1) {
      // Third or later draw after second commit.
      EXPECT_GE(impl->SourceAnimationFrameNumber(), 3);
      EXPECT_VECTOR_EQ(scroll_layer_->ScrollDelta(), gfx::Vector2d());
      EXPECT_VECTOR_EQ(
          scroll_layer_->scroll_offset(),
          gfx::ScrollOffsetWithDelta(initial_scroll_,
                                     scroll_amount_ + scroll_amount_));
      EndTest();
    }
  }

  void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
                           float scale,
                           float top_controls_delta) override {
    num_scrolls_++;
  }

  void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }

 private:
  gfx::ScrollOffset initial_scroll_;
  gfx::Vector2dF scroll_amount_;
  int num_scrolls_;
  scoped_refptr<Layer> scroll_layer_;
};

MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMultipleRedraw);

class LayerTreeHostScrollTestScrollAbortedCommit
    : public LayerTreeHostScrollTest {
 public:
  LayerTreeHostScrollTestScrollAbortedCommit()
      : initial_scroll_(50, 60),
        impl_scroll_(-3, 2),
        second_main_scroll_(14, -3),
        impl_scale_(2.f),
        num_will_begin_main_frames_(0),
        num_did_begin_main_frames_(0),
        num_will_commits_(0),
        num_did_commits_(0),
        num_impl_commits_(0),
        num_impl_scrolls_(0) {}

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void SetupTree() override {
    LayerTreeHostScrollTest::SetupTree();
    Layer* root_layer = layer_tree_host()->root_layer();
    scoped_refptr<Layer> root_scroll_layer = Layer::Create();
    root_scroll_layer->SetScrollClipLayerId(root_layer->id());
    root_scroll_layer->SetScrollOffset(initial_scroll_);
    root_scroll_layer->SetBounds(gfx::Size(200, 200));
    root_scroll_layer->SetIsDrawable(true);
    root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
    root_layer->AddChild(root_scroll_layer);

    layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
                                              root_scroll_layer, NULL);
    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
  }

  void WillBeginMainFrame() override {
    num_will_begin_main_frames_++;
    Layer* root_scroll_layer =
        layer_tree_host()->root_layer()->children()[0].get();
    switch (num_will_begin_main_frames_) {
      case 1:
        // This will not be aborted because of the initial prop changes.
        EXPECT_EQ(0, num_impl_scrolls_);
        EXPECT_EQ(0, layer_tree_host()->source_frame_number());
        EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);
        EXPECT_EQ(1.f, layer_tree_host()->page_scale_factor());
        break;
      case 2:
        // This commit will be aborted, and another commit will be
        // initiated from the redraw.
        EXPECT_EQ(1, num_impl_scrolls_);
        EXPECT_EQ(1, layer_tree_host()->source_frame_number());
        EXPECT_VECTOR_EQ(
            root_scroll_layer->scroll_offset(),
            gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_));
        EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
        PostSetNeedsRedrawToMainThread();
        break;
      case 3:
        // This commit will not be aborted because of the scroll change.
        EXPECT_EQ(2, num_impl_scrolls_);
        // The source frame number still increases even with the abort.
        EXPECT_EQ(2, layer_tree_host()->source_frame_number());
        EXPECT_VECTOR_EQ(
            root_scroll_layer->scroll_offset(),
            gfx::ScrollOffsetWithDelta(initial_scroll_,
                                       impl_scroll_ + impl_scroll_));
        EXPECT_EQ(impl_scale_ * impl_scale_,
                  layer_tree_host()->page_scale_factor());
        root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta(
            root_scroll_layer->scroll_offset(), second_main_scroll_));
        break;
      case 4:
        // This commit will also be aborted.
        EXPECT_EQ(3, num_impl_scrolls_);
        EXPECT_EQ(3, layer_tree_host()->source_frame_number());
        gfx::Vector2dF delta =
            impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
        EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
                         gfx::ScrollOffsetWithDelta(initial_scroll_, delta));

        // End the test by drawing to verify this commit is also aborted.
        PostSetNeedsRedrawToMainThread();
        break;
    }
  }

  void DidBeginMainFrame() override { num_did_begin_main_frames_++; }

  void WillCommit() override { num_will_commits_++; }

  void DidCommit() override { num_did_commits_++; }

  void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
    num_impl_commits_++;
  }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root_scroll_layer =
        impl->active_tree()->root_layer()->children()[0];

    if (impl->active_tree()->source_frame_number() == 0 &&
        impl->SourceAnimationFrameNumber() == 1) {
      // First draw
      EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
      root_scroll_layer->ScrollBy(impl_scroll_);
      EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
      EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), initial_scroll_);

      EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
      EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
      impl->SetPageScaleOnActiveTree(impl_scale_);
      EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
      EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());

      // To simplify the testing flow, don't redraw here, just commit.
      impl->SetNeedsCommit();
    } else if (impl->active_tree()->source_frame_number() == 0 &&
               impl->SourceAnimationFrameNumber() == 2) {
      // Test a second draw after an aborted commit.
      // The scroll/scale values should be baked into the offset/scale factor
      // since the main thread consumed but aborted the begin frame.
      EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
      root_scroll_layer->ScrollBy(impl_scroll_);
      EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
      EXPECT_VECTOR_EQ(
          root_scroll_layer->scroll_offset(),
          gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_));

      EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
      EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
      impl->SetPageScaleOnActiveTree(impl_scale_ * impl_scale_);
      EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
      EXPECT_EQ(impl_scale_ * impl_scale_,
                impl->active_tree()->current_page_scale_factor());

      impl->SetNeedsCommit();
    } else if (impl->active_tree()->source_frame_number() == 1) {
      // Commit for source frame 1 is aborted.
      NOTREACHED();
    } else if (impl->active_tree()->source_frame_number() == 2 &&
               impl->SourceAnimationFrameNumber() == 3) {
      // Third draw after the second full commit.
      EXPECT_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
      root_scroll_layer->ScrollBy(impl_scroll_);
      impl->SetNeedsCommit();
      EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_);
      gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + second_main_scroll_;
      EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
                       gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
    } else if (impl->active_tree()->source_frame_number() == 2 &&
               impl->SourceAnimationFrameNumber() == 4) {
      // Final draw after the second aborted commit.
      EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d());
      gfx::Vector2dF delta =
          impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
      EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(),
                       gfx::ScrollOffsetWithDelta(initial_scroll_, delta));
      EndTest();
    } else {
      // Commit for source frame 3 is aborted.
      NOTREACHED();
    }
  }

  void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
                           float scale,
                           float top_controls_delta) override {
    num_impl_scrolls_++;
  }

  void AfterTest() override {
    EXPECT_EQ(3, num_impl_scrolls_);
    // Verify that the embedder sees aborted commits as real commits.
    EXPECT_EQ(4, num_will_begin_main_frames_);
    EXPECT_EQ(4, num_did_begin_main_frames_);
    EXPECT_EQ(4, num_will_commits_);
    EXPECT_EQ(4, num_did_commits_);
    // ...but the compositor thread only sees two real ones.
    EXPECT_EQ(2, num_impl_commits_);
  }

 private:
  gfx::ScrollOffset initial_scroll_;
  gfx::Vector2dF impl_scroll_;
  gfx::Vector2dF second_main_scroll_;
  float impl_scale_;
  int num_will_begin_main_frames_;
  int num_did_begin_main_frames_;
  int num_will_commits_;
  int num_did_commits_;
  int num_impl_commits_;
  int num_impl_scrolls_;
};

MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit);

class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest {
 public:
  LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {}

  void SetupTree() override {
    LayerTreeHostScrollTest::SetupTree();
    Layer* root_layer = layer_tree_host()->root_layer();
    scoped_refptr<Layer> root_scroll_layer = Layer::Create();
    root_scroll_layer->SetScrollClipLayerId(root_layer->id());
    root_scroll_layer->SetBounds(
        gfx::Size(root_layer->bounds().width() + 100,
                  root_layer->bounds().height() + 100));
    root_scroll_layer->SetIsDrawable(true);
    root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
    root_layer->AddChild(root_scroll_layer);

    layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
                                              root_scroll_layer, NULL);
    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root = impl->active_tree()->root_layer();
    LayerImpl* scroll_layer = root->children()[0];

    // Check that a fractional scroll delta is correctly accumulated over
    // multiple commits.
    switch (impl->active_tree()->source_frame_number()) {
      case 0:
        EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), gfx::Vector2d(0, 0));
        EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d(0, 0));
        PostSetNeedsCommitToMainThread();
        break;
      case 1:
        EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(),
                         gfx::ToFlooredVector2d(scroll_amount_));
        EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
                         gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f));
        PostSetNeedsCommitToMainThread();
        break;
      case 2:
        EXPECT_VECTOR_EQ(
            scroll_layer->scroll_offset(),
            gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_));
        EXPECT_VECTOR_EQ(
            scroll_layer->ScrollDelta(),
            gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f));
        EndTest();
        break;
    }
    scroll_layer->ScrollBy(scroll_amount_);
  }

  void AfterTest() override {}

 private:
  gfx::Vector2dF scroll_amount_;
};

MULTI_THREAD_TEST_F(LayerTreeHostScrollTestFractionalScroll);

class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
 public:
  LayerTreeHostScrollTestCaseWithChild()
      : initial_offset_(10, 20),
        javascript_scroll_(40, 5),
        scroll_amount_(2, -1),
        num_scrolls_(0) {}

  void SetupTree() override {
    layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);

    scoped_refptr<Layer> root_layer = Layer::Create();
    root_layer->SetBounds(gfx::Size(10, 10));

    root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
    root_scroll_layer_->SetBounds(gfx::Size(110, 110));

    root_scroll_layer_->SetPosition(gfx::Point());

    root_scroll_layer_->SetIsDrawable(true);
    root_scroll_layer_->SetScrollClipLayerId(root_layer->id());
    root_scroll_layer_->SetIsContainerForFixedPositionLayers(true);
    root_layer->AddChild(root_scroll_layer_);

    child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_);
    child_layer_->set_did_scroll_callback(
        base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
                   base::Unretained(this)));
    child_layer_->SetBounds(gfx::Size(110, 110));

    if (scroll_child_layer_) {
      // Scrolls on the child layer will happen at 5, 5. If they are treated
      // like device pixels, and device scale factor is 2, then they will
      // be considered at 2.5, 2.5 in logical pixels, and will miss this layer.
      child_layer_->SetPosition(gfx::Point(5, 5));
    } else {
      // Adjust the child layer horizontally so that scrolls will never hit it.
      child_layer_->SetPosition(gfx::Point(60, 5));
    }

    child_layer_->SetIsDrawable(true);
    child_layer_->SetScrollClipLayerId(root_layer->id());
    child_layer_->SetBounds(root_scroll_layer_->bounds());
    root_scroll_layer_->AddChild(child_layer_);

    if (scroll_child_layer_) {
      expected_scroll_layer_ = child_layer_;
      expected_no_scroll_layer_ = root_scroll_layer_;
    } else {
      expected_scroll_layer_ = root_scroll_layer_;
      expected_no_scroll_layer_ = child_layer_;
    }

    expected_scroll_layer_->SetScrollOffset(initial_offset_);

    layer_tree_host()->SetRootLayer(root_layer);
    layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
                                              root_scroll_layer_, NULL);
    LayerTreeHostScrollTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void WillCommit() override {
    // Keep the test committing (otherwise the early out for no update
    // will stall the test).
    if (layer_tree_host()->source_frame_number() < 2) {
      layer_tree_host()->SetNeedsCommit();
    }
  }

  void DidScroll() {
    final_scroll_offset_ = expected_scroll_layer_->scroll_offset();
  }

  void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
                           float scale,
                           float top_controls_delta) override {
    num_scrolls_++;
  }

  void Layout() override {
    EXPECT_VECTOR_EQ(gfx::Vector2d(),
                     expected_no_scroll_layer_->scroll_offset());

    switch (layer_tree_host()->source_frame_number()) {
      case 0:
        EXPECT_VECTOR_EQ(initial_offset_,
                         expected_scroll_layer_->scroll_offset());
        break;
      case 1:
        EXPECT_VECTOR_EQ(
            gfx::ScrollOffsetWithDelta(initial_offset_, scroll_amount_),
            expected_scroll_layer_->scroll_offset());

        // Pretend like Javascript updated the scroll position itself.
        expected_scroll_layer_->SetScrollOffset(javascript_scroll_);
        break;
      case 2:
        EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
                                                    scroll_amount_),
                         expected_scroll_layer_->scroll_offset());
        break;
    }
  }

  void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root_impl = impl->active_tree()->root_layer();
    FakePictureLayerImpl* root_scroll_layer_impl =
        static_cast<FakePictureLayerImpl*>(root_impl->children()[0]);
    FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>(
        root_scroll_layer_impl->children()[0]);

    LayerImpl* expected_scroll_layer_impl = NULL;
    LayerImpl* expected_no_scroll_layer_impl = NULL;
    if (scroll_child_layer_) {
      expected_scroll_layer_impl = child_layer_impl;
      expected_no_scroll_layer_impl = root_scroll_layer_impl;
    } else {
      expected_scroll_layer_impl = root_scroll_layer_impl;
      expected_no_scroll_layer_impl = child_layer_impl;
    }

    EXPECT_VECTOR_EQ(gfx::Vector2d(), root_impl->ScrollDelta());
    EXPECT_VECTOR_EQ(gfx::Vector2d(),
                     expected_no_scroll_layer_impl->ScrollDelta());

    // Ensure device scale factor matches the active tree.
    EXPECT_EQ(device_scale_factor_, impl->active_tree()->device_scale_factor());
    switch (impl->active_tree()->source_frame_number()) {
      case 0: {
        // Gesture scroll on impl thread.
        InputHandler::ScrollStatus status = impl->ScrollBegin(
            gfx::ToCeiledPoint(expected_scroll_layer_impl->position() -
                               gfx::Vector2dF(0.5f, 0.5f)),
            InputHandler::Gesture);
        EXPECT_EQ(InputHandler::ScrollStarted, status);
        impl->ScrollBy(gfx::Point(), scroll_amount_);
        impl->ScrollEnd();

        // Check the scroll is applied as a delta.
        EXPECT_VECTOR_EQ(initial_offset_,
                         expected_scroll_layer_impl->scroll_offset());
        EXPECT_VECTOR_EQ(scroll_amount_,
                         expected_scroll_layer_impl->ScrollDelta());
        break;
      }
      case 1: {
        // Wheel scroll on impl thread.
        InputHandler::ScrollStatus status = impl->ScrollBegin(
            gfx::ToCeiledPoint(expected_scroll_layer_impl->position() +
                               gfx::Vector2dF(0.5f, 0.5f)),
            InputHandler::Wheel);
        EXPECT_EQ(InputHandler::ScrollStarted, status);
        impl->ScrollBy(gfx::Point(), scroll_amount_);
        impl->ScrollEnd();

        // Check the scroll is applied as a delta.
        EXPECT_VECTOR_EQ(javascript_scroll_,
                         expected_scroll_layer_impl->scroll_offset());
        EXPECT_VECTOR_EQ(scroll_amount_,
                         expected_scroll_layer_impl->ScrollDelta());
        break;
      }
      case 2:

        EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
                                                    scroll_amount_),
                         expected_scroll_layer_impl->scroll_offset());
        EXPECT_VECTOR_EQ(gfx::Vector2d(),
                         expected_scroll_layer_impl->ScrollDelta());

        EndTest();
        break;
    }
  }

  void AfterTest() override {
    if (scroll_child_layer_) {
      EXPECT_EQ(0, num_scrolls_);
      EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
                                                  scroll_amount_),
                       final_scroll_offset_);
    } else {
      EXPECT_EQ(2, num_scrolls_);
      EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_);
    }
  }

 protected:
  float device_scale_factor_;
  bool scroll_child_layer_;

  gfx::ScrollOffset initial_offset_;
  gfx::ScrollOffset javascript_scroll_;
  gfx::Vector2d scroll_amount_;
  int num_scrolls_;
  gfx::ScrollOffset final_scroll_offset_;

  FakeContentLayerClient fake_content_layer_client_;

  scoped_refptr<Layer> root_scroll_layer_;
  scoped_refptr<Layer> child_layer_;
  scoped_refptr<Layer> expected_scroll_layer_;
  scoped_refptr<Layer> expected_no_scroll_layer_;
};

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor1_ScrollChild_DirectRenderer) {
  device_scale_factor_ = 1.f;
  scroll_child_layer_ = true;
  RunTest(true, false, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor1_ScrollChild_DelegatingRenderer) {
  device_scale_factor_ = 1.f;
  scroll_child_layer_ = true;
  RunTest(true, true, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor15_ScrollChild_DirectRenderer) {
  device_scale_factor_ = 1.5f;
  scroll_child_layer_ = true;
  RunTest(true, false, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
  device_scale_factor_ = 1.5f;
  scroll_child_layer_ = true;
  RunTest(true, true, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor2_ScrollChild_DirectRenderer) {
  device_scale_factor_ = 2.f;
  scroll_child_layer_ = true;
  RunTest(true, false, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
  device_scale_factor_ = 2.f;
  scroll_child_layer_ = true;
  RunTest(true, true, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
  device_scale_factor_ = 1.f;
  scroll_child_layer_ = false;
  RunTest(true, false, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
  device_scale_factor_ = 1.f;
  scroll_child_layer_ = false;
  RunTest(true, true, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
  device_scale_factor_ = 1.5f;
  scroll_child_layer_ = false;
  RunTest(true, false, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
  device_scale_factor_ = 1.5f;
  scroll_child_layer_ = false;
  RunTest(true, true, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) {
  device_scale_factor_ = 2.f;
  scroll_child_layer_ = false;
  RunTest(true, false, true);
}

TEST_F(LayerTreeHostScrollTestCaseWithChild,
       DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
  device_scale_factor_ = 2.f;
  scroll_child_layer_ = false;
  RunTest(true, true, true);
}

class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest {
 public:
  void InitializeSettings(LayerTreeSettings* settings) override {
    settings->impl_side_painting = true;
  }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    if (impl->pending_tree())
      impl->SetNeedsRedraw();
  }
};

class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest {
 public:
  ImplSidePaintingScrollTestSimple()
      : initial_scroll_(10, 20),
        main_thread_scroll_(40, 5),
        impl_thread_scroll1_(2, -1),
        impl_thread_scroll2_(-3, 10),
        num_scrolls_(0) {}

  void SetupTree() override {
    LayerTreeHostScrollTest::SetupTree();
    Layer* root_layer = layer_tree_host()->root_layer();
    scoped_refptr<Layer> root_scroll_layer = Layer::Create();
    root_scroll_layer->SetScrollClipLayerId(root_layer->id());
    root_scroll_layer->SetScrollOffset(initial_scroll_);
    root_scroll_layer->SetBounds(
        gfx::Size(root_layer->bounds().width() + 100,
                  root_layer->bounds().height() + 100));
    root_scroll_layer->SetIsDrawable(true);
    root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
    root_layer->AddChild(root_scroll_layer);

    layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
                                              root_scroll_layer, NULL);
    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void Layout() override {
    Layer* root = layer_tree_host()->root_layer();
    Layer* scroll_layer = root->children()[0].get();
    if (!layer_tree_host()->source_frame_number()) {
      EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
    } else {
      EXPECT_VECTOR_EQ(
          scroll_layer->scroll_offset(),
          gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll1_));

      // Pretend like Javascript updated the scroll position itself with a
      // change of main_thread_scroll.
      scroll_layer->SetScrollOffset(
          gfx::ScrollOffsetWithDelta(
              initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
    }
  }

  void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
    // We force a second draw here of the first commit before activating
    // the second commit.
    if (impl->active_tree()->source_frame_number() == 0)
      impl->SetNeedsRedraw();
  }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    ImplSidePaintingScrollTest::DrawLayersOnThread(impl);

    LayerImpl* root = impl->active_tree()->root_layer();
    LayerImpl* scroll_layer = root->children()[0];
    LayerImpl* pending_root =
        impl->active_tree()->FindPendingTreeLayerById(root->id());

    switch (impl->active_tree()->source_frame_number()) {
      case 0:
        if (!impl->pending_tree()) {
          impl->BlockNotifyReadyToActivateForTesting(true);
          EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
          scroll_layer->ScrollBy(impl_thread_scroll1_);

          EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
          EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll1_);
          EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
          PostSetNeedsCommitToMainThread();

          // CommitCompleteOnThread will trigger this function again
          // and cause us to take the else clause.
        } else {
          impl->BlockNotifyReadyToActivateForTesting(false);
          ASSERT_TRUE(pending_root);
          EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);

          scroll_layer->ScrollBy(impl_thread_scroll2_);
          EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
          EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(),
                           impl_thread_scroll1_ + impl_thread_scroll2_);
          EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(),
                           impl_thread_scroll1_);

          LayerImpl* pending_scroll_layer = pending_root->children()[0];
          EXPECT_VECTOR_EQ(
              pending_scroll_layer->scroll_offset(),
              gfx::ScrollOffsetWithDelta(
                  initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
          EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
                           impl_thread_scroll2_);
          EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
                           gfx::Vector2d());
        }
        break;
      case 1:
        EXPECT_FALSE(impl->pending_tree());
        EXPECT_VECTOR_EQ(
            scroll_layer->scroll_offset(),
            gfx::ScrollOffsetWithDelta(
                initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
        EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll2_);
        EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
        EndTest();
        break;
    }
  }

  void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta,
                           float scale,
                           float top_controls_delta) override {
    num_scrolls_++;
  }

  void AfterTest() override { EXPECT_EQ(1, num_scrolls_); }

 private:
  gfx::ScrollOffset initial_scroll_;
  gfx::Vector2dF main_thread_scroll_;
  gfx::Vector2dF impl_thread_scroll1_;
  gfx::Vector2dF impl_thread_scroll2_;
  int num_scrolls_;
};

MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestSimple);

// This test makes sure that layers pick up scrolls that occur between
// beginning a commit and finishing a commit (aka scroll deltas not
// included in sent scroll delta) still apply to layers that don't
// push properties.
class ImplSidePaintingScrollTestImplOnlyScroll
    : public ImplSidePaintingScrollTest {
 public:
  ImplSidePaintingScrollTestImplOnlyScroll()
      : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3), impl_scale_(2.f) {}

  void SetupTree() override {
    LayerTreeHostScrollTest::SetupTree();
    Layer* root_layer = layer_tree_host()->root_layer();
    scoped_refptr<Layer> root_scroll_layer = Layer::Create();
    root_scroll_layer->SetScrollClipLayerId(root_layer->id());
    root_scroll_layer->SetScrollOffset(initial_scroll_);
    root_scroll_layer->SetBounds(
        gfx::Size(root_layer->bounds().width() + 100,
                  root_layer->bounds().height() + 100));
    root_scroll_layer->SetIsDrawable(true);
    root_scroll_layer->SetIsContainerForFixedPositionLayers(true);
    root_layer->AddChild(root_scroll_layer);

    layer_tree_host()->RegisterViewportLayers(NULL, root_layer,
                                              root_scroll_layer, NULL);
    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void WillCommit() override {
    Layer* root = layer_tree_host()->root_layer();
    Layer* scroll_layer = root->children()[0].get();
    switch (layer_tree_host()->source_frame_number()) {
      case 0:
        EXPECT_TRUE(scroll_layer->needs_push_properties());
        break;
      case 1:
        // Even if this layer doesn't need push properties, it should
        // still pick up scrolls that happen on the active layer during
        // commit.
        EXPECT_FALSE(scroll_layer->needs_push_properties());
        break;
    }
  }

  void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
    // Scroll after the 2nd commit has started.
    if (impl->active_tree()->source_frame_number() == 0) {
      LayerImpl* active_root = impl->active_tree()->root_layer();
      LayerImpl* active_scroll_layer = active_root->children()[0];
      ASSERT_TRUE(active_root);
      ASSERT_TRUE(active_scroll_layer);
      active_scroll_layer->ScrollBy(impl_thread_scroll_);
      impl->SetPageScaleOnActiveTree(impl_scale_);
    }
  }

  void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
    // We force a second draw here of the first commit before activating
    // the second commit.
    LayerImpl* active_root = impl->active_tree()->root_layer();
    LayerImpl* active_scroll_layer =
        active_root ? active_root->children()[0] : NULL;
    LayerImpl* pending_root = impl->pending_tree()->root_layer();
    LayerImpl* pending_scroll_layer = pending_root->children()[0];

    ASSERT_TRUE(pending_root);
    ASSERT_TRUE(pending_scroll_layer);
    switch (impl->pending_tree()->source_frame_number()) {
      case 0:
        EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
                         initial_scroll_);
        EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
        EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
                         gfx::Vector2d());
        EXPECT_FALSE(active_root);
        break;
      case 1:
        // Even though the scroll happened during the commit, both layers
        // should have the appropriate scroll delta.
        EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
                         initial_scroll_);
        EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(),
                         impl_thread_scroll_);
        EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
                         gfx::Vector2d());
        ASSERT_TRUE(active_root);
        EXPECT_VECTOR_EQ(active_scroll_layer->scroll_offset(), initial_scroll_);
        EXPECT_VECTOR_EQ(active_scroll_layer->ScrollDelta(),
                         impl_thread_scroll_);
        EXPECT_VECTOR_EQ(active_scroll_layer->sent_scroll_delta(),
                         gfx::Vector2d());
        break;
      case 2:
        // On the next commit, this delta should have been sent and applied.
        EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(),
                         gfx::ScrollOffsetWithDelta(initial_scroll_,
                                                    impl_thread_scroll_));
        EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d());
        EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(),
                         gfx::Vector2d());
        break;
    }
  }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    ImplSidePaintingScrollTest::DrawLayersOnThread(impl);

    LayerImpl* root = impl->active_tree()->root_layer();
    LayerImpl* scroll_layer = root->children()[0];

    switch (impl->active_tree()->source_frame_number()) {
      case 0:
        EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
        EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), gfx::Vector2d());
        EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
        EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
        EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
        PostSetNeedsCommitToMainThread();
        break;
      case 1:
        EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_);
        EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll_);
        EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d());
        EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
        EXPECT_EQ(impl_scale_,
                  impl->active_tree()->current_page_scale_factor());
        PostSetNeedsCommitToMainThread();
        break;
      case 2:
        EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
        EXPECT_EQ(impl_scale_,
                  impl->active_tree()->current_page_scale_factor());
        EndTest();
        break;
    }
  }

  void AfterTest() override {}

 private:
  gfx::ScrollOffset initial_scroll_;
  gfx::Vector2dF impl_thread_scroll_;
  float impl_scale_;
};

MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll);

class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
    : public LayerTreeHostScrollTest {
 public:
  LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {}

  void SetupTree() override {
    LayerTreeTest::SetupTree();
    scoped_refptr<Layer> scroll_layer = Layer::Create();
    layer_tree_host()->root_layer()->AddChild(scroll_layer);
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root = impl->active_tree()->root_layer();
    LayerImpl* scroll_layer = root->children()[0];
    scroll_layer->SetScrollClipLayer(root->id());

    // Set max_scroll_offset = (100, 100).
    scroll_layer->SetBounds(
        gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100));
    EXPECT_EQ(InputHandler::ScrollStarted,
              scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
                                      InputHandler::Gesture));

    // Set max_scroll_offset = (0, 0).
    scroll_layer->SetBounds(root->bounds());
    EXPECT_EQ(InputHandler::ScrollIgnored,
              scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
                                      InputHandler::Gesture));

    // Set max_scroll_offset = (-100, -100).
    scroll_layer->SetBounds(gfx::Size());
    EXPECT_EQ(InputHandler::ScrollIgnored,
              scroll_layer->TryScroll(gfx::PointF(0.0f, 1.0f),
                                      InputHandler::Gesture));

    EndTest();
  }

  void AfterTest() override {}
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostScrollTestScrollZeroMaxScrollOffset);

class ThreadCheckingInputHandlerClient : public InputHandlerClient {
 public:
  ThreadCheckingInputHandlerClient(base::SingleThreadTaskRunner* runner,
                                   bool* received_stop_flinging)
      : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {}

  void WillShutdown() override {
    if (!received_stop_flinging_)
      ADD_FAILURE() << "WillShutdown() called before fling stopped";
  }

  void Animate(base::TimeTicks time) override {
    if (!task_runner_->BelongsToCurrentThread())
      ADD_FAILURE() << "Animate called on wrong thread";
  }

  void MainThreadHasStoppedFlinging() override {
    if (!task_runner_->BelongsToCurrentThread())
      ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread";
    *received_stop_flinging_ = true;
  }

  void ReconcileElasticOverscrollAndRootScroll() override {
    if (!task_runner_->BelongsToCurrentThread()) {
      ADD_FAILURE() << "ReconcileElasticOverscrollAndRootScroll called on "
                    << "wrong thread";
    }
  }

 private:
  base::SingleThreadTaskRunner* task_runner_;
  bool* received_stop_flinging_;
};

void BindInputHandlerOnCompositorThread(
    const base::WeakPtr<InputHandler>& input_handler,
    ThreadCheckingInputHandlerClient* client) {
  input_handler->BindToClient(client);
}

TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
  base::Thread impl_thread("cc");
  ASSERT_TRUE(impl_thread.Start());

  bool received_stop_flinging = false;
  LayerTreeSettings settings;

  ThreadCheckingInputHandlerClient input_handler_client(
          impl_thread.message_loop_proxy().get(), &received_stop_flinging);
  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);

  ASSERT_TRUE(impl_thread.message_loop_proxy().get());
  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
      new TestSharedBitmapManager());
  scoped_ptr<LayerTreeHost> layer_tree_host =
      LayerTreeHost::CreateThreaded(&client,
                                    shared_bitmap_manager.get(),
                                    NULL,
                                    settings,
                                    base::MessageLoopProxy::current(),
                                    impl_thread.message_loop_proxy(),
                                    nullptr);

  impl_thread.message_loop_proxy()
      ->PostTask(FROM_HERE,
                 base::Bind(&BindInputHandlerOnCompositorThread,
                            layer_tree_host->GetInputHandler(),
                            base::Unretained(&input_handler_client)));

  layer_tree_host->DidStopFlinging();
  layer_tree_host = nullptr;
  impl_thread.Stop();
  EXPECT_TRUE(received_stop_flinging);
}

class LayerTreeHostScrollTestLayerStructureChange
    : public LayerTreeHostScrollTest {
 public:
  LayerTreeHostScrollTestLayerStructureChange()
      : scroll_destroy_whole_tree_(false) {}

  void SetupTree() override {
    scoped_refptr<Layer> root_layer = Layer::Create();
    root_layer->SetBounds(gfx::Size(10, 10));

    Layer* root_scroll_layer =
        CreateScrollLayer(root_layer.get(), &root_scroll_layer_client_);
    CreateScrollLayer(root_layer.get(), &sibling_scroll_layer_client_);
    CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_);

    layer_tree_host()->SetRootLayer(root_layer);
    LayerTreeHostScrollTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root = impl->active_tree()->root_layer();
    switch (impl->active_tree()->source_frame_number()) {
      case 0:
        root->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
        root->child_at(0)->child_at(0)->SetScrollDelta(gfx::Vector2dF(5, 5));
        root->child_at(1)->SetScrollDelta(gfx::Vector2dF(5, 5));
        PostSetNeedsCommitToMainThread();
        break;
      case 1:
        EndTest();
        break;
    }
  }

  void AfterTest() override {}

  virtual void DidScroll(Layer* layer) {
    if (scroll_destroy_whole_tree_) {
      layer_tree_host()->SetRootLayer(NULL);
      EndTest();
      return;
    }
    layer->RemoveFromParent();
  }

 protected:
  class FakeLayerScrollClient {
   public:
    void DidScroll() {
      owner_->DidScroll(layer_);
    }
    LayerTreeHostScrollTestLayerStructureChange* owner_;
    Layer* layer_;
  };

  Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
    scoped_refptr<PictureLayer> scroll_layer =
        PictureLayer::Create(&fake_content_layer_client_);
    scroll_layer->SetBounds(gfx::Size(110, 110));
    scroll_layer->SetPosition(gfx::Point(0, 0));
    scroll_layer->SetIsDrawable(true);
    scroll_layer->SetScrollClipLayerId(parent->id());
    scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
                                      parent->bounds().height() + 100));
    scroll_layer->set_did_scroll_callback(base::Bind(
        &FakeLayerScrollClient::DidScroll, base::Unretained(client)));
    client->owner_ = this;
    client->layer_ = scroll_layer.get();
    parent->AddChild(scroll_layer);
    return scroll_layer.get();
  }

  FakeLayerScrollClient root_scroll_layer_client_;
  FakeLayerScrollClient sibling_scroll_layer_client_;
  FakeLayerScrollClient child_scroll_layer_client_;

  FakeContentLayerClient fake_content_layer_client_;

  bool scroll_destroy_whole_tree_;
};

TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) {
  RunTest(true, false, true);
}

TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) {
  scroll_destroy_whole_tree_ = true;
  RunTest(true, false, true);
}

}  // namespace
}  // namespace cc
