select_to_speak_event_handler_unittest.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. // Copyright 2018 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/events/select_to_speak_event_handler.h"
  5. #include <memory>
  6. #include <set>
  7. #include "ash/accessibility/accessibility_controller_impl.h"
  8. #include "ash/public/cpp/select_to_speak_event_handler_delegate.h"
  9. #include "ash/shell.h"
  10. #include "ash/test/ash_test_base.h"
  11. #include "ash/test/ash_test_helper.h"
  12. #include "ash/test/ash_test_views_delegate.h"
  13. #include "ui/aura/test/aura_test_base.h"
  14. #include "ui/aura/window.h"
  15. #include "ui/display/manager/display_manager.h"
  16. #include "ui/events/event.h"
  17. #include "ui/events/event_constants.h"
  18. #include "ui/events/test/event_generator.h"
  19. #include "ui/events/test/events_test_utils.h"
  20. #include "ui/events/types/event_type.h"
  21. namespace ash {
  22. namespace {
  23. // Records all key events for testing.
  24. class EventCapturer : public ui::EventHandler {
  25. public:
  26. EventCapturer() {}
  27. EventCapturer(const EventCapturer&) = delete;
  28. EventCapturer& operator=(const EventCapturer&) = delete;
  29. ~EventCapturer() override {}
  30. void Reset() {
  31. last_key_event_.reset();
  32. last_mouse_event_.reset();
  33. last_touch_event_.reset();
  34. }
  35. ui::KeyEvent* last_key_event() { return last_key_event_.get(); }
  36. ui::MouseEvent* last_mouse_event() { return last_mouse_event_.get(); }
  37. ui::TouchEvent* last_touch_event() { return last_touch_event_.get(); }
  38. private:
  39. void OnMouseEvent(ui::MouseEvent* event) override {
  40. last_mouse_event_ = std::make_unique<ui::MouseEvent>(*event);
  41. }
  42. void OnKeyEvent(ui::KeyEvent* event) override {
  43. last_key_event_ = std::make_unique<ui::KeyEvent>(*event);
  44. }
  45. void OnTouchEvent(ui::TouchEvent* event) override {
  46. last_touch_event_ = std::make_unique<ui::TouchEvent>(*event);
  47. }
  48. std::unique_ptr<ui::KeyEvent> last_key_event_;
  49. std::unique_ptr<ui::MouseEvent> last_mouse_event_;
  50. std::unique_ptr<ui::TouchEvent> last_touch_event_;
  51. };
  52. class TestDelegate : public SelectToSpeakEventHandlerDelegate {
  53. public:
  54. TestDelegate() = default;
  55. TestDelegate(const TestDelegate&) = delete;
  56. TestDelegate& operator=(const TestDelegate&) = delete;
  57. virtual ~TestDelegate() = default;
  58. bool CapturedMouseEvent(ui::EventType event_type) {
  59. return mouse_events_captured_.find(event_type) !=
  60. mouse_events_captured_.end();
  61. }
  62. void Reset() {
  63. mouse_events_captured_.clear();
  64. last_mouse_location_.SetPoint(0, 0);
  65. last_mouse_root_location_.SetPoint(0, 0);
  66. }
  67. gfx::Point last_mouse_event_location() { return last_mouse_location_; }
  68. gfx::Point last_mouse_event_root_location() {
  69. return last_mouse_root_location_;
  70. }
  71. private:
  72. // SelectToSpeakEventHandlerDelegate:
  73. void DispatchMouseEvent(const ui::MouseEvent& event) override {
  74. mouse_events_captured_.insert(event.type());
  75. last_mouse_location_ = event.location();
  76. last_mouse_root_location_ = event.root_location();
  77. }
  78. void DispatchKeyEvent(const ui::KeyEvent& event) override {
  79. // Unused for now.
  80. }
  81. gfx::Point last_mouse_location_;
  82. gfx::Point last_mouse_root_location_;
  83. std::set<ui::EventType> mouse_events_captured_;
  84. };
  85. class SelectToSpeakEventHandlerTest : public AshTestBase {
  86. public:
  87. SelectToSpeakEventHandlerTest() = default;
  88. SelectToSpeakEventHandlerTest(const SelectToSpeakEventHandlerTest&) = delete;
  89. SelectToSpeakEventHandlerTest& operator=(
  90. const SelectToSpeakEventHandlerTest&) = delete;
  91. ~SelectToSpeakEventHandlerTest() override = default;
  92. void SetUp() override {
  93. AshTestBase::SetUp();
  94. // This test triggers a resize of WindowTreeHost, which will end up
  95. // throttling events. set_throttle_input_on_resize_for_testing() disables
  96. // this.
  97. aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false);
  98. // Make sure the display is initialized so we don't fail the test due to any
  99. // input events caused from creating the display.
  100. Shell::Get()->display_manager()->UpdateDisplays();
  101. base::RunLoop().RunUntilIdle();
  102. delegate_ = std::make_unique<TestDelegate>();
  103. generator_ = AshTestBase::GetEventGenerator();
  104. GetContext()->AddPreTargetHandler(&event_capturer_);
  105. controller_ = Shell::Get()->accessibility_controller();
  106. controller_->select_to_speak().SetEnabled(true);
  107. controller_->SetSelectToSpeakEventHandlerDelegate(delegate_.get());
  108. }
  109. void TearDown() override {
  110. GetContext()->RemovePreTargetHandler(&event_capturer_);
  111. generator_ = nullptr;
  112. controller_ = nullptr;
  113. AshTestBase::TearDown();
  114. }
  115. protected:
  116. ui::test::EventGenerator* generator_ = nullptr;
  117. EventCapturer event_capturer_;
  118. AccessibilityControllerImpl* controller_ = nullptr;
  119. std::unique_ptr<TestDelegate> delegate_;
  120. };
  121. TEST_F(SelectToSpeakEventHandlerTest, PressAndReleaseSearchNotHandled) {
  122. // If the user presses and releases the Search key, with no mouse
  123. // presses, the key events won't be handled by the SelectToSpeakEventHandler
  124. // and the normal behavior will occur.
  125. EXPECT_FALSE(event_capturer_.last_key_event());
  126. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  127. ASSERT_TRUE(event_capturer_.last_key_event());
  128. EXPECT_FALSE(event_capturer_.last_key_event()->handled());
  129. event_capturer_.Reset();
  130. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  131. ASSERT_TRUE(event_capturer_.last_key_event());
  132. EXPECT_FALSE(event_capturer_.last_key_event()->handled());
  133. }
  134. // Note: when running these tests locally on desktop Linux, you may need
  135. // to use xvfb-run, otherwise simulating the Search key press may not work.
  136. TEST_F(SelectToSpeakEventHandlerTest, SearchPlusClick) {
  137. // If the user holds the Search key and then clicks the mouse button,
  138. // the mouse events and the key release event get handled by the
  139. // SelectToSpeakEventHandler, and mouse events are forwarded to the
  140. // extension.
  141. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  142. ASSERT_TRUE(event_capturer_.last_key_event());
  143. EXPECT_FALSE(event_capturer_.last_key_event()->handled());
  144. gfx::Point click_location = gfx::Point(100, 12);
  145. generator_->set_current_screen_location(click_location);
  146. generator_->PressLeftButton();
  147. EXPECT_FALSE(event_capturer_.last_mouse_event());
  148. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  149. EXPECT_EQ(click_location, delegate_->last_mouse_event_location());
  150. generator_->ReleaseLeftButton();
  151. EXPECT_FALSE(event_capturer_.last_mouse_event());
  152. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  153. EXPECT_EQ(click_location, delegate_->last_mouse_event_location());
  154. event_capturer_.Reset();
  155. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  156. EXPECT_FALSE(event_capturer_.last_key_event());
  157. }
  158. TEST_F(SelectToSpeakEventHandlerTest, SearchPlusDrag) {
  159. // Mouse move events should also be captured.
  160. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  161. gfx::Point click_location = gfx::Point(100, 12);
  162. generator_->set_current_screen_location(click_location);
  163. generator_->PressLeftButton();
  164. EXPECT_EQ(click_location, delegate_->last_mouse_event_location());
  165. // Drags are not blocked.
  166. gfx::Point drag_location = gfx::Point(120, 32);
  167. generator_->DragMouseTo(drag_location);
  168. EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
  169. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
  170. EXPECT_TRUE(event_capturer_.last_mouse_event());
  171. event_capturer_.Reset();
  172. generator_->ReleaseLeftButton();
  173. EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
  174. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  175. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  176. }
  177. TEST_F(SelectToSpeakEventHandlerTest, SearchPlusDragOnLargeDisplay) {
  178. // This display has twice the number of pixels per DIP. This means that
  179. // each event coming in in px needs to be divided by two to be converted
  180. // to DIPs.
  181. UpdateDisplay("800x600*2");
  182. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  183. gfx::Point click_location_px = gfx::Point(100, 12);
  184. generator_->set_current_screen_location(click_location_px);
  185. generator_->PressLeftButton();
  186. EXPECT_EQ(gfx::Point(click_location_px.x() / 2, click_location_px.y() / 2),
  187. delegate_->last_mouse_event_location());
  188. gfx::Point drag_location_px = gfx::Point(120, 32);
  189. generator_->DragMouseTo(drag_location_px);
  190. EXPECT_EQ(gfx::Point(drag_location_px.x() / 2, drag_location_px.y() / 2),
  191. delegate_->last_mouse_event_location());
  192. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
  193. EXPECT_TRUE(event_capturer_.last_mouse_event());
  194. event_capturer_.Reset();
  195. generator_->ReleaseLeftButton();
  196. EXPECT_EQ(gfx::Point(drag_location_px.x() / 2, drag_location_px.y() / 2),
  197. delegate_->last_mouse_event_location());
  198. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  199. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  200. }
  201. TEST_F(SelectToSpeakEventHandlerTest, RepeatSearchKey) {
  202. // Holding the Search key may generate key repeat events. Make sure it's
  203. // still treated as if the search key is down.
  204. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  205. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  206. generator_->set_current_screen_location(gfx::Point(100, 12));
  207. generator_->PressLeftButton();
  208. EXPECT_FALSE(event_capturer_.last_mouse_event());
  209. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  210. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  211. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  212. generator_->ReleaseLeftButton();
  213. EXPECT_FALSE(event_capturer_.last_mouse_event());
  214. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  215. event_capturer_.Reset();
  216. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  217. EXPECT_FALSE(event_capturer_.last_key_event());
  218. }
  219. TEST_F(SelectToSpeakEventHandlerTest, TapSearchKey) {
  220. // Tapping the search key should not steal future events.
  221. event_capturer_.Reset();
  222. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  223. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  224. generator_->PressLeftButton();
  225. EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
  226. generator_->ReleaseLeftButton();
  227. EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
  228. }
  229. TEST_F(SelectToSpeakEventHandlerTest, SearchPlusClickTwice) {
  230. // Same as SearchPlusClick, above, but test that the user can keep
  231. // holding down Search and click again.
  232. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  233. ASSERT_TRUE(event_capturer_.last_key_event());
  234. EXPECT_FALSE(event_capturer_.last_key_event()->handled());
  235. generator_->set_current_screen_location(gfx::Point(100, 12));
  236. generator_->PressLeftButton();
  237. EXPECT_FALSE(event_capturer_.last_mouse_event());
  238. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  239. generator_->ReleaseLeftButton();
  240. EXPECT_FALSE(event_capturer_.last_mouse_event());
  241. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  242. delegate_->Reset();
  243. EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  244. EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  245. generator_->PressLeftButton();
  246. EXPECT_FALSE(event_capturer_.last_mouse_event());
  247. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  248. generator_->ReleaseLeftButton();
  249. EXPECT_FALSE(event_capturer_.last_mouse_event());
  250. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  251. event_capturer_.Reset();
  252. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  253. EXPECT_FALSE(event_capturer_.last_key_event());
  254. }
  255. TEST_F(SelectToSpeakEventHandlerTest, SearchPlusKeyIgnoresClicks) {
  256. // If the user presses the Search key and then some other key,
  257. // we should assume the user does not want select-to-speak, and
  258. // click events should be ignored.
  259. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  260. ASSERT_TRUE(event_capturer_.last_key_event());
  261. EXPECT_FALSE(event_capturer_.last_key_event()->handled());
  262. generator_->PressKey(ui::VKEY_I, ui::EF_COMMAND_DOWN);
  263. ASSERT_TRUE(event_capturer_.last_key_event());
  264. EXPECT_FALSE(event_capturer_.last_key_event()->handled());
  265. generator_->set_current_screen_location(gfx::Point(100, 12));
  266. generator_->PressLeftButton();
  267. ASSERT_TRUE(event_capturer_.last_mouse_event());
  268. EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
  269. EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  270. generator_->ReleaseLeftButton();
  271. ASSERT_TRUE(event_capturer_.last_mouse_event());
  272. EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
  273. EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  274. event_capturer_.Reset();
  275. generator_->ReleaseKey(ui::VKEY_I, ui::EF_COMMAND_DOWN);
  276. ASSERT_TRUE(event_capturer_.last_key_event());
  277. EXPECT_FALSE(event_capturer_.last_key_event()->handled());
  278. event_capturer_.Reset();
  279. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  280. ASSERT_TRUE(event_capturer_.last_key_event());
  281. EXPECT_FALSE(event_capturer_.last_key_event()->handled());
  282. }
  283. TEST_F(SelectToSpeakEventHandlerTest, SearchPlusSIsCaptured) {
  284. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  285. // Press and release S, key presses should be captured.
  286. event_capturer_.Reset();
  287. generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  288. ASSERT_FALSE(event_capturer_.last_key_event());
  289. generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  290. ASSERT_FALSE(event_capturer_.last_key_event());
  291. // Press and release again while still holding down search.
  292. // The events should continue to be captured.
  293. generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  294. ASSERT_FALSE(event_capturer_.last_key_event());
  295. generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  296. ASSERT_FALSE(event_capturer_.last_key_event());
  297. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  298. ASSERT_FALSE(event_capturer_.last_key_event());
  299. // S alone is not captured
  300. generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  301. ASSERT_TRUE(event_capturer_.last_key_event());
  302. ASSERT_FALSE(event_capturer_.last_key_event()->handled());
  303. }
  304. TEST_F(SelectToSpeakEventHandlerTest, SearchPlusSIgnoresMouse) {
  305. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  306. // Press S
  307. event_capturer_.Reset();
  308. generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  309. ASSERT_FALSE(event_capturer_.last_key_event());
  310. // Mouse events are passed through like normal.
  311. generator_->PressLeftButton();
  312. EXPECT_TRUE(event_capturer_.last_mouse_event());
  313. event_capturer_.Reset();
  314. generator_->ReleaseLeftButton();
  315. EXPECT_TRUE(event_capturer_.last_mouse_event());
  316. generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  317. ASSERT_FALSE(event_capturer_.last_key_event());
  318. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  319. ASSERT_FALSE(event_capturer_.last_key_event());
  320. }
  321. TEST_F(SelectToSpeakEventHandlerTest, SearchPlusMouseIgnoresS) {
  322. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  323. // Press the mouse
  324. event_capturer_.Reset();
  325. generator_->PressLeftButton();
  326. EXPECT_FALSE(event_capturer_.last_mouse_event());
  327. // S key events are passed through like normal.
  328. generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  329. EXPECT_TRUE(event_capturer_.last_key_event());
  330. event_capturer_.Reset();
  331. generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
  332. EXPECT_TRUE(event_capturer_.last_key_event());
  333. generator_->ReleaseLeftButton();
  334. EXPECT_FALSE(event_capturer_.last_mouse_event());
  335. event_capturer_.Reset();
  336. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  337. EXPECT_FALSE(event_capturer_.last_key_event());
  338. }
  339. TEST_F(SelectToSpeakEventHandlerTest, DoesntStartSelectionModeIfNotInactive) {
  340. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  341. // This shouldn't cause any changes since the state is not inactive.
  342. controller_->SetSelectToSpeakState(
  343. SelectToSpeakState::kSelectToSpeakStateSelecting);
  344. // Mouse event still captured.
  345. gfx::Point click_location = gfx::Point(100, 12);
  346. generator_->set_current_screen_location(click_location);
  347. generator_->PressLeftButton();
  348. EXPECT_FALSE(event_capturer_.last_mouse_event());
  349. // This shouldn't cause any changes since the state is not inactive.
  350. controller_->SetSelectToSpeakState(
  351. SelectToSpeakState::kSelectToSpeakStateSelecting);
  352. generator_->ReleaseLeftButton();
  353. // Releasing the search key is still captured per the end of the search+click
  354. // mode.
  355. event_capturer_.Reset();
  356. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  357. EXPECT_FALSE(event_capturer_.last_key_event());
  358. }
  359. TEST_F(SelectToSpeakEventHandlerTest,
  360. CancelSearchKeyUpAfterEarlyInactiveStateChange) {
  361. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  362. gfx::Point click_location = gfx::Point(100, 12);
  363. generator_->set_current_screen_location(click_location);
  364. generator_->PressLeftButton();
  365. EXPECT_FALSE(event_capturer_.last_mouse_event());
  366. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  367. generator_->ReleaseLeftButton();
  368. EXPECT_FALSE(event_capturer_.last_mouse_event());
  369. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  370. // Set the state to inactive.
  371. // This is realistic because Select-to-Speak will set the state to inactive
  372. // after the hittest / search for the focused node callbacks, which may occur
  373. // before the user actually releases the search key.
  374. controller_->SetSelectToSpeakState(
  375. SelectToSpeakState::kSelectToSpeakStateInactive);
  376. // The search key release should still be captured.
  377. event_capturer_.Reset();
  378. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  379. EXPECT_FALSE(event_capturer_.last_key_event());
  380. }
  381. TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedWorksWithMouse) {
  382. gfx::Point click_location = gfx::Point(100, 12);
  383. generator_->set_current_screen_location(click_location);
  384. // Mouse events are let through normally before entering selecting state.
  385. // Another mouse event is let through normally.
  386. controller_->SetSelectToSpeakState(
  387. SelectToSpeakState::kSelectToSpeakStateInactive);
  388. generator_->PressLeftButton();
  389. EXPECT_TRUE(event_capturer_.last_mouse_event());
  390. event_capturer_.Reset();
  391. generator_->ReleaseLeftButton();
  392. EXPECT_TRUE(event_capturer_.last_mouse_event());
  393. event_capturer_.Reset();
  394. // Start selection mode.
  395. controller_->SetSelectToSpeakState(
  396. SelectToSpeakState::kSelectToSpeakStateSelecting);
  397. generator_->PressLeftButton();
  398. EXPECT_FALSE(event_capturer_.last_mouse_event());
  399. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  400. event_capturer_.Reset();
  401. gfx::Point drag_location = gfx::Point(120, 32);
  402. generator_->DragMouseTo(drag_location);
  403. EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
  404. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
  405. EXPECT_TRUE(event_capturer_.last_mouse_event());
  406. event_capturer_.Reset();
  407. // Mouse up is the last event captured in the sequence
  408. generator_->ReleaseLeftButton();
  409. EXPECT_FALSE(event_capturer_.last_mouse_event());
  410. event_capturer_.Reset();
  411. // Another mouse event is let through normally.
  412. generator_->PressLeftButton();
  413. EXPECT_TRUE(event_capturer_.last_mouse_event());
  414. event_capturer_.Reset();
  415. }
  416. TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedWorksWithTouch) {
  417. gfx::Point touch_location = gfx::Point(100, 12);
  418. generator_->set_current_screen_location(touch_location);
  419. // Mouse events are let through normally before entering selecting state.
  420. // Another mouse event is let through normally.
  421. controller_->SetSelectToSpeakState(
  422. SelectToSpeakState::kSelectToSpeakStateInactive);
  423. generator_->PressTouch();
  424. EXPECT_TRUE(event_capturer_.last_touch_event());
  425. event_capturer_.Reset();
  426. generator_->ReleaseTouch();
  427. EXPECT_TRUE(event_capturer_.last_touch_event());
  428. event_capturer_.Reset();
  429. // Start selection mode.
  430. controller_->SetSelectToSpeakState(
  431. SelectToSpeakState::kSelectToSpeakStateSelecting);
  432. generator_->PressTouch();
  433. EXPECT_FALSE(event_capturer_.last_touch_event());
  434. // Touch events are converted to mouse events for the extension.
  435. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  436. event_capturer_.Reset();
  437. gfx::Point drag_location = gfx::Point(120, 32);
  438. generator_->MoveTouch(drag_location);
  439. EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
  440. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
  441. EXPECT_TRUE(event_capturer_.last_touch_event());
  442. event_capturer_.Reset();
  443. // Touch up is the last event captured in the sequence
  444. generator_->ReleaseTouch();
  445. EXPECT_FALSE(event_capturer_.last_touch_event());
  446. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  447. event_capturer_.Reset();
  448. // Another touch event is let through normally.
  449. generator_->PressTouch();
  450. EXPECT_TRUE(event_capturer_.last_touch_event());
  451. event_capturer_.Reset();
  452. }
  453. TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedIgnoresOtherInput) {
  454. // Start selection mode.
  455. controller_->SetSelectToSpeakState(
  456. SelectToSpeakState::kSelectToSpeakStateSelecting);
  457. // Search key events are not impacted.
  458. generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  459. EXPECT_TRUE(event_capturer_.last_key_event());
  460. event_capturer_.Reset();
  461. generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
  462. EXPECT_TRUE(event_capturer_.last_key_event());
  463. event_capturer_.Reset();
  464. // Start a touch selection, it should get captured and forwarded.
  465. generator_->PressTouch();
  466. EXPECT_FALSE(event_capturer_.last_touch_event());
  467. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  468. event_capturer_.Reset();
  469. // Mouse event happening during the touch selection are not impacted;
  470. // we are locked into a touch selection mode.
  471. generator_->PressLeftButton();
  472. EXPECT_TRUE(event_capturer_.last_mouse_event());
  473. event_capturer_.Reset();
  474. generator_->ReleaseLeftButton();
  475. EXPECT_TRUE(event_capturer_.last_mouse_event());
  476. event_capturer_.Reset();
  477. // Complete the touch selection.
  478. generator_->ReleaseTouch();
  479. EXPECT_FALSE(event_capturer_.last_touch_event());
  480. event_capturer_.Reset();
  481. }
  482. TEST_F(SelectToSpeakEventHandlerTest, TrackingTouchIgnoresOtherTouchPointers) {
  483. gfx::Point touch_location = gfx::Point(100, 12);
  484. gfx::Point drag_location = gfx::Point(120, 32);
  485. generator_->set_current_screen_location(touch_location);
  486. controller_->SetSelectToSpeakState(
  487. SelectToSpeakState::kSelectToSpeakStateSelecting);
  488. // The first touch event is captured and sent to the extension.
  489. generator_->PressTouchId(1);
  490. EXPECT_FALSE(event_capturer_.last_touch_event());
  491. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  492. event_capturer_.Reset();
  493. delegate_->Reset();
  494. // A second touch event up and down is canceled but not sent to the extension.
  495. generator_->PressTouchId(2);
  496. EXPECT_FALSE(event_capturer_.last_touch_event());
  497. EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  498. generator_->MoveTouchId(drag_location, 2);
  499. EXPECT_FALSE(event_capturer_.last_touch_event());
  500. EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
  501. generator_->ReleaseTouchId(2);
  502. EXPECT_FALSE(event_capturer_.last_touch_event());
  503. EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  504. // A pointer type event will not be sent either, as we are tracking touch,
  505. // even if the ID is the same.
  506. generator_->EnterPenPointerMode();
  507. generator_->PressTouchId(1);
  508. EXPECT_FALSE(event_capturer_.last_touch_event());
  509. EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  510. generator_->ExitPenPointerMode();
  511. // The first pointer is still tracked.
  512. generator_->MoveTouchId(drag_location, 1);
  513. EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
  514. EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
  515. EXPECT_TRUE(event_capturer_.last_touch_event());
  516. event_capturer_.Reset();
  517. // Touch up is the last event captured in the sequence
  518. generator_->ReleaseTouchId(1);
  519. EXPECT_FALSE(event_capturer_.last_touch_event());
  520. event_capturer_.Reset();
  521. // Another touch event is let through normally.
  522. generator_->PressTouchId(3);
  523. EXPECT_TRUE(event_capturer_.last_touch_event());
  524. event_capturer_.Reset();
  525. }
  526. TEST_F(SelectToSpeakEventHandlerTest, TouchFirstOfMultipleDisplays) {
  527. UpdateDisplay("1+0-800x700,801+1-800x700");
  528. // On the first display.
  529. gfx::Point touch_location(200, 200);
  530. generator_->set_current_screen_location(touch_location);
  531. controller_->SetSelectToSpeakState(
  532. SelectToSpeakState::kSelectToSpeakStateSelecting);
  533. generator_->PressTouch();
  534. EXPECT_EQ(touch_location, delegate_->last_mouse_event_root_location());
  535. }
  536. TEST_F(SelectToSpeakEventHandlerTest, TouchSecondOfMultipleDisplays) {
  537. UpdateDisplay("1+0-800x700,801+1-800x700");
  538. // On the second display.
  539. gfx::Point touch_location(1000, 200);
  540. generator_->set_current_screen_location(touch_location);
  541. controller_->SetSelectToSpeakState(
  542. SelectToSpeakState::kSelectToSpeakStateSelecting);
  543. generator_->PressTouch();
  544. EXPECT_EQ(touch_location, delegate_->last_mouse_event_root_location());
  545. }
  546. } // namespace
  547. } // namespace ash