touch_unittest.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  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 "components/exo/touch.h"
  5. #include "ash/public/cpp/shell_window_ids.h"
  6. #include "ash/shell.h"
  7. #include "ash/wm/window_positioner.h"
  8. #include "ash/wm/window_positioning_utils.h"
  9. #include "components/exo/buffer.h"
  10. #include "components/exo/data_source.h"
  11. #include "components/exo/data_source_delegate.h"
  12. #include "components/exo/seat.h"
  13. #include "components/exo/shell_surface.h"
  14. #include "components/exo/surface.h"
  15. #include "components/exo/test/exo_test_base.h"
  16. #include "components/exo/test/exo_test_data_exchange_delegate.h"
  17. #include "components/exo/test/exo_test_helper.h"
  18. #include "components/exo/test/shell_surface_builder.h"
  19. #include "components/exo/touch_delegate.h"
  20. #include "components/exo/touch_stylus_delegate.h"
  21. #include "testing/gmock/include/gmock/gmock.h"
  22. #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
  23. #include "ui/events/base_event_utils.h"
  24. #include "ui/events/test/event_generator.h"
  25. #include "ui/views/widget/widget.h"
  26. namespace exo {
  27. namespace {
  28. using TouchTest = test::ExoTestBase;
  29. class MockTouchDelegate : public TouchDelegate {
  30. public:
  31. MockTouchDelegate() {}
  32. // Overridden from TouchDelegate:
  33. MOCK_METHOD1(OnTouchDestroying, void(Touch*));
  34. MOCK_CONST_METHOD1(CanAcceptTouchEventsForSurface, bool(Surface*));
  35. MOCK_METHOD4(OnTouchDown,
  36. void(Surface*, base::TimeTicks, int, const gfx::PointF&));
  37. MOCK_METHOD2(OnTouchUp, void(base::TimeTicks, int));
  38. MOCK_METHOD3(OnTouchMotion, void(base::TimeTicks, int, const gfx::PointF&));
  39. MOCK_METHOD3(OnTouchShape, void(int, float, float));
  40. MOCK_METHOD0(OnTouchFrame, void());
  41. MOCK_METHOD0(OnTouchCancel, void());
  42. };
  43. class MockTouchStylusDelegate : public TouchStylusDelegate {
  44. public:
  45. MockTouchStylusDelegate() {}
  46. // Overridden from TouchStylusDelegate:
  47. MOCK_METHOD1(OnTouchDestroying, void(Touch*));
  48. MOCK_METHOD2(OnTouchTool, void(int, ui::EventPointerType));
  49. MOCK_METHOD3(OnTouchForce, void(base::TimeTicks, int, float));
  50. MOCK_METHOD3(OnTouchTilt, void(base::TimeTicks, int, const gfx::Vector2dF&));
  51. };
  52. class TestDataSourceDelegate : public DataSourceDelegate {
  53. public:
  54. TestDataSourceDelegate() {}
  55. TestDataSourceDelegate(const TestDataSourceDelegate&) = delete;
  56. TestDataSourceDelegate& operator=(const TestDataSourceDelegate&) = delete;
  57. // Overridden from DataSourceDelegate:
  58. void OnDataSourceDestroying(DataSource* device) override {}
  59. void OnTarget(const absl::optional<std::string>& mime_type) override {}
  60. void OnSend(const std::string& mime_type, base::ScopedFD fd) override {}
  61. void OnCancelled() override {}
  62. void OnDndDropPerformed() override {}
  63. void OnDndFinished() override {}
  64. void OnAction(DndAction dnd_action) override {}
  65. bool CanAcceptDataEventsForSurface(Surface* surface) const override {
  66. return true;
  67. }
  68. };
  69. TEST_F(TouchTest, OnTouchDown) {
  70. MockTouchDelegate delegate;
  71. Seat seat;
  72. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  73. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  74. auto bottom_shell_surface =
  75. test::ShellSurfaceBuilder({10, 10}).SetCentered().BuildShellSurface();
  76. auto top_shell_surface =
  77. test::ShellSurfaceBuilder({8, 8}).SetCentered().BuildShellSurface();
  78. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  79. .Times(testing::AnyNumber());
  80. EXPECT_CALL(delegate,
  81. CanAcceptTouchEventsForSurface(top_shell_surface->root_surface()))
  82. .WillRepeatedly(testing::Return(true));
  83. EXPECT_CALL(delegate, OnTouchDown(top_shell_surface->root_surface(),
  84. testing::_, 1, gfx::PointF()));
  85. EXPECT_CALL(delegate, OnTouchFrame());
  86. generator.set_current_screen_location(
  87. GetOriginOfShellSurface(top_shell_surface.get()));
  88. generator.PressTouchId(1);
  89. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(
  90. bottom_shell_surface->root_surface()))
  91. .WillRepeatedly(testing::Return(true));
  92. // Second touch point should be relative to the focus surface.
  93. EXPECT_CALL(delegate, OnTouchDown(top_shell_surface->root_surface(),
  94. testing::_, 2, gfx::PointF(-1, -1)));
  95. EXPECT_CALL(delegate, OnTouchFrame());
  96. generator.set_current_screen_location(
  97. GetOriginOfShellSurface(bottom_shell_surface.get()));
  98. generator.PressTouchId(2);
  99. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  100. touch.reset();
  101. }
  102. TEST_F(TouchTest, OnTouchUp) {
  103. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  104. auto* root_surface = shell_surface->root_surface();
  105. MockTouchDelegate delegate;
  106. Seat seat;
  107. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  108. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  109. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  110. .Times(testing::AnyNumber());
  111. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  112. .WillRepeatedly(testing::Return(true));
  113. EXPECT_CALL(delegate,
  114. OnTouchDown(root_surface, testing::_, testing::_, gfx::PointF()))
  115. .Times(2);
  116. EXPECT_CALL(delegate, OnTouchFrame()).Times(2);
  117. generator.set_current_screen_location(
  118. GetOriginOfShellSurface(shell_surface.get()));
  119. generator.PressTouchId(1);
  120. generator.PressTouchId(2);
  121. EXPECT_CALL(delegate, OnTouchUp(testing::_, 1));
  122. EXPECT_CALL(delegate, OnTouchFrame());
  123. generator.ReleaseTouchId(1);
  124. EXPECT_CALL(delegate, OnTouchUp(testing::_, 2));
  125. EXPECT_CALL(delegate, OnTouchFrame());
  126. generator.ReleaseTouchId(2);
  127. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  128. touch.reset();
  129. }
  130. TEST_F(TouchTest, OnTouchMotion) {
  131. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  132. auto* root_surface = shell_surface->root_surface();
  133. MockTouchDelegate delegate;
  134. Seat seat;
  135. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  136. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  137. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  138. .Times(testing::AnyNumber());
  139. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  140. .WillRepeatedly(testing::Return(true));
  141. EXPECT_CALL(delegate,
  142. OnTouchDown(root_surface, testing::_, testing::_, gfx::PointF()));
  143. EXPECT_CALL(delegate,
  144. OnTouchMotion(testing::_, testing::_, gfx::PointF(5, 5)));
  145. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
  146. EXPECT_CALL(delegate, OnTouchFrame()).Times(3);
  147. generator.set_current_screen_location(
  148. GetOriginOfShellSurface(shell_surface.get()));
  149. generator.PressMoveAndReleaseTouchBy(5, 5);
  150. // Check if touch point motion outside focus surface is reported properly to
  151. // the focus surface.
  152. EXPECT_CALL(delegate,
  153. OnTouchDown(root_surface, testing::_, testing::_, gfx::PointF()));
  154. EXPECT_CALL(delegate,
  155. OnTouchMotion(testing::_, testing::_, gfx::PointF(100, 100)));
  156. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
  157. EXPECT_CALL(delegate, OnTouchFrame()).Times(3);
  158. generator.set_current_screen_location(
  159. GetOriginOfShellSurface(shell_surface.get()));
  160. generator.PressMoveAndReleaseTouchBy(100, 100);
  161. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  162. touch.reset();
  163. }
  164. TEST_F(TouchTest, OnTouchShape) {
  165. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  166. auto* root_surface = shell_surface->root_surface();
  167. MockTouchDelegate delegate;
  168. Seat seat;
  169. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  170. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  171. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  172. .WillRepeatedly(testing::Return(true));
  173. {
  174. testing::InSequence sequence;
  175. EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
  176. gfx::PointF()));
  177. EXPECT_CALL(delegate, OnTouchShape(testing::_, 20, 10));
  178. EXPECT_CALL(delegate, OnTouchFrame());
  179. EXPECT_CALL(delegate,
  180. OnTouchMotion(testing::_, testing::_, gfx::PointF(5, 5)));
  181. EXPECT_CALL(delegate, OnTouchShape(testing::_, 20, 10));
  182. EXPECT_CALL(delegate, OnTouchFrame());
  183. EXPECT_CALL(delegate,
  184. OnTouchMotion(testing::_, testing::_, gfx::PointF(10, 10)));
  185. EXPECT_CALL(delegate, OnTouchShape(testing::_, 20, 20));
  186. EXPECT_CALL(delegate, OnTouchFrame());
  187. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
  188. EXPECT_CALL(delegate, OnTouchFrame());
  189. }
  190. generator.set_current_screen_location(
  191. GetOriginOfShellSurface(shell_surface.get()));
  192. generator.SetTouchRadius(10, 5);
  193. generator.PressTouch();
  194. generator.MoveTouchBy(5, 5);
  195. generator.SetTouchRadius(10, 0); // Minor not supported
  196. generator.MoveTouchBy(5, 5);
  197. generator.ReleaseTouch();
  198. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  199. touch.reset();
  200. }
  201. TEST_F(TouchTest, OnTouchCancel) {
  202. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  203. auto* root_surface = shell_surface->root_surface();
  204. MockTouchDelegate delegate;
  205. Seat seat;
  206. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  207. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  208. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  209. .Times(testing::AnyNumber());
  210. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  211. .WillRepeatedly(testing::Return(true));
  212. EXPECT_CALL(delegate,
  213. OnTouchDown(root_surface, testing::_, testing::_, gfx::PointF()))
  214. .Times(2);
  215. EXPECT_CALL(delegate, OnTouchFrame()).Times(2);
  216. generator.set_current_screen_location(
  217. GetOriginOfShellSurface(shell_surface.get()));
  218. generator.PressTouchId(1);
  219. generator.PressTouchId(2);
  220. // One touch point being canceled is enough for OnTouchCancel to be called.
  221. EXPECT_CALL(delegate, OnTouchCancel());
  222. EXPECT_CALL(delegate, OnTouchFrame());
  223. ui::TouchEvent cancel_event(
  224. ui::ET_TOUCH_CANCELLED, gfx::Point(), ui::EventTimeForNow(),
  225. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  226. generator.Dispatch(&cancel_event);
  227. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  228. touch.reset();
  229. }
  230. TEST_F(TouchTest, OnTouchCancelWhenSurfaceDestroying) {
  231. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  232. auto* root_surface = shell_surface->root_surface();
  233. MockTouchDelegate delegate;
  234. Seat seat;
  235. auto touch = std::make_unique<Touch>(&delegate, &seat);
  236. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  237. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  238. .Times(testing::AnyNumber());
  239. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  240. .WillRepeatedly(testing::Return(true));
  241. EXPECT_CALL(delegate,
  242. OnTouchDown(root_surface, testing::_, 1, gfx::PointF()));
  243. EXPECT_CALL(delegate, OnTouchFrame());
  244. generator.set_current_screen_location(
  245. GetOriginOfShellSurface(shell_surface.get()));
  246. generator.PressTouchId(1);
  247. // Since there is an active touch pointer on the surface, destroying the
  248. // surface should cancel touches.
  249. EXPECT_CALL(delegate, OnTouchCancel());
  250. EXPECT_CALL(delegate, OnTouchFrame());
  251. test::ShellSurfaceBuilder::DestroyRootSurface(shell_surface.get());
  252. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  253. touch.reset();
  254. }
  255. TEST_F(TouchTest, OnTouchCancelNotTriggeredAfterTouchReleased) {
  256. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  257. auto* root_surface = shell_surface->root_surface();
  258. MockTouchDelegate delegate;
  259. Seat seat;
  260. auto touch = std::make_unique<Touch>(&delegate, &seat);
  261. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  262. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  263. .Times(testing::AnyNumber());
  264. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  265. .WillRepeatedly(testing::Return(true));
  266. EXPECT_CALL(delegate,
  267. OnTouchDown(root_surface, testing::_, 1, gfx::PointF()));
  268. EXPECT_CALL(delegate, OnTouchFrame());
  269. generator.set_current_screen_location(
  270. GetOriginOfShellSurface(shell_surface.get()));
  271. generator.PressTouchId(1);
  272. EXPECT_CALL(delegate, OnTouchUp(testing::_, 1));
  273. EXPECT_CALL(delegate, OnTouchFrame());
  274. generator.ReleaseTouchId(1);
  275. // Since the surface no longer has any active touch pointers, destroying the
  276. // surface should not cancel any touches.
  277. EXPECT_CALL(delegate, OnTouchCancel()).Times(0);
  278. test::ShellSurfaceBuilder::DestroyRootSurface(shell_surface.get());
  279. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  280. touch.reset();
  281. }
  282. TEST_F(TouchTest, IgnoreTouchEventDuringModal) {
  283. auto shell_surface = test::ShellSurfaceBuilder({10, 10})
  284. .SetCentered()
  285. .SetCanMinimize(false)
  286. .BuildShellSurface();
  287. auto* root_surface = shell_surface->root_surface();
  288. auto modal_shell_surface = test::ShellSurfaceBuilder({5, 5})
  289. .SetCentered()
  290. .SetUseSystemModalContainer()
  291. .SetCanMinimize(false)
  292. .BuildShellSurface();
  293. auto* modal_root_surface = modal_shell_surface->root_surface();
  294. MockTouchDelegate delegate;
  295. Seat seat;
  296. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  297. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  298. // Make the window modal.
  299. EXPECT_FALSE(ash::Shell::IsSystemModalWindowOpen());
  300. modal_shell_surface->SetSystemModal(true);
  301. EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen());
  302. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  303. .Times(testing::AnyNumber());
  304. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  305. .WillRepeatedly(testing::Return(true));
  306. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(modal_root_surface))
  307. .WillRepeatedly(testing::Return(true));
  308. // Check if touch events on modal window are registered.
  309. {
  310. testing::InSequence sequence;
  311. EXPECT_CALL(delegate, OnTouchDown(modal_root_surface, testing::_,
  312. testing::_, gfx::PointF()));
  313. EXPECT_CALL(delegate, OnTouchFrame());
  314. EXPECT_CALL(delegate,
  315. OnTouchMotion(testing::_, testing::_, gfx::PointF(1, 1)));
  316. EXPECT_CALL(delegate, OnTouchFrame());
  317. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
  318. EXPECT_CALL(delegate, OnTouchFrame());
  319. }
  320. generator.set_current_screen_location(
  321. GetOriginOfShellSurface(modal_shell_surface.get()));
  322. generator.PressMoveAndReleaseTouchBy(1, 1);
  323. // Check if touch events on non-modal window are ignored.
  324. {
  325. testing::InSequence sequence;
  326. EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
  327. gfx::PointF()))
  328. .Times(0);
  329. EXPECT_CALL(delegate,
  330. OnTouchMotion(testing::_, testing::_, gfx::PointF(1, 1)))
  331. .Times(0);
  332. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_)).Times(0);
  333. EXPECT_CALL(delegate, OnTouchFrame()).Times(0);
  334. }
  335. generator.set_current_screen_location(
  336. GetOriginOfShellSurface(shell_surface.get()));
  337. generator.PressMoveAndReleaseTouchBy(1, 1);
  338. // Make the window non-modal.
  339. modal_shell_surface->SetSystemModal(false);
  340. EXPECT_FALSE(ash::Shell::IsSystemModalWindowOpen());
  341. // Check if touch events on non-modal window are registered.
  342. {
  343. testing::InSequence sequence;
  344. EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
  345. gfx::PointF()));
  346. EXPECT_CALL(delegate, OnTouchFrame());
  347. EXPECT_CALL(delegate,
  348. OnTouchMotion(testing::_, testing::_, gfx::PointF(1, 1)));
  349. EXPECT_CALL(delegate, OnTouchFrame());
  350. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
  351. EXPECT_CALL(delegate, OnTouchFrame());
  352. }
  353. generator.set_current_screen_location(
  354. GetOriginOfShellSurface(shell_surface.get()));
  355. generator.PressMoveAndReleaseTouchBy(1, 1);
  356. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  357. touch.reset();
  358. }
  359. TEST_F(TouchTest, OnTouchTool) {
  360. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  361. auto* root_surface = shell_surface->root_surface();
  362. MockTouchDelegate delegate;
  363. MockTouchStylusDelegate stylus_delegate;
  364. Seat seat;
  365. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  366. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  367. touch->SetStylusDelegate(&stylus_delegate);
  368. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  369. .Times(testing::AnyNumber());
  370. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  371. .WillRepeatedly(testing::Return(true));
  372. // Expect tool change to happen before frame of down event.
  373. {
  374. testing::InSequence sequence;
  375. EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
  376. gfx::PointF()));
  377. EXPECT_CALL(stylus_delegate, OnTouchTool(0, ui::EventPointerType::kPen));
  378. EXPECT_CALL(delegate, OnTouchFrame());
  379. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
  380. EXPECT_CALL(delegate, OnTouchFrame());
  381. }
  382. generator.set_current_screen_location(
  383. GetOriginOfShellSurface(shell_surface.get()));
  384. generator.SetTouchPointerType(ui::EventPointerType::kPen);
  385. generator.PressTouch();
  386. generator.ReleaseTouch();
  387. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  388. touch.reset();
  389. }
  390. TEST_F(TouchTest, OnTouchForce) {
  391. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  392. auto* root_surface = shell_surface->root_surface();
  393. MockTouchDelegate delegate;
  394. MockTouchStylusDelegate stylus_delegate;
  395. Seat seat;
  396. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  397. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  398. touch->SetStylusDelegate(&stylus_delegate);
  399. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  400. .Times(testing::AnyNumber());
  401. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  402. .WillRepeatedly(testing::Return(true));
  403. // Expect tool change to happen before frame of down event.
  404. {
  405. testing::InSequence sequence;
  406. EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
  407. gfx::PointF()));
  408. EXPECT_CALL(stylus_delegate, OnTouchTool(0, ui::EventPointerType::kPen));
  409. EXPECT_CALL(stylus_delegate, OnTouchForce(testing::_, 0, 1.0));
  410. EXPECT_CALL(delegate, OnTouchFrame());
  411. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
  412. EXPECT_CALL(delegate, OnTouchFrame());
  413. }
  414. generator.set_current_screen_location(
  415. GetOriginOfShellSurface(shell_surface.get()));
  416. generator.SetTouchPointerType(ui::EventPointerType::kPen);
  417. generator.SetTouchForce(1.0);
  418. generator.PressTouch();
  419. generator.ReleaseTouch();
  420. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  421. touch.reset();
  422. }
  423. TEST_F(TouchTest, OnTouchTilt) {
  424. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  425. auto* root_surface = shell_surface->root_surface();
  426. MockTouchDelegate delegate;
  427. MockTouchStylusDelegate stylus_delegate;
  428. Seat seat;
  429. std::unique_ptr<Touch> touch(new Touch(&delegate, &seat));
  430. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  431. touch->SetStylusDelegate(&stylus_delegate);
  432. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  433. .Times(testing::AnyNumber());
  434. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  435. .WillRepeatedly(testing::Return(true));
  436. // Expect tool change to happen before frame of down event.
  437. {
  438. testing::InSequence sequence;
  439. EXPECT_CALL(delegate, OnTouchDown(root_surface, testing::_, testing::_,
  440. gfx::PointF()));
  441. EXPECT_CALL(stylus_delegate, OnTouchTool(0, ui::EventPointerType::kPen));
  442. EXPECT_CALL(stylus_delegate,
  443. OnTouchTilt(testing::_, 0, gfx::Vector2dF(1.0, 2.0)));
  444. EXPECT_CALL(delegate, OnTouchFrame());
  445. EXPECT_CALL(delegate, OnTouchUp(testing::_, testing::_));
  446. EXPECT_CALL(delegate, OnTouchFrame());
  447. }
  448. generator.set_current_screen_location(
  449. GetOriginOfShellSurface(shell_surface.get()));
  450. generator.SetTouchPointerType(ui::EventPointerType::kPen);
  451. generator.SetTouchTilt(1.0, 2.0);
  452. generator.PressTouch();
  453. generator.ReleaseTouch();
  454. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  455. touch.reset();
  456. }
  457. TEST_F(TouchTest, DragDropAbort) {
  458. Seat seat(std::make_unique<TestDataExchangeDelegate>());
  459. MockTouchDelegate touch_delegate;
  460. std::unique_ptr<Touch> touch(new Touch(&touch_delegate, &seat));
  461. TestDataSourceDelegate data_source_delegate;
  462. DataSource source(&data_source_delegate);
  463. Surface origin, icon;
  464. // Make origin into a real window so the touch can click it
  465. ShellSurface shell_surface(&origin);
  466. Buffer buffer(exo_test_helper()->CreateGpuMemoryBuffer(gfx::Size(10, 10)));
  467. origin.Attach(&buffer);
  468. origin.Commit();
  469. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  470. EXPECT_CALL(touch_delegate, CanAcceptTouchEventsForSurface(&origin))
  471. .WillRepeatedly(testing::Return(true));
  472. EXPECT_CALL(touch_delegate, OnTouchFrame()).Times(2);
  473. generator.MoveTouch(origin.window()->GetBoundsInScreen().origin());
  474. seat.StartDrag(&source, &origin, &icon, ui::mojom::DragEventSource::kMouse);
  475. EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  476. EXPECT_CALL(touch_delegate, OnTouchDown).Times(1);
  477. EXPECT_CALL(touch_delegate, OnTouchUp).Times(1);
  478. EXPECT_CALL(touch_delegate, OnTouchShape).Times(1);
  479. generator.PressTouch();
  480. EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  481. generator.ReleaseTouch();
  482. EXPECT_FALSE(seat.get_drag_drop_operation_for_testing());
  483. EXPECT_CALL(touch_delegate, OnTouchDestroying(touch.get()));
  484. touch.reset();
  485. }
  486. TEST_F(TouchTest, TouchMultiple2Surfaces) {
  487. auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  488. auto* root_surface = shell_surface->root_surface();
  489. auto child_shell_surface = test::ShellSurfaceBuilder({15, 15})
  490. .SetParent(shell_surface.get())
  491. .SetCanMinimize(false)
  492. .SetDisableMovement()
  493. .BuildShellSurface();
  494. auto* child_surface = child_shell_surface->root_surface();
  495. MockTouchDelegate delegate;
  496. Seat seat;
  497. auto touch = std::make_unique<Touch>(&delegate, &seat);
  498. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  499. // Touch down on the two surfaces.
  500. EXPECT_CALL(delegate, OnTouchShape(testing::_, testing::_, testing::_))
  501. .Times(testing::AnyNumber());
  502. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(root_surface))
  503. .WillRepeatedly(testing::Return(true));
  504. EXPECT_CALL(delegate,
  505. OnTouchDown(root_surface, testing::_, 1, gfx::PointF()));
  506. EXPECT_CALL(delegate, OnTouchFrame());
  507. const gfx::Point origin = GetOriginOfShellSurface(shell_surface.get());
  508. generator.set_current_screen_location(origin);
  509. generator.PressTouchId(1);
  510. EXPECT_CALL(delegate, CanAcceptTouchEventsForSurface(child_surface))
  511. .WillRepeatedly(testing::Return(true));
  512. EXPECT_CALL(delegate,
  513. OnTouchDown(child_surface, testing::_, 2, gfx::PointF()));
  514. EXPECT_CALL(delegate, OnTouchFrame());
  515. const gfx::Point child_origin =
  516. GetOriginOfShellSurface(child_shell_surface.get());
  517. generator.set_current_screen_location(child_origin);
  518. generator.PressTouchId(2);
  519. // Move the two touch pointers.
  520. for (int i = 1; i <= 10; i++) {
  521. EXPECT_CALL(delegate, OnTouchMotion(testing::_, 1, gfx::PointF(i, i)));
  522. EXPECT_CALL(delegate, OnTouchFrame());
  523. generator.MoveTouchId(origin + gfx::Vector2d(i, i), 1);
  524. EXPECT_CALL(delegate, OnTouchMotion(testing::_, 2, gfx::PointF(i, i)));
  525. EXPECT_CALL(delegate, OnTouchFrame());
  526. generator.MoveTouchId(child_origin + gfx::Vector2d(i, i), 2);
  527. }
  528. // Release the two touch pointers.
  529. EXPECT_CALL(delegate, OnTouchUp(testing::_, 2));
  530. EXPECT_CALL(delegate, OnTouchFrame());
  531. generator.ReleaseTouchId(2);
  532. EXPECT_CALL(delegate, OnTouchUp(testing::_, 1));
  533. EXPECT_CALL(delegate, OnTouchFrame());
  534. generator.ReleaseTouchId(1);
  535. EXPECT_CALL(delegate, OnTouchDestroying(touch.get()));
  536. touch.reset();
  537. }
  538. TEST_F(TouchTest, IgnoresHandledEvents) {
  539. // A very dumb handler that simply marks all events as handled. This is needed
  540. // allows us to mark a mouse event as handled as it gets processed by the
  541. // event processor.
  542. class SetHandledHandler : public ui::EventHandler {
  543. void OnTouchEvent(ui::TouchEvent* event) override { event->SetHandled(); }
  544. };
  545. SetHandledHandler handler;
  546. ash::Shell::Get()->AddPreTargetHandler(&handler);
  547. Seat seat(std::make_unique<TestDataExchangeDelegate>());
  548. testing::NiceMock<MockTouchDelegate> touch_delegate;
  549. std::unique_ptr<Touch> touch(new Touch(&touch_delegate, &seat));
  550. // Make origin into a real window so the touch can click it
  551. std::unique_ptr<ShellSurface> shell_surface =
  552. test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  553. ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  554. // The SetHandlerHandler should have marked the event as processed. Therefore
  555. // the event should simply be ignored.
  556. EXPECT_CALL(touch_delegate, OnTouchFrame()).Times(0);
  557. generator.GestureTapAt(shell_surface->surface_for_testing()
  558. ->window()
  559. ->GetBoundsInScreen()
  560. .CenterPoint());
  561. ash::Shell::Get()->RemovePreTargetHandler(&handler);
  562. }
  563. } // namespace
  564. } // namespace exo