touch_selection_controller_unittest.cc 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782
  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 "ui/touch_selection/touch_selection_controller.h"
  5. #include <vector>
  6. #include "base/memory/raw_ptr.h"
  7. #include "testing/gmock/include/gmock/gmock.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. #include "ui/events/test/motion_event_test_utils.h"
  10. #include "ui/touch_selection/touch_selection_controller_test_api.h"
  11. using testing::ElementsAre;
  12. using testing::IsEmpty;
  13. using ui::test::MockMotionEvent;
  14. namespace ui {
  15. namespace {
  16. const int kDefaultTapTimeoutMs = 200;
  17. const float kDefaulTapSlop = 10.f;
  18. const gfx::PointF kIgnoredPoint(0, 0);
  19. class MockTouchHandleDrawable : public TouchHandleDrawable {
  20. public:
  21. explicit MockTouchHandleDrawable(bool* contains_point)
  22. : intersects_rect_(contains_point) {}
  23. MockTouchHandleDrawable(const MockTouchHandleDrawable&) = delete;
  24. MockTouchHandleDrawable& operator=(const MockTouchHandleDrawable&) = delete;
  25. ~MockTouchHandleDrawable() override {}
  26. void SetEnabled(bool enabled) override {}
  27. void SetOrientation(ui::TouchHandleOrientation orientation,
  28. bool mirror_vertical,
  29. bool mirror_horizontal) override {}
  30. void SetOrigin(const gfx::PointF& origin) override {}
  31. void SetAlpha(float alpha) override {}
  32. gfx::RectF GetVisibleBounds() const override {
  33. return *intersects_rect_ ? gfx::RectF(-1000, -1000, 2000, 2000)
  34. : gfx::RectF(-1000, -1000, 0, 0);
  35. }
  36. float GetDrawableHorizontalPaddingRatio() const override { return 0; }
  37. private:
  38. raw_ptr<bool> intersects_rect_;
  39. };
  40. } // namespace
  41. class TouchSelectionControllerTest : public testing::Test,
  42. public TouchSelectionControllerClient {
  43. public:
  44. TouchSelectionControllerTest()
  45. : caret_moved_(false),
  46. selection_moved_(false),
  47. selection_points_swapped_(false),
  48. needs_animate_(false),
  49. animation_enabled_(true),
  50. dragging_enabled_(false) {}
  51. TouchSelectionControllerTest(const TouchSelectionControllerTest&) = delete;
  52. TouchSelectionControllerTest& operator=(const TouchSelectionControllerTest&) =
  53. delete;
  54. ~TouchSelectionControllerTest() override {}
  55. // testing::Test implementation.
  56. void SetUp() override {
  57. controller_ =
  58. std::make_unique<TouchSelectionController>(this, DefaultConfig());
  59. // Simulate start of a TouchEvent sequence.
  60. controller_->WillHandleTouchEvent(
  61. MockMotionEvent(MotionEvent::Action::DOWN));
  62. }
  63. void TearDown() override { controller_.reset(); }
  64. // TouchSelectionControllerClient implementation.
  65. bool SupportsAnimation() const override { return animation_enabled_; }
  66. void SetNeedsAnimate() override { needs_animate_ = true; }
  67. void MoveCaret(const gfx::PointF& position) override {
  68. caret_moved_ = true;
  69. caret_position_ = position;
  70. }
  71. void SelectBetweenCoordinates(const gfx::PointF& base,
  72. const gfx::PointF& extent) override {
  73. if (base == selection_end_ && extent == selection_start_)
  74. selection_points_swapped_ = true;
  75. selection_start_ = base;
  76. selection_end_ = extent;
  77. }
  78. void MoveRangeSelectionExtent(const gfx::PointF& extent) override {
  79. selection_moved_ = true;
  80. selection_end_ = extent;
  81. }
  82. void OnSelectionEvent(SelectionEventType event) override {
  83. events_.push_back(event);
  84. last_event_start_ = controller_->GetStartPosition();
  85. last_event_end_ = controller_->GetEndPosition();
  86. last_event_bounds_rect_ = controller_->GetRectBetweenBounds();
  87. }
  88. void OnDragUpdate(const TouchSelectionDraggable::Type type,
  89. const gfx::PointF& position) override {
  90. last_drag_update_position_ = position;
  91. }
  92. std::unique_ptr<TouchHandleDrawable> CreateDrawable() override {
  93. return std::make_unique<MockTouchHandleDrawable>(&dragging_enabled_);
  94. }
  95. void DidScroll() override {}
  96. void EnableLongPressDragSelection() {
  97. TouchSelectionController::Config config = DefaultConfig();
  98. config.enable_longpress_drag_selection = true;
  99. controller_ = std::make_unique<TouchSelectionController>(this, config);
  100. }
  101. void SetHideActiveHandle(bool hide) {
  102. TouchSelectionController::Config config = DefaultConfig();
  103. config.hide_active_handle = hide;
  104. controller_ = std::make_unique<TouchSelectionController>(this, config);
  105. // Simulate start of a TouchEvent sequence.
  106. controller_->WillHandleTouchEvent(
  107. MockMotionEvent(MotionEvent::Action::DOWN));
  108. }
  109. void SetAnimationEnabled(bool enabled) { animation_enabled_ = enabled; }
  110. void SetDraggingEnabled(bool enabled) { dragging_enabled_ = enabled; }
  111. void ClearSelection() {
  112. controller_->OnSelectionBoundsChanged(gfx::SelectionBound(),
  113. gfx::SelectionBound());
  114. }
  115. void ClearInsertion() { ClearSelection(); }
  116. void ChangeInsertion(const gfx::RectF& rect, bool visible) {
  117. gfx::SelectionBound bound;
  118. bound.set_type(gfx::SelectionBound::CENTER);
  119. bound.SetEdge(rect.origin(), rect.bottom_left());
  120. bound.set_visible(visible);
  121. controller_->OnSelectionBoundsChanged(bound, bound);
  122. }
  123. void ChangeSelection(const gfx::RectF& start_rect,
  124. bool start_visible,
  125. const gfx::RectF& end_rect,
  126. bool end_visible) {
  127. gfx::SelectionBound start_bound, end_bound;
  128. start_bound.set_type(gfx::SelectionBound::LEFT);
  129. end_bound.set_type(gfx::SelectionBound::RIGHT);
  130. start_bound.SetEdge(start_rect.origin(), start_rect.bottom_left());
  131. end_bound.SetEdge(end_rect.origin(), end_rect.bottom_left());
  132. start_bound.set_visible(start_visible);
  133. end_bound.set_visible(end_visible);
  134. controller_->OnSelectionBoundsChanged(start_bound, end_bound);
  135. }
  136. void ChangeVerticalSelection(const gfx::RectF& start_rect,
  137. bool start_visible,
  138. const gfx::RectF& end_rect,
  139. bool end_visible) {
  140. gfx::SelectionBound start_bound, end_bound;
  141. start_bound.set_type(gfx::SelectionBound::RIGHT);
  142. end_bound.set_type(gfx::SelectionBound::LEFT);
  143. start_bound.SetEdge(start_rect.origin(), start_rect.bottom_right());
  144. end_bound.SetEdge(end_rect.bottom_right(), end_rect.origin());
  145. start_bound.set_visible(start_visible);
  146. end_bound.set_visible(end_visible);
  147. controller_->OnSelectionBoundsChanged(start_bound, end_bound);
  148. }
  149. void OnLongPressEvent() {
  150. controller().HandleLongPressEvent(base::TimeTicks(),
  151. kIgnoredPoint);
  152. }
  153. void OnTapEvent() {
  154. controller().HandleTapEvent(kIgnoredPoint, 1);
  155. }
  156. void OnDoubleTapEvent() {
  157. controller().HandleTapEvent(kIgnoredPoint, 2);
  158. }
  159. void OnTripleTapEvent() { controller().HandleTapEvent(kIgnoredPoint, 3); }
  160. void Animate() {
  161. base::TimeTicks now = base::TimeTicks::Now();
  162. while (needs_animate_) {
  163. needs_animate_ = controller_->Animate(now);
  164. now += base::Milliseconds(16);
  165. }
  166. }
  167. bool GetAndResetNeedsAnimate() {
  168. bool needs_animate = needs_animate_;
  169. Animate();
  170. return needs_animate;
  171. }
  172. bool GetAndResetCaretMoved() {
  173. bool moved = caret_moved_;
  174. caret_moved_ = false;
  175. return moved;
  176. }
  177. bool GetAndResetSelectionMoved() {
  178. bool moved = selection_moved_;
  179. selection_moved_ = false;
  180. return moved;
  181. }
  182. bool GetAndResetSelectionPointsSwapped() {
  183. bool swapped = selection_points_swapped_;
  184. selection_points_swapped_ = false;
  185. return swapped;
  186. }
  187. const gfx::PointF& GetLastCaretPosition() const { return caret_position_; }
  188. const gfx::PointF& GetLastSelectionStart() const { return selection_start_; }
  189. const gfx::PointF& GetLastSelectionEnd() const { return selection_end_; }
  190. const gfx::PointF& GetLastEventStart() const { return last_event_start_; }
  191. const gfx::PointF& GetLastEventEnd() const { return last_event_end_; }
  192. const gfx::RectF& GetLastEventBoundsRect() const {
  193. return last_event_bounds_rect_;
  194. }
  195. const gfx::PointF& GetLastDragUpdatePosition() const {
  196. return last_drag_update_position_;
  197. }
  198. std::vector<SelectionEventType> GetAndResetEvents() {
  199. std::vector<SelectionEventType> events;
  200. events.swap(events_);
  201. return events;
  202. }
  203. TouchSelectionController& controller() { return *controller_; }
  204. private:
  205. TouchSelectionController::Config DefaultConfig() {
  206. // |enable_longpress_drag_selection| is set to false by default, and should
  207. // be overriden for explicit testing.
  208. TouchSelectionController::Config config;
  209. config.max_tap_duration = base::Milliseconds(kDefaultTapTimeoutMs);
  210. config.tap_slop = kDefaulTapSlop;
  211. config.enable_longpress_drag_selection = false;
  212. return config;
  213. }
  214. gfx::PointF last_event_start_;
  215. gfx::PointF last_event_end_;
  216. gfx::PointF caret_position_;
  217. gfx::PointF selection_start_;
  218. gfx::PointF selection_end_;
  219. gfx::RectF last_event_bounds_rect_;
  220. gfx::PointF last_drag_update_position_;
  221. std::vector<SelectionEventType> events_;
  222. bool caret_moved_;
  223. bool selection_moved_;
  224. bool selection_points_swapped_;
  225. bool needs_animate_;
  226. bool animation_enabled_;
  227. bool dragging_enabled_;
  228. std::unique_ptr<TouchSelectionController> controller_;
  229. };
  230. TEST_F(TouchSelectionControllerTest, InsertionBasic) {
  231. gfx::RectF insertion_rect(5, 5, 0, 10);
  232. bool visible = true;
  233. OnTapEvent();
  234. ChangeInsertion(insertion_rect, visible);
  235. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  236. EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventStart());
  237. insertion_rect.Offset(1, 0);
  238. ChangeInsertion(insertion_rect, visible);
  239. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_MOVED));
  240. EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventStart());
  241. insertion_rect.Offset(0, 1);
  242. ChangeInsertion(insertion_rect, visible);
  243. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_MOVED));
  244. EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventStart());
  245. OnTapEvent();
  246. insertion_rect.Offset(1, 0);
  247. ChangeInsertion(insertion_rect, visible);
  248. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  249. EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventStart());
  250. ClearInsertion();
  251. EXPECT_THAT(GetAndResetEvents(),
  252. ElementsAre(INSERTION_HANDLE_CLEARED));
  253. }
  254. TEST_F(TouchSelectionControllerTest, InsertionToSelectionTransition) {
  255. OnLongPressEvent();
  256. gfx::RectF start_rect(5, 5, 0, 10);
  257. gfx::RectF end_rect(50, 5, 0, 10);
  258. bool visible = true;
  259. ChangeInsertion(start_rect, visible);
  260. EXPECT_THAT(GetAndResetEvents(),
  261. ElementsAre(INSERTION_HANDLE_SHOWN));
  262. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  263. ChangeSelection(start_rect, visible, end_rect, visible);
  264. EXPECT_THAT(GetAndResetEvents(),
  265. ElementsAre(INSERTION_HANDLE_CLEARED, SELECTION_HANDLES_SHOWN));
  266. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  267. ChangeInsertion(end_rect, visible);
  268. EXPECT_THAT(GetAndResetEvents(),
  269. ElementsAre(SELECTION_HANDLES_CLEARED, INSERTION_HANDLE_SHOWN));
  270. EXPECT_EQ(end_rect.bottom_left(), GetLastEventStart());
  271. ClearInsertion();
  272. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_CLEARED));
  273. OnTapEvent();
  274. ChangeInsertion(end_rect, visible);
  275. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  276. EXPECT_EQ(end_rect.bottom_left(), GetLastEventStart());
  277. }
  278. TEST_F(TouchSelectionControllerTest, InsertionDragged) {
  279. base::TimeTicks event_time = base::TimeTicks::Now();
  280. OnTapEvent();
  281. // The touch sequence should not be handled if insertion is not active.
  282. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
  283. EXPECT_FALSE(controller().WillHandleTouchEvent(event));
  284. float line_height = 10.f;
  285. gfx::RectF start_rect(10, 0, 0, line_height);
  286. bool visible = true;
  287. ChangeInsertion(start_rect, visible);
  288. EXPECT_THAT(GetAndResetEvents(),
  289. ElementsAre(INSERTION_HANDLE_SHOWN));
  290. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  291. // The touch sequence should be handled only if the drawable reports a hit.
  292. EXPECT_FALSE(controller().WillHandleTouchEvent(event));
  293. SetDraggingEnabled(true);
  294. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  295. EXPECT_FALSE(GetAndResetCaretMoved());
  296. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED));
  297. // The MoveCaret() result should reflect the movement.
  298. // The reported position is offset from the center of |start_rect|.
  299. gfx::PointF start_offset = start_rect.CenterPoint();
  300. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 0, 5);
  301. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  302. EXPECT_TRUE(GetAndResetCaretMoved());
  303. EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastCaretPosition());
  304. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 5, 5);
  305. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  306. EXPECT_TRUE(GetAndResetCaretMoved());
  307. EXPECT_EQ(start_offset + gfx::Vector2dF(5, 5), GetLastCaretPosition());
  308. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 10);
  309. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  310. EXPECT_TRUE(GetAndResetCaretMoved());
  311. EXPECT_EQ(start_offset + gfx::Vector2dF(10, 10), GetLastCaretPosition());
  312. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
  313. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  314. EXPECT_FALSE(GetAndResetCaretMoved());
  315. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STOPPED));
  316. // Following Action::DOWN should not be consumed if it does not start handle
  317. // dragging.
  318. SetDraggingEnabled(false);
  319. event = MockMotionEvent(MotionEvent::Action::DOWN, event_time, 0, 0);
  320. EXPECT_FALSE(controller().WillHandleTouchEvent(event));
  321. }
  322. TEST_F(TouchSelectionControllerTest, InsertionDeactivatedWhileDragging) {
  323. base::TimeTicks event_time = base::TimeTicks::Now();
  324. OnTapEvent();
  325. float line_height = 10.f;
  326. gfx::RectF start_rect(10, 0, 0, line_height);
  327. bool visible = true;
  328. ChangeInsertion(start_rect, visible);
  329. EXPECT_THAT(GetAndResetEvents(),
  330. ElementsAre(INSERTION_HANDLE_SHOWN));
  331. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  332. // Enable dragging so that the following Action::DOWN starts handle dragging.
  333. SetDraggingEnabled(true);
  334. // Touch down to start dragging.
  335. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
  336. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  337. EXPECT_FALSE(GetAndResetCaretMoved());
  338. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED));
  339. // Move the handle.
  340. gfx::PointF start_offset = start_rect.CenterPoint();
  341. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 0, 5);
  342. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  343. EXPECT_TRUE(GetAndResetCaretMoved());
  344. EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastCaretPosition());
  345. // Deactivate touch selection to end dragging.
  346. controller().HideAndDisallowShowingAutomatically();
  347. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STOPPED,
  348. INSERTION_HANDLE_CLEARED));
  349. // Move the finger. There is no handle to move, so the cursor is not moved;
  350. // but, the event is still consumed because the touch down that started the
  351. // touch sequence was consumed.
  352. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 5, 5);
  353. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  354. EXPECT_FALSE(GetAndResetCaretMoved());
  355. EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastCaretPosition());
  356. // Lift the finger to end the touch sequence.
  357. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 5, 5);
  358. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  359. EXPECT_FALSE(GetAndResetCaretMoved());
  360. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  361. // Following Action::DOWN should not be consumed if it does not start handle
  362. // dragging.
  363. SetDraggingEnabled(false);
  364. event = MockMotionEvent(MotionEvent::Action::DOWN, event_time, 0, 0);
  365. EXPECT_FALSE(controller().WillHandleTouchEvent(event));
  366. }
  367. TEST_F(TouchSelectionControllerTest, InsertionTapped) {
  368. base::TimeTicks event_time = base::TimeTicks::Now();
  369. OnTapEvent();
  370. SetDraggingEnabled(true);
  371. gfx::RectF start_rect(10, 0, 0, 10);
  372. bool visible = true;
  373. ChangeInsertion(start_rect, visible);
  374. EXPECT_THAT(GetAndResetEvents(),
  375. ElementsAre(INSERTION_HANDLE_SHOWN));
  376. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
  377. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  378. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED));
  379. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
  380. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  381. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_TAPPED,
  382. INSERTION_HANDLE_DRAG_STOPPED));
  383. // Reset the insertion.
  384. ClearInsertion();
  385. OnTapEvent();
  386. ChangeInsertion(start_rect, visible);
  387. EXPECT_THAT(GetAndResetEvents(),
  388. ElementsAre(INSERTION_HANDLE_CLEARED, INSERTION_HANDLE_SHOWN));
  389. // No tap should be signalled if the time between DOWN and UP was too long.
  390. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
  391. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  392. event = MockMotionEvent(MockMotionEvent::Action::UP,
  393. event_time + base::Seconds(1), 0, 0);
  394. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  395. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED,
  396. INSERTION_HANDLE_DRAG_STOPPED));
  397. // Reset the insertion.
  398. ClearInsertion();
  399. OnTapEvent();
  400. ChangeInsertion(start_rect, visible);
  401. EXPECT_THAT(GetAndResetEvents(),
  402. ElementsAre(INSERTION_HANDLE_CLEARED, INSERTION_HANDLE_SHOWN));
  403. // No tap should be signalled if the drag was too long.
  404. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
  405. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  406. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 100, 0);
  407. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  408. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 100, 0);
  409. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  410. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED,
  411. INSERTION_HANDLE_DRAG_STOPPED));
  412. // Reset the insertion.
  413. ClearInsertion();
  414. OnTapEvent();
  415. ChangeInsertion(start_rect, visible);
  416. EXPECT_THAT(GetAndResetEvents(),
  417. ElementsAre(INSERTION_HANDLE_CLEARED, INSERTION_HANDLE_SHOWN));
  418. // No tap should be signalled if the touch sequence is cancelled.
  419. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
  420. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  421. event = MockMotionEvent(MockMotionEvent::Action::CANCEL, event_time, 0, 0);
  422. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  423. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED,
  424. INSERTION_HANDLE_DRAG_STOPPED));
  425. }
  426. TEST_F(TouchSelectionControllerTest, SelectionBasic) {
  427. gfx::RectF start_rect(5, 5, 0, 10);
  428. gfx::RectF end_rect(50, 5, 0, 10);
  429. bool visible = true;
  430. OnLongPressEvent();
  431. ChangeSelection(start_rect, visible, end_rect, visible);
  432. EXPECT_THAT(GetAndResetEvents(),
  433. ElementsAre(SELECTION_HANDLES_SHOWN));
  434. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  435. start_rect.Offset(1, 0);
  436. ChangeSelection(start_rect, visible, end_rect, visible);
  437. // Selection movement does not currently trigger a separate event.
  438. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  439. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  440. EXPECT_EQ(end_rect.bottom_left(), GetLastEventEnd());
  441. ClearSelection();
  442. EXPECT_THAT(GetAndResetEvents(),
  443. ElementsAre(SELECTION_HANDLES_CLEARED));
  444. }
  445. TEST_F(TouchSelectionControllerTest, SelectionAllowedByDoubleTap) {
  446. gfx::RectF start_rect(5, 5, 0, 10);
  447. gfx::RectF end_rect(50, 5, 0, 10);
  448. bool visible = true;
  449. OnDoubleTapEvent();
  450. ChangeSelection(start_rect, visible, end_rect, visible);
  451. EXPECT_THAT(GetAndResetEvents(),
  452. ElementsAre(SELECTION_HANDLES_SHOWN));
  453. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  454. }
  455. TEST_F(TouchSelectionControllerTest, SelectionAllowedByDoubleTapOnEditable) {
  456. gfx::RectF start_rect(5, 5, 0, 10);
  457. gfx::RectF end_rect(50, 5, 0, 10);
  458. bool visible = true;
  459. // If the user double tap selects text in an editable region, the first tap
  460. // will register insertion and the second tap selection.
  461. OnTapEvent();
  462. ChangeInsertion(start_rect, visible);
  463. EXPECT_THAT(GetAndResetEvents(),
  464. ElementsAre(INSERTION_HANDLE_SHOWN));
  465. OnDoubleTapEvent();
  466. ChangeSelection(start_rect, visible, end_rect, visible);
  467. EXPECT_THAT(GetAndResetEvents(),
  468. ElementsAre(INSERTION_HANDLE_CLEARED, SELECTION_HANDLES_SHOWN));
  469. }
  470. TEST_F(TouchSelectionControllerTest,
  471. SelectionAllowedByTripleTapOnEditableArabicVowel) {
  472. gfx::RectF start_rect(5, 5, 0, 10);
  473. gfx::RectF end_rect(5, 5, 0, 10);
  474. bool visible = true;
  475. // If the user triple tap selects text in an editable region, the first tap
  476. // will register insertion.
  477. OnTapEvent();
  478. ChangeInsertion(start_rect, visible);
  479. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  480. // The second tap will also not select since the charcter (Arabic/Urdu vowel)
  481. // has zero width, the second tap will maintain insertion.
  482. OnDoubleTapEvent();
  483. ChangeInsertion(start_rect, visible);
  484. EXPECT_THAT(GetAndResetEvents(), ElementsAre());
  485. // The third tap selects everything in the editable text box. Since the only
  486. // text in the editable box is a zero length character the selection has the
  487. // same start and end rect.
  488. OnTripleTapEvent();
  489. ChangeSelection(start_rect, visible, end_rect, visible);
  490. EXPECT_THAT(GetAndResetEvents(),
  491. ElementsAre(INSERTION_HANDLE_CLEARED, SELECTION_HANDLES_SHOWN));
  492. }
  493. TEST_F(TouchSelectionControllerTest, SelectionAllowsEmptyUpdateAfterLongPress) {
  494. gfx::RectF start_rect(5, 5, 0, 10);
  495. gfx::RectF end_rect(50, 5, 0, 10);
  496. bool visible = true;
  497. OnLongPressEvent();
  498. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  499. // There may be several empty updates after a longpress due to the
  500. // asynchronous response. These empty updates should not prevent the selection
  501. // handles from (eventually) activating.
  502. ClearSelection();
  503. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  504. ClearSelection();
  505. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  506. ChangeSelection(start_rect, visible, end_rect, visible);
  507. EXPECT_THAT(GetAndResetEvents(),
  508. ElementsAre(SELECTION_HANDLES_SHOWN));
  509. }
  510. TEST_F(TouchSelectionControllerTest, SelectionRepeatedLongPress) {
  511. gfx::RectF start_rect(5, 5, 0, 10);
  512. gfx::RectF end_rect(50, 5, 0, 10);
  513. bool visible = true;
  514. OnLongPressEvent();
  515. ChangeSelection(start_rect, visible, end_rect, visible);
  516. EXPECT_THAT(GetAndResetEvents(),
  517. ElementsAre(SELECTION_HANDLES_SHOWN));
  518. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  519. EXPECT_EQ(end_rect.bottom_left(), GetLastEventEnd());
  520. // A long press triggering a new selection should re-send the
  521. // SELECTION_HANDLES_SHOWN
  522. // event notification.
  523. start_rect.Offset(10, 10);
  524. OnLongPressEvent();
  525. ChangeSelection(start_rect, visible, end_rect, visible);
  526. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_SHOWN));
  527. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  528. EXPECT_EQ(end_rect.bottom_left(), GetLastEventEnd());
  529. }
  530. TEST_F(TouchSelectionControllerTest, SelectionDragged) {
  531. base::TimeTicks event_time = base::TimeTicks::Now();
  532. OnLongPressEvent();
  533. // The touch sequence should not be handled if selection is not active.
  534. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
  535. EXPECT_FALSE(controller().WillHandleTouchEvent(event));
  536. float line_height = 10.f;
  537. gfx::RectF start_rect(0, 0, 0, line_height);
  538. gfx::RectF end_rect(50, 0, 0, line_height);
  539. bool visible = true;
  540. ChangeSelection(start_rect, visible, end_rect, visible);
  541. EXPECT_THAT(GetAndResetEvents(),
  542. ElementsAre(SELECTION_HANDLES_SHOWN));
  543. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  544. // The touch sequence should be handled only if the drawable reports a hit.
  545. EXPECT_FALSE(controller().WillHandleTouchEvent(event));
  546. SetDraggingEnabled(true);
  547. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  548. EXPECT_FALSE(GetAndResetSelectionMoved());
  549. // The SelectBetweenCoordinates() result should reflect the movement. Note
  550. // that the start coordinate will always reflect the "fixed" handle's
  551. // position, in this case the position from |end_rect|.
  552. // Note that the reported position is offset from the center of the
  553. // input rects (i.e., the middle of the corresponding text line).
  554. gfx::PointF fixed_offset = end_rect.CenterPoint();
  555. gfx::PointF start_offset = start_rect.CenterPoint();
  556. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 0, 5);
  557. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  558. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  559. EXPECT_TRUE(GetAndResetSelectionMoved());
  560. EXPECT_EQ(fixed_offset, GetLastSelectionStart());
  561. EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
  562. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 5, 5);
  563. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  564. EXPECT_TRUE(GetAndResetSelectionMoved());
  565. EXPECT_EQ(fixed_offset, GetLastSelectionStart());
  566. EXPECT_EQ(start_offset + gfx::Vector2dF(5, 5), GetLastSelectionEnd());
  567. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
  568. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  569. EXPECT_TRUE(GetAndResetSelectionMoved());
  570. EXPECT_EQ(fixed_offset, GetLastSelectionStart());
  571. EXPECT_EQ(start_offset + gfx::Vector2dF(10, 5), GetLastSelectionEnd());
  572. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
  573. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  574. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  575. EXPECT_FALSE(GetAndResetSelectionMoved());
  576. // Following Action::DOWN should not be consumed if it does not start handle
  577. // dragging.
  578. SetDraggingEnabled(false);
  579. event = MockMotionEvent(MotionEvent::Action::DOWN, event_time, 0, 0);
  580. EXPECT_FALSE(controller().WillHandleTouchEvent(event));
  581. }
  582. TEST_F(TouchSelectionControllerTest, SelectionDraggedWithOverlap) {
  583. base::TimeTicks event_time = base::TimeTicks::Now();
  584. OnLongPressEvent();
  585. float line_height = 10.f;
  586. gfx::RectF start_rect(0, 0, 0, line_height);
  587. gfx::RectF end_rect(50, 0, 0, line_height);
  588. bool visible = true;
  589. ChangeSelection(start_rect, visible, end_rect, visible);
  590. EXPECT_THAT(GetAndResetEvents(),
  591. ElementsAre(SELECTION_HANDLES_SHOWN));
  592. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  593. // The Action::DOWN should lock to the closest handle.
  594. gfx::PointF end_offset = end_rect.CenterPoint();
  595. gfx::PointF fixed_offset = start_rect.CenterPoint();
  596. float touch_down_x = (end_offset.x() + fixed_offset.x()) / 2 + 1.f;
  597. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, touch_down_x,
  598. 0);
  599. SetDraggingEnabled(true);
  600. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  601. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  602. EXPECT_FALSE(GetAndResetSelectionMoved());
  603. // Even though the Action::MOVE is over the start handle, it should continue
  604. // targetting the end handle that consumed the Action::DOWN.
  605. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 0, 0);
  606. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  607. EXPECT_TRUE(GetAndResetSelectionMoved());
  608. EXPECT_EQ(fixed_offset, GetLastSelectionStart());
  609. EXPECT_EQ(end_offset - gfx::Vector2dF(touch_down_x, 0),
  610. GetLastSelectionEnd());
  611. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
  612. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  613. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  614. EXPECT_FALSE(GetAndResetSelectionMoved());
  615. }
  616. TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
  617. base::TimeTicks event_time = base::TimeTicks::Now();
  618. OnLongPressEvent();
  619. float line_height = 10.f;
  620. gfx::RectF start_rect(50, line_height, 0, line_height);
  621. gfx::RectF end_rect(100, line_height, 0, line_height);
  622. bool visible = true;
  623. ChangeSelection(start_rect, visible, end_rect, visible);
  624. EXPECT_THAT(GetAndResetEvents(),
  625. ElementsAre(SELECTION_HANDLES_SHOWN));
  626. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  627. SetDraggingEnabled(true);
  628. // Move the extent, not triggering a swap of points.
  629. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, end_rect.x(),
  630. end_rect.bottom());
  631. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  632. EXPECT_FALSE(GetAndResetSelectionMoved());
  633. EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
  634. gfx::PointF base_offset = start_rect.CenterPoint();
  635. gfx::PointF extent_offset = end_rect.CenterPoint();
  636. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
  637. end_rect.x(), end_rect.bottom() + 5);
  638. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  639. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  640. EXPECT_TRUE(GetAndResetSelectionMoved());
  641. EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
  642. EXPECT_EQ(base_offset, GetLastSelectionStart());
  643. EXPECT_EQ(extent_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
  644. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
  645. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  646. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  647. EXPECT_FALSE(GetAndResetSelectionMoved());
  648. end_rect += gfx::Vector2dF(0, 5);
  649. ChangeSelection(start_rect, visible, end_rect, visible);
  650. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  651. // Move the base, triggering a swap of points.
  652. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
  653. start_rect.x(), start_rect.bottom());
  654. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  655. EXPECT_FALSE(GetAndResetSelectionMoved());
  656. EXPECT_TRUE(GetAndResetSelectionPointsSwapped());
  657. base_offset = end_rect.CenterPoint();
  658. extent_offset = start_rect.CenterPoint();
  659. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
  660. start_rect.x(), start_rect.bottom() + 5);
  661. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  662. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  663. EXPECT_TRUE(GetAndResetSelectionMoved());
  664. EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
  665. EXPECT_EQ(base_offset, GetLastSelectionStart());
  666. EXPECT_EQ(extent_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
  667. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
  668. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  669. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  670. EXPECT_FALSE(GetAndResetSelectionMoved());
  671. start_rect += gfx::Vector2dF(0, 5);
  672. ChangeSelection(start_rect, visible, end_rect, visible);
  673. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  674. // Move the same point again, not triggering a swap of points.
  675. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
  676. start_rect.x(), start_rect.bottom());
  677. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  678. EXPECT_FALSE(GetAndResetSelectionMoved());
  679. EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
  680. base_offset = end_rect.CenterPoint();
  681. extent_offset = start_rect.CenterPoint();
  682. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
  683. start_rect.x(), start_rect.bottom() + 5);
  684. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  685. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  686. EXPECT_TRUE(GetAndResetSelectionMoved());
  687. EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
  688. EXPECT_EQ(base_offset, GetLastSelectionStart());
  689. EXPECT_EQ(extent_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
  690. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
  691. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  692. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  693. EXPECT_FALSE(GetAndResetSelectionMoved());
  694. start_rect += gfx::Vector2dF(0, 5);
  695. ChangeSelection(start_rect, visible, end_rect, visible);
  696. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  697. // Move the base, triggering a swap of points.
  698. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
  699. end_rect.x(), end_rect.bottom());
  700. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  701. EXPECT_FALSE(GetAndResetSelectionMoved());
  702. EXPECT_TRUE(GetAndResetSelectionPointsSwapped());
  703. base_offset = start_rect.CenterPoint();
  704. extent_offset = end_rect.CenterPoint();
  705. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
  706. end_rect.x(), end_rect.bottom() + 5);
  707. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  708. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  709. EXPECT_TRUE(GetAndResetSelectionMoved());
  710. EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
  711. EXPECT_EQ(base_offset, GetLastSelectionStart());
  712. EXPECT_EQ(extent_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
  713. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
  714. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  715. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  716. EXPECT_FALSE(GetAndResetSelectionMoved());
  717. }
  718. TEST_F(TouchSelectionControllerTest, SelectionDragExtremeLineSize) {
  719. base::TimeTicks event_time = base::TimeTicks::Now();
  720. OnLongPressEvent();
  721. float small_line_height = 1.f;
  722. float large_line_height = 50.f;
  723. gfx::RectF small_line_rect(0, 0, 0, small_line_height);
  724. gfx::RectF large_line_rect(50, 50, 0, large_line_height);
  725. bool visible = true;
  726. ChangeSelection(small_line_rect, visible, large_line_rect, visible);
  727. EXPECT_THAT(GetAndResetEvents(),
  728. ElementsAre(SELECTION_HANDLES_SHOWN));
  729. EXPECT_EQ(small_line_rect.bottom_left(), GetLastEventStart());
  730. // Start dragging the handle on the small line.
  731. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time,
  732. small_line_rect.x(), small_line_rect.y());
  733. SetDraggingEnabled(true);
  734. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  735. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  736. // The drag coordinate for large lines should be capped to a reasonable
  737. // offset, allowing seamless transition to neighboring lines with different
  738. // sizes. The drag coordinate for small lines should have an offset
  739. // commensurate with the small line size.
  740. EXPECT_EQ(large_line_rect.bottom_left() - gfx::Vector2dF(0, 8.f),
  741. GetLastSelectionStart());
  742. EXPECT_EQ(small_line_rect.CenterPoint(), GetLastSelectionEnd());
  743. small_line_rect += gfx::Vector2dF(25.f, 0);
  744. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
  745. small_line_rect.x(), small_line_rect.y());
  746. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  747. EXPECT_TRUE(GetAndResetSelectionMoved());
  748. EXPECT_EQ(small_line_rect.CenterPoint(), GetLastSelectionEnd());
  749. }
  750. TEST_F(TouchSelectionControllerTest, Animation) {
  751. OnTapEvent();
  752. gfx::RectF insertion_rect(5, 5, 0, 10);
  753. bool visible = true;
  754. ChangeInsertion(insertion_rect, visible);
  755. EXPECT_FALSE(GetAndResetNeedsAnimate());
  756. visible = false;
  757. ChangeInsertion(insertion_rect, visible);
  758. EXPECT_TRUE(GetAndResetNeedsAnimate());
  759. visible = true;
  760. ChangeInsertion(insertion_rect, visible);
  761. EXPECT_TRUE(GetAndResetNeedsAnimate());
  762. // If the handles are explicity hidden, no animation should be triggered.
  763. controller().HideAndDisallowShowingAutomatically();
  764. EXPECT_FALSE(GetAndResetNeedsAnimate());
  765. // If the client doesn't support animation, no animation should be triggered.
  766. SetAnimationEnabled(false);
  767. OnTapEvent();
  768. visible = true;
  769. ChangeInsertion(insertion_rect, visible);
  770. EXPECT_FALSE(GetAndResetNeedsAnimate());
  771. }
  772. TEST_F(TouchSelectionControllerTest, TemporarilyHidden) {
  773. TouchSelectionControllerTestApi test_controller(&controller());
  774. OnTapEvent();
  775. gfx::RectF insertion_rect(5, 5, 0, 10);
  776. bool visible = true;
  777. ChangeInsertion(insertion_rect, visible);
  778. EXPECT_FALSE(GetAndResetNeedsAnimate());
  779. EXPECT_TRUE(test_controller.GetStartVisible());
  780. EXPECT_TRUE(test_controller.GetEndVisible());
  781. controller().SetTemporarilyHidden(true);
  782. EXPECT_TRUE(GetAndResetNeedsAnimate());
  783. EXPECT_FALSE(test_controller.GetStartVisible());
  784. EXPECT_FALSE(test_controller.GetEndVisible());
  785. EXPECT_EQ(0.f, test_controller.GetStartAlpha());
  786. EXPECT_EQ(0.f, test_controller.GetEndAlpha());
  787. visible = false;
  788. ChangeInsertion(insertion_rect, visible);
  789. EXPECT_FALSE(GetAndResetNeedsAnimate());
  790. EXPECT_FALSE(test_controller.GetStartVisible());
  791. EXPECT_EQ(0.f, test_controller.GetStartAlpha());
  792. visible = true;
  793. ChangeInsertion(insertion_rect, visible);
  794. EXPECT_FALSE(GetAndResetNeedsAnimate());
  795. EXPECT_FALSE(test_controller.GetStartVisible());
  796. EXPECT_EQ(0.f, test_controller.GetStartAlpha());
  797. controller().SetTemporarilyHidden(false);
  798. EXPECT_TRUE(GetAndResetNeedsAnimate());
  799. EXPECT_TRUE(test_controller.GetStartVisible());
  800. }
  801. TEST_F(TouchSelectionControllerTest, SelectionClearOnTap) {
  802. gfx::RectF start_rect(5, 5, 0, 10);
  803. gfx::RectF end_rect(50, 5, 0, 10);
  804. bool visible = true;
  805. OnLongPressEvent();
  806. ChangeSelection(start_rect, visible, end_rect, visible);
  807. EXPECT_THAT(GetAndResetEvents(),
  808. ElementsAre(SELECTION_HANDLES_SHOWN));
  809. // Selection should not be cleared if the selection bounds have not changed.
  810. OnTapEvent();
  811. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  812. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  813. OnTapEvent();
  814. ClearSelection();
  815. EXPECT_THAT(GetAndResetEvents(),
  816. ElementsAre(SELECTION_HANDLES_CLEARED));
  817. }
  818. TEST_F(TouchSelectionControllerTest, LongPressDrag) {
  819. EnableLongPressDragSelection();
  820. TouchSelectionControllerTestApi test_controller(&controller());
  821. gfx::RectF start_rect(-50, 0, 0, 10);
  822. gfx::RectF end_rect(50, 0, 0, 10);
  823. bool visible = true;
  824. // Start a touch sequence.
  825. MockMotionEvent event;
  826. EXPECT_FALSE(controller().WillHandleTouchEvent(event.PressPoint(0, 0)));
  827. // Activate a longpress-triggered selection.
  828. OnLongPressEvent();
  829. ChangeSelection(start_rect, visible, end_rect, visible);
  830. EXPECT_THAT(GetAndResetEvents(),
  831. ElementsAre(SELECTION_HANDLES_SHOWN));
  832. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  833. // The handles should remain invisible while the touch release and longpress
  834. // drag gesture are pending.
  835. EXPECT_FALSE(test_controller.GetStartVisible());
  836. EXPECT_FALSE(test_controller.GetEndVisible());
  837. EXPECT_EQ(0.f, test_controller.GetStartAlpha());
  838. EXPECT_EQ(0.f, test_controller.GetEndAlpha());
  839. // The selection coordinates should reflect the drag movement.
  840. gfx::PointF fixed_offset = start_rect.CenterPoint();
  841. gfx::PointF end_offset = end_rect.CenterPoint();
  842. EXPECT_TRUE(controller().WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
  843. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  844. EXPECT_TRUE(
  845. controller().WillHandleTouchEvent(event.MovePoint(0, 0, kDefaulTapSlop)));
  846. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  847. EXPECT_EQ(fixed_offset, GetLastSelectionStart());
  848. EXPECT_EQ(end_offset, GetLastSelectionEnd());
  849. // Movement after the start of drag will be relative to the moved endpoint.
  850. EXPECT_TRUE(controller().WillHandleTouchEvent(
  851. event.MovePoint(0, 0, 2 * kDefaulTapSlop)));
  852. EXPECT_TRUE(GetAndResetSelectionMoved());
  853. EXPECT_EQ(end_offset + gfx::Vector2dF(0, kDefaulTapSlop),
  854. GetLastSelectionEnd());
  855. EXPECT_TRUE(controller().WillHandleTouchEvent(
  856. event.MovePoint(0, kDefaulTapSlop, 2 * kDefaulTapSlop)));
  857. EXPECT_TRUE(GetAndResetSelectionMoved());
  858. EXPECT_EQ(end_offset + gfx::Vector2dF(kDefaulTapSlop, kDefaulTapSlop),
  859. GetLastSelectionEnd());
  860. EXPECT_TRUE(controller().WillHandleTouchEvent(
  861. event.MovePoint(0, 2 * kDefaulTapSlop, 2 * kDefaulTapSlop)));
  862. EXPECT_TRUE(GetAndResetSelectionMoved());
  863. EXPECT_EQ(end_offset + gfx::Vector2dF(2 * kDefaulTapSlop, kDefaulTapSlop),
  864. GetLastSelectionEnd());
  865. // The handles should still be hidden.
  866. EXPECT_FALSE(test_controller.GetStartVisible());
  867. EXPECT_FALSE(test_controller.GetEndVisible());
  868. EXPECT_EQ(0.f, test_controller.GetStartAlpha());
  869. EXPECT_EQ(0.f, test_controller.GetEndAlpha());
  870. // Releasing the touch sequence should end the drag and show the handles.
  871. EXPECT_FALSE(controller().WillHandleTouchEvent(event.ReleasePoint()));
  872. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  873. EXPECT_TRUE(test_controller.GetStartVisible());
  874. EXPECT_TRUE(test_controller.GetEndVisible());
  875. }
  876. TEST_F(TouchSelectionControllerTest, LongPressNoDrag) {
  877. EnableLongPressDragSelection();
  878. TouchSelectionControllerTestApi test_controller(&controller());
  879. gfx::RectF start_rect(-50, 0, 0, 10);
  880. gfx::RectF end_rect(50, 0, 0, 10);
  881. bool visible = true;
  882. // Start a touch sequence.
  883. MockMotionEvent event;
  884. EXPECT_FALSE(controller().WillHandleTouchEvent(event.PressPoint(0, 0)));
  885. // Activate a longpress-triggered selection.
  886. OnLongPressEvent();
  887. ChangeSelection(start_rect, visible, end_rect, visible);
  888. EXPECT_THAT(GetAndResetEvents(),
  889. ElementsAre(SELECTION_HANDLES_SHOWN));
  890. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  891. // The handles should remain invisible while the touch release and longpress
  892. // drag gesture are pending.
  893. EXPECT_FALSE(test_controller.GetStartVisible());
  894. EXPECT_FALSE(test_controller.GetEndVisible());
  895. EXPECT_EQ(0.f, test_controller.GetStartAlpha());
  896. EXPECT_EQ(0.f, test_controller.GetEndAlpha());
  897. // If no drag movement occurs, the handles should reappear after the touch
  898. // is released.
  899. EXPECT_FALSE(controller().WillHandleTouchEvent(event.ReleasePoint()));
  900. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  901. EXPECT_TRUE(test_controller.GetStartVisible());
  902. EXPECT_TRUE(test_controller.GetEndVisible());
  903. }
  904. TEST_F(TouchSelectionControllerTest, NoLongPressDragIfDisabled) {
  905. // The TouchSelectionController disables longpress drag selection by default.
  906. TouchSelectionControllerTestApi test_controller(&controller());
  907. gfx::RectF start_rect(-50, 0, 0, 10);
  908. gfx::RectF end_rect(50, 0, 0, 10);
  909. bool visible = true;
  910. // Start a touch sequence.
  911. MockMotionEvent event;
  912. EXPECT_FALSE(controller().WillHandleTouchEvent(event.PressPoint(0, 0)));
  913. // Activate a longpress-triggered selection.
  914. OnLongPressEvent();
  915. ChangeSelection(start_rect, visible, end_rect, visible);
  916. EXPECT_THAT(GetAndResetEvents(),
  917. ElementsAre(SELECTION_HANDLES_SHOWN));
  918. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  919. EXPECT_TRUE(test_controller.GetStartVisible());
  920. EXPECT_TRUE(test_controller.GetEndVisible());
  921. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  922. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  923. // Subsequent motion of the same touch sequence after longpress shouldn't
  924. // trigger drag selection.
  925. EXPECT_FALSE(controller().WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
  926. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  927. EXPECT_FALSE(controller().WillHandleTouchEvent(
  928. event.MovePoint(0, 0, kDefaulTapSlop * 10)));
  929. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  930. // Releasing the touch sequence should have no effect.
  931. EXPECT_FALSE(controller().WillHandleTouchEvent(event.ReleasePoint()));
  932. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  933. EXPECT_TRUE(test_controller.GetStartVisible());
  934. EXPECT_TRUE(test_controller.GetEndVisible());
  935. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  936. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  937. }
  938. TEST_F(TouchSelectionControllerTest, RectBetweenBounds) {
  939. gfx::RectF start_rect(5, 5, 0, 10);
  940. gfx::RectF end_rect(50, 5, 0, 10);
  941. bool visible = true;
  942. EXPECT_EQ(gfx::RectF(), controller().GetRectBetweenBounds());
  943. OnLongPressEvent();
  944. ChangeSelection(start_rect, visible, end_rect, visible);
  945. ASSERT_THAT(GetAndResetEvents(),
  946. ElementsAre(SELECTION_HANDLES_SHOWN));
  947. EXPECT_EQ(gfx::RectF(5, 5, 45, 10), controller().GetRectBetweenBounds());
  948. // The result of |GetRectBetweenBounds| should be available within the
  949. // |OnSelectionEvent| callback, as stored by |GetLastEventBoundsRect()|.
  950. EXPECT_EQ(GetLastEventBoundsRect(), controller().GetRectBetweenBounds());
  951. start_rect.Offset(1, 0);
  952. ChangeSelection(start_rect, visible, end_rect, visible);
  953. ASSERT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  954. EXPECT_EQ(gfx::RectF(6, 5, 44, 10), controller().GetRectBetweenBounds());
  955. EXPECT_EQ(GetLastEventBoundsRect(), controller().GetRectBetweenBounds());
  956. // If only one bound is visible, the selection bounding rect should reflect
  957. // only the visible bound.
  958. ChangeSelection(start_rect, visible, end_rect, false);
  959. ASSERT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  960. EXPECT_EQ(start_rect, controller().GetRectBetweenBounds());
  961. EXPECT_EQ(GetLastEventBoundsRect(), controller().GetRectBetweenBounds());
  962. ChangeSelection(start_rect, false, end_rect, visible);
  963. ASSERT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  964. EXPECT_EQ(end_rect, controller().GetRectBetweenBounds());
  965. EXPECT_EQ(GetLastEventBoundsRect(), controller().GetRectBetweenBounds());
  966. // If both bounds are visible, the full bounding rect should be returned.
  967. ChangeSelection(start_rect, false, end_rect, false);
  968. ASSERT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  969. EXPECT_EQ(gfx::RectF(6, 5, 44, 10), controller().GetRectBetweenBounds());
  970. EXPECT_EQ(GetLastEventBoundsRect(), controller().GetRectBetweenBounds());
  971. ClearSelection();
  972. ASSERT_THAT(GetAndResetEvents(),
  973. ElementsAre(SELECTION_HANDLES_CLEARED));
  974. EXPECT_EQ(gfx::RectF(), controller().GetRectBetweenBounds());
  975. }
  976. TEST_F(TouchSelectionControllerTest, TouchHandleHeight) {
  977. OnLongPressEvent();
  978. SetDraggingEnabled(true);
  979. gfx::RectF start_rect(5, 5, 0, 10);
  980. gfx::RectF end_rect(50, 5, 0, 10);
  981. // Handle height should be zero when there is no selection/ insertion.
  982. EXPECT_EQ(0.f, controller().GetTouchHandleHeight());
  983. // Insertion case - Handle shown.
  984. ChangeInsertion(start_rect, true);
  985. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  986. EXPECT_NE(0.f, controller().GetTouchHandleHeight());
  987. // Insertion case - Handle moved.
  988. start_rect.Offset(1, 0);
  989. ChangeInsertion(start_rect, true);
  990. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_MOVED));
  991. EXPECT_NE(0.f, controller().GetTouchHandleHeight());
  992. ClearInsertion();
  993. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_CLEARED));
  994. EXPECT_EQ(0.f, controller().GetTouchHandleHeight());
  995. // Selection case - Start and End are visible.
  996. ChangeSelection(start_rect, true, end_rect, true);
  997. ASSERT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_SHOWN));
  998. EXPECT_NE(0.f, controller().GetTouchHandleHeight());
  999. // Selection case - Only Start is visible.
  1000. ChangeSelection(start_rect, true, end_rect, false);
  1001. ASSERT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1002. EXPECT_NE(0.f, controller().GetTouchHandleHeight());
  1003. // Selection case - Only End is visible.
  1004. ChangeSelection(start_rect, false, end_rect, true);
  1005. ASSERT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1006. EXPECT_NE(0.f, controller().GetTouchHandleHeight());
  1007. ClearSelection();
  1008. ASSERT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_CLEARED));
  1009. EXPECT_EQ(0.f, controller().GetTouchHandleHeight());
  1010. }
  1011. TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
  1012. TouchSelectionControllerTestApi test_controller(&controller());
  1013. base::TimeTicks event_time = base::TimeTicks::Now();
  1014. OnLongPressEvent();
  1015. float line_height = 10.f;
  1016. gfx::RectF start_rect(50, line_height, 0, line_height);
  1017. gfx::RectF end_rect(100, line_height, 0, line_height);
  1018. bool visible = true;
  1019. ChangeSelection(start_rect, visible, end_rect, visible);
  1020. EXPECT_THAT(GetAndResetEvents(),
  1021. ElementsAre(SELECTION_HANDLES_SHOWN));
  1022. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  1023. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1024. TouchHandleOrientation::LEFT);
  1025. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1026. TouchHandleOrientation::RIGHT);
  1027. SetDraggingEnabled(true);
  1028. // Simulate moving the base, not triggering a swap of points.
  1029. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time,
  1030. start_rect.x(), start_rect.bottom());
  1031. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1032. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1033. gfx::RectF offset_rect = end_rect;
  1034. offset_rect.Offset(gfx::Vector2dF(-10, 0));
  1035. ChangeSelection(offset_rect, visible, end_rect, visible);
  1036. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1037. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1038. TouchHandleOrientation::LEFT);
  1039. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1040. TouchHandleOrientation::RIGHT);
  1041. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1042. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
  1043. offset_rect.x(), offset_rect.bottom());
  1044. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1045. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  1046. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1047. TouchHandleOrientation::LEFT);
  1048. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1049. TouchHandleOrientation::RIGHT);
  1050. // Simulate moving the base, triggering a swap of points.
  1051. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
  1052. offset_rect.x(), offset_rect.bottom());
  1053. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1054. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1055. offset_rect.Offset(gfx::Vector2dF(20, 0));
  1056. ChangeSelection(end_rect, visible, offset_rect, visible);
  1057. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1058. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1059. TouchHandleOrientation::LEFT);
  1060. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1061. TouchHandleOrientation::LEFT);
  1062. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1063. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
  1064. offset_rect.x(), offset_rect.bottom());
  1065. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1066. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  1067. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1068. TouchHandleOrientation::LEFT);
  1069. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1070. TouchHandleOrientation::RIGHT);
  1071. // Simulate moving the anchor, not triggering a swap of points.
  1072. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
  1073. offset_rect.x(), offset_rect.bottom());
  1074. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1075. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1076. offset_rect.Offset(gfx::Vector2dF(-5, 0));
  1077. ChangeSelection(end_rect, visible, offset_rect, visible);
  1078. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1079. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1080. TouchHandleOrientation::LEFT);
  1081. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1082. TouchHandleOrientation::RIGHT);
  1083. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1084. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
  1085. offset_rect.x(), offset_rect.bottom());
  1086. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1087. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  1088. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1089. TouchHandleOrientation::LEFT);
  1090. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1091. TouchHandleOrientation::RIGHT);
  1092. // Simulate moving the anchor, triggering a swap of points.
  1093. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
  1094. offset_rect.x(), offset_rect.bottom());
  1095. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1096. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1097. offset_rect.Offset(gfx::Vector2dF(-15, 0));
  1098. ChangeSelection(offset_rect, visible, end_rect, visible);
  1099. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1100. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1101. TouchHandleOrientation::RIGHT);
  1102. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1103. TouchHandleOrientation::RIGHT);
  1104. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1105. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
  1106. offset_rect.x(), offset_rect.bottom());
  1107. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1108. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  1109. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1110. TouchHandleOrientation::LEFT);
  1111. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1112. TouchHandleOrientation::RIGHT);
  1113. }
  1114. TEST_F(TouchSelectionControllerTest, VerticalTextSelectionHandleSwap) {
  1115. TouchSelectionControllerTestApi test_controller(&controller());
  1116. base::TimeTicks event_time = base::TimeTicks::Now();
  1117. OnLongPressEvent();
  1118. // Horizontal bounds.
  1119. gfx::RectF start_rect(0, 50, 16, 0);
  1120. gfx::RectF end_rect(0, 100, 16, 0);
  1121. bool visible = true;
  1122. ChangeVerticalSelection(start_rect, visible, end_rect, visible);
  1123. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_SHOWN));
  1124. EXPECT_EQ(start_rect.bottom_right(), GetLastEventStart());
  1125. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1126. TouchHandleOrientation::RIGHT);
  1127. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1128. TouchHandleOrientation::LEFT);
  1129. SetDraggingEnabled(true);
  1130. // Simulate moving the base, triggering a swap of points.
  1131. // Start to drag start handle.
  1132. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time,
  1133. start_rect.right(), start_rect.bottom());
  1134. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1135. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1136. // Move start handle down below end handle.
  1137. gfx::RectF offset_rect = end_rect;
  1138. offset_rect.Offset(gfx::Vector2dF(0, 20));
  1139. ChangeVerticalSelection(end_rect, visible, offset_rect, visible);
  1140. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1141. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1142. TouchHandleOrientation::RIGHT);
  1143. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1144. TouchHandleOrientation::RIGHT);
  1145. // Release.
  1146. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1147. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
  1148. offset_rect.x(), offset_rect.bottom());
  1149. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1150. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  1151. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1152. TouchHandleOrientation::RIGHT);
  1153. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1154. TouchHandleOrientation::LEFT);
  1155. // Move end handle up.
  1156. // Start to drag end handle.
  1157. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
  1158. offset_rect.x(), offset_rect.bottom());
  1159. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1160. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1161. // Move up end handle up above the start handle.
  1162. offset_rect = start_rect;
  1163. ChangeVerticalSelection(offset_rect, visible, end_rect, visible);
  1164. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1165. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1166. TouchHandleOrientation::LEFT);
  1167. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1168. TouchHandleOrientation::LEFT);
  1169. // Release.
  1170. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1171. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
  1172. offset_rect.x(), offset_rect.bottom());
  1173. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1174. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  1175. EXPECT_EQ(test_controller.GetStartHandleOrientation(),
  1176. TouchHandleOrientation::RIGHT);
  1177. EXPECT_EQ(test_controller.GetEndHandleOrientation(),
  1178. TouchHandleOrientation::LEFT);
  1179. }
  1180. TEST_F(TouchSelectionControllerTest, InsertionUpdateDragPosition) {
  1181. base::TimeTicks event_time = base::TimeTicks::Now();
  1182. float line_height = 10.f;
  1183. gfx::RectF insertion_rect(10, 0, 0, line_height);
  1184. bool visible = true;
  1185. OnTapEvent();
  1186. ChangeInsertion(insertion_rect, visible);
  1187. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  1188. EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastDragUpdatePosition());
  1189. SetDraggingEnabled(true);
  1190. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
  1191. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1192. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
  1193. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1194. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED));
  1195. EXPECT_EQ(gfx::PointF(10.f, 5.f), GetLastDragUpdatePosition());
  1196. insertion_rect.Offset(1, 0);
  1197. ChangeInsertion(insertion_rect, visible);
  1198. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 12, 6);
  1199. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1200. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_MOVED));
  1201. // Don't follow the y-coordinate change but only x-coordinate change.
  1202. EXPECT_EQ(gfx::PointF(12.f, 5.f), GetLastDragUpdatePosition());
  1203. insertion_rect.Offset(0, 1);
  1204. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 11, 6);
  1205. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1206. ChangeInsertion(insertion_rect, visible);
  1207. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 11, 7);
  1208. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1209. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_MOVED));
  1210. // Don't follow the y-coordinate change.
  1211. EXPECT_EQ(gfx::PointF(11.f, 6.f), GetLastDragUpdatePosition());
  1212. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1213. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
  1214. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1215. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STOPPED));
  1216. SetDraggingEnabled(false);
  1217. }
  1218. TEST_F(TouchSelectionControllerTest, SelectionUpdateDragPosition) {
  1219. base::TimeTicks event_time = base::TimeTicks::Now();
  1220. float line_height = 10.f;
  1221. gfx::RectF start_rect(10, 0, 0, line_height);
  1222. gfx::RectF end_rect(50, 0, 0, line_height);
  1223. bool visible = true;
  1224. OnLongPressEvent();
  1225. ChangeSelection(start_rect, visible, end_rect, visible);
  1226. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_SHOWN));
  1227. EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastDragUpdatePosition());
  1228. // Left handle.
  1229. SetDraggingEnabled(true);
  1230. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
  1231. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1232. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
  1233. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1234. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1235. EXPECT_EQ(gfx::PointF(10.f, 5.f), GetLastDragUpdatePosition());
  1236. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 16, 6);
  1237. start_rect.Offset(5, 0);
  1238. ChangeSelection(start_rect, visible, end_rect, visible);
  1239. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1240. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1241. // Don't follow the y-coordinate change but only x-coordinate change.
  1242. EXPECT_EQ(gfx::PointF(16.f, 5.f), GetLastDragUpdatePosition());
  1243. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1244. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 15, 5);
  1245. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1246. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  1247. // Right handle.
  1248. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 50, 5);
  1249. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1250. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 50, 5);
  1251. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1252. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1253. EXPECT_EQ(gfx::PointF(50.f, 5.f), GetLastDragUpdatePosition());
  1254. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 45, 5);
  1255. end_rect.Offset(-5, 0);
  1256. ChangeSelection(start_rect, visible, end_rect, visible);
  1257. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1258. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
  1259. EXPECT_EQ(gfx::PointF(45.f, 5.f), GetLastDragUpdatePosition());
  1260. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1261. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 45, 5);
  1262. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1263. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
  1264. }
  1265. TEST_F(TouchSelectionControllerTest, LongpressDragSelectorUpdageDragPosition) {
  1266. EnableLongPressDragSelection();
  1267. float line_height = 10.f;
  1268. gfx::RectF start_rect(-40, 0, 0, line_height);
  1269. gfx::RectF end_rect(50, 0, 0, line_height);
  1270. bool visible = true;
  1271. // Start a touch sequence.
  1272. MockMotionEvent event;
  1273. EXPECT_FALSE(controller().WillHandleTouchEvent(event.PressPoint(0, 0)));
  1274. // Activate a longpress-triggered selection
  1275. OnLongPressEvent();
  1276. ChangeSelection(start_rect, visible, end_rect, visible);
  1277. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_SHOWN));
  1278. EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
  1279. EXPECT_TRUE(controller().WillHandleTouchEvent(event.MovePoint(0, 0, 0)));
  1280. EXPECT_THAT(GetAndResetEvents(), IsEmpty());
  1281. // Move within tap slop, move haven't started yet.
  1282. EXPECT_TRUE(
  1283. controller().WillHandleTouchEvent(event.MovePoint(0, 0, kDefaulTapSlop)));
  1284. EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
  1285. EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastDragUpdatePosition());
  1286. // Movement after the start of drag will be relative to the moved endpoint,
  1287. // the actual selection change offset is not necessary equal to the event
  1288. // moving distance.
  1289. end_rect.Offset(6, 0);
  1290. ChangeSelection(start_rect, visible, end_rect, visible);
  1291. EXPECT_TRUE(controller().WillHandleTouchEvent(event.MovePoint(0, 5, 0)));
  1292. EXPECT_TRUE(GetAndResetSelectionMoved());
  1293. EXPECT_EQ(gfx::PointF(56.f, 5.f), GetLastDragUpdatePosition());
  1294. // Vertical move
  1295. end_rect.Offset(0, 10);
  1296. ChangeSelection(start_rect, visible, end_rect, visible);
  1297. EXPECT_TRUE(controller().WillHandleTouchEvent(event.MovePoint(0, 5, 10)));
  1298. EXPECT_TRUE(GetAndResetSelectionMoved());
  1299. EXPECT_EQ(gfx::PointF(56.f, 15.f), GetLastDragUpdatePosition());
  1300. // Move start
  1301. start_rect.Offset(30, 0);
  1302. ChangeSelection(start_rect, visible, end_rect, visible);
  1303. EXPECT_TRUE(controller().WillHandleTouchEvent(event.MovePoint(0, 35, 10)));
  1304. EXPECT_TRUE(GetAndResetSelectionMoved());
  1305. EXPECT_EQ(gfx::PointF(-10.f, 5.f), GetLastDragUpdatePosition());
  1306. }
  1307. TEST_F(TouchSelectionControllerTest, NoHideActiveInsertionHandle) {
  1308. SetHideActiveHandle(false);
  1309. TouchSelectionControllerTestApi test_controller(&controller());
  1310. base::TimeTicks event_time = base::TimeTicks::Now();
  1311. float line_height = 10.f;
  1312. gfx::RectF insertion_rect(10, 0, 0, line_height);
  1313. bool visible = true;
  1314. OnTapEvent();
  1315. ChangeInsertion(insertion_rect, visible);
  1316. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  1317. SetDraggingEnabled(true);
  1318. EXPECT_EQ(1.f, test_controller.GetInsertionHandleAlpha());
  1319. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
  1320. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1321. EXPECT_EQ(1.f, test_controller.GetInsertionHandleAlpha());
  1322. }
  1323. TEST_F(TouchSelectionControllerTest, HideActiveInsertionHandle) {
  1324. SetHideActiveHandle(true);
  1325. TouchSelectionControllerTestApi test_controller(&controller());
  1326. base::TimeTicks event_time = base::TimeTicks::Now();
  1327. float line_height = 10.f;
  1328. gfx::RectF insertion_rect(10, 0, 0, line_height);
  1329. bool visible = true;
  1330. OnTapEvent();
  1331. ChangeInsertion(insertion_rect, visible);
  1332. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  1333. SetDraggingEnabled(true);
  1334. EXPECT_EQ(1.f, test_controller.GetInsertionHandleAlpha());
  1335. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
  1336. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1337. EXPECT_EQ(0.f, test_controller.GetInsertionHandleAlpha());
  1338. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
  1339. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1340. EXPECT_EQ(0.f, test_controller.GetInsertionHandleAlpha());
  1341. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1342. // UP will reset the alpha to visible.
  1343. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
  1344. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1345. EXPECT_EQ(1.f, test_controller.GetInsertionHandleAlpha());
  1346. }
  1347. TEST_F(TouchSelectionControllerTest, NoHideActiveSelectionHandle) {
  1348. SetHideActiveHandle(false);
  1349. TouchSelectionControllerTestApi test_controller(&controller());
  1350. base::TimeTicks event_time = base::TimeTicks::Now();
  1351. float line_height = 10.f;
  1352. gfx::RectF start_rect(10, 0, 0, line_height);
  1353. gfx::RectF end_rect(50, 0, 0, line_height);
  1354. bool visible = true;
  1355. OnLongPressEvent();
  1356. ChangeSelection(start_rect, visible, end_rect, visible);
  1357. // Start handle.
  1358. SetDraggingEnabled(true);
  1359. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1360. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1361. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
  1362. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1363. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1364. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1365. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
  1366. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1367. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1368. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1369. // End handle.
  1370. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 50, 5);
  1371. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1372. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1373. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1374. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1375. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 50, 5);
  1376. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1377. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1378. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1379. }
  1380. TEST_F(TouchSelectionControllerTest, HideActiveSelectionHandle) {
  1381. SetHideActiveHandle(true);
  1382. TouchSelectionControllerTestApi test_controller(&controller());
  1383. base::TimeTicks event_time = base::TimeTicks::Now();
  1384. float line_height = 10.f;
  1385. gfx::RectF start_rect(10, 0, 0, line_height);
  1386. gfx::RectF end_rect(50, 0, 0, line_height);
  1387. bool visible = true;
  1388. OnLongPressEvent();
  1389. ChangeSelection(start_rect, visible, end_rect, visible);
  1390. // Start handle.
  1391. SetDraggingEnabled(true);
  1392. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1393. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1394. MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
  1395. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1396. EXPECT_EQ(0.f, test_controller.GetStartAlpha());
  1397. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1398. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
  1399. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1400. EXPECT_EQ(0.f, test_controller.GetStartAlpha());
  1401. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1402. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1403. // UP will reset alpha to be visible.
  1404. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
  1405. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1406. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1407. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1408. // End handle.
  1409. event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 50, 5);
  1410. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1411. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1412. EXPECT_EQ(0.f, test_controller.GetEndAlpha());
  1413. event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 50, 5);
  1414. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1415. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1416. EXPECT_EQ(0.f, test_controller.GetEndAlpha());
  1417. event_time += base::Milliseconds(2 * kDefaultTapTimeoutMs);
  1418. // UP will reset alpha to be visible.
  1419. event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 50, 5);
  1420. EXPECT_TRUE(controller().WillHandleTouchEvent(event));
  1421. EXPECT_EQ(1.f, test_controller.GetStartAlpha());
  1422. EXPECT_EQ(1.f, test_controller.GetEndAlpha());
  1423. }
  1424. TEST_F(TouchSelectionControllerTest, SwipeToMoveCursor_HideHandlesIfShown) {
  1425. // Step 1: Extra set-up.
  1426. // For Android P+, we need to hide handles while showing magnifier.
  1427. SetHideActiveHandle(true);
  1428. TouchSelectionControllerTestApi test_controller(&controller());
  1429. gfx::RectF insertion_rect(5, 5, 0, 10);
  1430. bool visible = true;
  1431. OnTapEvent();
  1432. ChangeInsertion(insertion_rect, visible);
  1433. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  1434. EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventStart());
  1435. EXPECT_TRUE(test_controller.GetStartVisible());
  1436. // Step 2: Swipe-to-move-cursor begins: hide handles.
  1437. controller().OnSwipeToMoveCursorBegin();
  1438. EXPECT_FALSE(test_controller.GetStartVisible());
  1439. // Step 3: Move insertion: still hidden.
  1440. gfx::RectF new_insertion_rect(10, 5, 0, 10);
  1441. ChangeInsertion(new_insertion_rect, visible);
  1442. EXPECT_FALSE(test_controller.GetStartVisible());
  1443. // Step 4: Swipe-to-move-cursor ends: show handles.
  1444. controller().OnSwipeToMoveCursorEnd();
  1445. EXPECT_TRUE(test_controller.GetStartVisible());
  1446. }
  1447. TEST_F(TouchSelectionControllerTest, SwipeToMoveCursor_HandleWasNotShown) {
  1448. // Step 1: Extra set-up.
  1449. // For Android P+, we need to hide handles while showing magnifier.
  1450. SetHideActiveHandle(true);
  1451. TouchSelectionControllerTestApi test_controller(&controller());
  1452. gfx::RectF insertion_rect(5, 5, 0, 10);
  1453. bool visible = true;
  1454. OnTapEvent();
  1455. ChangeInsertion(insertion_rect, visible);
  1456. EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
  1457. EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventStart());
  1458. EXPECT_TRUE(test_controller.GetStartVisible());
  1459. // Step 2: Handle is initially hidden, i.e., due to user typing.
  1460. controller().HideAndDisallowShowingAutomatically();
  1461. EXPECT_FALSE(test_controller.GetStartVisible());
  1462. // Step 3: Swipe-to-move-cursor begins: hide handles.
  1463. controller().OnSwipeToMoveCursorBegin();
  1464. EXPECT_FALSE(test_controller.GetStartVisible());
  1465. // Step 4: Move insertion.
  1466. // Note that this step is needed to show handle at the end since
  1467. // OnInsertionChanged() should activate start_ again, although it will stay
  1468. // temporarily hidden.
  1469. gfx::RectF new_insertion_rect(10, 5, 0, 10);
  1470. ChangeInsertion(new_insertion_rect, visible);
  1471. EXPECT_FALSE(test_controller.GetStartVisible());
  1472. // Step 5: Swipe-to-move-cursor ends: show handles.
  1473. controller().OnSwipeToMoveCursorEnd();
  1474. EXPECT_TRUE(test_controller.GetStartVisible());
  1475. }
  1476. } // namespace ui