Commit 7751fadb authored by Jonathan Ross's avatar Jonathan Ross Committed by Commit Bot

Mock Viz Hit Testing in RenderWidgetHostInputEventRouterTest

RenderWidgetHostInputEventRouterTest has some heavy overrides of the classic hit testing path, to force what target is used when. With these the test never actually set sizes, or correct FrameSinkIds, on the views in use.

However in Viz RenderWidgetHostInputEventRouter::FindViewAtLocation uses a
completely different method for determining targets while in Viz Hit Testing
Mode.

This change updates the test to als provide mock hit testing data.

A test wrapper HostFrameSinkManagerTestApi was added to allow for the setting
of hit testing data while in unittests. Or in testing where Viz is not actually
initialized.

TEST=RenderWidgetHostInputEventRouterTest

Bug: 796605
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel
Change-Id: I66c4322f70fdd8c5be07c3560110519153370cff
Reviewed-on: https://chromium-review.googlesource.com/1145773
Commit-Queue: Jonathan Ross <jonross@chromium.org>
Reviewed-by: default avatarRia Jiang <riajiang@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578723}
parent 2e857b37
......@@ -179,6 +179,7 @@ class VIZ_HOST_EXPORT HostFrameSinkManager
uint32_t frame_token) override;
private:
friend class HostFrameSinkManagerTestApi;
friend class HostFrameSinkManagerTestBase;
struct FrameSinkData {
......
......@@ -25,6 +25,8 @@ viz_static_library("test_support") {
"fake_output_surface.h",
"fake_surface_observer.cc",
"fake_surface_observer.h",
"host_frame_sink_manager_test_api.cc",
"host_frame_sink_manager_test_api.h",
"mock_compositor_frame_sink_client.cc",
"mock_compositor_frame_sink_client.h",
"mock_display_client.cc",
......
// Copyright 2018 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 "components/viz/test/host_frame_sink_manager_test_api.h"
namespace viz {
HostFrameSinkManagerTestApi::HostFrameSinkManagerTestApi(
HostFrameSinkManager* host_frame_sink_manager)
: host_frame_sink_manager_(host_frame_sink_manager) {}
void HostFrameSinkManagerTestApi::SetDisplayHitTestQuery(
HostFrameSinkManager::DisplayHitTestQueryMap map) {
host_frame_sink_manager_->display_hit_test_query_.clear();
host_frame_sink_manager_->display_hit_test_query_ = std::move(map);
}
} // namespace viz
// Copyright 2018 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.
#ifndef COMPONENTS_VIZ_TEST_HOST_FRAME_SINK_MANAGER_TEST_API_H_
#define COMPONENTS_VIZ_TEST_HOST_FRAME_SINK_MANAGER_TEST_API_H_
#include "base/macros.h"
#include "components/viz/host/host_frame_sink_manager.h"
namespace viz {
// A test wrapper for HostFrameSinkManager. For use in unit testing, where the
// Viz Host never instanciates Viz. Without Viz, HostFrameSinkManager can never
// actually establish connections to compositor frame sinks.
//
// This allows for the explicit overriding of the hit test data with the
// HostFrameSinkManager. So that unit tests can test event routing without Viz
// providing the hit test data.
class HostFrameSinkManagerTestApi {
public:
explicit HostFrameSinkManagerTestApi(
HostFrameSinkManager* host_frame_sink_manager);
~HostFrameSinkManagerTestApi() = default;
// Clears out the currently set hit test queries, and overrides it with |map|.
// The HostFrameSinkManager will take ownership of |map|. There should only be
// one HitTestQuery per root FrameSinkId.
void SetDisplayHitTestQuery(HostFrameSinkManager::DisplayHitTestQueryMap map);
private:
// Not owned.
HostFrameSinkManager* host_frame_sink_manager_;
DISALLOW_COPY_AND_ASSIGN(HostFrameSinkManagerTestApi);
};
} // namespace viz
#endif // COMPONENTS_VIZ_TEST_HOST_FRAME_SINK_MANAGER_TEST_API_H_
......@@ -4,9 +4,17 @@
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include <vector>
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "components/viz/common/features.h"
#include "components/viz/common/hit_test/aggregated_hit_test_region.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"
......@@ -53,6 +61,7 @@ class TestRenderWidgetHostViewChildFrame
public:
explicit TestRenderWidgetHostViewChildFrame(RenderWidgetHost* widget)
: RenderWidgetHostViewChildFrame(widget),
frame_sink_id_(2, 1),
last_gesture_seen_(blink::WebInputEvent::kUndefined) {}
~TestRenderWidgetHostViewChildFrame() override = default;
......@@ -66,12 +75,22 @@ class TestRenderWidgetHostViewChildFrame
unique_id_for_last_touch_ack_ = touch.event.unique_touch_event_id;
}
void SetBounds(const gfx::Rect& rect) override { bounds_ = rect; }
gfx::Rect GetViewBounds() const override { return bounds_; }
const viz::FrameSinkId& GetFrameSinkId() const override {
return frame_sink_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:
gfx::Rect bounds_;
viz::FrameSinkId frame_sink_id_;
blink::WebInputEvent::Type last_gesture_seen_;
uint32_t unique_id_for_last_touch_ack_ = 0;
};
......@@ -85,6 +104,7 @@ class MockRootRenderWidgetHostView : public TestRenderWidgetHostView {
RenderWidgetHost* rwh,
std::map<RenderWidgetHostViewBase*, viz::FrameSinkId>& frame_sink_id_map)
: TestRenderWidgetHostView(rwh),
frame_sink_id_(1, 1),
frame_sink_id_map_(frame_sink_id_map),
current_hittest_result_(nullptr),
force_query_renderer_on_hit_test_(false),
......@@ -120,6 +140,16 @@ class MockRootRenderWidgetHostView : public TestRenderWidgetHostView {
unique_id_for_last_touch_ack_ = touch.event.unique_touch_event_id;
}
void SetBounds(const gfx::Rect& rect) override { bounds_ = rect; }
gfx::Rect GetViewBounds() const override { return bounds_; }
const viz::FrameSinkId& GetFrameSinkId() const override {
return frame_sink_id_;
}
viz::FrameSinkId GetRootFrameSinkId() override { return frame_sink_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_; }
......@@ -134,6 +164,8 @@ class MockRootRenderWidgetHostView : public TestRenderWidgetHostView {
void Reset() { last_gesture_seen_ = blink::WebInputEvent::kUndefined; }
private:
gfx::Rect bounds_;
viz::FrameSinkId frame_sink_id_;
std::map<RenderWidgetHostViewBase*, viz::FrameSinkId>& frame_sink_id_map_;
RenderWidgetHostViewBase* current_hittest_result_;
bool force_query_renderer_on_hit_test_;
......@@ -147,6 +179,12 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test {
public:
RenderWidgetHostInputEventRouterTest() {}
// Initializes the hit testing data required when
// features::IsVizHitTestingEnabled. Where both |view_root_flags| and
// |view_other_flags| are viz::HitTestRegionFlags, representing the type of
// events to be responded to by each view, along with how they are processed.
void InitVizHitTestData(int view_root_flags, int view_other_flags);
protected:
// testing::Test:
void SetUp() override {
......@@ -189,8 +227,8 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test {
// Set up the RWHIER's FrameSinkId to RWHV map so that we can control the
// result of RWHIER's hittesting.
frame_sink_id_map_ = {{view_root_.get(), viz::FrameSinkId(1, 1)},
{view_other_.get(), viz::FrameSinkId(2, 2)}};
frame_sink_id_map_ = {{view_root_.get(), view_root_->GetFrameSinkId()},
{view_other_.get(), view_other_->GetFrameSinkId()}};
rwhier_.AddFrameSinkIdOwner(frame_sink_id_map_[view_root_.get()],
view_root_.get());
rwhier_.AddFrameSinkIdOwner(frame_sink_id_map_[view_other_.get()],
......@@ -217,6 +255,8 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test {
MockRenderWidgetHostDelegate delegate_;
std::unique_ptr<BrowserContext> browser_context_;
std::unique_ptr<viz::HostFrameSinkManagerTestApi>
host_frame_sink_manager_test_api_;
std::unique_ptr<MockRenderProcessHost> process_host1_;
std::unique_ptr<MockRenderProcessHost> process_host2_;
std::unique_ptr<MockWidgetImpl> widget_impl1_;
......@@ -236,6 +276,42 @@ class RenderWidgetHostInputEventRouterTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostInputEventRouterTest);
};
void RenderWidgetHostInputEventRouterTest::InitVizHitTestData(
int view_root_flags,
int view_other_flags) {
if (!features::IsVizHitTestingEnabled())
return;
DCHECK(GetHostFrameSinkManager());
// Bounds chosen so that both |view_root_| and |view_other_| occupy (0, 0);
// the default position in WebPointerProperties. This is done as the test
// suite overrides enough of the classic hit testing path that there the
// bounds do not matter. However Viz hit-testing always performs a contains
// check on input events. This allows both views to handle the input
// targetting in the tests below.
view_root_->SetBounds(gfx::Rect(0, 0, 10, 10));
view_other_->SetBounds(gfx::Rect(0, 0, 10, 5));
host_frame_sink_manager_test_api_ =
std::make_unique<viz::HostFrameSinkManagerTestApi>(
GetHostFrameSinkManager());
viz::HostFrameSinkManager::DisplayHitTestQueryMap hit_test_map;
hit_test_map[view_root_->GetFrameSinkId()] =
std::make_unique<viz::HitTestQuery>();
std::vector<viz::AggregatedHitTestRegion> hit_test_data;
hit_test_data.push_back(viz::AggregatedHitTestRegion(
view_root_->GetFrameSinkId(), view_root_flags,
view_root_->GetViewBounds(), gfx::Transform(), 1));
hit_test_data.push_back(viz::AggregatedHitTestRegion(
view_other_->GetFrameSinkId(), view_other_flags,
view_other_->GetViewBounds(), gfx::Transform(), 0));
hit_test_map[view_root_->GetFrameSinkId()]
->OnAggregatedHitTestRegionListUpdated(hit_test_data);
host_frame_sink_manager_test_api_->SetDisplayHitTestQuery(
std::move(hit_test_map));
}
// 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.
......@@ -247,6 +323,11 @@ TEST_F(RenderWidgetHostInputEventRouterTest,
// We start the touch in the area for |view_other_|.
view_root_->SetHittestResult(view_other_.get());
// Each view will want to process the touch event.
InitVizHitTestData(viz::HitTestRegionFlags::kHitTestTouch |
viz::HitTestRegionFlags::kHitTestMine,
viz::HitTestRegionFlags::kHitTestTouch |
viz::HitTestRegionFlags::kHitTestMine);
blink::WebTouchEvent touch_event(
blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
......@@ -299,9 +380,20 @@ TEST_F(RenderWidgetHostInputEventRouterTest,
rwhier_.RouteGestureEvent(view_root_.get(), &gesture_event,
ui::LatencyInfo(ui::SourceEventType::TOUCH));
// Now the touch moves out of |view_other_| and into |view_root_|, but
// |view_other_| should continue to be the target for gesture events.
// The continuation of the touch moves should maintain their current target of
// |view_other_|, even if they move outside of that view, and into
// |view_root_|.
//
// Since this test is not using actual view sizes, nor event positions, we
// need to setup our hit testing overrides to prevent targeting |view_other_|.
//
// 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());
InitVizHitTestData(viz::HitTestRegionFlags::kHitTestTouch |
viz::HitTestRegionFlags::kHitTestMine,
viz::HitTestRegionFlags::kHitTestTouch |
viz::HitTestRegionFlags::kHitTestIgnore);
view_root_->Reset();
view_other_->Reset();
......@@ -369,6 +461,13 @@ TEST_F(RenderWidgetHostInputEventRouterTest, DoNotCoalesceTouchEvents) {
RenderWidgetTargeter* targeter = rwhier_.GetRenderWidgetTargeterForTests();
view_root_->SetHittestResult(view_root_.get());
view_root_->set_force_query_renderer_on_hit_test(true);
// Also force the renderer to be queried.
InitVizHitTestData(viz::HitTestRegionFlags::kHitTestTouch |
viz::HitTestRegionFlags::kHitTestMine |
viz::HitTestRegionFlags::kHitTestAsk,
viz::HitTestRegionFlags::kHitTestTouch |
viz::HitTestRegionFlags::kHitTestMine |
viz::HitTestRegionFlags::kHitTestAsk);
// 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
......@@ -423,6 +522,13 @@ TEST_F(RenderWidgetHostInputEventRouterTest, DoNotCoalesceGestureEvents) {
RenderWidgetTargeter* targeter = rwhier_.GetRenderWidgetTargeterForTests();
view_root_->SetHittestResult(view_root_.get());
view_root_->set_force_query_renderer_on_hit_test(true);
// Also force the renderer to be queried.
InitVizHitTestData(viz::HitTestRegionFlags::kHitTestTouch |
viz::HitTestRegionFlags::kHitTestMine |
viz::HitTestRegionFlags::kHitTestAsk,
viz::HitTestRegionFlags::kHitTestTouch |
viz::HitTestRegionFlags::kHitTestMine |
viz::HitTestRegionFlags::kHitTestAsk);
// 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
......
# Not finding the correct target crbug.com/796605
-RenderWidgetHostInputEventRouterTest.DoNotChangeTargetViewDuringTouchScrollGesture
-RenderWidgetHostInputEventRouterTest.DoNotCoalesceGestureEvents
-RenderWidgetHostInputEventRouterTest.DoNotCoalesceTouchEvents
# TODO(crbug.com/601869): Reflector needs to be rewritten for viz.
-ReflectorImplTest.*
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment