touch_exploration_controller_unittest.cc 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
  1. // Copyright 2014 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/accessibility/chromevox/touch_exploration_controller.h"
  5. #include <math.h>
  6. #include <stddef.h>
  7. #include <memory>
  8. #include <vector>
  9. #include "ash/accessibility/chromevox/mock_touch_exploration_controller_delegate.h"
  10. #include "base/memory/ptr_util.h"
  11. #include "base/test/simple_test_tick_clock.h"
  12. #include "base/time/time.h"
  13. #include "ui/accessibility/ax_enums.mojom.h"
  14. #include "ui/aura/client/cursor_client.h"
  15. #include "ui/aura/test/aura_test_base.h"
  16. #include "ui/aura/test/test_cursor_client.h"
  17. #include "ui/aura/window.h"
  18. #include "ui/events/event.h"
  19. #include "ui/events/event_utils.h"
  20. #include "ui/events/gestures/gesture_provider_aura.h"
  21. #include "ui/events/test/event_generator.h"
  22. #include "ui/events/test/events_test_utils.h"
  23. #include "ui/gfx/geometry/point.h"
  24. #include "ui/gfx/geometry/transform.h"
  25. #include "ui/gl/gl_implementation.h"
  26. #include "ui/gl/test/gl_surface_test_support.h"
  27. using EventList = std::vector<std::unique_ptr<ui::Event>>;
  28. namespace ash {
  29. namespace {
  30. // Records all mouse, touch, gesture, and key events.
  31. class EventCapturer : public ui::EventHandler {
  32. public:
  33. EventCapturer() {}
  34. EventCapturer(const EventCapturer&) = delete;
  35. EventCapturer& operator=(const EventCapturer&) = delete;
  36. ~EventCapturer() override {}
  37. void Reset() { events_.clear(); }
  38. void OnEvent(ui::Event* event) override {
  39. if (event->IsMouseEvent() || event->IsTouchEvent() ||
  40. event->IsGestureEvent() || event->IsKeyEvent()) {
  41. events_.push_back(event->Clone());
  42. } else {
  43. return;
  44. }
  45. // Stop event propagation so we don't click on random stuff that
  46. // might break test assumptions.
  47. event->StopPropagation();
  48. // If there is a possibility that we're in an infinite loop, we should
  49. // exit early with a sensible error rather than letting the test time out.
  50. ASSERT_LT(events_.size(), 100u);
  51. }
  52. const EventList& captured_events() const { return events_; }
  53. private:
  54. EventList events_;
  55. };
  56. int Factorial(int n) {
  57. if (n <= 0)
  58. return 0;
  59. if (n == 1)
  60. return 1;
  61. return n * Factorial(n - 1);
  62. }
  63. } // namespace
  64. class TouchExplorationControllerTestApi {
  65. public:
  66. TouchExplorationControllerTestApi(
  67. TouchExplorationController* touch_exploration_controller) {
  68. touch_exploration_controller_.reset(touch_exploration_controller);
  69. }
  70. TouchExplorationControllerTestApi(const TouchExplorationControllerTestApi&) =
  71. delete;
  72. TouchExplorationControllerTestApi& operator=(
  73. const TouchExplorationControllerTestApi&) = delete;
  74. void CallTapTimerNowForTesting() {
  75. DCHECK(touch_exploration_controller_->tap_timer_.IsRunning());
  76. touch_exploration_controller_->tap_timer_.Stop();
  77. touch_exploration_controller_->OnTapTimerFired();
  78. }
  79. void CallTapTimerNowIfRunningForTesting() {
  80. if (touch_exploration_controller_->tap_timer_.IsRunning()) {
  81. touch_exploration_controller_->tap_timer_.Stop();
  82. touch_exploration_controller_->OnTapTimerFired();
  83. }
  84. }
  85. void CallLongPressTimerNowIfRunningForTesting() {
  86. if (touch_exploration_controller_->long_press_timer_.IsRunning()) {
  87. touch_exploration_controller_->long_press_timer_.Stop();
  88. touch_exploration_controller_->OnLiftActivationLongPressTimerFired();
  89. }
  90. }
  91. bool IsInNoFingersDownStateForTesting() const {
  92. return touch_exploration_controller_->state_ ==
  93. touch_exploration_controller_->NO_FINGERS_DOWN;
  94. }
  95. bool IsInGestureInProgressStateForTesting() const {
  96. return touch_exploration_controller_->state_ ==
  97. touch_exploration_controller_->GESTURE_IN_PROGRESS;
  98. }
  99. bool IsInSlideGestureStateForTesting() const {
  100. return touch_exploration_controller_->state_ ==
  101. touch_exploration_controller_->SLIDE_GESTURE;
  102. }
  103. bool IsInTwoFingerTapStateForTesting() const {
  104. return touch_exploration_controller_->state_ ==
  105. touch_exploration_controller_->TWO_FINGER_TAP;
  106. }
  107. gfx::Rect BoundsOfRootWindowInDIPForTesting() const {
  108. return touch_exploration_controller_->root_window_->GetBoundsInScreen();
  109. }
  110. // VLOGs should be suppressed in tests that generate a lot of logs,
  111. // for example permutations of nine touch events.
  112. void SuppressVLOGsForTesting(bool suppress) {
  113. touch_exploration_controller_->VLOG_on_ = !suppress;
  114. }
  115. float GetMaxDistanceFromEdge() const {
  116. return touch_exploration_controller_->kMaxDistanceFromEdge;
  117. }
  118. float GetSlopDistanceFromEdge() const {
  119. return touch_exploration_controller_->kSlopDistanceFromEdge;
  120. }
  121. void SetTouchAccessibilityAnchorPoint(const gfx::Point& location) {
  122. touch_exploration_controller_->SetTouchAccessibilityAnchorPoint(location);
  123. }
  124. void SetExcludeBounds(const gfx::Rect& bounds) {
  125. touch_exploration_controller_->SetExcludeBounds(bounds);
  126. }
  127. void SetLiftActivationBounds(const gfx::Rect& bounds) {
  128. touch_exploration_controller_->SetLiftActivationBounds(bounds);
  129. }
  130. private:
  131. std::unique_ptr<TouchExplorationController> touch_exploration_controller_;
  132. };
  133. class TouchExplorationTest : public aura::test::AuraTestBase {
  134. public:
  135. TouchExplorationTest() {}
  136. TouchExplorationTest(const TouchExplorationTest&) = delete;
  137. TouchExplorationTest& operator=(const TouchExplorationTest&) = delete;
  138. ~TouchExplorationTest() override {}
  139. void SetUp() override {
  140. if (gl::GetGLImplementation() == gl::kGLImplementationNone)
  141. gl::GLSurfaceTestSupport::InitializeOneOff();
  142. aura::test::AuraTestBase::SetUp();
  143. cursor_client_ =
  144. std::make_unique<aura::test::TestCursorClient>(root_window());
  145. root_window()->AddPreTargetHandler(&event_capturer_);
  146. generator_ = std::make_unique<ui::test::EventGenerator>(root_window());
  147. // Tests fail if time is ever 0.
  148. simulated_clock_.Advance(base::Milliseconds(10));
  149. // ui takes ownership of the tick clock.
  150. ui::SetEventTickClockForTesting(&simulated_clock_);
  151. cursor_client()->ShowCursor();
  152. cursor_client()->DisableMouseEvents();
  153. }
  154. void TearDown() override {
  155. ui::SetEventTickClockForTesting(nullptr);
  156. root_window()->RemovePreTargetHandler(&event_capturer_);
  157. SwitchTouchExplorationMode(false);
  158. cursor_client_.reset();
  159. aura::test::AuraTestBase::TearDown();
  160. }
  161. protected:
  162. aura::client::CursorClient* cursor_client() { return cursor_client_.get(); }
  163. const EventList& GetCapturedEvents() {
  164. return event_capturer_.captured_events();
  165. }
  166. std::vector<ui::LocatedEvent*> GetCapturedLocatedEvents() {
  167. const EventList& all_events = GetCapturedEvents();
  168. std::vector<ui::LocatedEvent*> located_events;
  169. for (size_t i = 0; i < all_events.size(); ++i) {
  170. if (all_events[i]->IsMouseEvent() || all_events[i]->IsTouchEvent() ||
  171. all_events[i]->IsGestureEvent()) {
  172. located_events.push_back(
  173. static_cast<ui::LocatedEvent*>(all_events[i].get()));
  174. }
  175. }
  176. return located_events;
  177. }
  178. std::vector<ui::Event*> GetCapturedEventsOfType(int type) {
  179. const EventList& all_events = GetCapturedEvents();
  180. std::vector<ui::Event*> events;
  181. for (size_t i = 0; i < all_events.size(); ++i) {
  182. if (type == all_events[i]->type())
  183. events.push_back(all_events[i].get());
  184. }
  185. return events;
  186. }
  187. std::vector<ui::LocatedEvent*> GetCapturedLocatedEventsOfType(int type) {
  188. std::vector<ui::LocatedEvent*> located_events = GetCapturedLocatedEvents();
  189. std::vector<ui::LocatedEvent*> events;
  190. for (size_t i = 0; i < located_events.size(); ++i) {
  191. if (type == located_events[i]->type())
  192. events.push_back(located_events[i]);
  193. }
  194. return events;
  195. }
  196. std::vector<gfx::Point>& GetTouchExplorePoints() {
  197. return delegate_.GetTouchExplorePoints();
  198. }
  199. void ClearCapturedAndGestureEvents() {
  200. event_capturer_.Reset();
  201. GetTouchExplorePoints().clear();
  202. }
  203. void AdvanceSimulatedTimePastTapDelay() {
  204. simulated_clock_.Advance(gesture_detector_config_.double_tap_timeout);
  205. simulated_clock_.Advance(base::Milliseconds(1));
  206. touch_exploration_controller_->CallTapTimerNowForTesting();
  207. }
  208. void AdvanceSimulatedTimePastPotentialTapDelay() {
  209. simulated_clock_.Advance(base::Milliseconds(1000));
  210. touch_exploration_controller_->CallTapTimerNowIfRunningForTesting();
  211. }
  212. void AdvanceSimulatedTimePastLongPressDelay() {
  213. simulated_clock_.Advance(base::Milliseconds(5000));
  214. touch_exploration_controller_->CallLongPressTimerNowIfRunningForTesting();
  215. }
  216. void SuppressVLOGs(bool suppress) {
  217. touch_exploration_controller_->SuppressVLOGsForTesting(suppress);
  218. }
  219. void SwitchTouchExplorationMode(bool on) {
  220. if (!on && touch_exploration_controller_.get()) {
  221. touch_exploration_controller_.reset();
  222. } else if (on && !touch_exploration_controller_.get()) {
  223. touch_exploration_controller_ =
  224. std::make_unique<TouchExplorationControllerTestApi>(
  225. new TouchExplorationController(root_window(), &delegate_,
  226. nullptr));
  227. cursor_client()->ShowCursor();
  228. cursor_client()->DisableMouseEvents();
  229. }
  230. }
  231. void EnterTouchExplorationModeAtLocation(gfx::Point tap_location) {
  232. ui::TouchEvent touch_press(
  233. ui::ET_TOUCH_PRESSED, tap_location, Now(),
  234. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  235. generator_->Dispatch(&touch_press);
  236. AdvanceSimulatedTimePastTapDelay();
  237. EXPECT_TRUE(IsInTouchToMouseMode());
  238. }
  239. bool IsInTouchToMouseMode() {
  240. aura::client::CursorClient* cursor_client =
  241. aura::client::GetCursorClient(root_window());
  242. return cursor_client && cursor_client->IsMouseEventsEnabled() &&
  243. !cursor_client->IsCursorVisible();
  244. }
  245. bool IsInNoFingersDownState() {
  246. return touch_exploration_controller_->IsInNoFingersDownStateForTesting();
  247. }
  248. bool IsInGestureInProgressState() {
  249. return touch_exploration_controller_
  250. ->IsInGestureInProgressStateForTesting();
  251. }
  252. bool IsInSlideGestureState() {
  253. return touch_exploration_controller_->IsInSlideGestureStateForTesting();
  254. }
  255. bool IsInTwoFingerTapState() {
  256. return touch_exploration_controller_->IsInTwoFingerTapStateForTesting();
  257. }
  258. gfx::Rect BoundsOfRootWindowInDIP() {
  259. return touch_exploration_controller_->BoundsOfRootWindowInDIPForTesting();
  260. }
  261. float GetMaxDistanceFromEdge() const {
  262. return touch_exploration_controller_->GetMaxDistanceFromEdge();
  263. }
  264. float GetSlopDistanceFromEdge() const {
  265. return touch_exploration_controller_->GetSlopDistanceFromEdge();
  266. }
  267. base::TimeTicks Now() { return ui::EventTimeForNow(); }
  268. void SetTouchAccessibilityAnchorPoint(const gfx::Point& location) {
  269. touch_exploration_controller_->SetTouchAccessibilityAnchorPoint(location);
  270. }
  271. void SetExcludeBounds(const gfx::Rect& bounds) {
  272. touch_exploration_controller_->SetExcludeBounds(bounds);
  273. }
  274. void SetLiftActivationBounds(const gfx::Rect& bounds) {
  275. touch_exploration_controller_->SetLiftActivationBounds(bounds);
  276. }
  277. // Taps at |tap_location|, waiting past tap delay to enter touch
  278. // exploration. Pass true to |set_anchor_point| to ensure any subsequent
  279. // gestures like a double tap go to |tap_location|. Usually, ChromeVox sets
  280. // the anchor, which is the center of the focused node and can differ from
  281. // |tap_location|.
  282. void TapAndVerifyTouchExplore(gfx::Point tap_location,
  283. bool set_anchor_point = false) {
  284. generator_->set_current_screen_location(tap_location);
  285. generator_->PressTouchId(1);
  286. generator_->ReleaseTouchId(1);
  287. AdvanceSimulatedTimePastTapDelay();
  288. if (set_anchor_point)
  289. SetTouchAccessibilityAnchorPoint(tap_location);
  290. std::vector<ui::LocatedEvent*> events =
  291. GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
  292. ASSERT_TRUE(events.empty());
  293. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  294. EXPECT_EQ(tap_location, GetTouchExplorePoints()[0]);
  295. ClearCapturedAndGestureEvents();
  296. }
  297. std::unique_ptr<ui::test::EventGenerator> generator_;
  298. ui::GestureDetector::Config gesture_detector_config_;
  299. base::SimpleTestTickClock simulated_clock_;
  300. MockTouchExplorationControllerDelegate delegate_;
  301. private:
  302. EventCapturer event_capturer_;
  303. std::unique_ptr<TouchExplorationControllerTestApi>
  304. touch_exploration_controller_;
  305. std::unique_ptr<aura::test::TestCursorClient> cursor_client_;
  306. };
  307. // Executes a number of assertions to confirm that |e1| and |e2| are touch
  308. // events and are equal to each other.
  309. void ConfirmEventsAreTouchAndEqual(ui::Event* e1, ui::Event* e2) {
  310. ASSERT_TRUE(e1->IsTouchEvent());
  311. ASSERT_TRUE(e2->IsTouchEvent());
  312. ui::TouchEvent* touch_event1 = e1->AsTouchEvent();
  313. ui::TouchEvent* touch_event2 = e2->AsTouchEvent();
  314. EXPECT_EQ(touch_event1->type(), touch_event2->type());
  315. EXPECT_EQ(touch_event1->location(), touch_event2->location());
  316. EXPECT_EQ(touch_event1->pointer_details().id,
  317. touch_event2->pointer_details().id);
  318. EXPECT_EQ(touch_event1->flags(), touch_event2->flags());
  319. EXPECT_EQ(touch_event1->time_stamp(), touch_event2->time_stamp());
  320. }
  321. // Executes a number of assertions to confirm that |e1| and |e2| are mouse
  322. // events and are equal to each other.
  323. void ConfirmEventsAreMouseAndEqual(ui::Event* e1, ui::Event* e2) {
  324. ASSERT_TRUE(e1->IsMouseEvent());
  325. ASSERT_TRUE(e2->IsMouseEvent());
  326. ui::MouseEvent* mouse_event1 = e1->AsMouseEvent();
  327. ui::MouseEvent* mouse_event2 = e2->AsMouseEvent();
  328. EXPECT_EQ(mouse_event1->type(), mouse_event2->type());
  329. EXPECT_EQ(mouse_event1->location(), mouse_event2->location());
  330. EXPECT_EQ(mouse_event1->root_location(), mouse_event2->root_location());
  331. EXPECT_EQ(mouse_event1->flags(), mouse_event2->flags());
  332. }
  333. // Executes a number of assertions to confirm that |e1| and |e2| are key events
  334. // and are equal to each other.
  335. void ConfirmEventsAreKeyAndEqual(ui::Event* e1, ui::Event* e2) {
  336. ASSERT_TRUE(e1->IsKeyEvent());
  337. ASSERT_TRUE(e2->IsKeyEvent());
  338. ui::KeyEvent* key_event1 = e1->AsKeyEvent();
  339. ui::KeyEvent* key_event2 = e2->AsKeyEvent();
  340. EXPECT_EQ(key_event1->type(), key_event2->type());
  341. EXPECT_EQ(key_event1->key_code(), key_event2->key_code());
  342. EXPECT_EQ(key_event1->code(), key_event2->code());
  343. EXPECT_EQ(key_event1->flags(), key_event2->flags());
  344. }
  345. #define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \
  346. ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2))
  347. #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \
  348. ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2))
  349. #define CONFIRM_EVENTS_ARE_KEY_AND_EQUAL(e1, e2) \
  350. ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreKeyAndEqual(e1, e2))
  351. // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit
  352. // events when running these tests as part of ui_base_unittests. We do get them
  353. // when the tests are run as part of ash unit tests.
  354. TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterPressAndDelay) {
  355. SwitchTouchExplorationMode(true);
  356. EXPECT_FALSE(IsInTouchToMouseMode());
  357. generator_->PressTouch();
  358. AdvanceSimulatedTimePastTapDelay();
  359. EXPECT_TRUE(IsInTouchToMouseMode());
  360. }
  361. TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterMoveOutsideSlop) {
  362. int slop = gesture_detector_config_.touch_slop;
  363. int half_slop = slop / 2;
  364. SwitchTouchExplorationMode(true);
  365. EXPECT_FALSE(IsInTouchToMouseMode());
  366. generator_->set_current_screen_location(gfx::Point(11, 12));
  367. generator_->PressTouch();
  368. generator_->MoveTouch(gfx::Point(11 + half_slop, 12));
  369. EXPECT_FALSE(IsInTouchToMouseMode());
  370. generator_->MoveTouch(gfx::Point(11, 12 + half_slop));
  371. EXPECT_FALSE(IsInTouchToMouseMode());
  372. AdvanceSimulatedTimePastTapDelay();
  373. generator_->MoveTouch(gfx::Point(11 + slop + 1, 12));
  374. EXPECT_TRUE(IsInTouchToMouseMode());
  375. }
  376. TEST_F(TouchExplorationTest, OneFingerTap) {
  377. SwitchTouchExplorationMode(true);
  378. gfx::Point location(11, 12);
  379. generator_->set_current_screen_location(location);
  380. generator_->PressTouch();
  381. generator_->ReleaseTouch();
  382. AdvanceSimulatedTimePastTapDelay();
  383. std::vector<ui::LocatedEvent*> events =
  384. GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
  385. ASSERT_EQ(0U, events.size());
  386. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  387. EXPECT_EQ(location, GetTouchExplorePoints()[0]);
  388. EXPECT_TRUE(IsInNoFingersDownState());
  389. }
  390. TEST_F(TouchExplorationTest, ActualMouseMovesUnaffected) {
  391. SwitchTouchExplorationMode(true);
  392. gfx::Point location_start(11, 12);
  393. gfx::Point location_end(13, 14);
  394. generator_->set_current_screen_location(location_start);
  395. generator_->PressTouch();
  396. AdvanceSimulatedTimePastTapDelay();
  397. generator_->MoveTouch(location_end);
  398. gfx::Point location_real_mouse_move(15, 16);
  399. ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, location_real_mouse_move,
  400. location_real_mouse_move, ui::EventTimeForNow(), 0,
  401. 0);
  402. generator_->Dispatch(&mouse_move);
  403. generator_->ReleaseTouch();
  404. AdvanceSimulatedTimePastTapDelay();
  405. std::vector<ui::LocatedEvent*> events =
  406. GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
  407. std::vector<gfx::Point> touch_explore_points = GetTouchExplorePoints();
  408. ASSERT_EQ(1U, events.size());
  409. ASSERT_EQ(3U, touch_explore_points.size());
  410. EXPECT_EQ(location_start, touch_explore_points[0]);
  411. EXPECT_EQ(location_end, touch_explore_points[1]);
  412. EXPECT_EQ(location_end, touch_explore_points[2]);
  413. // The real mouse move goes through.
  414. EXPECT_EQ(location_real_mouse_move, events[0]->location());
  415. CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(events[0], &mouse_move);
  416. EXPECT_FALSE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
  417. EXPECT_FALSE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
  418. EXPECT_TRUE(IsInNoFingersDownState());
  419. }
  420. // Turn the touch exploration mode on in the middle of the touch gesture.
  421. // Confirm that events from the finger which was touching when the mode was
  422. // turned on don't get rewritten.
  423. TEST_F(TouchExplorationTest, TurnOnMidTouch) {
  424. SwitchTouchExplorationMode(false);
  425. generator_->PressTouchId(1);
  426. EXPECT_TRUE(cursor_client()->IsCursorVisible());
  427. ClearCapturedAndGestureEvents();
  428. // Enable touch exploration mode while the first finger is touching the
  429. // screen. Ensure that subsequent events from that first finger are not
  430. // affected by the touch exploration mode, while the touch events from another
  431. // finger get rewritten.
  432. SwitchTouchExplorationMode(true);
  433. ui::TouchEvent touch_move(
  434. ui::ET_TOUCH_MOVED, gfx::Point(11, 12), Now(),
  435. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  436. generator_->Dispatch(&touch_move);
  437. EXPECT_TRUE(cursor_client()->IsCursorVisible());
  438. EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
  439. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  440. ASSERT_EQ(1u, captured_events.size());
  441. CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
  442. ClearCapturedAndGestureEvents();
  443. // The press from the second finger should get rewritten.
  444. generator_->PressTouchId(2);
  445. AdvanceSimulatedTimePastTapDelay();
  446. EXPECT_TRUE(IsInTouchToMouseMode());
  447. ASSERT_FALSE(GetTouchExplorePoints().empty());
  448. // The release of the first finger shouldn't be affected.
  449. ui::TouchEvent touch_release(
  450. ui::ET_TOUCH_RELEASED, gfx::Point(11, 12), Now(),
  451. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  452. generator_->Dispatch(&touch_release);
  453. captured_events = GetCapturedLocatedEvents();
  454. ASSERT_EQ(1u, captured_events.size());
  455. CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release);
  456. ClearCapturedAndGestureEvents();
  457. // The move and release from the second finger should get rewritten.
  458. generator_->MoveTouchId(gfx::Point(13, 14), 2);
  459. generator_->ReleaseTouchId(2);
  460. AdvanceSimulatedTimePastTapDelay();
  461. captured_events = GetCapturedLocatedEvents();
  462. ASSERT_TRUE(captured_events.empty());
  463. ASSERT_EQ(2U, GetTouchExplorePoints().size());
  464. EXPECT_TRUE(IsInNoFingersDownState());
  465. }
  466. // If an event is received after the double-tap timeout has elapsed, but
  467. // before the timer has fired, a mouse move should still be generated.
  468. TEST_F(TouchExplorationTest, TimerFiresLateDuringTouchExploration) {
  469. SwitchTouchExplorationMode(true);
  470. // Make sure the touch is not in a corner of the screen.
  471. generator_->MoveTouch(gfx::Point(100, 200));
  472. // Send a press, then add another finger after the double-tap timeout.
  473. generator_->PressTouchId(1);
  474. simulated_clock_.Advance(base::Milliseconds(1000));
  475. generator_->PressTouchId(2);
  476. std::vector<ui::LocatedEvent*> events =
  477. GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
  478. ASSERT_TRUE(events.empty());
  479. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  480. generator_->ReleaseTouchId(2);
  481. generator_->ReleaseTouchId(1);
  482. AdvanceSimulatedTimePastTapDelay();
  483. EXPECT_TRUE(IsInNoFingersDownState());
  484. }
  485. // If a new tap is received after the double-tap timeout has elapsed from
  486. // a previous tap, but before the timer has fired, a mouse move should
  487. // still be generated from the old tap.
  488. TEST_F(TouchExplorationTest, TimerFiresLateAfterTap) {
  489. SwitchTouchExplorationMode(true);
  490. // Send a tap at location1.
  491. gfx::Point location0(11, 12);
  492. generator_->set_current_screen_location(location0);
  493. generator_->PressTouch();
  494. generator_->ReleaseTouch();
  495. // Send a tap at location2, after the double-tap timeout, but before the
  496. // timer fires.
  497. gfx::Point location1(33, 34);
  498. generator_->set_current_screen_location(location1);
  499. simulated_clock_.Advance(base::Milliseconds(301));
  500. generator_->PressTouch();
  501. generator_->ReleaseTouch();
  502. AdvanceSimulatedTimePastTapDelay();
  503. std::vector<ui::LocatedEvent*> events =
  504. GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
  505. ASSERT_TRUE(events.empty());
  506. ASSERT_EQ(2U, GetTouchExplorePoints().size());
  507. EXPECT_EQ(location0, GetTouchExplorePoints()[0]);
  508. EXPECT_EQ(location1, GetTouchExplorePoints()[1]);
  509. EXPECT_TRUE(IsInNoFingersDownState());
  510. }
  511. // Double-tapping should send a touch press and release through to the location
  512. // of the last successful touch exploration.
  513. TEST_F(TouchExplorationTest, DoubleTap) {
  514. SwitchTouchExplorationMode(true);
  515. gfx::Point tap_location(51, 52);
  516. TapAndVerifyTouchExplore(tap_location);
  517. // Now double-tap at a different location. This should result in
  518. // no touches at all, but a click gesture to ChromeVox.
  519. gfx::Point double_tap_location(33, 34);
  520. generator_->set_current_screen_location(double_tap_location);
  521. generator_->PressTouch();
  522. generator_->ReleaseTouch();
  523. generator_->PressTouch();
  524. generator_->ReleaseTouch();
  525. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  526. ASSERT_TRUE(captured_events.empty());
  527. EXPECT_EQ(ax::mojom::Gesture::kClick, delegate_.GetLastGesture());
  528. EXPECT_TRUE(IsInNoFingersDownState());
  529. }
  530. // The press of the second tap in a double-tap must come within the double-tap
  531. // timeout, but the release of the second tap can come later.
  532. TEST_F(TouchExplorationTest, DoubleTapTiming) {
  533. SwitchTouchExplorationMode(true);
  534. gfx::Point tap_location(51, 52);
  535. TapAndVerifyTouchExplore(tap_location, true);
  536. // The press of the second tap happens in time, but the release does not.
  537. gfx::Point double_tap_location(33, 34);
  538. generator_->set_current_screen_location(double_tap_location);
  539. generator_->PressTouch();
  540. generator_->ReleaseTouch();
  541. simulated_clock_.Advance(gesture_detector_config_.double_tap_timeout -
  542. base::Milliseconds(25));
  543. generator_->PressTouch();
  544. simulated_clock_.Advance(base::Milliseconds(50));
  545. generator_->ReleaseTouch();
  546. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  547. ASSERT_EQ(0U, captured_events.size());
  548. EXPECT_EQ(ax::mojom::Gesture::kClick, delegate_.GetLastGesture());
  549. }
  550. // If an explicit anchor point is set during touch exploration, double-tapping
  551. // should send a 'click' gesture rather than a simulated touch press and
  552. // release.
  553. TEST_F(TouchExplorationTest, DoubleTapWithExplicitAnchorPoint) {
  554. SwitchTouchExplorationMode(true);
  555. gfx::Point tap_location(51, 52);
  556. TapAndVerifyTouchExplore(tap_location, true);
  557. // Now double-tap at a different location. This should result in
  558. // a click gesture.
  559. gfx::Point double_tap_location(33, 34);
  560. generator_->set_current_screen_location(double_tap_location);
  561. generator_->PressTouch();
  562. generator_->ReleaseTouch();
  563. generator_->PressTouch();
  564. generator_->ReleaseTouch();
  565. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  566. ASSERT_EQ(0U, captured_events.size());
  567. EXPECT_TRUE(IsInNoFingersDownState());
  568. EXPECT_EQ(ax::mojom::Gesture::kClick, delegate_.GetLastGesture());
  569. }
  570. // Double-tapping where the user holds their finger down for the second time
  571. // for a longer press should send a touch press and passthrough all further
  572. // events from that finger. Other finger presses should be ignored.
  573. TEST_F(TouchExplorationTest, DoubleTapPassthrough) {
  574. SwitchTouchExplorationMode(true);
  575. gfx::Point tap_location(11, 12);
  576. TapAndVerifyTouchExplore(tap_location);
  577. // Now double-tap and hold at a different location.
  578. // This should result in a single touch press at the location of the tap,
  579. // not at the location of the double-tap.
  580. gfx::Point first_tap_location(13, 14);
  581. generator_->set_current_screen_location(first_tap_location);
  582. generator_->PressTouchId(1);
  583. generator_->ReleaseTouchId(1);
  584. ASSERT_EQ(0U, delegate_.NumPassthroughSounds());
  585. gfx::Point second_tap_location(15, 16);
  586. generator_->set_current_screen_location(second_tap_location);
  587. generator_->PressTouchId(1);
  588. // Advance to the finger passing through.
  589. AdvanceSimulatedTimePastTapDelay();
  590. ASSERT_EQ(1U, delegate_.NumPassthroughSounds());
  591. gfx::Vector2d passthrough_offset = second_tap_location - tap_location;
  592. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  593. ASSERT_EQ(1U, captured_events.size());
  594. EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
  595. EXPECT_EQ(second_tap_location - passthrough_offset,
  596. captured_events[0]->location());
  597. EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
  598. ClearCapturedAndGestureEvents();
  599. // All events for the first finger should pass through now, displaced
  600. // relative to the last touch exploration location.
  601. gfx::Point first_move_location(17, 18);
  602. generator_->MoveTouchId(first_move_location, 1);
  603. gfx::Point second_move_location(12, 13);
  604. generator_->MoveTouchId(second_move_location, 1);
  605. captured_events = GetCapturedLocatedEvents();
  606. ASSERT_EQ(2U, captured_events.size());
  607. EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
  608. EXPECT_EQ(first_move_location - passthrough_offset,
  609. captured_events[0]->location());
  610. EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[1]->type());
  611. EXPECT_EQ(second_move_location - passthrough_offset,
  612. captured_events[1]->location());
  613. EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
  614. ClearCapturedAndGestureEvents();
  615. // Events for other fingers should do nothing.
  616. generator_->PressTouchId(2);
  617. generator_->PressTouchId(3);
  618. generator_->MoveTouchId(gfx::Point(34, 36), 2);
  619. generator_->ReleaseTouchId(2);
  620. captured_events = GetCapturedLocatedEvents();
  621. ASSERT_EQ(0U, captured_events.size());
  622. // Even with finger 3 still down, events for the first finger should still
  623. // pass through.
  624. gfx::Point third_move_location(14, 15);
  625. generator_->MoveTouchId(third_move_location, 1);
  626. captured_events = GetCapturedLocatedEvents();
  627. ASSERT_EQ(1U, captured_events.size());
  628. EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
  629. EXPECT_EQ(third_move_location - passthrough_offset,
  630. captured_events[0]->location());
  631. EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
  632. // No fingers down state is only reached when every finger is lifted.
  633. generator_->ReleaseTouchId(1);
  634. EXPECT_FALSE(IsInNoFingersDownState());
  635. generator_->ReleaseTouchId(3);
  636. EXPECT_TRUE(IsInNoFingersDownState());
  637. // There should have only ever been one pass through earcon played.
  638. ASSERT_EQ(1U, delegate_.NumPassthroughSounds());
  639. }
  640. // Double-tapping, going into passthrough, and holding for the longpress
  641. // time should send a touch press and released (right click)
  642. // to the location of the last successful touch exploration.
  643. TEST_F(TouchExplorationTest, DoubleTapLongPress) {
  644. SwitchTouchExplorationMode(true);
  645. gfx::Point tap_location(11, 12);
  646. TapAndVerifyTouchExplore(tap_location);
  647. // Now double-tap and hold at a different location.
  648. // This should result in a single touch long press and release
  649. // at the location of the tap, not at the location of the double-tap.
  650. // There should be a time delay between the touch press and release.
  651. gfx::Point first_tap_location(33, 34);
  652. generator_->set_current_screen_location(first_tap_location);
  653. generator_->PressTouch();
  654. generator_->ReleaseTouch();
  655. gfx::Point second_tap_location(23, 24);
  656. generator_->set_current_screen_location(second_tap_location);
  657. generator_->PressTouch();
  658. // Advance to the finger passing through, and then to the longpress timeout.
  659. AdvanceSimulatedTimePastTapDelay();
  660. simulated_clock_.Advance(gesture_detector_config_.longpress_timeout);
  661. generator_->ReleaseTouch();
  662. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  663. ASSERT_EQ(2U, captured_events.size());
  664. EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
  665. EXPECT_EQ(tap_location, captured_events[0]->location());
  666. EXPECT_TRUE(captured_events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
  667. base::TimeTicks pressed_time = captured_events[0]->time_stamp();
  668. EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
  669. EXPECT_EQ(tap_location, captured_events[1]->location());
  670. EXPECT_TRUE(captured_events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
  671. base::TimeTicks released_time = captured_events[1]->time_stamp();
  672. EXPECT_EQ(released_time - pressed_time,
  673. gesture_detector_config_.longpress_timeout);
  674. }
  675. // Single-tapping should send a touch press and release through to the location
  676. // of the last successful touch exploration if the grace period has not
  677. // elapsed.
  678. TEST_F(TouchExplorationTest, SingleTap) {
  679. SwitchTouchExplorationMode(true);
  680. // Tap once to simulate a touch explore point.
  681. gfx::Point initial_location(11, 12);
  682. generator_->set_current_screen_location(initial_location);
  683. generator_->PressTouch();
  684. AdvanceSimulatedTimePastTapDelay();
  685. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  686. // Move to another location for single tap
  687. gfx::Point tap_location(22, 23);
  688. generator_->MoveTouch(tap_location);
  689. generator_->ReleaseTouch();
  690. // Allow time to pass within the grace period of releasing before
  691. // tapping again.
  692. gfx::Point final_location(33, 34);
  693. generator_->set_current_screen_location(final_location);
  694. simulated_clock_.Advance(base::Milliseconds(250));
  695. generator_->PressTouch();
  696. generator_->ReleaseTouch();
  697. ASSERT_EQ(3U, GetTouchExplorePoints().size());
  698. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  699. ASSERT_TRUE(captured_events.empty());
  700. EXPECT_EQ(ax::mojom::Gesture::kClick, delegate_.GetLastGesture());
  701. }
  702. // Double-tapping without coming from touch exploration (no previous touch
  703. // exploration event) should not generate any events.
  704. TEST_F(TouchExplorationTest, DoubleTapNoTouchExplore) {
  705. SwitchTouchExplorationMode(true);
  706. // Double-tap without any previous touch.
  707. // Touch exploration mode has not been entered, so there is no previous
  708. // touch exploration event. The double-tap should be discarded, and no events
  709. // should be generated at all.
  710. gfx::Point double_tap_location(33, 34);
  711. generator_->set_current_screen_location(double_tap_location);
  712. generator_->PressTouch();
  713. generator_->ReleaseTouch();
  714. generator_->PressTouch();
  715. // Since the state stays in single_tap_released, we need to make sure the
  716. // tap timer doesn't fire and set the state to no fingers down (since there
  717. // is still a finger down).
  718. AdvanceSimulatedTimePastPotentialTapDelay();
  719. EXPECT_FALSE(IsInNoFingersDownState());
  720. generator_->ReleaseTouch();
  721. EXPECT_TRUE(IsInNoFingersDownState());
  722. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  723. ASSERT_EQ(0U, captured_events.size());
  724. }
  725. // Tapping and releasing with a second finger when in touch exploration mode
  726. // should send a touch press and released to the location of the last
  727. // successful touch exploration and return to touch explore.
  728. TEST_F(TouchExplorationTest, SplitTap) {
  729. SwitchTouchExplorationMode(true);
  730. gfx::Point initial_touch_location(11, 12);
  731. gfx::Point second_touch_location(33, 34);
  732. // Tap and hold at one location, and get a mouse move event in touch explore.
  733. EnterTouchExplorationModeAtLocation(initial_touch_location);
  734. std::vector<ui::LocatedEvent*> events =
  735. GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
  736. ASSERT_TRUE(events.empty());
  737. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  738. EXPECT_EQ(initial_touch_location, GetTouchExplorePoints()[0]);
  739. ClearCapturedAndGestureEvents();
  740. EXPECT_TRUE(IsInTouchToMouseMode());
  741. // Now tap and release at a different location. This should result in a
  742. // single touch and release at the location of the first (held) tap,
  743. // not at the location of the second tap and release.
  744. // After the release, there is still a finger in touch explore mode.
  745. ui::TouchEvent split_tap_press(
  746. ui::ET_TOUCH_PRESSED, second_touch_location, Now(),
  747. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  748. generator_->Dispatch(&split_tap_press);
  749. // To simulate the behavior of the real device, we manually disable
  750. // mouse events. To not rely on manually setting the state, this is also
  751. // tested in touch_exploration_controller_browsertest.
  752. cursor_client()->DisableMouseEvents();
  753. EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
  754. EXPECT_FALSE(cursor_client()->IsCursorVisible());
  755. EXPECT_FALSE(IsInGestureInProgressState());
  756. ui::TouchEvent split_tap_release(
  757. ui::ET_TOUCH_RELEASED, second_touch_location, Now(),
  758. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  759. generator_->Dispatch(&split_tap_release);
  760. // Releasing the second finger should re-enable mouse events putting us
  761. // back into the touch exploration mode.
  762. EXPECT_TRUE(IsInTouchToMouseMode());
  763. EXPECT_FALSE(IsInNoFingersDownState());
  764. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  765. ASSERT_TRUE(captured_events.empty());
  766. EXPECT_EQ(ax::mojom::Gesture::kClick, delegate_.GetLastGesture());
  767. ClearCapturedAndGestureEvents();
  768. ui::TouchEvent touch_explore_release(
  769. ui::ET_TOUCH_RELEASED, initial_touch_location, Now(),
  770. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  771. generator_->Dispatch(&touch_explore_release);
  772. AdvanceSimulatedTimePastTapDelay();
  773. EXPECT_TRUE(IsInNoFingersDownState());
  774. }
  775. // If split tap is started but the touch explore finger is released first,
  776. // there should still be a touch press and release sent to the location of
  777. // the last successful touch exploration.
  778. // Both fingers should be released after the click goes through.
  779. TEST_F(TouchExplorationTest, SplitTapRelease) {
  780. SwitchTouchExplorationMode(true);
  781. gfx::Point initial_touch_location(11, 12);
  782. gfx::Point second_touch_location(33, 34);
  783. // Tap and hold at one location, and get a mouse move event in touch explore.
  784. EnterTouchExplorationModeAtLocation(initial_touch_location);
  785. std::vector<ui::LocatedEvent*> events =
  786. GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
  787. ASSERT_TRUE(events.empty());
  788. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  789. // Now tap at a different location. Release at the first location,
  790. // then release at the second. This should result in a
  791. // click gesture to ChromeVox.
  792. ui::TouchEvent split_tap_press(
  793. ui::ET_TOUCH_PRESSED, second_touch_location, Now(),
  794. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  795. generator_->Dispatch(&split_tap_press);
  796. ui::TouchEvent touch_explore_release(
  797. ui::ET_TOUCH_RELEASED, initial_touch_location, Now(),
  798. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  799. generator_->Dispatch(&touch_explore_release);
  800. ui::TouchEvent split_tap_release(
  801. ui::ET_TOUCH_RELEASED, second_touch_location, Now(),
  802. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  803. generator_->Dispatch(&split_tap_release);
  804. EXPECT_TRUE(IsInNoFingersDownState());
  805. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  806. EXPECT_TRUE(captured_events.empty());
  807. EXPECT_EQ(ax::mojom::Gesture::kClick, delegate_.GetLastGesture());
  808. }
  809. TEST_F(TouchExplorationTest, SplitTapMultiFinger) {
  810. SwitchTouchExplorationMode(true);
  811. gfx::Point initial_touch_location(11, 12);
  812. gfx::Point second_touch_location(33, 34);
  813. gfx::Point third_touch_location(16, 17);
  814. // Tap and hold at one location, and get a mouse move event in touch explore.
  815. EnterTouchExplorationModeAtLocation(initial_touch_location);
  816. std::vector<ui::LocatedEvent*> events =
  817. GetCapturedLocatedEventsOfType(ui::ET_MOUSE_MOVED);
  818. ASSERT_TRUE(events.empty());
  819. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  820. EXPECT_EQ(initial_touch_location, GetTouchExplorePoints()[0]);
  821. ClearCapturedAndGestureEvents();
  822. // Now tap at a different location
  823. ui::TouchEvent split_tap_press(
  824. ui::ET_TOUCH_PRESSED, second_touch_location, Now(),
  825. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  826. generator_->Dispatch(&split_tap_press);
  827. simulated_clock_.Advance(gesture_detector_config_.longpress_timeout);
  828. // Placing a third finger on the screen should cancel the split tap and
  829. // enter the wait state.
  830. ui::TouchEvent third_press(
  831. ui::ET_TOUCH_PRESSED, third_touch_location, Now(),
  832. ui::PointerDetails(ui::EventPointerType::kTouch, 2));
  833. generator_->Dispatch(&third_press);
  834. // When all three fingers are released, no events should be captured.
  835. // All fingers should then be up.
  836. ui::TouchEvent touch_explore_release(
  837. ui::ET_TOUCH_RELEASED, initial_touch_location, Now(),
  838. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  839. generator_->Dispatch(&touch_explore_release);
  840. ui::TouchEvent split_tap_release(
  841. ui::ET_TOUCH_RELEASED, second_touch_location, Now(),
  842. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  843. generator_->Dispatch(&split_tap_release);
  844. ui::TouchEvent third_tap_release(
  845. ui::ET_TOUCH_RELEASED, third_touch_location, Now(),
  846. ui::PointerDetails(ui::EventPointerType::kTouch, 2));
  847. generator_->Dispatch(&third_tap_release);
  848. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  849. ASSERT_EQ(0U, captured_events.size());
  850. EXPECT_TRUE(IsInNoFingersDownState());
  851. }
  852. TEST_F(TouchExplorationTest, SplitTapLeaveSlop) {
  853. SwitchTouchExplorationMode(true);
  854. gfx::Point first_touch_location(11, 12);
  855. gfx::Point second_touch_location(33, 34);
  856. gfx::Point first_move_location(
  857. first_touch_location.x() + gesture_detector_config_.touch_slop * 3 + 1,
  858. first_touch_location.y());
  859. gfx::Point second_move_location(
  860. second_touch_location.x() + gesture_detector_config_.touch_slop * 3 + 1,
  861. second_touch_location.y());
  862. // Tap and hold at one location, and get a mouse move event in touch explore.
  863. EnterTouchExplorationModeAtLocation(first_touch_location);
  864. ClearCapturedAndGestureEvents();
  865. // Now tap at a different location for split tap.
  866. ui::TouchEvent split_tap_press(
  867. ui::ET_TOUCH_PRESSED, second_touch_location, Now(),
  868. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  869. generator_->Dispatch(&split_tap_press);
  870. // Move the first finger out of slop and release both fingers. The split
  871. // tap should have been cancelled.
  872. ui::TouchEvent first_touch_move(
  873. ui::ET_TOUCH_MOVED, first_move_location, Now(),
  874. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  875. generator_->Dispatch(&first_touch_move);
  876. ui::TouchEvent first_touch_release(
  877. ui::ET_TOUCH_RELEASED, first_move_location, Now(),
  878. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  879. generator_->Dispatch(&first_touch_release);
  880. ui::TouchEvent second_touch_release(
  881. ui::ET_TOUCH_RELEASED, second_touch_location, Now(),
  882. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  883. generator_->Dispatch(&second_touch_release);
  884. std::vector<ui::LocatedEvent*> captured_events = GetCapturedLocatedEvents();
  885. ASSERT_EQ(0U, captured_events.size());
  886. EXPECT_TRUE(IsInNoFingersDownState());
  887. // Now do the same, but moving the split tap finger out of slop
  888. EnterTouchExplorationModeAtLocation(first_touch_location);
  889. ClearCapturedAndGestureEvents();
  890. ui::TouchEvent split_tap_press2(
  891. ui::ET_TOUCH_PRESSED, second_touch_location, Now(),
  892. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  893. generator_->Dispatch(&split_tap_press2);
  894. // Move the second finger out of slop and release both fingers. The split
  895. // tap should have been cancelled.
  896. ui::TouchEvent second_touch_move2(
  897. ui::ET_TOUCH_MOVED, second_move_location, Now(),
  898. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  899. generator_->Dispatch(&second_touch_move2);
  900. ui::TouchEvent first_touch_release2(
  901. ui::ET_TOUCH_RELEASED, first_touch_location, Now(),
  902. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  903. generator_->Dispatch(&first_touch_release2);
  904. ui::TouchEvent second_touch_release2(
  905. ui::ET_TOUCH_RELEASED, second_move_location, Now(),
  906. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  907. generator_->Dispatch(&second_touch_release2);
  908. captured_events = GetCapturedLocatedEvents();
  909. ASSERT_EQ(0U, captured_events.size());
  910. EXPECT_TRUE(IsInNoFingersDownState());
  911. }
  912. // Finger must have moved more than slop, faster than the minimum swipe
  913. // velocity, and before the tap timer fires in order to enter
  914. // GestureInProgress state. Otherwise, if the tap timer fires before the a
  915. // gesture is completed, enter touch exploration.
  916. TEST_F(TouchExplorationTest, EnterGestureInProgressState) {
  917. SwitchTouchExplorationMode(true);
  918. EXPECT_FALSE(IsInTouchToMouseMode());
  919. EXPECT_FALSE(IsInGestureInProgressState());
  920. float distance = gesture_detector_config_.touch_slop + 1;
  921. ui::TouchEvent first_press(
  922. ui::ET_TOUCH_PRESSED, gfx::Point(0, 1), Now(),
  923. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  924. gfx::Point second_location(distance / 2, 1);
  925. gfx::Point third_location(distance, 1);
  926. gfx::Point touch_exploration_location(20, 21);
  927. generator_->Dispatch(&first_press);
  928. simulated_clock_.Advance(base::Milliseconds(10));
  929. // Since we are not out of the touch slop yet, we should not be in gesture in
  930. // progress.
  931. generator_->MoveTouch(second_location);
  932. EXPECT_FALSE(IsInTouchToMouseMode());
  933. EXPECT_FALSE(IsInGestureInProgressState());
  934. simulated_clock_.Advance(base::Milliseconds(10));
  935. // Once we are out of slop, we should be in GestureInProgress.
  936. generator_->MoveTouch(third_location);
  937. EXPECT_TRUE(IsInGestureInProgressState());
  938. EXPECT_FALSE(IsInTouchToMouseMode());
  939. const EventList& captured_events = GetCapturedEvents();
  940. ASSERT_EQ(0U, captured_events.size());
  941. // Exit out of gesture mode once grace period is over and enter touch
  942. // exploration. There should be a touch explore gesture when entering touch
  943. // exploration and also for the touch move.
  944. AdvanceSimulatedTimePastTapDelay();
  945. generator_->MoveTouch(touch_exploration_location);
  946. ASSERT_TRUE(captured_events.empty());
  947. EXPECT_EQ(2U, GetTouchExplorePoints().size());
  948. EXPECT_TRUE(IsInTouchToMouseMode());
  949. EXPECT_FALSE(IsInGestureInProgressState());
  950. }
  951. // A swipe+direction gesture should trigger a Shift+Search+Direction
  952. // keyboard event.
  953. TEST_F(TouchExplorationTest, GestureSwipe) {
  954. SwitchTouchExplorationMode(true);
  955. // Test all four swipe directions with 1 to 4 fingers.
  956. struct GestureInfo {
  957. int move_x;
  958. int move_y;
  959. int num_fingers;
  960. ax::mojom::Gesture expected_gesture;
  961. } gestures_to_test[] = {
  962. {-1, 0, 1, ax::mojom::Gesture::kSwipeLeft1},
  963. {0, -1, 1, ax::mojom::Gesture::kSwipeUp1},
  964. {1, 0, 1, ax::mojom::Gesture::kSwipeRight1},
  965. {0, 1, 1, ax::mojom::Gesture::kSwipeDown1},
  966. {-1, 0, 2, ax::mojom::Gesture::kSwipeLeft2},
  967. {0, -1, 2, ax::mojom::Gesture::kSwipeUp2},
  968. {1, 0, 2, ax::mojom::Gesture::kSwipeRight2},
  969. {0, 1, 2, ax::mojom::Gesture::kSwipeDown2},
  970. {-1, 0, 3, ax::mojom::Gesture::kSwipeLeft3},
  971. {0, -1, 3, ax::mojom::Gesture::kSwipeUp3},
  972. {1, 0, 3, ax::mojom::Gesture::kSwipeRight3},
  973. {0, 1, 3, ax::mojom::Gesture::kSwipeDown3},
  974. {-1, 0, 4, ax::mojom::Gesture::kSwipeLeft4},
  975. {0, -1, 4, ax::mojom::Gesture::kSwipeUp4},
  976. {1, 0, 4, ax::mojom::Gesture::kSwipeRight4},
  977. {0, 1, 4, ax::mojom::Gesture::kSwipeDown4},
  978. };
  979. // This value was taken from gesture_recognizer_unittest.cc in a swipe
  980. // detector test, since it seems to be about the right amount to get a swipe.
  981. const int kSteps = 15;
  982. for (size_t i = 0; i < std::size(gestures_to_test); ++i) {
  983. const float distance = 2 * gesture_detector_config_.touch_slop + 1;
  984. int move_x = gestures_to_test[i].move_x * distance;
  985. int move_y = gestures_to_test[i].move_y * distance;
  986. int num_fingers = gestures_to_test[i].num_fingers;
  987. ax::mojom::Gesture expected_gesture = gestures_to_test[i].expected_gesture;
  988. std::vector<gfx::Point> start_points;
  989. for (int j = 0; j < num_fingers; j++) {
  990. start_points.push_back(gfx::Point(j * 10 + 100, j * 10 + 200));
  991. }
  992. gfx::Point* start_points_array = &start_points[0];
  993. // A swipe is made when a fling starts
  994. float delta_time =
  995. distance / gesture_detector_config_.maximum_fling_velocity;
  996. // delta_time is in seconds, so we convert to ms.
  997. int delta_time_ms = floor(delta_time * 1000);
  998. generator_->GestureMultiFingerScroll(num_fingers, start_points_array,
  999. delta_time_ms, kSteps, move_x, move_y);
  1000. EXPECT_EQ(expected_gesture, delegate_.GetLastGesture());
  1001. EXPECT_TRUE(IsInNoFingersDownState());
  1002. EXPECT_FALSE(IsInTouchToMouseMode());
  1003. EXPECT_FALSE(IsInGestureInProgressState());
  1004. ClearCapturedAndGestureEvents();
  1005. }
  1006. }
  1007. TEST_F(TouchExplorationTest, GestureSwipePortrit) {
  1008. // Rotate the window 90-degrees counter-clockwise.
  1009. root_window()->GetHost()->SetRootTransform(
  1010. gfx::Transform(0, 1, 0, 0, -1, 0, 0, root_window()->bounds().height(), 0,
  1011. 0, 0, 0, 0, 0, 0, 0));
  1012. SwitchTouchExplorationMode(true);
  1013. // Test 2-4 finger gestures.
  1014. struct GestureInfo {
  1015. int move_x;
  1016. int move_y;
  1017. int num_fingers;
  1018. ax::mojom::Gesture expected_gesture;
  1019. } gestures_to_test[] = {
  1020. {-1, 0, 2, ax::mojom::Gesture::kSwipeDown2},
  1021. {0, -1, 2, ax::mojom::Gesture::kSwipeLeft2},
  1022. {1, 0, 2, ax::mojom::Gesture::kSwipeUp2},
  1023. {0, 1, 2, ax::mojom::Gesture::kSwipeRight2},
  1024. {-1, 0, 3, ax::mojom::Gesture::kSwipeDown3},
  1025. {0, -1, 3, ax::mojom::Gesture::kSwipeLeft3},
  1026. {1, 0, 3, ax::mojom::Gesture::kSwipeUp3},
  1027. {0, 1, 3, ax::mojom::Gesture::kSwipeRight3},
  1028. {-1, 0, 4, ax::mojom::Gesture::kSwipeDown4},
  1029. {0, -1, 4, ax::mojom::Gesture::kSwipeLeft4},
  1030. {1, 0, 4, ax::mojom::Gesture::kSwipeUp4},
  1031. {0, 1, 4, ax::mojom::Gesture::kSwipeRight4},
  1032. };
  1033. // This value was taken from gesture_recognizer_unittest.cc in a swipe
  1034. // detector test, since it seems to be about the right amount to get a swipe.
  1035. const int kSteps = 15;
  1036. for (size_t i = 0; i < std::size(gestures_to_test); ++i) {
  1037. const float distance = 2 * gesture_detector_config_.touch_slop + 1;
  1038. int move_x = gestures_to_test[i].move_x * distance;
  1039. int move_y = gestures_to_test[i].move_y * distance;
  1040. int num_fingers = gestures_to_test[i].num_fingers;
  1041. ax::mojom::Gesture expected_gesture = gestures_to_test[i].expected_gesture;
  1042. std::vector<gfx::Point> start_points;
  1043. for (int j = 0; j < num_fingers; j++) {
  1044. start_points.push_back(gfx::Point(j * 10 + 100, j * 10 + 200));
  1045. }
  1046. gfx::Point* start_points_array = &start_points[0];
  1047. // A swipe is made when a fling starts
  1048. float delta_time =
  1049. distance / gesture_detector_config_.maximum_fling_velocity;
  1050. // delta_time is in seconds, so we convert to ms.
  1051. int delta_time_ms = floor(delta_time * 1000);
  1052. generator_->GestureMultiFingerScroll(num_fingers, start_points_array,
  1053. delta_time_ms, kSteps, move_x, move_y);
  1054. EXPECT_EQ(expected_gesture, delegate_.GetLastGesture());
  1055. EXPECT_TRUE(IsInNoFingersDownState());
  1056. EXPECT_FALSE(IsInTouchToMouseMode());
  1057. EXPECT_FALSE(IsInGestureInProgressState());
  1058. ClearCapturedAndGestureEvents();
  1059. }
  1060. }
  1061. // Since there are so many permutations, this test is fairly slow. Therefore, it
  1062. // is disabled and will be turned on to check during development.
  1063. TEST_F(TouchExplorationTest, DISABLED_AllFingerPermutations) {
  1064. SwitchTouchExplorationMode(true);
  1065. SuppressVLOGs(true);
  1066. // We will test all permutations of events from three different fingers
  1067. // to ensure that we return to NO_FINGERS_DOWN when fingers have been
  1068. // released.
  1069. std::vector<std::unique_ptr<ui::TouchEvent>> all_events;
  1070. // A copy of all events list which can be modified without destrying events.
  1071. std::vector<ui::TouchEvent*> queued_events;
  1072. for (int touch_id = 0; touch_id < 3; touch_id++) {
  1073. int x = 10 * touch_id + 1;
  1074. int y = 10 * touch_id + 2;
  1075. all_events.push_back(std::make_unique<ui::TouchEvent>(
  1076. ui::ET_TOUCH_PRESSED, gfx::Point(x++, y++), Now(),
  1077. ui::PointerDetails(ui::EventPointerType::kTouch, touch_id)));
  1078. queued_events.push_back(all_events.back().get());
  1079. all_events.push_back(std::make_unique<ui::TouchEvent>(
  1080. ui::ET_TOUCH_MOVED, gfx::Point(x++, y++), Now(),
  1081. ui::PointerDetails(ui::EventPointerType::kTouch, touch_id)));
  1082. queued_events.push_back(all_events.back().get());
  1083. all_events.push_back(std::make_unique<ui::TouchEvent>(
  1084. ui::ET_TOUCH_RELEASED, gfx::Point(x, y), Now(),
  1085. ui::PointerDetails(ui::EventPointerType::kTouch, touch_id)));
  1086. queued_events.push_back(all_events.back().get());
  1087. }
  1088. // I'm going to explain this algorithm, and use an example in parentheses.
  1089. // The example will be all permutations of a b c d.
  1090. // There are four letters and 4! = 24 permutations.
  1091. const int num_events = all_events.size();
  1092. const int num_permutations = Factorial(num_events);
  1093. for (int p = 0; p < num_permutations; p++) {
  1094. std::vector<bool> fingers_pressed(3, false);
  1095. int current_num_permutations = num_permutations;
  1096. for (int events_left = num_events; events_left > 0; events_left--) {
  1097. // |p| indexes to each permutation when there are num_permutations
  1098. // permutations. (e.g. 0 is abcd, 1 is abdc, 2 is acbd, 3 is acdb...)
  1099. // But how do we find the index for the current number of permutations?
  1100. // To find the permutation within the part of the sequence we're
  1101. // currently looking at, we need a number between 0 and
  1102. // |current_num_permutations| - 1.
  1103. // (e.g. if we already chose the first letter, there are 3! = 6
  1104. // options left, so we do p % 6. So |current_permutation| would go
  1105. // from 0 to 5 and then reset to 0 again, for all combinations of
  1106. // whichever three letters are remaining, as we loop through the
  1107. // permutations)
  1108. int current_permutation = p % current_num_permutations;
  1109. // Since this is is the total number of permutations starting with
  1110. // this event and including future events, there could be multiple
  1111. // values of current_permutation that will generate the same event
  1112. // in this iteration.
  1113. // (e.g. If we chose 'a' but have b c d to choose from, we choose b when
  1114. // |current_permutation| = 0, 1 and c when |current_permutation| = 2, 3.
  1115. // Note that each letter gets two numbers, which is the next
  1116. // current_num_permutations, 2! for the two letters left.)
  1117. // Branching out from the first event, there are num_permutations
  1118. // permutations, and each value of |p| is associated with one of these
  1119. // permutations. However, once the first event is chosen, there
  1120. // are now |num_events| - 1 events left, so the number of permutations
  1121. // for the rest of the events changes, and will always be equal to
  1122. // the factorial of the events_left.
  1123. // (e.g. There are 3! = 6 permutations that start with 'a', so if we
  1124. // start with 'a' there will be 6 ways to then choose from b c d.)
  1125. // So we now set-up for the next iteration by setting
  1126. // current_num_permutations to the factorial of the next number of
  1127. // events left.
  1128. current_num_permutations /= events_left;
  1129. // To figure out what current event we want to choose, we integer
  1130. // divide the current permutation by the next current_num_permutations.
  1131. // (e.g. If there are 4 letters a b c d and 24 permutations, we divide
  1132. // by 24/4 = 6. Values 0 to 5 when divided by 6 equals 0, so the first
  1133. // 6 permutations start with 'a', and the last 6 will start with 'd'.
  1134. // Note that there are 6 that start with 'a' because there are 6
  1135. // permutations for the next three letters that follow 'a'.)
  1136. int index = current_permutation / current_num_permutations;
  1137. ui::TouchEvent* next_dispatch = queued_events[index];
  1138. ASSERT_TRUE(next_dispatch != NULL);
  1139. // |next_dispatch| has to be put in this container so that its time
  1140. // stamp can be changed to this point in the test, when it is being
  1141. // dispatched..
  1142. ui::EventTestApi test_dispatch(next_dispatch);
  1143. test_dispatch.set_time_stamp(Now());
  1144. generator_->Dispatch(next_dispatch);
  1145. queued_events.erase(queued_events.begin() + index);
  1146. // Keep track of what fingers have been pressed, to release
  1147. // only those fingers at the end, so the check for being in
  1148. // no fingers down can be accurate.
  1149. if (next_dispatch->type() == ui::ET_TOUCH_PRESSED) {
  1150. fingers_pressed[next_dispatch->pointer_details().id] = true;
  1151. } else if (next_dispatch->type() == ui::ET_TOUCH_RELEASED) {
  1152. fingers_pressed[next_dispatch->pointer_details().id] = false;
  1153. }
  1154. }
  1155. ASSERT_EQ(queued_events.size(), 0u);
  1156. // Release fingers recorded as pressed.
  1157. for (int j = 0; j < int(fingers_pressed.size()); j++) {
  1158. if (fingers_pressed[j] == true) {
  1159. generator_->ReleaseTouchId(j);
  1160. fingers_pressed[j] = false;
  1161. }
  1162. }
  1163. AdvanceSimulatedTimePastPotentialTapDelay();
  1164. EXPECT_TRUE(IsInNoFingersDownState());
  1165. ClearCapturedAndGestureEvents();
  1166. }
  1167. }
  1168. // With the simple swipe gestures, if additional fingers are added and the tap
  1169. // timer times out, then the state should change to the wait for one finger
  1170. // state.
  1171. TEST_F(TouchExplorationTest, GestureAddedFinger) {
  1172. SwitchTouchExplorationMode(true);
  1173. EXPECT_FALSE(IsInTouchToMouseMode());
  1174. EXPECT_FALSE(IsInGestureInProgressState());
  1175. float distance = gesture_detector_config_.touch_slop + 1;
  1176. ui::TouchEvent first_press(
  1177. ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), Now(),
  1178. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  1179. generator_->Dispatch(&first_press);
  1180. simulated_clock_.Advance(base::Milliseconds(10));
  1181. gfx::Point second_location(100 + distance, 200);
  1182. generator_->MoveTouch(second_location);
  1183. EXPECT_TRUE(IsInGestureInProgressState());
  1184. EXPECT_FALSE(IsInTouchToMouseMode());
  1185. const EventList& captured_events = GetCapturedEvents();
  1186. ASSERT_EQ(0U, captured_events.size());
  1187. // Generate a second press, but time out past the gesture period so that
  1188. // gestures are prevented from continuing to go through.
  1189. ui::TouchEvent second_press(
  1190. ui::ET_TOUCH_PRESSED, gfx::Point(20, 21), Now(),
  1191. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  1192. generator_->Dispatch(&second_press);
  1193. AdvanceSimulatedTimePastTapDelay();
  1194. EXPECT_FALSE(IsInGestureInProgressState());
  1195. EXPECT_FALSE(IsInTouchToMouseMode());
  1196. ASSERT_EQ(0U, captured_events.size());
  1197. }
  1198. TEST_F(TouchExplorationTest, EnterSlideGestureState) {
  1199. SwitchTouchExplorationMode(true);
  1200. EXPECT_FALSE(IsInTouchToMouseMode());
  1201. EXPECT_FALSE(IsInGestureInProgressState());
  1202. int window_right = BoundsOfRootWindowInDIP().right();
  1203. float distance = gesture_detector_config_.touch_slop + 1;
  1204. ui::TouchEvent first_press(
  1205. ui::ET_TOUCH_PRESSED, gfx::Point(window_right, 1), Now(),
  1206. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  1207. gfx::Point second_location(window_right, 1 + distance / 2);
  1208. gfx::Point third_location(window_right, 1 + distance);
  1209. gfx::Point fourth_location(window_right, 35);
  1210. generator_->Dispatch(&first_press);
  1211. simulated_clock_.Advance(base::Milliseconds(10));
  1212. // Since we haven't moved past slop yet, we should not be in slide gesture.
  1213. generator_->MoveTouch(second_location);
  1214. EXPECT_FALSE(IsInTouchToMouseMode());
  1215. EXPECT_FALSE(IsInGestureInProgressState());
  1216. EXPECT_FALSE(IsInSlideGestureState());
  1217. simulated_clock_.Advance(base::Milliseconds(10));
  1218. // Once we are out of slop, we should be in slide gesture since we are along
  1219. // the edge of the screen.
  1220. generator_->MoveTouch(third_location);
  1221. EXPECT_FALSE(IsInGestureInProgressState());
  1222. EXPECT_TRUE(IsInSlideGestureState());
  1223. EXPECT_FALSE(IsInTouchToMouseMode());
  1224. // Now that we are in slide gesture, we can adjust the volume.
  1225. generator_->MoveTouch(fourth_location);
  1226. const EventList& captured_events = GetCapturedEvents();
  1227. ASSERT_EQ(0U, captured_events.size());
  1228. // Since we are at the right edge of the screen, but the sound timer has not
  1229. // elapsed, there should have been a sound that fired and a volume
  1230. // change.
  1231. size_t num_adjust_sounds = delegate_.NumAdjustSounds();
  1232. ASSERT_EQ(1U, num_adjust_sounds);
  1233. ASSERT_EQ(1U, delegate_.VolumeChanges().size());
  1234. // Exit out of slide gesture once touch is lifted, but not before even if the
  1235. // grace period is over.
  1236. AdvanceSimulatedTimePastPotentialTapDelay();
  1237. ASSERT_EQ(0U, captured_events.size());
  1238. EXPECT_FALSE(IsInTouchToMouseMode());
  1239. EXPECT_FALSE(IsInGestureInProgressState());
  1240. EXPECT_TRUE(IsInSlideGestureState());
  1241. generator_->ReleaseTouch();
  1242. ASSERT_EQ(0U, captured_events.size());
  1243. EXPECT_FALSE(IsInTouchToMouseMode());
  1244. EXPECT_FALSE(IsInGestureInProgressState());
  1245. EXPECT_FALSE(IsInSlideGestureState());
  1246. }
  1247. // If a press + move occurred outside the boundaries, but within the slop
  1248. // boundaries and then moved into the boundaries of an edge, there still should
  1249. // not be a slide gesture.
  1250. TEST_F(TouchExplorationTest, AvoidEnteringSlideGesture) {
  1251. SwitchTouchExplorationMode(true);
  1252. gfx::Rect window = BoundsOfRootWindowInDIP();
  1253. float distance = gesture_detector_config_.touch_slop + 1;
  1254. ui::TouchEvent first_press(
  1255. ui::ET_TOUCH_PRESSED,
  1256. gfx::Point(window.right() - GetSlopDistanceFromEdge(), 1), Now(),
  1257. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  1258. gfx::Point out_of_slop(window.right() - GetSlopDistanceFromEdge() + distance,
  1259. 1);
  1260. gfx::Point into_boundaries(window.right() - GetMaxDistanceFromEdge() / 2, 1);
  1261. generator_->Dispatch(&first_press);
  1262. simulated_clock_.Advance(base::Milliseconds(10));
  1263. generator_->MoveTouch(out_of_slop);
  1264. EXPECT_FALSE(IsInTouchToMouseMode());
  1265. EXPECT_TRUE(IsInGestureInProgressState());
  1266. EXPECT_FALSE(IsInSlideGestureState());
  1267. simulated_clock_.Advance(base::Milliseconds(10));
  1268. // Since we did not start moving while in the boundaries, we should not be in
  1269. // slide gestures.
  1270. generator_->MoveTouch(into_boundaries);
  1271. EXPECT_TRUE(IsInGestureInProgressState());
  1272. EXPECT_FALSE(IsInSlideGestureState());
  1273. EXPECT_FALSE(IsInTouchToMouseMode());
  1274. const EventList& captured_events = GetCapturedEvents();
  1275. ASSERT_EQ(0U, captured_events.size());
  1276. generator_->ReleaseTouch();
  1277. }
  1278. // If the slide gesture begins within the boundaries and then moves
  1279. // SlopDistanceFromEdge there should still be a sound change. If the finger
  1280. // moves into the center screen, there should no longer be a sound change but it
  1281. // should still be in slide gesture. If the finger moves back into the edges
  1282. // without lifting, it should start changing sound again.
  1283. TEST_F(TouchExplorationTest, TestingBoundaries) {
  1284. SwitchTouchExplorationMode(true);
  1285. gfx::Rect window = BoundsOfRootWindowInDIP();
  1286. gfx::Point initial_press(window.right() - GetMaxDistanceFromEdge() / 2, 1);
  1287. gfx::Point center_screen(window.right() / 2, window.bottom() / 2);
  1288. ui::TouchEvent first_press(
  1289. ui::ET_TOUCH_PRESSED, initial_press, Now(),
  1290. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  1291. generator_->Dispatch(&first_press);
  1292. simulated_clock_.Advance(base::Milliseconds(10));
  1293. EXPECT_FALSE(IsInGestureInProgressState());
  1294. EXPECT_FALSE(IsInSlideGestureState());
  1295. EXPECT_FALSE(IsInTouchToMouseMode());
  1296. // Move past the touch slop to begin slide gestures.
  1297. // + slop + 1 to actually leave slop.
  1298. gfx::Point touch_move(
  1299. initial_press.x(),
  1300. initial_press.y() + gesture_detector_config_.touch_slop + 1);
  1301. generator_->MoveTouch(touch_move);
  1302. EXPECT_FALSE(IsInGestureInProgressState());
  1303. EXPECT_TRUE(IsInSlideGestureState());
  1304. EXPECT_FALSE(IsInTouchToMouseMode());
  1305. simulated_clock_.Advance(base::Milliseconds(10));
  1306. // Move the touch into slop boundaries. It should still be in slide gestures
  1307. // and adjust the volume.
  1308. gfx::Point into_slop_boundaries(
  1309. window.right() - GetSlopDistanceFromEdge() / 2, 1);
  1310. generator_->MoveTouch(into_slop_boundaries);
  1311. EXPECT_FALSE(IsInGestureInProgressState());
  1312. EXPECT_TRUE(IsInSlideGestureState());
  1313. EXPECT_FALSE(IsInTouchToMouseMode());
  1314. // The sound is rate limiting so it only activates every 150ms.
  1315. simulated_clock_.Advance(base::Milliseconds(200));
  1316. size_t num_adjust_sounds = delegate_.NumAdjustSounds();
  1317. ASSERT_EQ(1U, num_adjust_sounds);
  1318. ASSERT_EQ(1U, delegate_.VolumeChanges().size());
  1319. // Move the touch into the center of the window. It should still be in slide
  1320. // gestures, but there should not be anymore volume adjustments.
  1321. generator_->MoveTouch(center_screen);
  1322. EXPECT_FALSE(IsInGestureInProgressState());
  1323. EXPECT_TRUE(IsInSlideGestureState());
  1324. EXPECT_FALSE(IsInTouchToMouseMode());
  1325. simulated_clock_.Advance(base::Milliseconds(200));
  1326. num_adjust_sounds = delegate_.NumAdjustSounds();
  1327. ASSERT_EQ(1U, num_adjust_sounds);
  1328. ASSERT_EQ(1U, delegate_.VolumeChanges().size());
  1329. // Move the touch back into slop edge distance and volume should be changing
  1330. // again, one volume change for each new move.
  1331. generator_->MoveTouch(into_slop_boundaries);
  1332. EXPECT_FALSE(IsInGestureInProgressState());
  1333. EXPECT_TRUE(IsInSlideGestureState());
  1334. EXPECT_FALSE(IsInTouchToMouseMode());
  1335. generator_->MoveTouch(
  1336. gfx::Point(into_slop_boundaries.x() + gesture_detector_config_.touch_slop,
  1337. into_slop_boundaries.y()));
  1338. simulated_clock_.Advance(base::Milliseconds(200));
  1339. num_adjust_sounds = delegate_.NumAdjustSounds();
  1340. ASSERT_EQ(2U, num_adjust_sounds);
  1341. ASSERT_EQ(3U, delegate_.VolumeChanges().size());
  1342. const EventList& captured_events = GetCapturedEvents();
  1343. ASSERT_EQ(0U, captured_events.size());
  1344. generator_->ReleaseTouch();
  1345. }
  1346. // Even if the gesture starts within bounds, if it has not moved past slop
  1347. // within the grace period, it should go to touch exploration.
  1348. TEST_F(TouchExplorationTest, InBoundariesTouchExploration) {
  1349. SwitchTouchExplorationMode(true);
  1350. gfx::Rect window = BoundsOfRootWindowInDIP();
  1351. gfx::Point initial_press(window.right() - GetMaxDistanceFromEdge() / 2, 1);
  1352. ui::TouchEvent first_press(
  1353. ui::ET_TOUCH_PRESSED, initial_press, Now(),
  1354. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  1355. generator_->Dispatch(&first_press);
  1356. EXPECT_FALSE(IsInGestureInProgressState());
  1357. EXPECT_FALSE(IsInSlideGestureState());
  1358. EXPECT_FALSE(IsInTouchToMouseMode());
  1359. AdvanceSimulatedTimePastTapDelay();
  1360. EXPECT_FALSE(IsInGestureInProgressState());
  1361. EXPECT_FALSE(IsInSlideGestureState());
  1362. EXPECT_TRUE(IsInTouchToMouseMode());
  1363. }
  1364. // If two fingers tap the screen at the same time and release before the tap
  1365. // timer runs out, a control key event should be sent to silence chromevox.
  1366. TEST_F(TouchExplorationTest, TwoFingerTap) {
  1367. SwitchTouchExplorationMode(true);
  1368. generator_->set_current_screen_location(gfx::Point(101, 102));
  1369. generator_->PressTouchId(1);
  1370. EXPECT_FALSE(IsInTwoFingerTapState());
  1371. generator_->PressTouchId(2);
  1372. EXPECT_TRUE(IsInTwoFingerTapState());
  1373. const EventList& captured_events = GetCapturedEvents();
  1374. ASSERT_EQ(0U, captured_events.size());
  1375. generator_->ReleaseTouchId(1);
  1376. EXPECT_TRUE(IsInTwoFingerTapState());
  1377. generator_->ReleaseTouchId(2);
  1378. EXPECT_EQ(0U, captured_events.size());
  1379. ASSERT_EQ(ax::mojom::Gesture::kTap2, delegate_.GetLastGesture());
  1380. }
  1381. // If the fingers are not released before the tap timer runs out, a control
  1382. // keyevent is not sent and the state will no longer be in two finger tap.
  1383. TEST_F(TouchExplorationTest, TwoFingerTapAndHold) {
  1384. SwitchTouchExplorationMode(true);
  1385. generator_->PressTouchId(1);
  1386. EXPECT_FALSE(IsInTwoFingerTapState());
  1387. generator_->PressTouchId(2);
  1388. EXPECT_TRUE(IsInTwoFingerTapState());
  1389. const EventList& captured_events = GetCapturedEvents();
  1390. ASSERT_EQ(0U, captured_events.size());
  1391. AdvanceSimulatedTimePastTapDelay();
  1392. // Since the tap delay has elapsed, it should no longer be in two finger tap.
  1393. EXPECT_FALSE(IsInTwoFingerTapState());
  1394. }
  1395. // The next two tests set up two finger swipes to happen. If one of the fingers
  1396. // moves out of slop before the tap timer fires, a two finger tap is not made.
  1397. // In this first test, the first finger placed will move out of slop.
  1398. TEST_F(TouchExplorationTest, TwoFingerTapAndMoveFirstFinger) {
  1399. SwitchTouchExplorationMode(true);
  1400. // Once one of the fingers leaves slop, it should no longer be in two finger
  1401. // tap.
  1402. ui::TouchEvent first_press_id_1(
  1403. ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), Now(),
  1404. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  1405. ui::TouchEvent first_press_id_2(
  1406. ui::ET_TOUCH_PRESSED, gfx::Point(110, 200), Now(),
  1407. ui::PointerDetails(ui::EventPointerType::kTouch, 2));
  1408. ui::TouchEvent slop_move_id_1(
  1409. ui::ET_TOUCH_MOVED,
  1410. gfx::Point(100 + gesture_detector_config_.touch_slop, 200), Now(),
  1411. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  1412. ui::TouchEvent slop_move_id_2(
  1413. ui::ET_TOUCH_MOVED,
  1414. gfx::Point(110 + gesture_detector_config_.touch_slop, 200), Now(),
  1415. ui::PointerDetails(ui::EventPointerType::kTouch, 2));
  1416. ui::TouchEvent out_slop_id_1(
  1417. ui::ET_TOUCH_MOVED,
  1418. gfx::Point(100 + gesture_detector_config_.touch_slop + 1, 200), Now(),
  1419. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  1420. // Dispatch the inital presses.
  1421. generator_->Dispatch(&first_press_id_1);
  1422. EXPECT_FALSE(IsInTwoFingerTapState());
  1423. generator_->Dispatch(&first_press_id_2);
  1424. EXPECT_TRUE(IsInTwoFingerTapState());
  1425. const EventList& captured_events = GetCapturedEvents();
  1426. ASSERT_EQ(0U, captured_events.size());
  1427. // The presses have not moved out of slop yet so it should still be in
  1428. // TwoFingerTap.
  1429. generator_->Dispatch(&slop_move_id_1);
  1430. EXPECT_TRUE(IsInTwoFingerTapState());
  1431. generator_->Dispatch(&slop_move_id_2);
  1432. EXPECT_TRUE(IsInTwoFingerTapState());
  1433. // Once one of the fingers moves out of slop, we are no longer in
  1434. // TwoFingerTap.
  1435. generator_->Dispatch(&out_slop_id_1);
  1436. EXPECT_FALSE(IsInTwoFingerTapState());
  1437. }
  1438. // Similar test to the previous test except the second finger placed will be the
  1439. // one to move out of slop.
  1440. TEST_F(TouchExplorationTest, TwoFingerTapAndMoveSecondFinger) {
  1441. SwitchTouchExplorationMode(true);
  1442. // Once one of the fingers leaves slop, it should no longer be in two finger
  1443. // tap.
  1444. ui::TouchEvent first_press_id_1(
  1445. ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), Now(),
  1446. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  1447. ui::TouchEvent first_press_id_2(
  1448. ui::ET_TOUCH_PRESSED, gfx::Point(110, 200), Now(),
  1449. ui::PointerDetails(ui::EventPointerType::kTouch, 2));
  1450. ui::TouchEvent out_slop_id_2(
  1451. ui::ET_TOUCH_MOVED,
  1452. gfx::Point(100 + gesture_detector_config_.touch_slop + 1, 200), Now(),
  1453. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  1454. generator_->Dispatch(&first_press_id_1);
  1455. EXPECT_FALSE(IsInTwoFingerTapState());
  1456. generator_->Dispatch(&first_press_id_2);
  1457. EXPECT_TRUE(IsInTwoFingerTapState());
  1458. const EventList& captured_events = GetCapturedEvents();
  1459. ASSERT_EQ(0U, captured_events.size());
  1460. generator_->Dispatch(&out_slop_id_2);
  1461. EXPECT_FALSE(IsInTwoFingerTapState());
  1462. }
  1463. TEST_F(TouchExplorationTest, ExclusionArea) {
  1464. SwitchTouchExplorationMode(true);
  1465. gfx::Rect window = BoundsOfRootWindowInDIP();
  1466. gfx::Rect exclude = window;
  1467. exclude.Inset(gfx::Insets::TLBR(0, 0, 30, 0));
  1468. SetExcludeBounds(exclude);
  1469. gfx::Point in_pt = exclude.CenterPoint();
  1470. gfx::Point in_mv_pt(in_pt.x(), (in_pt.y() + exclude.bottom()) / 2);
  1471. gfx::Point out_pt(in_pt.x(), exclude.bottom() + 20);
  1472. gfx::Point out_mv_pt(in_pt.x(), exclude.bottom() + 10);
  1473. // Motion starting in exclusion bounds is passed-through unchanged.
  1474. {
  1475. generator_->set_current_screen_location(in_pt);
  1476. generator_->PressTouchId(0);
  1477. AdvanceSimulatedTimePastPotentialTapDelay();
  1478. generator_->MoveTouchId(out_mv_pt, 0);
  1479. generator_->ReleaseTouchId(0);
  1480. EXPECT_TRUE(IsInNoFingersDownState());
  1481. const EventList& captured_events = GetCapturedEvents();
  1482. ASSERT_EQ(3U, captured_events.size());
  1483. EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
  1484. EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[1]->type());
  1485. EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[2]->type());
  1486. ClearCapturedAndGestureEvents();
  1487. }
  1488. // Complete motion outside exclusion is rewritten.
  1489. {
  1490. generator_->set_current_screen_location(out_pt);
  1491. generator_->PressTouchId(0);
  1492. AdvanceSimulatedTimePastTapDelay();
  1493. generator_->MoveTouchId(out_mv_pt, 0);
  1494. generator_->ReleaseTouchId(0);
  1495. AdvanceSimulatedTimePastTapDelay();
  1496. EXPECT_TRUE(IsInNoFingersDownState());
  1497. const EventList& captured_events = GetCapturedEvents();
  1498. ASSERT_TRUE(captured_events.empty());
  1499. ASSERT_EQ(3U, GetTouchExplorePoints().size());
  1500. ClearCapturedAndGestureEvents();
  1501. }
  1502. // For a motion starting outside: outside events are rewritten, inside
  1503. // events are discarded unless they end the motion.
  1504. {
  1505. // finger 0 down outside, moves inside.
  1506. generator_->set_current_screen_location(out_pt);
  1507. generator_->PressTouchId(0);
  1508. AdvanceSimulatedTimePastTapDelay();
  1509. generator_->MoveTouchId(out_mv_pt, 0);
  1510. generator_->MoveTouchId(in_mv_pt, 0);
  1511. ASSERT_TRUE(GetCapturedEvents().empty());
  1512. ASSERT_EQ(2U, GetTouchExplorePoints().size());
  1513. ClearCapturedAndGestureEvents();
  1514. // finger 1 down inside, moves outside
  1515. generator_->set_current_screen_location(in_pt);
  1516. generator_->PressTouchId(1);
  1517. generator_->MoveTouchId(out_mv_pt, 1);
  1518. generator_->ReleaseTouchId(1);
  1519. ASSERT_TRUE(GetCapturedEvents().empty());
  1520. ASSERT_TRUE(GetTouchExplorePoints().empty());
  1521. EXPECT_FALSE(IsInNoFingersDownState());
  1522. generator_->ReleaseTouchId(0);
  1523. AdvanceSimulatedTimePastTapDelay();
  1524. EXPECT_TRUE(IsInNoFingersDownState());
  1525. ASSERT_TRUE(GetCapturedEvents().empty());
  1526. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  1527. }
  1528. }
  1529. TEST_F(TouchExplorationTest, SingleTapInLiftActivationArea) {
  1530. SwitchTouchExplorationMode(true);
  1531. gfx::Rect lift_activation = BoundsOfRootWindowInDIP();
  1532. lift_activation.Inset(gfx::Insets::TLBR(0, 0, 30, 0));
  1533. SetLiftActivationBounds(lift_activation);
  1534. // Tap at one location, and get tap and mouse move events.
  1535. gfx::Point tap_location = lift_activation.CenterPoint();
  1536. // The user has to have previously selected something.
  1537. SetTouchAccessibilityAnchorPoint(tap_location);
  1538. generator_->set_current_screen_location(tap_location);
  1539. generator_->PressTouchId(1);
  1540. generator_->ReleaseTouchId(1);
  1541. AdvanceSimulatedTimePastTapDelay();
  1542. const EventList& captured_events = GetCapturedEvents();
  1543. ASSERT_EQ(2U, captured_events.size());
  1544. EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
  1545. EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
  1546. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  1547. ClearCapturedAndGestureEvents();
  1548. gfx::Point out_tap_location(tap_location.x(), lift_activation.bottom() + 20);
  1549. SetTouchAccessibilityAnchorPoint(out_tap_location);
  1550. generator_->set_current_screen_location(out_tap_location);
  1551. generator_->PressTouchId(1);
  1552. generator_->ReleaseTouchId(1);
  1553. AdvanceSimulatedTimePastTapDelay();
  1554. const EventList& out_captured_events = GetCapturedEvents();
  1555. ASSERT_TRUE(out_captured_events.empty());
  1556. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  1557. }
  1558. TEST_F(TouchExplorationTest, TouchExploreLiftInLiftActivationArea) {
  1559. SwitchTouchExplorationMode(true);
  1560. gfx::Rect lift_activation = BoundsOfRootWindowInDIP();
  1561. lift_activation.Inset(gfx::Insets::TLBR(0, 0, 30, 0));
  1562. SetLiftActivationBounds(lift_activation);
  1563. // Explore at one location, and get tap and touch explore events.
  1564. gfx::Point tap_location = lift_activation.CenterPoint();
  1565. EnterTouchExplorationModeAtLocation(tap_location);
  1566. ClearCapturedAndGestureEvents();
  1567. ASSERT_EQ(0U, delegate_.NumTouchTypeSounds());
  1568. // A touch release should trigger a tap.
  1569. ui::TouchEvent touch_explore_release(
  1570. ui::ET_TOUCH_RELEASED, tap_location, Now(),
  1571. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  1572. generator_->Dispatch(&touch_explore_release);
  1573. AdvanceSimulatedTimePastTapDelay();
  1574. const EventList& captured_events = GetCapturedEvents();
  1575. ASSERT_EQ(2U, captured_events.size());
  1576. EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
  1577. EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
  1578. ASSERT_EQ(1U, delegate_.NumTouchTypeSounds());
  1579. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  1580. ClearCapturedAndGestureEvents();
  1581. delegate_.ResetCountersToZero();
  1582. // Touch explore inside the activation bounds, but lift outside.
  1583. gfx::Point out_tap_location(tap_location.x(), lift_activation.bottom() + 20);
  1584. SetTouchAccessibilityAnchorPoint(out_tap_location);
  1585. EnterTouchExplorationModeAtLocation(tap_location);
  1586. ClearCapturedAndGestureEvents();
  1587. ui::TouchEvent out_touch_explore_release(
  1588. ui::ET_TOUCH_RELEASED, out_tap_location, Now(),
  1589. ui::PointerDetails(ui::EventPointerType::kTouch, 0));
  1590. generator_->Dispatch(&out_touch_explore_release);
  1591. AdvanceSimulatedTimePastTapDelay();
  1592. const EventList& out_captured_events = GetCapturedEvents();
  1593. ASSERT_TRUE(out_captured_events.empty());
  1594. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  1595. ASSERT_EQ(0U, delegate_.NumTouchTypeSounds());
  1596. }
  1597. // Ensure that any touch release events received after
  1598. // TouchExplorationController starts up are canceled, if we haven't
  1599. // seen any touch press events yet. http://crbug.com/751348
  1600. TEST_F(TouchExplorationTest, AlreadyHeldFingersGetCanceled) {
  1601. generator_->PressTouch();
  1602. SwitchTouchExplorationMode(true);
  1603. generator_->ReleaseTouch();
  1604. std::vector<ui::LocatedEvent*> events =
  1605. GetCapturedLocatedEventsOfType(ui::ET_TOUCH_CANCELLED);
  1606. ASSERT_EQ(1U, events.size());
  1607. }
  1608. // Ensure 3 or 4 finger tap gets recognized correctly.
  1609. TEST_F(TouchExplorationTest, ThreeOrFourFingerTap) {
  1610. SwitchTouchExplorationMode(true);
  1611. ui::TouchEvent press_id_1(
  1612. ui::ET_TOUCH_PRESSED, gfx::Point(100, 200), Now(),
  1613. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  1614. ui::TouchEvent release_id_1(
  1615. ui::ET_TOUCH_RELEASED, gfx::Point(100, 200), Now(),
  1616. ui::PointerDetails(ui::EventPointerType::kTouch, 1));
  1617. ui::TouchEvent press_id_2(
  1618. ui::ET_TOUCH_PRESSED, gfx::Point(110, 200), Now(),
  1619. ui::PointerDetails(ui::EventPointerType::kTouch, 2));
  1620. ui::TouchEvent release_id_2(
  1621. ui::ET_TOUCH_RELEASED, gfx::Point(110, 200), Now(),
  1622. ui::PointerDetails(ui::EventPointerType::kTouch, 2));
  1623. ui::TouchEvent press_id_3(
  1624. ui::ET_TOUCH_PRESSED, gfx::Point(120, 200), Now(),
  1625. ui::PointerDetails(ui::EventPointerType::kTouch, 3));
  1626. ui::TouchEvent release_id_3(
  1627. ui::ET_TOUCH_RELEASED, gfx::Point(120, 200), Now(),
  1628. ui::PointerDetails(ui::EventPointerType::kTouch, 3));
  1629. ui::TouchEvent press_id_4(
  1630. ui::ET_TOUCH_PRESSED, gfx::Point(130, 200), Now(),
  1631. ui::PointerDetails(ui::EventPointerType::kTouch, 4));
  1632. ui::TouchEvent release_id_4(
  1633. ui::ET_TOUCH_RELEASED, gfx::Point(120, 200), Now(),
  1634. ui::PointerDetails(ui::EventPointerType::kTouch, 4));
  1635. // Three fingers down.
  1636. generator_->Dispatch(&press_id_1);
  1637. EXPECT_FALSE(IsInTwoFingerTapState());
  1638. generator_->Dispatch(&press_id_2);
  1639. EXPECT_TRUE(IsInTwoFingerTapState());
  1640. generator_->Dispatch(&press_id_3);
  1641. EXPECT_TRUE(IsInGestureInProgressState());
  1642. // Three fingers up.
  1643. generator_->Dispatch(&release_id_1);
  1644. EXPECT_TRUE(IsInGestureInProgressState());
  1645. generator_->Dispatch(&release_id_2);
  1646. EXPECT_TRUE(IsInGestureInProgressState());
  1647. ASSERT_EQ(ax::mojom::Gesture::kNone, delegate_.GetLastGesture());
  1648. generator_->Dispatch(&release_id_3);
  1649. EXPECT_TRUE(IsInNoFingersDownState());
  1650. ASSERT_EQ(ax::mojom::Gesture::kTap3, delegate_.GetLastGesture());
  1651. delegate_.ResetLastGesture();
  1652. // Four fingers down.
  1653. generator_->Dispatch(&press_id_1);
  1654. EXPECT_FALSE(IsInTwoFingerTapState());
  1655. generator_->Dispatch(&press_id_2);
  1656. EXPECT_TRUE(IsInTwoFingerTapState());
  1657. generator_->Dispatch(&press_id_3);
  1658. EXPECT_TRUE(IsInGestureInProgressState());
  1659. generator_->Dispatch(&press_id_4);
  1660. EXPECT_TRUE(IsInGestureInProgressState());
  1661. // Four fingers up.
  1662. generator_->Dispatch(&release_id_1);
  1663. EXPECT_TRUE(IsInGestureInProgressState());
  1664. generator_->Dispatch(&release_id_2);
  1665. EXPECT_TRUE(IsInGestureInProgressState());
  1666. generator_->Dispatch(&release_id_3);
  1667. EXPECT_TRUE(IsInGestureInProgressState());
  1668. ASSERT_EQ(ax::mojom::Gesture::kNone, delegate_.GetLastGesture());
  1669. generator_->Dispatch(&release_id_4);
  1670. EXPECT_TRUE(IsInNoFingersDownState());
  1671. ASSERT_EQ(ax::mojom::Gesture::kTap4, delegate_.GetLastGesture());
  1672. }
  1673. // Triggers right-click when anchor point remains in position after delay.
  1674. TEST_F(TouchExplorationTest, TriggersRightClickAfterDelay) {
  1675. SwitchTouchExplorationMode(true);
  1676. gfx::Rect lift_activation = BoundsOfRootWindowInDIP();
  1677. SetLiftActivationBounds(lift_activation);
  1678. // Explore at one location.
  1679. gfx::Point tap_location = lift_activation.CenterPoint();
  1680. EnterTouchExplorationModeAtLocation(tap_location);
  1681. ClearCapturedAndGestureEvents();
  1682. ASSERT_EQ(0U, delegate_.NumTouchTypeSounds());
  1683. // Stay in the same anchor point after delay.
  1684. AdvanceSimulatedTimePastLongPressDelay();
  1685. // Any event should be rewritten as a right-mouse click.
  1686. generator_->set_current_screen_location(tap_location);
  1687. generator_->MoveTouch(tap_location);
  1688. const EventList& captured_events = GetCapturedEvents();
  1689. ASSERT_EQ(2U, captured_events.size());
  1690. EXPECT_EQ(ui::ET_MOUSE_PRESSED, captured_events[0]->type());
  1691. EXPECT_EQ(ui::ET_MOUSE_RELEASED, captured_events[1]->type());
  1692. // We immediately go back to touch exploration so there will be a touch
  1693. // explore event from the touch exploration.
  1694. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  1695. EXPECT_EQ(1U, delegate_.NumLongPressRightClickSounds());
  1696. ClearCapturedAndGestureEvents();
  1697. delegate_.ResetCountersToZero();
  1698. }
  1699. // Does not trigger right-click when anchor point is not in lift activation
  1700. // bounds.
  1701. TEST_F(TouchExplorationTest,
  1702. DoesNotTriggerRightClickInNonLiftActivationBounds) {
  1703. SwitchTouchExplorationMode(true);
  1704. // Explore at one location.
  1705. gfx::Point tap_location = BoundsOfRootWindowInDIP().CenterPoint();
  1706. EnterTouchExplorationModeAtLocation(tap_location);
  1707. ClearCapturedAndGestureEvents();
  1708. ASSERT_EQ(0U, delegate_.NumTouchTypeSounds());
  1709. // Stay in the same anchor point after delay.
  1710. AdvanceSimulatedTimePastLongPressDelay();
  1711. generator_->set_current_screen_location(tap_location);
  1712. generator_->MoveTouch(tap_location);
  1713. const EventList& captured_events = GetCapturedEvents();
  1714. ASSERT_TRUE(captured_events.empty());
  1715. ASSERT_EQ(1U, GetTouchExplorePoints().size());
  1716. EXPECT_EQ(0U, delegate_.NumLongPressRightClickSounds());
  1717. ClearCapturedAndGestureEvents();
  1718. delegate_.ResetCountersToZero();
  1719. }
  1720. } // namespace ash