OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "components/viz/host/hit_test/hit_test_query.h" |
| 6 |
| 7 #include <cstdint> |
| 8 |
| 9 #include "services/viz/hit_test/public/interfaces/hit_test_region_list.mojom.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 |
| 12 namespace viz { |
| 13 namespace test { |
| 14 |
| 15 class HitTestQueryTest : public testing::Test { |
| 16 public: |
| 17 HitTestQueryTest() = default; |
| 18 ~HitTestQueryTest() override = default; |
| 19 |
| 20 HitTestQuery hit_test_query_; |
| 21 |
| 22 private: |
| 23 // testing::Test: |
| 24 void SetUp() override {} |
| 25 void TearDown() override {} |
| 26 |
| 27 DISALLOW_COPY_AND_ASSIGN(HitTestQueryTest); |
| 28 }; |
| 29 |
| 30 // One surface. |
| 31 // |
| 32 // +e---------+ |
| 33 // | | |
| 34 // | | |
| 35 // | | |
| 36 // +----------+ |
| 37 // |
| 38 TEST_F(HitTestQueryTest, OneSurface) { |
| 39 FrameSinkId e_id = FrameSinkId(1, 1); |
| 40 gfx::Rect e_bounds = gfx::Rect(0, 0, 600, 600); |
| 41 gfx::Transform transform_e_to_e; |
| 42 AggregatedHitTestRegion aggregated_hit_test_region_list[1] = { |
| 43 {e_id, mojom::kHitTestMine, e_bounds, transform_e_to_e, 0} // e |
| 44 }; |
| 45 hit_test_query_.set_aggregated_hit_test_region_list( |
| 46 aggregated_hit_test_region_list, 1); |
| 47 |
| 48 // All points are in e's coordinate system when we reach this case. |
| 49 gfx::Point point1(1, 1); |
| 50 gfx::Point point2(600, 600); |
| 51 gfx::Point point3(0, 0); |
| 52 |
| 53 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 54 EXPECT_EQ(e_id, target1.frame_sink_id); |
| 55 EXPECT_EQ(point1, target1.location_in_target); |
| 56 EXPECT_EQ(mojom::kHitTestMine, target1.flags); |
| 57 |
| 58 // point2 is on the bounds of e so no target found. |
| 59 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 60 EXPECT_EQ(FrameSinkId(), target2.frame_sink_id); |
| 61 EXPECT_EQ(gfx::Point(), target2.location_in_target); |
| 62 EXPECT_FALSE(target2.flags); |
| 63 |
| 64 // There's a valid Target for point3, see Rect::Contains. |
| 65 Target target3 = hit_test_query_.FindTargetForLocation(point3); |
| 66 EXPECT_EQ(e_id, target3.frame_sink_id); |
| 67 EXPECT_EQ(point3, target3.location_in_target); |
| 68 EXPECT_EQ(mojom::kHitTestMine, target3.flags); |
| 69 } |
| 70 |
| 71 // One embedder with two children. |
| 72 // |
| 73 // +e------------+ Point maps to |
| 74 // | +c1-+ +c2---| ----- ------- |
| 75 // |1| | | | 1 e |
| 76 // | | 2 | | 3 | 4 2 c1 |
| 77 // | +---+ | | 3 c2 |
| 78 // +-------------+ 4 none |
| 79 // |
| 80 TEST_F(HitTestQueryTest, OneEmbedderTwoChildren) { |
| 81 FrameSinkId e_id = FrameSinkId(1, 1); |
| 82 FrameSinkId c1_id = FrameSinkId(2, 2); |
| 83 FrameSinkId c2_id = FrameSinkId(3, 3); |
| 84 gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
| 85 gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 200, 200); |
| 86 gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 400, 400); |
| 87 gfx::Transform transform_e_to_e, transform_e_to_c1, transform_e_to_c2; |
| 88 transform_e_to_c1.Translate(-100, -100); |
| 89 transform_e_to_c2.Translate(-300, -300); |
| 90 AggregatedHitTestRegion aggregated_hit_test_region_list[3] = { |
| 91 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 2}, // e |
| 92 {c1_id, mojom::kHitTestMine, c1_bounds_in_e, transform_e_to_c1, 0}, // c1 |
| 93 {c2_id, mojom::kHitTestMine, c2_bounds_in_e, transform_e_to_c2, 0} // c2 |
| 94 }; |
| 95 hit_test_query_.set_aggregated_hit_test_region_list( |
| 96 aggregated_hit_test_region_list, 3); |
| 97 |
| 98 // All points are in e's coordinate system when we reach this case. |
| 99 gfx::Point point1(99, 200); |
| 100 gfx::Point point2(150, 150); |
| 101 gfx::Point point3(400, 400); |
| 102 gfx::Point point4(650, 350); |
| 103 |
| 104 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 105 EXPECT_EQ(e_id, target1.frame_sink_id); |
| 106 EXPECT_EQ(point1, target1.location_in_target); |
| 107 EXPECT_EQ(mojom::kHitTestMine, target1.flags); |
| 108 |
| 109 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 110 EXPECT_EQ(c1_id, target2.frame_sink_id); |
| 111 EXPECT_EQ(gfx::Point(50, 50), target2.location_in_target); |
| 112 EXPECT_EQ(mojom::kHitTestMine, target2.flags); |
| 113 |
| 114 Target target3 = hit_test_query_.FindTargetForLocation(point3); |
| 115 EXPECT_EQ(c2_id, target3.frame_sink_id); |
| 116 EXPECT_EQ(gfx::Point(100, 100), target3.location_in_target); |
| 117 EXPECT_EQ(mojom::kHitTestMine, target3.flags); |
| 118 |
| 119 Target target4 = hit_test_query_.FindTargetForLocation(point4); |
| 120 EXPECT_EQ(FrameSinkId(), target4.frame_sink_id); |
| 121 EXPECT_EQ(gfx::Point(), target4.location_in_target); |
| 122 EXPECT_FALSE(target4.flags); |
| 123 } |
| 124 |
| 125 // One embedder with a rotated child. |
| 126 TEST_F(HitTestQueryTest, OneEmbedderRotatedChild) { |
| 127 FrameSinkId e_id = FrameSinkId(1, 1); |
| 128 FrameSinkId c_id = FrameSinkId(2, 2); |
| 129 gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
| 130 gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 1000, 1000); |
| 131 gfx::Transform transform_e_to_e, transform_e_to_c; |
| 132 transform_e_to_c.Translate(-100, -100); |
| 133 transform_e_to_c.Skew(2, 3); |
| 134 transform_e_to_c.Scale(.5f, .7f); |
| 135 |
| 136 AggregatedHitTestRegion aggregated_hit_test_region_list[2] = { |
| 137 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 1}, // e |
| 138 {c_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c_bounds_in_e, |
| 139 transform_e_to_c, 0} // c |
| 140 }; |
| 141 hit_test_query_.set_aggregated_hit_test_region_list( |
| 142 aggregated_hit_test_region_list, 2); |
| 143 |
| 144 // All points are in e's coordinate system when we reach this case. |
| 145 gfx::Point point1(150, 120); // Point(-22, -12) after transform. |
| 146 gfx::Point point2(550, 400); // Point(185, 194) after transform. |
| 147 |
| 148 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 149 EXPECT_EQ(e_id, target1.frame_sink_id); |
| 150 EXPECT_EQ(point1, target1.location_in_target); |
| 151 EXPECT_EQ(mojom::kHitTestMine, target1.flags); |
| 152 |
| 153 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 154 EXPECT_EQ(c_id, target2.frame_sink_id); |
| 155 EXPECT_EQ(gfx::Point(185, 194), target2.location_in_target); |
| 156 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags); |
| 157 } |
| 158 |
| 159 // One embedder with a clipped child with a tab and transparent background. |
| 160 // |
| 161 // +e-------------+ |
| 162 // | +c---------| Point maps to |
| 163 // | 1 |+a--+ | ----- ------- |
| 164 // | || 2 | 3 | 1 e |
| 165 // | |+b--------| 2 a |
| 166 // | || | 3 e ( transparent area in c ) |
| 167 // | || 4 | 4 b |
| 168 // +--------------+ |
| 169 // |
| 170 TEST_F(HitTestQueryTest, ClippedChildWithTabAndTransparentBackground) { |
| 171 FrameSinkId e_id = FrameSinkId(1, 1); |
| 172 FrameSinkId c_id = FrameSinkId(2, 2); |
| 173 FrameSinkId a_id = FrameSinkId(3, 3); |
| 174 FrameSinkId b_id = FrameSinkId(4, 4); |
| 175 gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
| 176 gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
| 177 gfx::Rect a_bounds_in_c = gfx::Rect(0, 0, 200, 100); |
| 178 gfx::Rect b_bounds_in_c = gfx::Rect(0, 0, 800, 600); |
| 179 gfx::Transform transform_e_to_e, transform_e_to_c, transform_c_to_a, |
| 180 transform_c_to_b; |
| 181 transform_e_to_c.Translate(-200, -100); |
| 182 transform_c_to_b.Translate(0, -100); |
| 183 AggregatedHitTestRegion aggregated_hit_test_region_list[4] = { |
| 184 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3}, // e |
| 185 {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e, |
| 186 transform_e_to_c, 2}, // c |
| 187 {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c, |
| 188 transform_c_to_a, 0}, // a |
| 189 {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c, |
| 190 transform_c_to_b, 0} // b |
| 191 }; |
| 192 hit_test_query_.set_aggregated_hit_test_region_list( |
| 193 aggregated_hit_test_region_list, 4); |
| 194 |
| 195 // All points are in e's coordinate system when we reach this case. |
| 196 gfx::Point point1(1, 1); |
| 197 gfx::Point point2(202, 102); |
| 198 gfx::Point point3(403, 103); |
| 199 gfx::Point point4(202, 202); |
| 200 |
| 201 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 202 EXPECT_EQ(e_id, target1.frame_sink_id); |
| 203 EXPECT_EQ(point1, target1.location_in_target); |
| 204 EXPECT_EQ(mojom::kHitTestMine, target1.flags); |
| 205 |
| 206 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 207 EXPECT_EQ(a_id, target2.frame_sink_id); |
| 208 EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target); |
| 209 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags); |
| 210 |
| 211 Target target3 = hit_test_query_.FindTargetForLocation(point3); |
| 212 EXPECT_EQ(e_id, target3.frame_sink_id); |
| 213 EXPECT_EQ(point3, target3.location_in_target); |
| 214 EXPECT_EQ(mojom::kHitTestMine, target3.flags); |
| 215 |
| 216 Target target4 = hit_test_query_.FindTargetForLocation(point4); |
| 217 EXPECT_EQ(b_id, target4.frame_sink_id); |
| 218 EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target); |
| 219 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target4.flags); |
| 220 } |
| 221 |
| 222 // One embedder with a clipped child with a tab and transparent background, and |
| 223 // a child d under that. |
| 224 // |
| 225 // +e-------------+ |
| 226 // | +d------| |
| 227 // | +c-|-------| Point maps to |
| 228 // | 1 |+a|-+ | ----- ------- |
| 229 // | || 2 | 3 | 1 e |
| 230 // | |+b|-------| 2 a |
| 231 // | || | | 3 d |
| 232 // | || | 4 | 4 b |
| 233 // +--------------+ |
| 234 // |
| 235 TEST_F(HitTestQueryTest, ClippedChildWithChildUnderneath) { |
| 236 FrameSinkId e_id = FrameSinkId(1, 1); |
| 237 FrameSinkId c_id = FrameSinkId(2, 2); |
| 238 FrameSinkId a_id = FrameSinkId(3, 3); |
| 239 FrameSinkId b_id = FrameSinkId(4, 4); |
| 240 FrameSinkId d_id = FrameSinkId(5, 5); |
| 241 gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
| 242 gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
| 243 gfx::Rect a_bounds_in_c = gfx::Rect(0, 0, 200, 100); |
| 244 gfx::Rect b_bounds_in_c = gfx::Rect(0, 0, 800, 600); |
| 245 gfx::Rect d_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
| 246 gfx::Transform transform_e_to_e, transform_e_to_c, transform_c_to_a, |
| 247 transform_c_to_b, transform_e_to_d; |
| 248 transform_e_to_c.Translate(-200, -100); |
| 249 transform_c_to_b.Translate(0, -100); |
| 250 transform_e_to_d.Translate(-400, -50); |
| 251 AggregatedHitTestRegion aggregated_hit_test_region_list[5] = { |
| 252 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 4}, // e |
| 253 {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e, |
| 254 transform_e_to_c, 2}, // c |
| 255 {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c, |
| 256 transform_c_to_a, 0}, // a |
| 257 {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c, |
| 258 transform_c_to_b, 0}, // b |
| 259 {d_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, d_bounds_in_e, |
| 260 transform_e_to_d, 0} // d |
| 261 }; |
| 262 hit_test_query_.set_aggregated_hit_test_region_list( |
| 263 aggregated_hit_test_region_list, 5); |
| 264 |
| 265 // All points are in e's coordinate system when we reach this case. |
| 266 gfx::Point point1(1, 1); |
| 267 gfx::Point point2(202, 102); |
| 268 gfx::Point point3(450, 150); |
| 269 gfx::Point point4(202, 202); |
| 270 |
| 271 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 272 EXPECT_EQ(e_id, target1.frame_sink_id); |
| 273 EXPECT_EQ(point1, target1.location_in_target); |
| 274 EXPECT_EQ(mojom::kHitTestMine, target1.flags); |
| 275 |
| 276 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 277 EXPECT_EQ(a_id, target2.frame_sink_id); |
| 278 EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target); |
| 279 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags); |
| 280 |
| 281 Target target3 = hit_test_query_.FindTargetForLocation(point3); |
| 282 EXPECT_EQ(d_id, target3.frame_sink_id); |
| 283 EXPECT_EQ(gfx::Point(50, 100), target3.location_in_target); |
| 284 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target3.flags); |
| 285 |
| 286 Target target4 = hit_test_query_.FindTargetForLocation(point4); |
| 287 EXPECT_EQ(b_id, target4.frame_sink_id); |
| 288 EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target); |
| 289 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target4.flags); |
| 290 } |
| 291 |
| 292 // One embedder with two clipped children with a tab and transparent background. |
| 293 // |
| 294 // +e-------------+ |
| 295 // | +c1--------| Point maps to |
| 296 // | 1 |+a--+ | ----- ------- |
| 297 // | || 2 | 3 | 1 e |
| 298 // | |+b--------| 2 a |
| 299 // | || | 3 e ( transparent area in c1 ) |
| 300 // | || 4 | 4 b |
| 301 // | +----------| 5 g |
| 302 // | +c2--------| 6 e ( transparent area in c2 ) |
| 303 // | |+g--+ | 7 h |
| 304 // | || 5 | 6 | |
| 305 // | |+h--------| |
| 306 // | || | |
| 307 // | || 7 | |
| 308 // +--------------+ |
| 309 // |
| 310 TEST_F(HitTestQueryTest, ClippedChildrenWithTabAndTransparentBackground) { |
| 311 FrameSinkId e_id = FrameSinkId(1, 1); |
| 312 FrameSinkId c1_id = FrameSinkId(2, 2); |
| 313 FrameSinkId a_id = FrameSinkId(3, 3); |
| 314 FrameSinkId b_id = FrameSinkId(4, 4); |
| 315 FrameSinkId c2_id = FrameSinkId(5, 5); |
| 316 FrameSinkId g_id = FrameSinkId(6, 6); |
| 317 FrameSinkId h_id = FrameSinkId(7, 7); |
| 318 gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 1200); |
| 319 gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 500); |
| 320 gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 200, 100); |
| 321 gfx::Rect b_bounds_in_c1 = gfx::Rect(0, 0, 800, 400); |
| 322 gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 500); |
| 323 gfx::Rect g_bounds_in_c2 = gfx::Rect(0, 0, 200, 100); |
| 324 gfx::Rect h_bounds_in_c2 = gfx::Rect(0, 0, 800, 800); |
| 325 gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a, |
| 326 transform_c1_to_b, transform_e_to_c2, transform_c2_to_g, |
| 327 transform_c2_to_h; |
| 328 transform_e_to_c1.Translate(-200, -100); |
| 329 transform_c1_to_b.Translate(0, -100); |
| 330 transform_e_to_c2.Translate(-200, -700); |
| 331 transform_c2_to_h.Translate(0, -100); |
| 332 AggregatedHitTestRegion aggregated_hit_test_region_list[7] = { |
| 333 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 6}, // e |
| 334 {c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, |
| 335 c1_bounds_in_e, transform_e_to_c1, 2}, // c1 |
| 336 {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c1, |
| 337 transform_c1_to_a, 0}, // a |
| 338 {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c1, |
| 339 transform_c1_to_b, 0}, // b |
| 340 {c2_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, |
| 341 c2_bounds_in_e, transform_e_to_c2, 2}, // c2 |
| 342 {g_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, g_bounds_in_c2, |
| 343 transform_c2_to_g, 0}, // g |
| 344 {h_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, h_bounds_in_c2, |
| 345 transform_c2_to_h, 0} // h |
| 346 }; |
| 347 hit_test_query_.set_aggregated_hit_test_region_list( |
| 348 aggregated_hit_test_region_list, 7); |
| 349 |
| 350 // All points are in e's coordinate system when we reach this case. |
| 351 gfx::Point point1(1, 1); |
| 352 gfx::Point point2(202, 102); |
| 353 gfx::Point point3(403, 103); |
| 354 gfx::Point point4(202, 202); |
| 355 gfx::Point point5(250, 750); |
| 356 gfx::Point point6(450, 750); |
| 357 gfx::Point point7(350, 1100); |
| 358 |
| 359 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 360 EXPECT_EQ(e_id, target1.frame_sink_id); |
| 361 EXPECT_EQ(point1, target1.location_in_target); |
| 362 EXPECT_EQ(mojom::kHitTestMine, target1.flags); |
| 363 |
| 364 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 365 EXPECT_EQ(a_id, target2.frame_sink_id); |
| 366 EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target); |
| 367 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags); |
| 368 |
| 369 Target target3 = hit_test_query_.FindTargetForLocation(point3); |
| 370 EXPECT_EQ(e_id, target3.frame_sink_id); |
| 371 EXPECT_EQ(point3, target3.location_in_target); |
| 372 EXPECT_EQ(mojom::kHitTestMine, target3.flags); |
| 373 |
| 374 Target target4 = hit_test_query_.FindTargetForLocation(point4); |
| 375 EXPECT_EQ(b_id, target4.frame_sink_id); |
| 376 EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target); |
| 377 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target4.flags); |
| 378 |
| 379 Target target5 = hit_test_query_.FindTargetForLocation(point5); |
| 380 EXPECT_EQ(g_id, target5.frame_sink_id); |
| 381 EXPECT_EQ(gfx::Point(50, 50), target5.location_in_target); |
| 382 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target5.flags); |
| 383 |
| 384 Target target6 = hit_test_query_.FindTargetForLocation(point6); |
| 385 EXPECT_EQ(e_id, target6.frame_sink_id); |
| 386 EXPECT_EQ(point6, target6.location_in_target); |
| 387 EXPECT_EQ(mojom::kHitTestMine, target6.flags); |
| 388 |
| 389 Target target7 = hit_test_query_.FindTargetForLocation(point7); |
| 390 EXPECT_EQ(h_id, target7.frame_sink_id); |
| 391 EXPECT_EQ(gfx::Point(150, 300), target7.location_in_target); |
| 392 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target7.flags); |
| 393 } |
| 394 |
| 395 // Children that are multiple layers deep. |
| 396 // |
| 397 // +e--------------------+ |
| 398 // | +c2--------| Point maps to |
| 399 // | +c1------|----+ | ----- ------- |
| 400 // |1| +a-----|---+| | 1 e |
| 401 // | | |+b----|--+|| | 2 g |
| 402 // | | ||+g--+| ||| | 3 b |
| 403 // | | ||| 2 || 3||| 4 | 4 c2 |
| 404 // | | ||+---+| ||| | |
| 405 // | | |+-----|--+|| | |
| 406 // | | +------| --+| | |
| 407 // | +--------|----+ | |
| 408 // +---------------------+ |
| 409 // |
| 410 TEST_F(HitTestQueryTest, MultipleLayerChild) { |
| 411 FrameSinkId e_id = FrameSinkId(1, 1); |
| 412 FrameSinkId c1_id = FrameSinkId(2, 2); |
| 413 FrameSinkId a_id = FrameSinkId(3, 3); |
| 414 FrameSinkId b_id = FrameSinkId(4, 4); |
| 415 FrameSinkId g_id = FrameSinkId(5, 5); |
| 416 FrameSinkId c2_id = FrameSinkId(6, 6); |
| 417 gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 1000, 1000); |
| 418 gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
| 419 gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 700, 700); |
| 420 gfx::Rect b_bounds_in_a = gfx::Rect(0, 0, 600, 600); |
| 421 gfx::Rect g_bounds_in_b = gfx::Rect(0, 0, 200, 200); |
| 422 gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
| 423 gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a, |
| 424 transform_a_to_b, transform_b_to_g, transform_e_to_c2; |
| 425 transform_e_to_c1.Translate(-100, -100); |
| 426 transform_a_to_b.Translate(-50, -30); |
| 427 transform_b_to_g.Translate(-150, -200); |
| 428 transform_e_to_c2.Translate(-400, -50); |
| 429 AggregatedHitTestRegion aggregated_hit_test_region_list[6] = { |
| 430 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 5}, // e |
| 431 {c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, |
| 432 c1_bounds_in_e, transform_e_to_c1, 3}, // c1 |
| 433 {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c1, |
| 434 transform_c1_to_a, 2}, // a |
| 435 {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_a, |
| 436 transform_a_to_b, 1}, // b |
| 437 {g_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, g_bounds_in_b, |
| 438 transform_b_to_g, 0}, // g |
| 439 {c2_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c2_bounds_in_e, |
| 440 transform_e_to_c2, 0} // c2 |
| 441 }; |
| 442 hit_test_query_.set_aggregated_hit_test_region_list( |
| 443 aggregated_hit_test_region_list, 6); |
| 444 |
| 445 // All points are in e's coordinate system when we reach this case. |
| 446 gfx::Point point1(1, 1); |
| 447 gfx::Point point2(300, 350); |
| 448 gfx::Point point3(550, 350); |
| 449 gfx::Point point4(900, 350); |
| 450 |
| 451 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 452 EXPECT_EQ(e_id, target1.frame_sink_id); |
| 453 EXPECT_EQ(point1, target1.location_in_target); |
| 454 EXPECT_EQ(mojom::kHitTestMine, target1.flags); |
| 455 |
| 456 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 457 EXPECT_EQ(g_id, target2.frame_sink_id); |
| 458 EXPECT_EQ(gfx::Point(0, 20), target2.location_in_target); |
| 459 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target2.flags); |
| 460 |
| 461 Target target3 = hit_test_query_.FindTargetForLocation(point3); |
| 462 EXPECT_EQ(b_id, target3.frame_sink_id); |
| 463 EXPECT_EQ(gfx::Point(400, 220), target3.location_in_target); |
| 464 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target3.flags); |
| 465 |
| 466 Target target4 = hit_test_query_.FindTargetForLocation(point4); |
| 467 EXPECT_EQ(c2_id, target4.frame_sink_id); |
| 468 EXPECT_EQ(gfx::Point(500, 300), target4.location_in_target); |
| 469 EXPECT_EQ(mojom::kHitTestChildSurface | mojom::kHitTestMine, target4.flags); |
| 470 } |
| 471 |
| 472 // Multiple layers deep of transparent children. |
| 473 // |
| 474 // +e--------------------+ |
| 475 // | +c2--------| Point maps to |
| 476 // | +c1------|----+ | ----- ------- |
| 477 // |1| +a-----|---+| | 1 e |
| 478 // | | |+b----|--+|| | 2 e |
| 479 // | | ||+g--+| ||| | 3 c2 |
| 480 // | | ||| 2 || 3||| 4 | 4 c2 |
| 481 // | | ||+---+| ||| | |
| 482 // | | |+-----|--+|| | |
| 483 // | | +------| --+| | |
| 484 // | +--------|----+ | |
| 485 // +---------------------+ |
| 486 // |
| 487 TEST_F(HitTestQueryTest, MultipleLayerTransparentChild) { |
| 488 FrameSinkId e_id = FrameSinkId(1, 1); |
| 489 FrameSinkId c1_id = FrameSinkId(2, 2); |
| 490 FrameSinkId a_id = FrameSinkId(3, 3); |
| 491 FrameSinkId b_id = FrameSinkId(4, 4); |
| 492 FrameSinkId g_id = FrameSinkId(5, 5); |
| 493 FrameSinkId c2_id = FrameSinkId(6, 6); |
| 494 gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 1000, 1000); |
| 495 gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
| 496 gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 700, 700); |
| 497 gfx::Rect b_bounds_in_a = gfx::Rect(0, 0, 600, 600); |
| 498 gfx::Rect g_bounds_in_b = gfx::Rect(0, 0, 200, 200); |
| 499 gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
| 500 gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a, |
| 501 transform_a_to_b, transform_b_to_g, transform_e_to_c2; |
| 502 transform_e_to_c1.Translate(-100, -100); |
| 503 transform_a_to_b.Translate(-50, -30); |
| 504 transform_b_to_g.Translate(-150, -200); |
| 505 transform_e_to_c2.Translate(-400, -50); |
| 506 AggregatedHitTestRegion aggregated_hit_test_region_list[6] = { |
| 507 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 5}, // e |
| 508 {c1_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, |
| 509 c1_bounds_in_e, transform_e_to_c1, 3}, // c1 |
| 510 {a_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, |
| 511 a_bounds_in_c1, transform_c1_to_a, 2}, // a |
| 512 {b_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, b_bounds_in_a, |
| 513 transform_a_to_b, 1}, // b |
| 514 {g_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, g_bounds_in_b, |
| 515 transform_b_to_g, 0}, // g |
| 516 {c2_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, c2_bounds_in_e, |
| 517 transform_e_to_c2, 0} // c2 |
| 518 }; |
| 519 hit_test_query_.set_aggregated_hit_test_region_list( |
| 520 aggregated_hit_test_region_list, 6); |
| 521 |
| 522 // All points are in e's coordinate system when we reach this case. |
| 523 gfx::Point point1(1, 1); |
| 524 gfx::Point point2(300, 350); |
| 525 gfx::Point point3(450, 350); |
| 526 gfx::Point point4(900, 350); |
| 527 |
| 528 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 529 EXPECT_EQ(e_id, target1.frame_sink_id); |
| 530 EXPECT_EQ(point1, target1.location_in_target); |
| 531 EXPECT_TRUE(target1.flags); |
| 532 |
| 533 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 534 EXPECT_EQ(e_id, target2.frame_sink_id); |
| 535 EXPECT_EQ(point2, target2.location_in_target); |
| 536 EXPECT_TRUE(target2.flags); |
| 537 |
| 538 Target target3 = hit_test_query_.FindTargetForLocation(point3); |
| 539 EXPECT_EQ(c2_id, target3.frame_sink_id); |
| 540 EXPECT_EQ(gfx::Point(50, 300), target3.location_in_target); |
| 541 EXPECT_TRUE(target3.flags); |
| 542 |
| 543 Target target4 = hit_test_query_.FindTargetForLocation(point4); |
| 544 EXPECT_EQ(c2_id, target4.frame_sink_id); |
| 545 EXPECT_EQ(gfx::Point(500, 300), target4.location_in_target); |
| 546 EXPECT_TRUE(target4.flags); |
| 547 } |
| 548 |
| 549 TEST_F(HitTestQueryTest, InvalidAggregatedHitTestRegionData) { |
| 550 FrameSinkId e_id = FrameSinkId(1, 1); |
| 551 FrameSinkId c_id = FrameSinkId(2, 2); |
| 552 FrameSinkId a_id = FrameSinkId(3, 3); |
| 553 FrameSinkId b_id = FrameSinkId(4, 4); |
| 554 gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
| 555 gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
| 556 gfx::Rect a_bounds_in_c = gfx::Rect(0, 0, 200, 100); |
| 557 gfx::Rect b_bounds_in_c = gfx::Rect(0, 0, 800, 600); |
| 558 gfx::Transform transform_e_to_e, transform_e_to_c, transform_c_to_a, |
| 559 transform_c_to_b; |
| 560 transform_e_to_c.Translate(-200, -100); |
| 561 transform_c_to_b.Translate(0, -100); |
| 562 AggregatedHitTestRegion aggregated_hit_test_region_list_min[4] = { |
| 563 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3}, // e |
| 564 {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e, |
| 565 transform_e_to_c, INT32_MIN}, // c |
| 566 {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c, |
| 567 transform_c_to_a, 0}, // a |
| 568 {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c, |
| 569 transform_c_to_b, 0} // b |
| 570 }; |
| 571 hit_test_query_.set_aggregated_hit_test_region_list( |
| 572 aggregated_hit_test_region_list_min, 4); |
| 573 |
| 574 // All points are in e's coordinate system when we reach this case. |
| 575 gfx::Point point1(1, 1); |
| 576 gfx::Point point2(202, 102); |
| 577 |
| 578 // |child_count| is invalid, which is a security fault. For now, check to see |
| 579 // if the returned Target is invalid. |
| 580 Target target1 = hit_test_query_.FindTargetForLocation(point1); |
| 581 EXPECT_EQ(FrameSinkId(), target1.frame_sink_id); |
| 582 EXPECT_EQ(gfx::Point(), target1.location_in_target); |
| 583 EXPECT_FALSE(target1.flags); |
| 584 |
| 585 Target target2 = hit_test_query_.FindTargetForLocation(point2); |
| 586 EXPECT_EQ(FrameSinkId(), target2.frame_sink_id); |
| 587 EXPECT_EQ(gfx::Point(), target2.location_in_target); |
| 588 EXPECT_FALSE(target2.flags); |
| 589 |
| 590 AggregatedHitTestRegion aggregated_hit_test_region_list_max[4] = { |
| 591 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, |
| 592 INT32_MAX}, // e |
| 593 {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e, |
| 594 transform_e_to_c, 2}, // c |
| 595 {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c, |
| 596 transform_c_to_a, 0}, // a |
| 597 {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c, |
| 598 transform_c_to_b, 0} // b |
| 599 }; |
| 600 hit_test_query_.set_aggregated_hit_test_region_list( |
| 601 aggregated_hit_test_region_list_max, 4); |
| 602 |
| 603 Target target3 = hit_test_query_.FindTargetForLocation(point1); |
| 604 EXPECT_EQ(FrameSinkId(), target3.frame_sink_id); |
| 605 EXPECT_EQ(gfx::Point(), target3.location_in_target); |
| 606 EXPECT_FALSE(target3.flags); |
| 607 |
| 608 AggregatedHitTestRegion aggregated_hit_test_region_list_bigger[4] = { |
| 609 {e_id, mojom::kHitTestMine, e_bounds_in_e, transform_e_to_e, 3}, // e |
| 610 {c_id, mojom::kHitTestChildSurface | mojom::kHitTestIgnore, c_bounds_in_e, |
| 611 transform_e_to_c, 3}, // c |
| 612 {a_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, a_bounds_in_c, |
| 613 transform_c_to_a, 0}, // a |
| 614 {b_id, mojom::kHitTestChildSurface | mojom::kHitTestMine, b_bounds_in_c, |
| 615 transform_c_to_b, 0} // b |
| 616 }; |
| 617 hit_test_query_.set_aggregated_hit_test_region_list( |
| 618 aggregated_hit_test_region_list_bigger, 4); |
| 619 |
| 620 Target target4 = hit_test_query_.FindTargetForLocation(point1); |
| 621 EXPECT_EQ(FrameSinkId(), target4.frame_sink_id); |
| 622 EXPECT_EQ(gfx::Point(), target4.location_in_target); |
| 623 EXPECT_FALSE(target4.flags); |
| 624 } |
| 625 |
| 626 } // namespace test |
| 627 } // namespace viz |
OLD | NEW |