touch_observer_hud_unittest.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. // Copyright (c) 2013 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/touch/touch_observer_hud.h"
  5. #include "ash/constants/ash_switches.h"
  6. #include "ash/root_window_controller.h"
  7. #include "ash/shell.h"
  8. #include "ash/test/ash_test_base.h"
  9. #include "ash/touch/touch_devices_controller.h"
  10. #include "ash/touch/touch_hud_debug.h"
  11. #include "ash/touch/touch_hud_projection.h"
  12. #include "ash/touch/touch_hud_renderer.h"
  13. #include "base/command_line.h"
  14. #include "base/format_macros.h"
  15. #include "base/strings/stringprintf.h"
  16. #include "base/time/time.h"
  17. #include "ui/aura/window.h"
  18. #include "ui/display/manager/display_manager.h"
  19. #include "ui/display/test/display_manager_test_api.h"
  20. #include "ui/views/widget/widget.h"
  21. namespace ash {
  22. class TouchHudTestBase : public AshTestBase {
  23. public:
  24. TouchHudTestBase() = default;
  25. TouchHudTestBase(const TouchHudTestBase&) = delete;
  26. TouchHudTestBase& operator=(const TouchHudTestBase&) = delete;
  27. ~TouchHudTestBase() override = default;
  28. void SetUp() override {
  29. AshTestBase::SetUp();
  30. // Initialize display infos. They should be initialized after Ash
  31. // environment is set up, i.e., after AshTestBase::SetUp().
  32. internal_display_id_ =
  33. display::test::DisplayManagerTestApi(Shell::Get()->display_manager())
  34. .SetFirstDisplayAsInternalDisplay();
  35. external_display_id_ = 10;
  36. mirrored_display_id_ = 11;
  37. internal_display_info_ =
  38. CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 600, 500));
  39. external_display_info_ =
  40. CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 200, 100));
  41. mirrored_display_info_ =
  42. CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 200, 100));
  43. }
  44. display::Display GetPrimaryDisplay() {
  45. return display::Screen::GetScreen()->GetPrimaryDisplay();
  46. }
  47. void SetupSingleDisplay() {
  48. display_info_list_.clear();
  49. display_info_list_.push_back(internal_display_info_);
  50. display_manager()->OnNativeDisplaysChanged(display_info_list_);
  51. }
  52. void SetupDualDisplays() {
  53. display_info_list_.clear();
  54. display_info_list_.push_back(internal_display_info_);
  55. display_info_list_.push_back(external_display_info_);
  56. display_manager()->OnNativeDisplaysChanged(display_info_list_);
  57. }
  58. void SetInternalAsPrimary() {
  59. GetWindowTreeHostManager()->SetPrimaryDisplayId(internal_display_id_);
  60. }
  61. void SetExternalAsPrimary() {
  62. GetWindowTreeHostManager()->SetPrimaryDisplayId(external_display_id_);
  63. }
  64. void MirrorDisplays() {
  65. DCHECK_EQ(2U, display_info_list_.size());
  66. DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
  67. DCHECK_EQ(external_display_id_, display_info_list_[1].id());
  68. display_info_list_[1] = mirrored_display_info_;
  69. display_manager()->OnNativeDisplaysChanged(display_info_list_);
  70. }
  71. void UnmirrorDisplays() {
  72. DCHECK_EQ(2U, display_info_list_.size());
  73. DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
  74. DCHECK_EQ(mirrored_display_id_, display_info_list_[1].id());
  75. display_info_list_[1] = external_display_info_;
  76. display_manager()->OnNativeDisplaysChanged(display_info_list_);
  77. }
  78. void RemoveInternalDisplay() {
  79. DCHECK_LT(0U, display_info_list_.size());
  80. DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
  81. display_info_list_.erase(display_info_list_.begin());
  82. display_manager()->OnNativeDisplaysChanged(display_info_list_);
  83. }
  84. void RemoveExternalDisplay() {
  85. DCHECK_EQ(2U, display_info_list_.size());
  86. display_info_list_.pop_back();
  87. display_manager()->OnNativeDisplaysChanged(display_info_list_);
  88. }
  89. void AddInternalDisplay() {
  90. DCHECK_EQ(0U, display_info_list_.size());
  91. display_info_list_.push_back(internal_display_info_);
  92. display_manager()->OnNativeDisplaysChanged(display_info_list_);
  93. }
  94. void AddExternalDisplay() {
  95. DCHECK_EQ(1U, display_info_list_.size());
  96. display_info_list_.push_back(external_display_info_);
  97. display_manager()->OnNativeDisplaysChanged(display_info_list_);
  98. }
  99. int64_t internal_display_id() const { return internal_display_id_; }
  100. int64_t external_display_id() const { return external_display_id_; }
  101. protected:
  102. WindowTreeHostManager* GetWindowTreeHostManager() {
  103. return Shell::Get()->window_tree_host_manager();
  104. }
  105. const display::Display& GetInternalDisplay() {
  106. return display_manager()->GetDisplayForId(internal_display_id_);
  107. }
  108. const display::Display& GetExternalDisplay() {
  109. return display_manager()->GetDisplayForId(external_display_id_);
  110. }
  111. aura::Window* GetInternalRootWindow() {
  112. return Shell::GetRootWindowForDisplayId(internal_display_id_);
  113. }
  114. aura::Window* GetExternalRootWindow() {
  115. return Shell::GetRootWindowForDisplayId(external_display_id_);
  116. }
  117. aura::Window* GetPrimaryRootWindow() {
  118. const display::Display& display = GetPrimaryDisplay();
  119. return Shell::GetRootWindowForDisplayId(display.id());
  120. }
  121. aura::Window* GetSecondaryRootWindow() {
  122. const display::Display& display =
  123. display::test::DisplayManagerTestApi(display_manager())
  124. .GetSecondaryDisplay();
  125. return Shell::GetRootWindowForDisplayId(display.id());
  126. }
  127. RootWindowController* GetInternalRootController() {
  128. aura::Window* root = GetInternalRootWindow();
  129. return RootWindowController::ForWindow(root);
  130. }
  131. RootWindowController* GetExternalRootController() {
  132. aura::Window* root = GetExternalRootWindow();
  133. return RootWindowController::ForWindow(root);
  134. }
  135. RootWindowController* GetPrimaryRootController() {
  136. aura::Window* root = GetPrimaryRootWindow();
  137. return RootWindowController::ForWindow(root);
  138. }
  139. RootWindowController* GetSecondaryRootController() {
  140. aura::Window* root = GetSecondaryRootWindow();
  141. return RootWindowController::ForWindow(root);
  142. }
  143. display::ManagedDisplayInfo CreateDisplayInfo(int64_t id,
  144. const gfx::Rect& bounds) {
  145. display::ManagedDisplayInfo info(id, base::StringPrintf("x-%" PRId64, id),
  146. false);
  147. info.SetBounds(bounds);
  148. return info;
  149. }
  150. aura::Window* GetRootWindowForTouchHud(TouchObserverHud* hud) {
  151. return hud->root_window_;
  152. }
  153. views::Widget* GetWidgetForTouchHud(TouchObserverHud* hud) {
  154. return hud->widget_;
  155. }
  156. int64_t internal_display_id_;
  157. int64_t external_display_id_;
  158. int64_t mirrored_display_id_;
  159. display::ManagedDisplayInfo internal_display_info_;
  160. display::ManagedDisplayInfo external_display_info_;
  161. display::ManagedDisplayInfo mirrored_display_info_;
  162. std::vector<display::ManagedDisplayInfo> display_info_list_;
  163. };
  164. class TouchHudDebugTest : public TouchHudTestBase {
  165. public:
  166. TouchHudDebugTest() = default;
  167. TouchHudDebugTest(const TouchHudDebugTest&) = delete;
  168. TouchHudDebugTest& operator=(const TouchHudDebugTest&) = delete;
  169. ~TouchHudDebugTest() override = default;
  170. void SetUp() override {
  171. // Add ash-touch-hud flag to enable debug touch HUD. This flag should be set
  172. // before Ash environment is set up, i.e., before TouchHudTestBase::SetUp().
  173. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  174. switches::kAshTouchHud);
  175. TouchHudTestBase::SetUp();
  176. }
  177. void CheckInternalDisplay() {
  178. EXPECT_NE(nullptr, GetInternalTouchHudDebug());
  179. EXPECT_EQ(internal_display_id(), GetInternalTouchHudDebug()->display_id());
  180. EXPECT_EQ(GetInternalRootWindow(),
  181. GetRootWindowForTouchHud(GetInternalTouchHudDebug()));
  182. EXPECT_EQ(GetInternalRootWindow(),
  183. GetWidgetForTouchHud(GetInternalTouchHudDebug())
  184. ->GetNativeView()
  185. ->GetRootWindow());
  186. EXPECT_EQ(GetInternalDisplay().size(),
  187. GetWidgetForTouchHud(GetInternalTouchHudDebug())
  188. ->GetWindowBoundsInScreen()
  189. .size());
  190. }
  191. void CheckExternalDisplay() {
  192. EXPECT_NE(nullptr, GetExternalTouchHudDebug());
  193. EXPECT_EQ(external_display_id(), GetExternalTouchHudDebug()->display_id());
  194. EXPECT_EQ(GetExternalRootWindow(),
  195. GetRootWindowForTouchHud(GetExternalTouchHudDebug()));
  196. EXPECT_EQ(GetExternalRootWindow(),
  197. GetWidgetForTouchHud(GetExternalTouchHudDebug())
  198. ->GetNativeView()
  199. ->GetRootWindow());
  200. EXPECT_EQ(GetExternalDisplay().size(),
  201. GetWidgetForTouchHud(GetExternalTouchHudDebug())
  202. ->GetWindowBoundsInScreen()
  203. .size());
  204. }
  205. private:
  206. TouchHudDebug* GetInternalTouchHudDebug() {
  207. return GetInternalRootController()->touch_hud_debug();
  208. }
  209. TouchHudDebug* GetExternalTouchHudDebug() {
  210. return GetExternalRootController()->touch_hud_debug();
  211. }
  212. TouchHudDebug* GetPrimaryTouchHudDebug() {
  213. return GetPrimaryRootController()->touch_hud_debug();
  214. }
  215. TouchHudDebug* GetSecondaryTouchHudDebug() {
  216. return GetSecondaryRootController()->touch_hud_debug();
  217. }
  218. };
  219. class TouchHudProjectionTest : public TouchHudTestBase {
  220. public:
  221. TouchHudProjectionTest() = default;
  222. TouchHudProjectionTest(const TouchHudProjectionTest&) = delete;
  223. TouchHudProjectionTest& operator=(const TouchHudProjectionTest&) = delete;
  224. ~TouchHudProjectionTest() override = default;
  225. // testing::Test:
  226. void SetUp() override {
  227. base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kShowTaps);
  228. TouchHudTestBase::SetUp();
  229. }
  230. TouchHudProjection* GetInternalTouchHudProjection() {
  231. return GetInternalRootController()->touch_hud_projection();
  232. }
  233. int GetInternalTouchPointsCount() {
  234. return GetInternalTouchHudProjection()->touch_hud_renderer_->points_.size();
  235. }
  236. void SendTouchEventToInternalHud(ui::EventType type,
  237. const gfx::Point& location,
  238. int touch_id) {
  239. ui::TouchEvent event(
  240. type, location, event_time,
  241. ui::PointerDetails(ui::EventPointerType::kTouch, touch_id));
  242. GetInternalTouchHudProjection()->OnTouchEvent(&event);
  243. // Advance time for next event.
  244. event_time += base::Milliseconds(100);
  245. }
  246. private:
  247. base::TimeTicks event_time;
  248. };
  249. // Checks if debug touch HUD is correctly initialized for a single display.
  250. TEST_F(TouchHudDebugTest, SingleDisplay) {
  251. // Setup a single display setting.
  252. SetupSingleDisplay();
  253. // Check if touch HUD is set correctly and associated with appropriate
  254. // display.
  255. CheckInternalDisplay();
  256. }
  257. // Checks if debug touch HUDs are correctly initialized for two displays.
  258. TEST_F(TouchHudDebugTest, DualDisplays) {
  259. // Setup a dual display setting.
  260. SetupDualDisplays();
  261. // Check if touch HUDs are set correctly and associated with appropriate
  262. // displays.
  263. CheckInternalDisplay();
  264. CheckExternalDisplay();
  265. }
  266. // Checks if debug touch HUDs are correctly handled when primary display is
  267. // changed.
  268. TEST_F(TouchHudDebugTest, SwapPrimaryDisplay) {
  269. // Setup a dual display setting.
  270. SetupDualDisplays();
  271. // Set the primary display to the external one.
  272. SetExternalAsPrimary();
  273. display::test::DisplayManagerTestApi display_manager_test(display_manager());
  274. // Check if displays' touch HUDs are not swapped as root windows are.
  275. EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
  276. EXPECT_EQ(internal_display_id(),
  277. display_manager_test.GetSecondaryDisplay().id());
  278. CheckInternalDisplay();
  279. CheckExternalDisplay();
  280. // Set the primary display back to the internal one.
  281. SetInternalAsPrimary();
  282. // Check if displays' touch HUDs are not swapped back as root windows are.
  283. EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
  284. EXPECT_EQ(external_display_id(),
  285. display_manager_test.GetSecondaryDisplay().id());
  286. CheckInternalDisplay();
  287. CheckExternalDisplay();
  288. }
  289. // Checks if debug touch HUDs are correctly handled when displays are mirrored.
  290. TEST_F(TouchHudDebugTest, MirrorDisplays) {
  291. // Disable restoring mirror mode to prevent interference from previous
  292. // display configuration.
  293. display_manager()->set_disable_restoring_mirror_mode_for_test(true);
  294. // Setup a dual display setting.
  295. SetupDualDisplays();
  296. // Mirror displays.
  297. MirrorDisplays();
  298. // Check if the internal display is intact.
  299. EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
  300. CheckInternalDisplay();
  301. // Unmirror displays.
  302. UnmirrorDisplays();
  303. // Check if external display is added back correctly.
  304. EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
  305. EXPECT_EQ(external_display_id(),
  306. display::test::DisplayManagerTestApi(display_manager())
  307. .GetSecondaryDisplay()
  308. .id());
  309. CheckInternalDisplay();
  310. CheckExternalDisplay();
  311. display_manager()->set_disable_restoring_mirror_mode_for_test(false);
  312. }
  313. // Checks if debug touch HUDs are correctly handled when displays are mirrored
  314. // after setting the external display as the primary one.
  315. TEST_F(TouchHudDebugTest, SwapPrimaryThenMirrorDisplays) {
  316. display_manager()->set_disable_restoring_mirror_mode_for_test(true);
  317. // Setup a dual display setting.
  318. SetupDualDisplays();
  319. // Set the primary display to the external one.
  320. SetExternalAsPrimary();
  321. // Mirror displays.
  322. MirrorDisplays();
  323. // Check if the internal display is set as the primary one.
  324. EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
  325. CheckInternalDisplay();
  326. // Unmirror displays.
  327. UnmirrorDisplays();
  328. // Check if the external display is added back as the primary display and
  329. // touch HUDs are set correctly.
  330. EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
  331. EXPECT_EQ(internal_display_id(),
  332. display::test::DisplayManagerTestApi(display_manager())
  333. .GetSecondaryDisplay()
  334. .id());
  335. CheckInternalDisplay();
  336. CheckExternalDisplay();
  337. display_manager()->set_disable_restoring_mirror_mode_for_test(false);
  338. }
  339. // Checks if debug touch HUDs are correctly handled when the external display,
  340. // which is the secondary one, is removed.
  341. TEST_F(TouchHudDebugTest, RemoveSecondaryDisplay) {
  342. // Setup a dual display setting.
  343. SetupDualDisplays();
  344. // Remove external display which is the secondary one.
  345. RemoveExternalDisplay();
  346. // Check if the internal display is intact.
  347. EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
  348. CheckInternalDisplay();
  349. // Add external display back.
  350. AddExternalDisplay();
  351. // Check if displays' touch HUDs are set correctly.
  352. EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
  353. EXPECT_EQ(external_display_id(),
  354. display::test::DisplayManagerTestApi(display_manager())
  355. .GetSecondaryDisplay()
  356. .id());
  357. CheckInternalDisplay();
  358. CheckExternalDisplay();
  359. }
  360. // Checks if debug touch HUDs are correctly handled when the external display,
  361. // which is set as the primary display, is removed.
  362. TEST_F(TouchHudDebugTest, RemovePrimaryDisplay) {
  363. // Setup a dual display setting.
  364. SetupDualDisplays();
  365. // Set the primary display to the external one.
  366. SetExternalAsPrimary();
  367. // Remove the external display which is the primary display.
  368. RemoveExternalDisplay();
  369. // Check if the internal display is set as the primary one.
  370. EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
  371. CheckInternalDisplay();
  372. // Add the external display back.
  373. AddExternalDisplay();
  374. // Check if the external display is set as primary and touch HUDs are set
  375. // correctly.
  376. EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
  377. EXPECT_EQ(internal_display_id(),
  378. display::test::DisplayManagerTestApi(display_manager())
  379. .GetSecondaryDisplay()
  380. .id());
  381. CheckInternalDisplay();
  382. CheckExternalDisplay();
  383. }
  384. // Checks if debug touch HUDs are correctly handled when all displays are
  385. // removed.
  386. TEST_F(TouchHudDebugTest, Headless) {
  387. // Setup a single display setting.
  388. SetupSingleDisplay();
  389. // Remove the only display which is the internal one.
  390. RemoveInternalDisplay();
  391. // Add the internal display back.
  392. AddInternalDisplay();
  393. // Check if the display's touch HUD is set correctly.
  394. EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
  395. CheckInternalDisplay();
  396. }
  397. // Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
  398. // and touch-released events.
  399. // Test if the WM sets correct work area under different density.
  400. TEST_F(TouchHudProjectionTest, TouchMoveRelease) {
  401. SetupSingleDisplay();
  402. EXPECT_NE(nullptr, GetInternalTouchHudProjection());
  403. EXPECT_EQ(0, GetInternalTouchPointsCount());
  404. SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
  405. EXPECT_EQ(1, GetInternalTouchPointsCount());
  406. SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
  407. EXPECT_EQ(1, GetInternalTouchPointsCount());
  408. SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
  409. EXPECT_EQ(0, GetInternalTouchPointsCount());
  410. }
  411. // Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
  412. // and touch-cancelled events.
  413. TEST_F(TouchHudProjectionTest, TouchMoveCancel) {
  414. SetupSingleDisplay();
  415. EXPECT_NE(nullptr, GetInternalTouchHudProjection());
  416. EXPECT_EQ(0, GetInternalTouchPointsCount());
  417. SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
  418. EXPECT_EQ(1, GetInternalTouchPointsCount());
  419. SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
  420. EXPECT_EQ(1, GetInternalTouchPointsCount());
  421. SendTouchEventToInternalHud(ui::ET_TOUCH_CANCELLED, gfx::Point(10, 20), 1);
  422. EXPECT_EQ(0, GetInternalTouchPointsCount());
  423. }
  424. // Checks projection touch HUD with two simultaneous touches.
  425. TEST_F(TouchHudProjectionTest, DoubleTouch) {
  426. SetupSingleDisplay();
  427. EXPECT_NE(nullptr, GetInternalTouchHudProjection());
  428. EXPECT_EQ(0, GetInternalTouchPointsCount());
  429. SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
  430. EXPECT_EQ(1, GetInternalTouchPointsCount());
  431. SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(20, 10), 2);
  432. EXPECT_EQ(2, GetInternalTouchPointsCount());
  433. SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
  434. EXPECT_EQ(2, GetInternalTouchPointsCount());
  435. SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 2);
  436. EXPECT_EQ(2, GetInternalTouchPointsCount());
  437. SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
  438. EXPECT_EQ(1, GetInternalTouchPointsCount());
  439. SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 2);
  440. EXPECT_EQ(0, GetInternalTouchPointsCount());
  441. }
  442. } // namespace ash