// Copyright 2017 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 "content/browser/renderer_host/render_widget_host_input_event_router.h"

#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "components/viz/host/hit_test/hit_test_query.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/test/host_frame_sink_manager_test_api.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/compositor/test/test_image_transport_factory.h"
#include "content/browser/renderer_host/frame_connector_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/renderer_host/render_widget_targeter.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/mock_render_widget_host_delegate.h"
#include "content/test/mock_widget_impl.h"
#include "content/test/test_render_view_host.h"
#include "services/viz/public/interfaces/hit_test/input_target_client.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {

class MockFrameConnectorDelegate : public FrameConnectorDelegate {
 public:
  MockFrameConnectorDelegate(RenderWidgetHostViewChildFrame* view,
                             RenderWidgetHostViewBase* parent_view,
                             RenderWidgetHostViewBase* root_view,
                             bool use_zoom_for_device_scale_factor)
      : FrameConnectorDelegate(use_zoom_for_device_scale_factor),
        parent_view_(parent_view),
        root_view_(root_view) {
    view_ = view;
    view_->SetFrameConnectorDelegate(this);
  }

  ~MockFrameConnectorDelegate() override {
    if (view_) {
      view_->SetFrameConnectorDelegate(nullptr);
      view_ = nullptr;
    }
  }

  RenderWidgetHostViewBase* GetParentRenderWidgetHostView() override {
    return parent_view_;
  }

  RenderWidgetHostViewBase* GetRootRenderWidgetHostView() override {
    return root_view_;
  }

 private:
  RenderWidgetHostViewBase* parent_view_;
  RenderWidgetHostViewBase* root_view_;

  DISALLOW_COPY_AND_ASSIGN(MockFrameConnectorDelegate);
};

// Used as a target for the RenderWidgetHostInputEventRouter. We record what
// events were forwarded to us in order to verify that the events are being
// routed correctly.
class TestRenderWidgetHostViewChildFrame
    : public RenderWidgetHostViewChildFrame {
 public:
  explicit TestRenderWidgetHostViewChildFrame(RenderWidgetHost* widget)
      : RenderWidgetHostViewChildFrame(widget) {
    Init();
  }
  ~TestRenderWidgetHostViewChildFrame() override = default;

  void ProcessGestureEvent(const blink::WebGestureEvent& event,
                           const ui::LatencyInfo&) override {
    last_gesture_seen_ = event.GetType();
  }

  void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
                              InputEventAckState ack_result) override {
    unique_id_for_last_touch_ack_ = touch.event.unique_touch_event_id;
  }

  blink::WebInputEvent::Type last_gesture_seen() { return last_gesture_seen_; }
  uint32_t last_id_for_touch_ack() { return unique_id_for_last_touch_ack_; }

  void Reset() { last_gesture_seen_ = blink::WebInputEvent::kUndefined; }

 private:
  blink::WebInputEvent::Type last_gesture_seen_ =
      blink::WebInputEvent::kUndefined;
  uint32_t unique_id_for_last_touch_ack_ = 0;
};

class StubHitTestQuery : public viz::HitTestQuery {
 public:
  StubHitTestQuery(RenderWidgetHostViewBase* hittest_result,
                   bool query_renderer)
      : hittest_result_(hittest_result), query_renderer_(query_renderer) {}
  ~StubHitTestQuery() override = default;

  viz::Target FindTargetForLocationStartingFromImpl(
      viz::EventSource event_source,
      const gfx::PointF& location,
      const viz::FrameSinkId& sink_id,
      bool is_location_relative_to_parent) const override {
    return {hittest_result_->GetFrameSinkId(), gfx::PointF(),
            viz::HitTestRegionFlags::kHitTestMouse |
                viz::HitTestRegionFlags::kHitTestTouch |
                viz::HitTestRegionFlags::kHitTestMine |
                (query_renderer_ ? viz::HitTestRegionFlags::kHitTestAsk : 0)};
  }

 private:
  const RenderWidgetHostViewBase* hittest_result_;
  const bool query_renderer_;
};

// The RenderWidgetHostInputEventRouter uses the root RWHV for hittesting, so
// here we stub out the hittesting logic so we can control which RWHV will be
// the result of a hittest by the RWHIER. Note that since the hittesting is
// stubbed out, the event coordinates and view bounds are irrelevant for these
// tests.
class MockRootRenderWidgetHostView : public TestRenderWidgetHostView {
 public:
  MockRootRenderWidgetHostView(RenderWidgetHost* rwh)
      : TestRenderWidgetHostView(rwh) {}
  ~MockRootRenderWidgetHostView() override = default;

  bool TransformPointToCoordSpaceForView(
      const gfx::PointF& point,
      RenderWidgetHostViewBase* target_view,
      gfx::PointF* transformed_point) override {
    return true;
  }

  void ProcessGestureEvent(const blink::WebGestureEvent& event,
                           const ui::LatencyInfo&) override {
    last_gesture_seen_ = event.GetType();
  }

  void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
                              InputEventAckState ack_result) override {
    unique_id_for_last_touch_ack_ = touch.event.unique_touch_event_id;
  }

  viz::FrameSinkId GetRootFrameSinkId() override { return GetFrameSinkId(); }

  blink::WebInputEvent::Type last_gesture_seen() { return last_gesture_seen_; }
  uint32_t last_id_for_touch_ack() { return unique_id_for_last_touch_ack_; }

  void SetHittestResult(RenderWidgetHostViewBase* result_view,
                        bool query_renderer) {
    DCHECK(GetHostFrameSinkManager());

    viz::HostFrameSinkManager::DisplayHitTestQueryMap hit_test_map;
    hit_test_map[GetFrameSinkId()] =
        std::make_unique<StubHitTestQuery>(result_view, query_renderer);

    viz::HostFrameSinkManagerTestApi(GetHostFrameSinkManager())
        .SetDisplayHitTestQuery(std::move(hit_test_map));
  }

  void Reset() { last_gesture_seen_ = blink::WebInputEvent::kUndefined; }

 private:
  blink::WebInputEvent::Type last_gesture_seen_ =
      blink::WebInputEvent::kUndefined;
  uint32_t unique_id_for_last_touch_ack_ = 0;
};

}  // namespace

class RenderWidgetHostInputEventRouterTest : public testing::Test {
 protected:
  RenderWidgetHostInputEventRouterTest() = default;

  RenderWidgetHostInputEventRouter* rwhier() {
    return delegate_.GetInputEventRouter();
  }

  // testing::Test:
  void SetUp() override {
    browser_context_ = std::make_unique<TestBrowserContext>();

// ImageTransportFactory doesn't exist on Android. This is needed to create
// a RenderWidgetHostViewChildFrame in the test.
#if !defined(OS_ANDROID)
    ImageTransportFactory::SetFactory(
        std::make_unique<TestImageTransportFactory>());
#endif

    delegate_.CreateInputEventRouter();

    process_host_root_ =
        std::make_unique<MockRenderProcessHost>(browser_context_.get());
    mojom::WidgetPtr widget_root;
    widget_impl_root_ =
        std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget_root));
    widget_host_root_ = std::make_unique<RenderWidgetHostImpl>(
        &delegate_, process_host_root_.get(),
        process_host_root_->GetNextRoutingID(), std::move(widget_root), false);
    view_root_ =
        std::make_unique<MockRootRenderWidgetHostView>(widget_host_root_.get());

    // We need to set up a comm pipe, or else the targeter will crash when it
    // tries to query the renderer. It doesn't matter that the pipe isn't
    // connected on the other end, as we really don't want it to respond
    // anyways.
    viz::mojom::InputTargetClientPtr input_target_client;
    service_manager::InterfaceProvider().GetInterface(&input_target_client);
    widget_host_root_->SetInputTargetClient(std::move(input_target_client));

    EXPECT_EQ(view_root_.get(),
              rwhier()->FindViewFromFrameSinkId(view_root_->GetFrameSinkId()));
  }

  struct ChildViewState {
    std::unique_ptr<MockRenderProcessHost> process_host;
    std::unique_ptr<MockWidgetImpl> widget_impl;
    std::unique_ptr<RenderWidgetHostImpl> widget_host;
    std::unique_ptr<TestRenderWidgetHostViewChildFrame> view;
    std::unique_ptr<MockFrameConnectorDelegate> frame_connector;
  };

  ChildViewState MakeChildView(RenderWidgetHostViewBase* parent_view) {
    ChildViewState child;

    child.process_host =
        std::make_unique<MockRenderProcessHost>(browser_context_.get());
    mojom::WidgetPtr widget_child;
    child.widget_impl =
        std::make_unique<MockWidgetImpl>(mojo::MakeRequest(&widget_child));
    child.widget_host = std::make_unique<RenderWidgetHostImpl>(
        &delegate_, child.process_host.get(),
        child.process_host->GetNextRoutingID(), std::move(widget_child), false);
    child.view = std::make_unique<TestRenderWidgetHostViewChildFrame>(
        child.widget_host.get());
    child.frame_connector = std::make_unique<MockFrameConnectorDelegate>(
        child.view.get(), parent_view, view_root_.get(),
        false /* use_zoom_for_device_scale_factor */);

    EXPECT_EQ(child.view.get(),
              rwhier()->FindViewFromFrameSinkId(child.view->GetFrameSinkId()));

    return child;
  }

  void TearDown() override {
    view_root_.reset();
    widget_host_root_.reset();
    process_host_root_.reset();
    base::RunLoop().RunUntilIdle();

#if !defined(OS_ANDROID)
    ImageTransportFactory::Terminate();
#endif
  }

  RenderWidgetHostViewBase* touch_target() { return rwhier()->touch_target_; }
  RenderWidgetHostViewBase* touchscreen_gesture_target() {
    return rwhier()->touchscreen_gesture_target_;
  }
  RenderWidgetHostViewChildFrame* bubbling_gesture_scroll_origin() {
    return rwhier()->bubbling_gesture_scroll_origin_;
  }
  RenderWidgetHostViewBase* bubbling_gesture_scroll_target() {
    return rwhier()->bubbling_gesture_scroll_target_;
  }

  void TestSendNewGestureWhileBubbling(
      TestRenderWidgetHostViewChildFrame* bubbling_origin,
      RenderWidgetHostViewBase* gesture_target,
      bool should_cancel);

  TestBrowserThreadBundle thread_bundle_;

  MockRenderWidgetHostDelegate delegate_;
  std::unique_ptr<BrowserContext> browser_context_;

  std::unique_ptr<MockRenderProcessHost> process_host_root_;
  std::unique_ptr<MockWidgetImpl> widget_impl_root_;
  std::unique_ptr<RenderWidgetHostImpl> widget_host_root_;
  std::unique_ptr<MockRootRenderWidgetHostView> view_root_;

 private:
  DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostInputEventRouterTest);
};

// Make sure that when a touch scroll crosses out of the area for a
// RenderWidgetHostView, the RenderWidgetHostInputEventRouter continues to
// route gesture events to the same RWHV until the end of the gesture.
// See crbug.com/739831
TEST_F(RenderWidgetHostInputEventRouterTest,
       DoNotChangeTargetViewDuringTouchScrollGesture) {
  ChildViewState child = MakeChildView(view_root_.get());
  // Simulate the touch and gesture events produced from scrolling on a
  // touchscreen.

  // We start the touch in the area for |child.view|.
  view_root_->SetHittestResult(child.view.get(), false);

  blink::WebTouchEvent touch_event(
      blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_event.touches_length = 1;
  touch_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
  touch_event.unique_touch_event_id = 1;

  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(child.view.get(), touch_target());

  blink::WebGestureEvent gesture_event(
      blink::WebInputEvent::kGestureTapDown, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;

  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(child.view.get(), touchscreen_gesture_target());
  EXPECT_EQ(blink::WebInputEvent::kGestureTapDown,
            child.view->last_gesture_seen());
  EXPECT_NE(blink::WebInputEvent::kGestureTapDown,
            view_root_->last_gesture_seen());

  touch_event.SetType(blink::WebInputEvent::kTouchMove);
  touch_event.touches[0].state = blink::WebTouchPoint::kStateMoved;
  touch_event.unique_touch_event_id += 1;
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));

  gesture_event.SetType(blink::WebInputEvent::kGestureTapCancel);
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));

  gesture_event.SetType(blink::WebInputEvent::kGestureScrollBegin);
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));

  gesture_event.SetType(blink::WebInputEvent::kGestureScrollUpdate);
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));

  touch_event.unique_touch_event_id += 1;
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));

  // The continuation of the touch moves should maintain their current target of
  // |child.view|, even if they move outside of that view, and into
  // |view_root_|.
  // If the target is maintained through the gesture this will pass. If instead
  // the hit testing logic is refered to, then this test will fail.
  view_root_->SetHittestResult(view_root_.get(), false);
  view_root_->Reset();
  child.view->Reset();

  touch_event.unique_touch_event_id += 1;
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));

  EXPECT_EQ(child.view.get(), touch_target());
  EXPECT_EQ(child.view.get(), touchscreen_gesture_target());
  EXPECT_EQ(blink::WebInputEvent::kGestureScrollUpdate,
            child.view->last_gesture_seen());
  EXPECT_NE(blink::WebInputEvent::kGestureScrollUpdate,
            view_root_->last_gesture_seen());

  touch_event.SetType(blink::WebInputEvent::kTouchEnd);
  touch_event.touches[0].state = blink::WebTouchPoint::kStateReleased;
  touch_event.unique_touch_event_id += 1;
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));

  gesture_event.SetType(blink::WebInputEvent::kGestureScrollEnd);
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));

  EXPECT_EQ(blink::WebInputEvent::kGestureScrollEnd,
            child.view->last_gesture_seen());
  EXPECT_NE(blink::WebInputEvent::kGestureScrollEnd,
            view_root_->last_gesture_seen());
}

TEST_F(RenderWidgetHostInputEventRouterTest,
       EnsureRendererDestroyedHandlesUnAckedTouchEvents) {
  ChildViewState child = MakeChildView(view_root_.get());

  // Tell the child that it has event handlers, to prevent the touch event
  // queue in the renderer host from acking the touch events immediately.
  child.widget_host->OnHasTouchEventHandlers(true);

  // Make sure we route touch events to child. This will cause the RWH's
  // InputRouter to IPC the event into the ether, from which it will never
  // return, which is perfect for this test.
  view_root_->SetHittestResult(child.view.get(), false);

  // Send a TouchStart/End sequence.
  blink::WebTouchEvent touch_start_event(
      blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_start_event.touches_length = 1;
  touch_start_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
  touch_start_event.unique_touch_event_id = 1;

  rwhier()->RouteTouchEvent(view_root_.get(), &touch_start_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));

  blink::WebTouchEvent touch_end_event(
      blink::WebInputEvent::kTouchEnd, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_end_event.touches_length = 1;
  touch_end_event.touches[0].state = blink::WebTouchPoint::kStateReleased;
  touch_end_event.unique_touch_event_id = 2;

  rwhier()->RouteTouchEvent(view_root_.get(), &touch_end_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));

  // Make sure both touch events were added to the TEAQ.
  EXPECT_EQ(2u, rwhier()->TouchEventAckQueueLengthForTesting());

  // Now, tell the router that the child view was destroyed, and verify the
  // acks.
  rwhier()->OnRenderWidgetHostViewBaseDestroyed(child.view.get());
  EXPECT_EQ(view_root_->last_id_for_touch_ack(), 2lu);
  EXPECT_EQ(0u, rwhier()->TouchEventAckQueueLengthForTesting());
}

// Ensure that when RenderWidgetHostInputEventRouter receives an unexpected
// touch event, it calls the root view's method to Ack the event before
// dropping it.
TEST_F(RenderWidgetHostInputEventRouterTest, EnsureDroppedTouchEventsAreAcked) {
  // Send a touch move without a touch start.
  blink::WebTouchEvent touch_move_event(
      blink::WebInputEvent::kTouchMove, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_move_event.touches_length = 1;
  touch_move_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
  touch_move_event.unique_touch_event_id = 1;

  rwhier()->RouteTouchEvent(view_root_.get(), &touch_move_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(view_root_->last_id_for_touch_ack(), 1lu);

  // Send a touch cancel without a touch start.
  blink::WebTouchEvent touch_cancel_event(
      blink::WebInputEvent::kTouchCancel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_cancel_event.touches_length = 1;
  touch_cancel_event.touches[0].state = blink::WebTouchPoint::kStateCancelled;
  touch_cancel_event.unique_touch_event_id = 2;

  rwhier()->RouteTouchEvent(view_root_.get(), &touch_cancel_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(view_root_->last_id_for_touch_ack(), 2lu);
}

TEST_F(RenderWidgetHostInputEventRouterTest, DoNotCoalesceTouchEvents) {
  // We require the presence of a child view, otherwise targeting is short
  // circuited.
  ChildViewState child = MakeChildView(view_root_.get());

  RenderWidgetTargeter* targeter = rwhier()->GetRenderWidgetTargeterForTests();
  view_root_->SetHittestResult(view_root_.get(), true);

  // Send TouchStart, TouchMove, TouchMove, TouchMove, TouchEnd and make sure
  // the targeter doesn't attempt to coalesce.
  blink::WebTouchEvent touch_event(
      blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_event.touches_length = 1;
  touch_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
  touch_event.unique_touch_event_id = 1;

  EXPECT_EQ(0u, targeter->num_requests_in_queue_for_testing());
  EXPECT_FALSE(targeter->is_request_in_flight_for_testing());
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(0u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  touch_event.SetType(blink::WebInputEvent::kTouchMove);
  touch_event.touches[0].state = blink::WebTouchPoint::kStateMoved;
  touch_event.unique_touch_event_id += 1;
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(1u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  touch_event.unique_touch_event_id += 1;
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(2u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  touch_event.SetType(blink::WebInputEvent::kTouchEnd);
  touch_event.touches[0].state = blink::WebTouchPoint::kStateReleased;
  touch_event.unique_touch_event_id += 1;
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));

  EXPECT_EQ(3u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());
}

TEST_F(RenderWidgetHostInputEventRouterTest, DoNotCoalesceGestureEvents) {
  // We require the presence of a child view, otherwise targeting is short
  // circuited.
  ChildViewState child = MakeChildView(view_root_.get());

  RenderWidgetTargeter* targeter = rwhier()->GetRenderWidgetTargeterForTests();
  view_root_->SetHittestResult(view_root_.get(), true);

  // Send TouchStart, GestureTapDown, TouchEnd, GestureScrollBegin,
  // GestureScrollUpdate (x2), GestureScrollEnd and make sure
  // the targeter doesn't attempt to coalesce.
  blink::WebTouchEvent touch_event(
      blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_event.touches_length = 1;
  touch_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
  touch_event.unique_touch_event_id = 1;

  EXPECT_EQ(0u, targeter->num_requests_in_queue_for_testing());
  EXPECT_FALSE(targeter->is_request_in_flight_for_testing());
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(0u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  blink::WebGestureEvent gesture_event(
      blink::WebInputEvent::kGestureTapDown, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(1u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  touch_event.SetType(blink::WebInputEvent::kTouchEnd);
  touch_event.touches[0].state = blink::WebTouchPoint::kStateReleased;
  touch_event.unique_touch_event_id += 1;
  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(2u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  gesture_event.SetType(blink::WebInputEvent::kGestureScrollBegin);
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(3u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  gesture_event.SetType(blink::WebInputEvent::kGestureScrollUpdate);
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(4u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  gesture_event.SetType(blink::WebInputEvent::kGestureScrollUpdate);
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(5u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());

  gesture_event.SetType(blink::WebInputEvent::kGestureScrollEnd);
  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(6u, targeter->num_requests_in_queue_for_testing());
  EXPECT_TRUE(targeter->is_request_in_flight_for_testing());
}

// Test that when a child view involved in scroll bubbling detaches, scroll
// bubbling is canceled.
TEST_F(RenderWidgetHostInputEventRouterTest,
       CancelScrollBubblingWhenChildDetaches) {
  gfx::Vector2dF delta(0.f, 10.f);
  blink::WebGestureEvent scroll_begin =
      SyntheticWebGestureEventBuilder::BuildScrollBegin(
          delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen);

  {
    ChildViewState child = MakeChildView(view_root_.get());

    ASSERT_TRUE(rwhier()->BubbleScrollEvent(view_root_.get(), child.view.get(),
                                            scroll_begin));
    EXPECT_EQ(child.view.get(), bubbling_gesture_scroll_origin());
    EXPECT_EQ(view_root_.get(), bubbling_gesture_scroll_target());
    EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
              view_root_->last_gesture_seen());

    rwhier()->WillDetachChildView(child.view.get());
    EXPECT_EQ(nullptr, bubbling_gesture_scroll_origin());
    EXPECT_EQ(nullptr, bubbling_gesture_scroll_target());
    EXPECT_EQ(blink::WebInputEvent::kGestureScrollEnd,
              view_root_->last_gesture_seen());
  }

  {
    ChildViewState outer = MakeChildView(view_root_.get());
    ChildViewState inner = MakeChildView(outer.view.get());

    ASSERT_TRUE(rwhier()->BubbleScrollEvent(outer.view.get(), inner.view.get(),
                                            scroll_begin));
    EXPECT_EQ(inner.view.get(), bubbling_gesture_scroll_origin());
    EXPECT_EQ(outer.view.get(), bubbling_gesture_scroll_target());
    EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
              outer.view->last_gesture_seen());
    ASSERT_TRUE(rwhier()->BubbleScrollEvent(view_root_.get(), outer.view.get(),
                                            scroll_begin));
    EXPECT_EQ(inner.view.get(), bubbling_gesture_scroll_origin());
    EXPECT_EQ(view_root_.get(), bubbling_gesture_scroll_target());
    EXPECT_EQ(blink::WebInputEvent::kGestureScrollEnd,
              outer.view->last_gesture_seen());
    EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
              view_root_->last_gesture_seen());

    rwhier()->WillDetachChildView(outer.view.get());
    EXPECT_EQ(nullptr, bubbling_gesture_scroll_origin());
    EXPECT_EQ(nullptr, bubbling_gesture_scroll_target());
    EXPECT_EQ(blink::WebInputEvent::kGestureScrollEnd,
              view_root_->last_gesture_seen());
  }
}

// Test that when a child view that is irrelevant to any ongoing scroll
// bubbling detaches, scroll bubbling is not canceled.
TEST_F(RenderWidgetHostInputEventRouterTest,
       ContinueScrollBubblingWhenIrrelevantChildDetaches) {
  gfx::Vector2dF delta(0.f, 10.f);
  blink::WebGestureEvent scroll_begin =
      SyntheticWebGestureEventBuilder::BuildScrollBegin(
          delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen);

  ChildViewState outer = MakeChildView(view_root_.get());
  ChildViewState inner = MakeChildView(outer.view.get());

  ASSERT_TRUE(rwhier()->BubbleScrollEvent(view_root_.get(), outer.view.get(),
                                          scroll_begin));
  EXPECT_EQ(outer.view.get(), bubbling_gesture_scroll_origin());
  EXPECT_EQ(view_root_.get(), bubbling_gesture_scroll_target());
  EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
            view_root_->last_gesture_seen());

  rwhier()->WillDetachChildView(inner.view.get());
  EXPECT_EQ(outer.view.get(), bubbling_gesture_scroll_origin());
  EXPECT_EQ(view_root_.get(), bubbling_gesture_scroll_target());
  EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
            view_root_->last_gesture_seen());
}

void RenderWidgetHostInputEventRouterTest::TestSendNewGestureWhileBubbling(
    TestRenderWidgetHostViewChildFrame* bubbling_origin,
    RenderWidgetHostViewBase* gesture_target,
    bool should_cancel) {
  gfx::Vector2dF delta(0.f, 10.f);
  blink::WebGestureEvent scroll_begin =
      SyntheticWebGestureEventBuilder::BuildScrollBegin(
          delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen);

  TestRenderWidgetHostViewChildFrame* cur_target = bubbling_origin;
  RenderWidgetHostViewBase* parent = bubbling_origin->GetParentView();
  while (parent) {
    ASSERT_TRUE(rwhier()->BubbleScrollEvent(parent, cur_target, scroll_begin));
    EXPECT_EQ(bubbling_origin, bubbling_gesture_scroll_origin());
    EXPECT_EQ(parent, bubbling_gesture_scroll_target());
    if (cur_target != bubbling_origin) {
      EXPECT_EQ(blink::WebInputEvent::kGestureScrollEnd,
                cur_target->last_gesture_seen());
    }

    if (parent->IsRenderWidgetHostViewChildFrame()) {
      TestRenderWidgetHostViewChildFrame* next_child =
          static_cast<TestRenderWidgetHostViewChildFrame*>(parent);
      EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
                next_child->last_gesture_seen());
      cur_target = next_child;
      parent = next_child->GetParentView();
    } else {
      MockRootRenderWidgetHostView* root =
          static_cast<MockRootRenderWidgetHostView*>(parent);
      EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
                root->last_gesture_seen());
      parent = nullptr;
    }
  }

  // While bubbling scroll, a new gesture is targeted to |gesture_target|.

  view_root_->SetHittestResult(gesture_target, false);

  blink::WebTouchEvent touch_event(
      blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_event.touches_length = 1;
  touch_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
  touch_event.unique_touch_event_id = 123;

  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(gesture_target, touch_target());

  blink::WebGestureEvent gesture_event(
      blink::WebInputEvent::kGestureTapDown, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;

  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(gesture_target, touchscreen_gesture_target());

  if (should_cancel) {
    EXPECT_EQ(nullptr, bubbling_gesture_scroll_origin());
    EXPECT_EQ(nullptr, bubbling_gesture_scroll_target());
  } else {
    EXPECT_NE(nullptr, bubbling_gesture_scroll_origin());
    EXPECT_NE(nullptr, bubbling_gesture_scroll_target());
  }
}

// If we're bubbling scroll to a view and a new gesture is to be targeted to
// that view, cancel scroll bubbling, so that the view does not have multiple
// gestures happening at the same time.
TEST_F(RenderWidgetHostInputEventRouterTest,
       CancelBubblingOnNewGestureToBubblingTarget) {
  ChildViewState child = MakeChildView(view_root_.get());

  TestSendNewGestureWhileBubbling(child.view.get(), view_root_.get(), true);
}

// Like CancelBubblingOnNewGestureToBubblingTarget, but tests that we also
// cancel in the case of nested bubbling.
TEST_F(RenderWidgetHostInputEventRouterTest,
       CancelNestedBubblingOnNewGestureToBubblingTarget) {
  ChildViewState outer = MakeChildView(view_root_.get());
  ChildViewState inner = MakeChildView(outer.view.get());

  TestSendNewGestureWhileBubbling(inner.view.get(), view_root_.get(), true);
}

// If we're bubbling scroll and a new gesture is to be targeted to an
// intermediate bubbling target, cancel scroll bubbling.
TEST_F(RenderWidgetHostInputEventRouterTest,
       CancelNestedBubblingOnNewGestureToIntermediateTarget) {
  ChildViewState outer = MakeChildView(view_root_.get());
  ChildViewState inner = MakeChildView(outer.view.get());

  TestSendNewGestureWhileBubbling(inner.view.get(), outer.view.get(), true);
}

// If we're bubbling scroll, the child that is bubbling may receive a new
// gesture. Since this doesn't conflict with the bubbling, we should not
// cancel it.
TEST_F(RenderWidgetHostInputEventRouterTest,
       ContinueBubblingOnNewGestureToBubblingOrigin) {
  ChildViewState child = MakeChildView(view_root_.get());

  TestSendNewGestureWhileBubbling(child.view.get(), child.view.get(), false);
}

// If a view tries to bubble a scroll sequence while we are already bubbling
// a scroll sequence from another view, do not bubble the conflicting sequence.
TEST_F(RenderWidgetHostInputEventRouterTest, DoNotBubbleMultipleSequences) {
  gfx::Vector2dF delta(0.f, 10.f);
  blink::WebGestureEvent scroll_begin =
      SyntheticWebGestureEventBuilder::BuildScrollBegin(
          delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen);

  ChildViewState outer1 = MakeChildView(view_root_.get());
  ChildViewState inner1 = MakeChildView(outer1.view.get());
  ChildViewState outer2 = MakeChildView(view_root_.get());
  ChildViewState inner2 = MakeChildView(outer2.view.get());

  ASSERT_TRUE(rwhier()->BubbleScrollEvent(outer1.view.get(), inner1.view.get(),
                                          scroll_begin));
  EXPECT_EQ(inner1.view.get(), bubbling_gesture_scroll_origin());
  EXPECT_EQ(outer1.view.get(), bubbling_gesture_scroll_target());
  EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
            outer1.view->last_gesture_seen());

  EXPECT_FALSE(rwhier()->BubbleScrollEvent(outer2.view.get(), inner2.view.get(),
                                           scroll_begin));

  EXPECT_EQ(inner1.view.get(), bubbling_gesture_scroll_origin());
  EXPECT_EQ(outer1.view.get(), bubbling_gesture_scroll_target());
}

// If a view tries to bubble scroll and the target view has an unrelated
// gesture in progress, do not bubble the conflicting sequence.
TEST_F(RenderWidgetHostInputEventRouterTest,
       DoNotBubbleIfUnrelatedGestureInTarget) {
  gfx::Vector2dF delta(0.f, 10.f);
  blink::WebGestureEvent scroll_begin =
      SyntheticWebGestureEventBuilder::BuildScrollBegin(
          delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen);

  ChildViewState child = MakeChildView(view_root_.get());

  view_root_->SetHittestResult(view_root_.get(), false);

  blink::WebTouchEvent touch_event(
      blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_event.touches_length = 1;
  touch_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
  touch_event.unique_touch_event_id = 123;

  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(view_root_.get(), touch_target());

  blink::WebGestureEvent gesture_event(
      blink::WebInputEvent::kGestureTapDown, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;

  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(view_root_.get(), touchscreen_gesture_target());

  // Now that we have a gesture in |view_root_|, suppose that there was a
  // previous gesture in |child.view| that has resulted in a scroll which we
  // will now attempt to bubble.

  EXPECT_FALSE(rwhier()->BubbleScrollEvent(view_root_.get(), child.view.get(),
                                           scroll_begin));
  EXPECT_EQ(nullptr, bubbling_gesture_scroll_origin());
  EXPECT_EQ(nullptr, bubbling_gesture_scroll_target());
}

// Like DoNotBubbleIfUnrelatedGestureInTarget, but considers bubbling from a
// nested view.
TEST_F(RenderWidgetHostInputEventRouterTest,
       NestedDoNotBubbleIfUnrelatedGestureInTarget) {
  gfx::Vector2dF delta(0.f, 10.f);
  blink::WebGestureEvent scroll_begin =
      SyntheticWebGestureEventBuilder::BuildScrollBegin(
          delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen);

  ChildViewState outer = MakeChildView(view_root_.get());
  ChildViewState inner = MakeChildView(outer.view.get());

  view_root_->SetHittestResult(view_root_.get(), false);

  blink::WebTouchEvent touch_event(
      blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  touch_event.touches_length = 1;
  touch_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
  touch_event.unique_touch_event_id = 123;

  rwhier()->RouteTouchEvent(view_root_.get(), &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(view_root_.get(), touch_target());

  blink::WebGestureEvent gesture_event(
      blink::WebInputEvent::kGestureTapDown, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_event.unique_touch_event_id = touch_event.unique_touch_event_id;

  rwhier()->RouteGestureEvent(view_root_.get(), &gesture_event,
                              ui::LatencyInfo(ui::SourceEventType::TOUCH));
  EXPECT_EQ(view_root_.get(), touchscreen_gesture_target());

  // Now that we have a gesture in |view_root_|, suppose that there was a
  // previous gesture in |inner.view| that has resulted in a scroll which we
  // will now attempt to bubble.

  // Bubbling to |outer.view| is fine, since it doesn't interfere with the
  // gesture in |view_root_|.
  ASSERT_TRUE(rwhier()->BubbleScrollEvent(outer.view.get(), inner.view.get(),
                                          scroll_begin));
  EXPECT_EQ(inner.view.get(), bubbling_gesture_scroll_origin());
  EXPECT_EQ(outer.view.get(), bubbling_gesture_scroll_target());
  EXPECT_EQ(blink::WebInputEvent::kGestureScrollBegin,
            outer.view->last_gesture_seen());

  // We cannot bubble any further, as that would interfere with the gesture in
  // |view_root_|.
  EXPECT_FALSE(rwhier()->BubbleScrollEvent(view_root_.get(), outer.view.get(),
                                           scroll_begin));
  EXPECT_NE(view_root_.get(), bubbling_gesture_scroll_target());
}

}  // namespace content
