unified_mouse_warp_controller_unittest.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. // Copyright 2015 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. #include "ash/display/unified_mouse_warp_controller.h"
  5. #include <sstream>
  6. #include "ash/display/display_util.h"
  7. #include "ash/display/mirror_window_controller.h"
  8. #include "ash/display/mouse_cursor_event_filter.h"
  9. #include "ash/host/ash_window_tree_host.h"
  10. #include "ash/shell.h"
  11. #include "ash/test/ash_test_base.h"
  12. #include "ui/aura/env.h"
  13. #include "ui/aura/window_tree_host.h"
  14. #include "ui/display/display.h"
  15. #include "ui/display/display_finder.h"
  16. #include "ui/display/manager/display_manager.h"
  17. #include "ui/display/screen.h"
  18. #include "ui/events/test/event_generator.h"
  19. #include "ui/wm/core/coordinate_conversion.h"
  20. namespace ash {
  21. namespace {
  22. struct WarpGroup {
  23. // Native point at a warp edge before warping.
  24. gfx::Point native_point_at_edge;
  25. // Expected DIP point after warping.
  26. gfx::Point expected_point_after_warp;
  27. // Expected display ID after warping.
  28. int64_t expected_target_display_id;
  29. };
  30. } // namespace
  31. class UnifiedMouseWarpControllerTest : public AshTestBase {
  32. public:
  33. UnifiedMouseWarpControllerTest() = default;
  34. UnifiedMouseWarpControllerTest(const UnifiedMouseWarpControllerTest&) =
  35. delete;
  36. UnifiedMouseWarpControllerTest& operator=(
  37. const UnifiedMouseWarpControllerTest&) = delete;
  38. ~UnifiedMouseWarpControllerTest() override = default;
  39. void SetUp() override {
  40. AshTestBase::SetUp();
  41. display_manager()->SetUnifiedDesktopEnabled(true);
  42. }
  43. protected:
  44. bool MoveMouseToNativePoint(const gfx::Point& point_in_native,
  45. int64_t* out_original_mirroring_display_id) {
  46. for (auto display : display_manager()->software_mirroring_display_list()) {
  47. display::ManagedDisplayInfo info =
  48. display_manager()->GetDisplayInfo(display.id());
  49. if (info.bounds_in_native().Contains(point_in_native)) {
  50. *out_original_mirroring_display_id = info.id();
  51. gfx::Point point_in_mirroring_host = point_in_native;
  52. const gfx::Point& origin = info.bounds_in_native().origin();
  53. // Convert to mirroring host.
  54. point_in_mirroring_host.Offset(-origin.x(), -origin.y());
  55. // Move the mouse inside the host.
  56. AshWindowTreeHost* ash_host =
  57. Shell::Get()
  58. ->window_tree_host_manager()
  59. ->mirror_window_controller()
  60. ->GetAshWindowTreeHostForDisplayId(info.id());
  61. ui::test::EventGenerator gen(ash_host->AsWindowTreeHost()->window());
  62. gen.MoveMouseToWithNative(point_in_mirroring_host,
  63. point_in_mirroring_host);
  64. return true;
  65. }
  66. }
  67. return false;
  68. }
  69. bool TestIfMouseWarpsAt(const gfx::Point& point_in_native) {
  70. static_cast<UnifiedMouseWarpController*>(
  71. Shell::Get()->mouse_cursor_filter()->mouse_warp_controller_for_test())
  72. ->update_location_for_test();
  73. int64_t orig_mirroring_display_id;
  74. if (!MoveMouseToNativePoint(point_in_native, &orig_mirroring_display_id))
  75. return false;
  76. aura::Window* root = Shell::GetPrimaryRootWindow();
  77. gfx::Point new_location_in_unified_host =
  78. aura::Env::GetInstance()->last_mouse_location();
  79. // Convert screen to the host.
  80. root->GetHost()->ConvertDIPToPixels(&new_location_in_unified_host);
  81. auto iter = display::FindDisplayContainingPoint(
  82. display_manager()->software_mirroring_display_list(),
  83. new_location_in_unified_host);
  84. if (iter == display_manager()->software_mirroring_display_list().end())
  85. return false;
  86. return orig_mirroring_display_id != iter->id();
  87. }
  88. MouseCursorEventFilter* event_filter() {
  89. return Shell::Get()->mouse_cursor_filter();
  90. }
  91. UnifiedMouseWarpController* mouse_warp_controller() {
  92. return static_cast<UnifiedMouseWarpController*>(
  93. event_filter()->mouse_warp_controller_for_test());
  94. }
  95. // |expected_edges| should have a row for each display which contains the
  96. // expected native bounds of the shared edges with that display in the order
  97. // "top", "left", "right", "bottom".
  98. // If |matrix| is empty, default unified layout will be used.
  99. void BoundaryTestBody(
  100. const std::string& displays_specs,
  101. const display::UnifiedDesktopLayoutMatrix& matrix,
  102. const std::vector<std::vector<std::string>>& expected_edges) {
  103. UpdateDisplay(displays_specs);
  104. display_manager()->SetUnifiedDesktopMatrix(matrix);
  105. // Let the UnifiedMouseWarpController compute the bounds by
  106. // generating a mouse move event.
  107. GetEventGenerator()->MoveMouseTo(gfx::Point(0, 0));
  108. const display::Displays& mirroring_displays =
  109. display_manager()->software_mirroring_display_list();
  110. ASSERT_EQ(expected_edges.size(), mirroring_displays.size());
  111. int index = 0;
  112. for (const auto& display : mirroring_displays) {
  113. const int64_t id = display.id();
  114. std::stringstream scoped_trace_message;
  115. scoped_trace_message << "Edges of display with ID: " << id
  116. << " at index: " << index;
  117. SCOPED_TRACE(scoped_trace_message.str());
  118. const auto& display_expected_edges = expected_edges[index++];
  119. const auto& display_actual_edges =
  120. mouse_warp_controller()->displays_edges_map_.at(id);
  121. ASSERT_EQ(display_expected_edges.size(), display_actual_edges.size());
  122. for (size_t i = 0; i < display_expected_edges.size(); ++i) {
  123. EXPECT_EQ(display_expected_edges[i],
  124. display_actual_edges[i]
  125. .edge_native_bounds_in_source_display.ToString());
  126. }
  127. }
  128. }
  129. void WarpTestBody(const std::vector<WarpGroup>& warp_groups) {
  130. for (const auto& group : warp_groups) {
  131. EXPECT_TRUE(TestIfMouseWarpsAt(group.native_point_at_edge));
  132. gfx::Point new_location = aura::Env::GetInstance()->last_mouse_location();
  133. EXPECT_EQ(group.expected_point_after_warp, new_location);
  134. // Convert screen to the host.
  135. aura::Window* root = Shell::GetPrimaryRootWindow();
  136. root->GetHost()->ConvertDIPToPixels(&new_location);
  137. auto iter = display::FindDisplayContainingPoint(
  138. display_manager()->software_mirroring_display_list(), new_location);
  139. EXPECT_FALSE(iter ==
  140. display_manager()->software_mirroring_display_list().end());
  141. EXPECT_EQ(group.expected_target_display_id, iter->id());
  142. }
  143. }
  144. void NoWarpTestBody() {
  145. // Touch the left edge of the first display.
  146. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(0, 10)));
  147. // Touch the top edge of the first display.
  148. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 0)));
  149. // Touch the bottom edge of the first display.
  150. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 499)));
  151. // Touch the right edge of the second display.
  152. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(1099, 10)));
  153. // Touch the top edge of the second display.
  154. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(610, 0)));
  155. // Touch the bottom edge of the second display.
  156. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(610, 499)));
  157. }
  158. };
  159. // Verifies if MouseCursorEventFilter's bounds calculation works correctly.
  160. TEST_F(UnifiedMouseWarpControllerTest, BoundaryTest) {
  161. {
  162. SCOPED_TRACE("1x1");
  163. BoundaryTestBody("500x400,0+450-700x400",
  164. {}, // Empty matrix (use horizontal layout).
  165. {{"499,0 1x400"}, {"0,450 1x400"}});
  166. BoundaryTestBody("500x400,0+450-700x600",
  167. {}, // Empty matrix (use horizontal layout).
  168. {{"499,0 1x400"}, {"0,450 1x600"}});
  169. }
  170. {
  171. SCOPED_TRACE("2x1");
  172. BoundaryTestBody("500x400*2,0+450-700x400",
  173. {}, // Empty matrix (use horizontal layout).
  174. {{"499,0 1x400"}, {"0,450 1x400"}});
  175. BoundaryTestBody("500x400*2,0+450-700x600",
  176. {}, // Empty matrix (use horizontal layout).
  177. {{"499,0 1x400"}, {"0,450 1x600"}});
  178. }
  179. {
  180. SCOPED_TRACE("1x2");
  181. BoundaryTestBody("500x400,0+450-700x400*2",
  182. {}, // Empty matrix (use horizontal layout).
  183. {{"499,0 1x400"}, {"0,450 1x400"}});
  184. BoundaryTestBody("500x400,0+450-700x600*2",
  185. {}, // Empty matrix (use horizontal layout).
  186. {{"499,0 1x400"}, {"0,450 1x600"}});
  187. }
  188. {
  189. SCOPED_TRACE("2x2");
  190. BoundaryTestBody("500x400*2,0+450-700x400*2",
  191. {}, // Empty matrix (use horizontal layout).
  192. {{"499,0 1x400"}, {"0,450 1x400"}});
  193. BoundaryTestBody("500x400*2,0+450-700x600*2",
  194. {}, // Empty matrix (use horizontal layout).
  195. {{"499,0 1x400"}, {"0,450 1x600"}});
  196. }
  197. }
  198. TEST_F(UnifiedMouseWarpControllerTest, BoundaryAndWarpSimpleTest) {
  199. const std::vector<std::vector<std::string>> expected_edges = {
  200. // Display 0 edges.
  201. {
  202. "1919,0 1x1080", // Right with display 1.
  203. },
  204. // Display 1 edges.
  205. {
  206. "1930,0 1x1200", // Left with display 0.
  207. },
  208. };
  209. BoundaryTestBody("0+0-1920x1080,1930+0-1920x1200",
  210. {} /* empty matrix = default */, expected_edges);
  211. display::DisplayIdList list = display_manager()->GetConnectedDisplayIdList();
  212. ASSERT_EQ(2u, list.size());
  213. // Assert mouse warps in all bounds to the correct display.
  214. const std::vector<WarpGroup> warp_groups = {
  215. {{1919, 500}, {1920, 499}, list[1]}, // Display 0 --> 1.
  216. {{1930, 600}, {1918, 540}, list[0]}, // Display 1 --> 0.
  217. };
  218. WarpTestBody(warp_groups);
  219. }
  220. TEST_F(UnifiedMouseWarpControllerTest, BoundaryTestGrid) {
  221. // Update displays here first so we get the correct display IDs list. The
  222. // below are the native bounds.
  223. const std::string display_specs =
  224. "0+0-500x300,510+0-400x500,920+0-300x600,"
  225. "0+600-200x300,210+600-700x200,920+600-350x480,"
  226. "0+1080-300x500,310+1080-600x599,920+1080-400x450";
  227. UpdateDisplay(display_specs);
  228. display_manager()->SetUnifiedDesktopEnabled(true);
  229. display::DisplayIdList list = display_manager()->GetConnectedDisplayIdList();
  230. ASSERT_EQ(9u, list.size());
  231. // Test a very general case of a 3 x 3 matrix.
  232. // 0:[500 x 300] 1:[400 x 500] 2:[300 x 600]
  233. // 3:[200 x 300] 4:[700 x 200] 5:[350 x 480]
  234. // 6:[300 x 500] 7:[600 x 599] 8:[400 x 450]
  235. display::UnifiedDesktopLayoutMatrix matrix;
  236. matrix.resize(3u);
  237. matrix[0].emplace_back(list[0]);
  238. matrix[0].emplace_back(list[1]);
  239. matrix[0].emplace_back(list[2]);
  240. matrix[1].emplace_back(list[3]);
  241. matrix[1].emplace_back(list[4]);
  242. matrix[1].emplace_back(list[5]);
  243. matrix[2].emplace_back(list[6]);
  244. matrix[2].emplace_back(list[7]);
  245. matrix[2].emplace_back(list[8]);
  246. const std::vector<std::vector<std::string>> expected_edges = {
  247. // Display 0 edges.
  248. {
  249. "499,0 1x300", // Right with display 1.
  250. "0,299 121x1", // Bottom with display 3.
  251. "121,299 379x1", // Bottom with display 4.
  252. },
  253. // Display 1 edges.
  254. {
  255. "510,0 1x500", // Left with display 0.
  256. "909,0 1x500", // Right with display 2.
  257. "510,499 400x1", // Bottom with display 4.
  258. },
  259. // Display 2 edges.
  260. {
  261. "920,0 1x600", // Left with display 1.
  262. "920,599 34x1", // Bottom with display 4.
  263. "954,599 266x1", // Bottom with display 5.
  264. },
  265. // Display 3 edges.
  266. {
  267. "0,600 199x1", // Top with display 0.
  268. "199,600 1x300", // Right with display 4.
  269. "0,899 199x1", // Bottom with display 6.
  270. },
  271. // Display 4 edges.
  272. {
  273. "210,600 416x1", // Top with display 0.
  274. "626,600 264x1", // Top with display 1.
  275. "890,600 18x1", // Top with display 2.
  276. "210,600 1x200", // Left with display 3.
  277. "909,600 1x200", // Right with display 5.
  278. "210,799 102x1", // Bottom with display 6.
  279. "312,799 393x1", // Bottom with display 7.
  280. "705,799 203x1", // Bottom with display 8.
  281. },
  282. // Display 5 edges.
  283. {
  284. "920,600 350x1", // Top with display 2.
  285. "920,600 1x480", // Left with display 4.
  286. "920,1079 350x1", // Bottom with display 8.
  287. },
  288. // Display 6 edges.
  289. {
  290. "0,1080 169x1", // Top with display 3.
  291. "169,1080 130x1", // Top with display 4.
  292. "299,1080 1x500", // Right with display 7.
  293. },
  294. // Display 7 edges.
  295. {
  296. "310,1080 600x1", // Top with display 4.
  297. "310,1080 1x599", // Left with display 6.
  298. "909,1080 1x599", // Right with display 8.
  299. },
  300. // Display 8 edges.
  301. {
  302. "920,1080 233x1", // Top with display 4.
  303. "1153,1080 167x1", // Top with display 5.
  304. "920,1080 1x450", // Left with display 7.
  305. },
  306. };
  307. BoundaryTestBody(display_specs, matrix, expected_edges);
  308. ASSERT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
  309. // Assert mouse warps in all bounds to the correct display.
  310. const std::vector<WarpGroup> warp_groups = {
  311. {{499, 10}, {500, 9}, list[1]}, // Display 0 --> 1.
  312. {{10, 299}, {9, 300}, list[3]}, // Display 0 --> 3.
  313. {{130, 299}, {129, 300}, list[4]}, // Display 0 --> 4.
  314. {{510, 10}, {498, 6}, list[0]}, // Display 1 --> 0.
  315. {{909, 50}, {740, 30}, list[2]}, // Display 1 --> 2.
  316. {{600, 499}, {553, 300}, list[4]}, // Display 1 --> 4.
  317. {{920, 50}, {738, 24}, list[1]}, // Display 2 --> 1.
  318. {{930, 599}, {744, 300}, list[4]}, // Display 2 --> 4.
  319. {{970, 599}, {764, 300}, list[5]}, // Display 2 --> 5.
  320. {{10, 600}, {6, 298}, list[0]}, // Display 3 --> 0.
  321. {{199, 700}, {121, 359}, list[4]}, // Display 3 --> 4.
  322. {{100, 899}, {59, 482}, list[6]}, // Display 3 --> 6.
  323. {{250, 600}, {157, 298}, list[0]}, // Display 4 --> 0.
  324. {{700, 600}, {566, 298}, list[1]}, // Display 4 --> 1.
  325. {{900, 600}, {748, 299}, list[2]}, // Display 4 --> 2.
  326. {{210, 700}, {120, 391}, list[3]}, // Display 4 --> 3.
  327. {{909, 650}, {757, 344}, list[5]}, // Display 4 --> 5.
  328. {{250, 799}, {156, 482}, list[6]}, // Display 4 --> 6.
  329. {{500, 799}, {383, 482}, list[7]}, // Display 4 --> 7.
  330. {{800, 799}, {656, 482}, list[8]}, // Display 4 --> 8.
  331. {{950, 600}, {768, 299}, list[2]}, // Display 5 --> 2.
  332. {{920, 750}, {756, 355}, list[4]}, // Display 5 --> 4.
  333. {{1000, 1079}, {786, 482}, list[8]}, // Display 5 --> 8.
  334. {{100, 1080}, {70, 480}, list[3]}, // Display 6 --> 3.
  335. {{200, 1080}, {141, 480}, list[4]}, // Display 6 --> 4.
  336. {{299, 1200}, {214, 566}, list[7]}, // Display 6 --> 7.
  337. {{500, 1080}, {326, 480}, list[4]}, // Display 7 --> 4.
  338. {{310, 1500}, {212, 731}, list[6]}, // Display 7 --> 6.
  339. {{909, 1500}, {572, 731}, list[8]}, // Display 7 --> 8.
  340. {{1000, 1080}, {634, 480}, list[4]}, // Display 8 --> 4.
  341. {{1200, 1080}, {793, 481}, list[5]}, // Display 8 --> 5.
  342. {{920, 1500}, {570, 814}, list[7]}, // Display 8 --> 7.
  343. };
  344. WarpTestBody(warp_groups);
  345. }
  346. // Verifies if the mouse pointer correctly moves to another display in
  347. // unified desktop mode.
  348. TEST_F(UnifiedMouseWarpControllerTest, WarpMouse) {
  349. UpdateDisplay("600x500,700+0-600x500");
  350. ASSERT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
  351. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 10)));
  352. // Touch the right edge of the first display. Pointer should warp.
  353. EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(599, 10)));
  354. EXPECT_EQ("601,10", // by 2px.
  355. aura::Env::GetInstance()->last_mouse_location().ToString());
  356. // Touch the left edge of the second display. Pointer should warp.
  357. EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(700, 10)));
  358. EXPECT_EQ("598,10", // by 2px.
  359. aura::Env::GetInstance()->last_mouse_location().ToString());
  360. {
  361. SCOPED_TRACE("1x1 NO WARP");
  362. NoWarpTestBody();
  363. }
  364. // With 2X and 1X displays
  365. UpdateDisplay("600x500*2,700+0-600x500");
  366. ASSERT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
  367. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 10)));
  368. // Touch the right edge of the first display. Pointer should warp.
  369. EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(599, 10)));
  370. EXPECT_EQ("300,5", // moved to 601 by 2px, divided by 2 (dsf).
  371. aura::Env::GetInstance()->last_mouse_location().ToString());
  372. // Touch the left edge of the second display. Pointer should warp.
  373. EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(700, 10)));
  374. EXPECT_EQ("299,5", // moved to 598 by 2px, divided by 2 (dsf).
  375. aura::Env::GetInstance()->last_mouse_location().ToString());
  376. {
  377. SCOPED_TRACE("2x1 NO WARP");
  378. NoWarpTestBody();
  379. }
  380. // With 1X and 2X displays
  381. UpdateDisplay("600x500,700+0-600x500*2");
  382. ASSERT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
  383. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 10)));
  384. // Touch the right edge of the first display. Pointer should warp.
  385. EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(599, 10)));
  386. EXPECT_EQ("601,10", // by 2px.
  387. aura::Env::GetInstance()->last_mouse_location().ToString());
  388. // Touch the left edge of the second display. Pointer should warp.
  389. EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(700, 10)));
  390. EXPECT_EQ("598,10", // by 2px.
  391. aura::Env::GetInstance()->last_mouse_location().ToString());
  392. {
  393. SCOPED_TRACE("1x2 NO WARP");
  394. NoWarpTestBody();
  395. }
  396. // With two 2X displays
  397. UpdateDisplay("600x500*2,700+0-600x500*2");
  398. ASSERT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
  399. EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(10, 10)));
  400. // Touch the right edge of the first display. Pointer should warp.
  401. EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(599, 10)));
  402. EXPECT_EQ("300,5", // by 2px.
  403. aura::Env::GetInstance()->last_mouse_location().ToString());
  404. // Touch the left edge of the second display. Pointer should warp.
  405. EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(700, 10)));
  406. EXPECT_EQ("299,5", // moved to 598 by 2px, divided by 2 (dsf).
  407. aura::Env::GetInstance()->last_mouse_location().ToString());
  408. {
  409. SCOPED_TRACE("1x2 NO WARP");
  410. NoWarpTestBody();
  411. }
  412. }
  413. } // namespace aura