Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Unified Diff: components/viz/host/hit_test/hit_test_query_unittest.cc

Issue 2933493003: Add viz-host HitTestQuery. (Closed)
Patch Set: don't combine uint and int; check for overflow Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/viz/host/hit_test/hit_test_query_unittest.cc
diff --git a/components/viz/host/hit_test/hit_test_query_unittest.cc b/components/viz/host/hit_test/hit_test_query_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1f9eadccc30c00d9b062c3efd5e0da0f13fd7f93
--- /dev/null
+++ b/components/viz/host/hit_test/hit_test_query_unittest.cc
@@ -0,0 +1,627 @@
+// 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 "components/viz/host/hit_test/hit_test_query.h"
+
+#include <cstdint>
+
+#include "services/viz/hit_test/public/interfaces/hit_test_region_list.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace viz {
+namespace test {
+
+class HitTestQueryTest : public testing::Test {
+ public:
+ HitTestQueryTest() = default;
+ ~HitTestQueryTest() override = default;
+
+ HitTestQuery hit_test_query_;
+
+ private:
+ // testing::Test:
+ void SetUp() override {}
+ void TearDown() override {}
+
+ DISALLOW_COPY_AND_ASSIGN(HitTestQueryTest);
+};
+
+// One surface.
+//
+// +e---------+
+// | |
+// | |
+// | |
+// +----------+
+//
+TEST_F(HitTestQueryTest, OneSurface) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ gfx::Rect e_bounds = gfx::Rect(0, 0, 600, 600);
+ gfx::Transform transform_e_to_e;
+ AggregatedHitTestRegion aggregated_hit_test_region_list[1] = {
+ {e_id, mojom::kHitTestMine, e_bounds, transform_e_to_e, 0} // e
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list, 1);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(1, 1);
+ gfx::Point point2(600, 600);
+ gfx::Point point3(0, 0);
+
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(e_id, target1.frame_sink_id);
+ EXPECT_EQ(point1, target1.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target1.flags);
+
+ // point2 is on the bounds of e so no target found.
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(FrameSinkId(), target2.frame_sink_id);
+ EXPECT_EQ(gfx::Point(), target2.location_in_target);
+ EXPECT_FALSE(target2.flags);
+
+ // There's a valid Target for point3, see Rect::Contains.
+ Target target3 = hit_test_query_.FindTargetForLocation(point3);
+ EXPECT_EQ(e_id, target3.frame_sink_id);
+ EXPECT_EQ(point3, target3.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target3.flags);
+}
+
+// One embedder with two children.
+//
+// +e------------+ Point maps to
+// | +c1-+ +c2---| ----- -------
+// |1| | | | 1 e
+// | | 2 | | 3 | 4 2 c1
+// | +---+ | | 3 c2
+// +-------------+ 4 none
+//
+TEST_F(HitTestQueryTest, OneEmbedderTwoChildren) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ FrameSinkId c1_id = FrameSinkId(2, 2);
+ FrameSinkId c2_id = FrameSinkId(3, 3);
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600);
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 200, 200);
+ gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 400, 400);
+ gfx::Transform transform_e_to_e, transform_e_to_c1, transform_e_to_c2;
+ transform_e_to_c1.Translate(-100, -100);
+ transform_e_to_c2.Translate(-300, -300);
+ AggregatedHitTestRegion aggregated_hit_test_region_list[3] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 2}, // e
+ {c1_id, mojom::kHitTestMine, c1_bounds_in_e, transform_e_to_c1, 0}, // c1
+ {c2_id, mojom::kHitTestMine, c2_bounds_in_e, transform_e_to_c2, 0} // c2
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list, 3);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(99, 200);
+ gfx::Point point2(150, 150);
+ gfx::Point point3(400, 400);
+ gfx::Point point4(650, 350);
+
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(e_id, target1.frame_sink_id);
+ EXPECT_EQ(point1, target1.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target1.flags);
+
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(c1_id, target2.frame_sink_id);
+ EXPECT_EQ(gfx::Point(50, 50), target2.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target2.flags);
+
+ Target target3 = hit_test_query_.FindTargetForLocation(point3);
+ EXPECT_EQ(c2_id, target3.frame_sink_id);
+ EXPECT_EQ(gfx::Point(100, 100), target3.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target3.flags);
+
+ Target target4 = hit_test_query_.FindTargetForLocation(point4);
+ EXPECT_EQ(FrameSinkId(), target4.frame_sink_id);
+ EXPECT_EQ(gfx::Point(), target4.location_in_target);
+ EXPECT_FALSE(target4.flags);
+}
+
+// One embedder with a rotated child.
+TEST_F(HitTestQueryTest, OneEmbedderRotatedChild) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ FrameSinkId c_id = FrameSinkId(2, 2);
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600);
+ gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 1000, 1000);
+ gfx::Transform transform_e_to_e, transform_e_to_c;
+ transform_e_to_c.Translate(-100, -100);
+ transform_e_to_c.Skew(2, 3);
+ transform_e_to_c.Scale(.5f, .7f);
+
+ AggregatedHitTestRegion aggregated_hit_test_region_list[2] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 1}, // e
+ {c_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c_bounds_in_e,
+ transform_e_to_c, 0} // c
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list, 2);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(150, 120); // Point(-22, -12) after transform.
+ gfx::Point point2(550, 400); // Point(185, 194) after transform.
+
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(e_id, target1.frame_sink_id);
+ EXPECT_EQ(point1, target1.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target1.flags);
+
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(c_id, target2.frame_sink_id);
+ EXPECT_EQ(gfx::Point(185, 194), target2.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags);
+}
+
+// One embedder with a clipped child with a tab and transparent background.
+//
+// +e-------------+
+// | +c---------| Point maps to
+// | 1 |+a--+ | ----- -------
+// | || 2 | 3 | 1 e
+// | |+b--------| 2 a
+// | || | 3 e ( transparent area in c )
+// | || 4 | 4 b
+// +--------------+
+//
+TEST_F(HitTestQueryTest, ClippedChildWithTabAndTransparentBackground) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ FrameSinkId c_id = FrameSinkId(2, 2);
+ FrameSinkId a_id = FrameSinkId(3, 3);
+ FrameSinkId b_id = FrameSinkId(4, 4);
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600);
+ gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 800, 800);
+ gfx::Rect a_bounds_in_c = gfx::Rect(0, 0, 200, 100);
+ gfx::Rect b_bounds_in_c = gfx::Rect(0, 0, 800, 600);
+ gfx::Transform transform_e_to_e, transform_e_to_c, transform_c_to_a,
+ transform_c_to_b;
+ transform_e_to_c.Translate(-200, -100);
+ transform_c_to_b.Translate(0, -100);
+ AggregatedHitTestRegion aggregated_hit_test_region_list[4] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3}, // e
+ {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
+ transform_e_to_c, 2}, // c
+ {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
+ transform_c_to_a, 0}, // a
+ {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
+ transform_c_to_b, 0} // b
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list, 4);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(1, 1);
+ gfx::Point point2(202, 102);
+ gfx::Point point3(403, 103);
+ gfx::Point point4(202, 202);
+
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(e_id, target1.frame_sink_id);
+ EXPECT_EQ(point1, target1.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target1.flags);
+
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(a_id, target2.frame_sink_id);
+ EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags);
+
+ Target target3 = hit_test_query_.FindTargetForLocation(point3);
+ EXPECT_EQ(e_id, target3.frame_sink_id);
+ EXPECT_EQ(point3, target3.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target3.flags);
+
+ Target target4 = hit_test_query_.FindTargetForLocation(point4);
+ EXPECT_EQ(b_id, target4.frame_sink_id);
+ EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target4.flags);
+}
+
+// One embedder with a clipped child with a tab and transparent background, and
+// a child d under that.
+//
+// +e-------------+
+// | +d------|
+// | +c-|-------| Point maps to
+// | 1 |+a|-+ | ----- -------
+// | || 2 | 3 | 1 e
+// | |+b|-------| 2 a
+// | || | | 3 d
+// | || | 4 | 4 b
+// +--------------+
+//
+TEST_F(HitTestQueryTest, ClippedChildWithChildUnderneath) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ FrameSinkId c_id = FrameSinkId(2, 2);
+ FrameSinkId a_id = FrameSinkId(3, 3);
+ FrameSinkId b_id = FrameSinkId(4, 4);
+ FrameSinkId d_id = FrameSinkId(5, 5);
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600);
+ gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 800, 800);
+ gfx::Rect a_bounds_in_c = gfx::Rect(0, 0, 200, 100);
+ gfx::Rect b_bounds_in_c = gfx::Rect(0, 0, 800, 600);
+ gfx::Rect d_bounds_in_e = gfx::Rect(0, 0, 800, 800);
+ gfx::Transform transform_e_to_e, transform_e_to_c, transform_c_to_a,
+ transform_c_to_b, transform_e_to_d;
+ transform_e_to_c.Translate(-200, -100);
+ transform_c_to_b.Translate(0, -100);
+ transform_e_to_d.Translate(-400, -50);
+ AggregatedHitTestRegion aggregated_hit_test_region_list[5] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 4}, // e
+ {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
+ transform_e_to_c, 2}, // c
+ {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
+ transform_c_to_a, 0}, // a
+ {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
+ transform_c_to_b, 0}, // b
+ {d_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, d_bounds_in_e,
+ transform_e_to_d, 0} // d
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list, 5);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(1, 1);
+ gfx::Point point2(202, 102);
+ gfx::Point point3(450, 150);
+ gfx::Point point4(202, 202);
+
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(e_id, target1.frame_sink_id);
+ EXPECT_EQ(point1, target1.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target1.flags);
+
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(a_id, target2.frame_sink_id);
+ EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags);
+
+ Target target3 = hit_test_query_.FindTargetForLocation(point3);
+ EXPECT_EQ(d_id, target3.frame_sink_id);
+ EXPECT_EQ(gfx::Point(50, 100), target3.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target3.flags);
+
+ Target target4 = hit_test_query_.FindTargetForLocation(point4);
+ EXPECT_EQ(b_id, target4.frame_sink_id);
+ EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target4.flags);
+}
+
+// One embedder with two clipped children with a tab and transparent background.
+//
+// +e-------------+
+// | +c1--------| Point maps to
+// | 1 |+a--+ | ----- -------
+// | || 2 | 3 | 1 e
+// | |+b--------| 2 a
+// | || | 3 e ( transparent area in c1 )
+// | || 4 | 4 b
+// | +----------| 5 g
+// | +c2--------| 6 e ( transparent area in c2 )
+// | |+g--+ | 7 h
+// | || 5 | 6 |
+// | |+h--------|
+// | || |
+// | || 7 |
+// +--------------+
+//
+TEST_F(HitTestQueryTest, ClippedChildrenWithTabAndTransparentBackground) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ FrameSinkId c1_id = FrameSinkId(2, 2);
+ FrameSinkId a_id = FrameSinkId(3, 3);
+ FrameSinkId b_id = FrameSinkId(4, 4);
+ FrameSinkId c2_id = FrameSinkId(5, 5);
+ FrameSinkId g_id = FrameSinkId(6, 6);
+ FrameSinkId h_id = FrameSinkId(7, 7);
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 1200);
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 500);
+ gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 200, 100);
+ gfx::Rect b_bounds_in_c1 = gfx::Rect(0, 0, 800, 400);
+ gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 500);
+ gfx::Rect g_bounds_in_c2 = gfx::Rect(0, 0, 200, 100);
+ gfx::Rect h_bounds_in_c2 = gfx::Rect(0, 0, 800, 800);
+ gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a,
+ transform_c1_to_b, transform_e_to_c2, transform_c2_to_g,
+ transform_c2_to_h;
+ transform_e_to_c1.Translate(-200, -100);
+ transform_c1_to_b.Translate(0, -100);
+ transform_e_to_c2.Translate(-200, -700);
+ transform_c2_to_h.Translate(0, -100);
+ AggregatedHitTestRegion aggregated_hit_test_region_list[7] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 6}, // e
+ {c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
+ c1_bounds_in_e, transform_e_to_c1, 2}, // c1
+ {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c1,
+ transform_c1_to_a, 0}, // a
+ {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c1,
+ transform_c1_to_b, 0}, // b
+ {c2_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
+ c2_bounds_in_e, transform_e_to_c2, 2}, // c2
+ {g_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, g_bounds_in_c2,
+ transform_c2_to_g, 0}, // g
+ {h_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, h_bounds_in_c2,
+ transform_c2_to_h, 0} // h
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list, 7);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(1, 1);
+ gfx::Point point2(202, 102);
+ gfx::Point point3(403, 103);
+ gfx::Point point4(202, 202);
+ gfx::Point point5(250, 750);
+ gfx::Point point6(450, 750);
+ gfx::Point point7(350, 1100);
+
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(e_id, target1.frame_sink_id);
+ EXPECT_EQ(point1, target1.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target1.flags);
+
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(a_id, target2.frame_sink_id);
+ EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags);
+
+ Target target3 = hit_test_query_.FindTargetForLocation(point3);
+ EXPECT_EQ(e_id, target3.frame_sink_id);
+ EXPECT_EQ(point3, target3.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target3.flags);
+
+ Target target4 = hit_test_query_.FindTargetForLocation(point4);
+ EXPECT_EQ(b_id, target4.frame_sink_id);
+ EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target4.flags);
+
+ Target target5 = hit_test_query_.FindTargetForLocation(point5);
+ EXPECT_EQ(g_id, target5.frame_sink_id);
+ EXPECT_EQ(gfx::Point(50, 50), target5.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target5.flags);
+
+ Target target6 = hit_test_query_.FindTargetForLocation(point6);
+ EXPECT_EQ(e_id, target6.frame_sink_id);
+ EXPECT_EQ(point6, target6.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target6.flags);
+
+ Target target7 = hit_test_query_.FindTargetForLocation(point7);
+ EXPECT_EQ(h_id, target7.frame_sink_id);
+ EXPECT_EQ(gfx::Point(150, 300), target7.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target7.flags);
+}
+
+// Children that are multiple layers deep.
+//
+// +e--------------------+
+// | +c2--------| Point maps to
+// | +c1------|----+ | ----- -------
+// |1| +a-----|---+| | 1 e
+// | | |+b----|--+|| | 2 g
+// | | ||+g--+| ||| | 3 b
+// | | ||| 2 || 3||| 4 | 4 c2
+// | | ||+---+| ||| |
+// | | |+-----|--+|| |
+// | | +------| --+| |
+// | +--------|----+ |
+// +---------------------+
+//
+TEST_F(HitTestQueryTest, MultipleLayerChild) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ FrameSinkId c1_id = FrameSinkId(2, 2);
+ FrameSinkId a_id = FrameSinkId(3, 3);
+ FrameSinkId b_id = FrameSinkId(4, 4);
+ FrameSinkId g_id = FrameSinkId(5, 5);
+ FrameSinkId c2_id = FrameSinkId(6, 6);
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 1000, 1000);
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 800);
+ gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 700, 700);
+ gfx::Rect b_bounds_in_a = gfx::Rect(0, 0, 600, 600);
+ gfx::Rect g_bounds_in_b = gfx::Rect(0, 0, 200, 200);
+ gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 800);
+ gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a,
+ transform_a_to_b, transform_b_to_g, transform_e_to_c2;
+ transform_e_to_c1.Translate(-100, -100);
+ transform_a_to_b.Translate(-50, -30);
+ transform_b_to_g.Translate(-150, -200);
+ transform_e_to_c2.Translate(-400, -50);
+ AggregatedHitTestRegion aggregated_hit_test_region_list[6] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 5}, // e
+ {c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
+ c1_bounds_in_e, transform_e_to_c1, 3}, // c1
+ {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c1,
+ transform_c1_to_a, 2}, // a
+ {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_a,
+ transform_a_to_b, 1}, // b
+ {g_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, g_bounds_in_b,
+ transform_b_to_g, 0}, // g
+ {c2_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c2_bounds_in_e,
+ transform_e_to_c2, 0} // c2
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list, 6);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(1, 1);
+ gfx::Point point2(300, 350);
+ gfx::Point point3(550, 350);
+ gfx::Point point4(900, 350);
+
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(e_id, target1.frame_sink_id);
+ EXPECT_EQ(point1, target1.location_in_target);
+ EXPECT_EQ(mojom::kHitTestMine, target1.flags);
+
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(g_id, target2.frame_sink_id);
+ EXPECT_EQ(gfx::Point(0, 20), target2.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags);
+
+ Target target3 = hit_test_query_.FindTargetForLocation(point3);
+ EXPECT_EQ(b_id, target3.frame_sink_id);
+ EXPECT_EQ(gfx::Point(400, 220), target3.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target3.flags);
+
+ Target target4 = hit_test_query_.FindTargetForLocation(point4);
+ EXPECT_EQ(c2_id, target4.frame_sink_id);
+ EXPECT_EQ(gfx::Point(500, 300), target4.location_in_target);
+ EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target4.flags);
+}
+
+// Multiple layers deep of transparent children.
+//
+// +e--------------------+
+// | +c2--------| Point maps to
+// | +c1------|----+ | ----- -------
+// |1| +a-----|---+| | 1 e
+// | | |+b----|--+|| | 2 e
+// | | ||+g--+| ||| | 3 c2
+// | | ||| 2 || 3||| 4 | 4 c2
+// | | ||+---+| ||| |
+// | | |+-----|--+|| |
+// | | +------| --+| |
+// | +--------|----+ |
+// +---------------------+
+//
+TEST_F(HitTestQueryTest, MultipleLayerTransparentChild) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ FrameSinkId c1_id = FrameSinkId(2, 2);
+ FrameSinkId a_id = FrameSinkId(3, 3);
+ FrameSinkId b_id = FrameSinkId(4, 4);
+ FrameSinkId g_id = FrameSinkId(5, 5);
+ FrameSinkId c2_id = FrameSinkId(6, 6);
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 1000, 1000);
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 800);
+ gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 700, 700);
+ gfx::Rect b_bounds_in_a = gfx::Rect(0, 0, 600, 600);
+ gfx::Rect g_bounds_in_b = gfx::Rect(0, 0, 200, 200);
+ gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 800);
+ gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a,
+ transform_a_to_b, transform_b_to_g, transform_e_to_c2;
+ transform_e_to_c1.Translate(-100, -100);
+ transform_a_to_b.Translate(-50, -30);
+ transform_b_to_g.Translate(-150, -200);
+ transform_e_to_c2.Translate(-400, -50);
+ AggregatedHitTestRegion aggregated_hit_test_region_list[6] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 5}, // e
+ {c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
+ c1_bounds_in_e, transform_e_to_c1, 3}, // c1
+ {a_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore,
+ a_bounds_in_c1, transform_c1_to_a, 2}, // a
+ {b_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, b_bounds_in_a,
+ transform_a_to_b, 1}, // b
+ {g_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, g_bounds_in_b,
+ transform_b_to_g, 0}, // g
+ {c2_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c2_bounds_in_e,
+ transform_e_to_c2, 0} // c2
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list, 6);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(1, 1);
+ gfx::Point point2(300, 350);
+ gfx::Point point3(450, 350);
+ gfx::Point point4(900, 350);
+
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(e_id, target1.frame_sink_id);
+ EXPECT_EQ(point1, target1.location_in_target);
+ EXPECT_TRUE(target1.flags);
+
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(e_id, target2.frame_sink_id);
+ EXPECT_EQ(point2, target2.location_in_target);
+ EXPECT_TRUE(target2.flags);
+
+ Target target3 = hit_test_query_.FindTargetForLocation(point3);
+ EXPECT_EQ(c2_id, target3.frame_sink_id);
+ EXPECT_EQ(gfx::Point(50, 300), target3.location_in_target);
+ EXPECT_TRUE(target3.flags);
+
+ Target target4 = hit_test_query_.FindTargetForLocation(point4);
+ EXPECT_EQ(c2_id, target4.frame_sink_id);
+ EXPECT_EQ(gfx::Point(500, 300), target4.location_in_target);
+ EXPECT_TRUE(target4.flags);
+}
+
+TEST_F(HitTestQueryTest, InvalidAggregatedHitTestRegionData) {
+ FrameSinkId e_id = FrameSinkId(1, 1);
+ FrameSinkId c_id = FrameSinkId(2, 2);
+ FrameSinkId a_id = FrameSinkId(3, 3);
+ FrameSinkId b_id = FrameSinkId(4, 4);
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600);
+ gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 800, 800);
+ gfx::Rect a_bounds_in_c = gfx::Rect(0, 0, 200, 100);
+ gfx::Rect b_bounds_in_c = gfx::Rect(0, 0, 800, 600);
+ gfx::Transform transform_e_to_e, transform_e_to_c, transform_c_to_a,
+ transform_c_to_b;
+ transform_e_to_c.Translate(-200, -100);
+ transform_c_to_b.Translate(0, -100);
+ AggregatedHitTestRegion aggregated_hit_test_region_list_min[4] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3}, // e
+ {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
+ transform_e_to_c, INT32_MIN}, // c
+ {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
+ transform_c_to_a, 0}, // a
+ {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
+ transform_c_to_b, 0} // b
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list_min, 4);
+
+ // All points are in e's coordinate system when we reach this case.
+ gfx::Point point1(1, 1);
+ gfx::Point point2(202, 102);
+
+ // |child_count| is invalid, which is a security fault. For now, check to see
+ // if the returned Target is invalid.
+ Target target1 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(FrameSinkId(), target1.frame_sink_id);
+ EXPECT_EQ(gfx::Point(), target1.location_in_target);
+ EXPECT_FALSE(target1.flags);
+
+ Target target2 = hit_test_query_.FindTargetForLocation(point2);
+ EXPECT_EQ(FrameSinkId(), target2.frame_sink_id);
+ EXPECT_EQ(gfx::Point(), target2.location_in_target);
+ EXPECT_FALSE(target2.flags);
+
+ AggregatedHitTestRegion aggregated_hit_test_region_list_max[4] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e,
+ INT32_MAX}, // e
+ {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
+ transform_e_to_c, 2}, // c
+ {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
+ transform_c_to_a, 0}, // a
+ {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
+ transform_c_to_b, 0} // b
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list_max, 4);
+
+ Target target3 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(FrameSinkId(), target3.frame_sink_id);
+ EXPECT_EQ(gfx::Point(), target3.location_in_target);
+ EXPECT_FALSE(target3.flags);
+
+ AggregatedHitTestRegion aggregated_hit_test_region_list_bigger[4] = {
+ {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3}, // e
+ {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e,
+ transform_e_to_c, 3}, // c
+ {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c,
+ transform_c_to_a, 0}, // a
+ {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c,
+ transform_c_to_b, 0} // b
+ };
+ hit_test_query_.set_aggregated_hit_test_region_list(
+ aggregated_hit_test_region_list_bigger, 4);
+
+ Target target4 = hit_test_query_.FindTargetForLocation(point1);
+ EXPECT_EQ(FrameSinkId(), target4.frame_sink_id);
+ EXPECT_EQ(gfx::Point(), target4.location_in_target);
+ EXPECT_FALSE(target4.flags);
+}
+
+} // namespace test
+} // namespace viz

Powered by Google App Engine
This is Rietveld 408576698