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.
5 #include "ui/touch_selection/touch_selection_controller.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/events/test/motion_event_test_utils.h"
13 using testing::ElementsAre
;
14 using testing::IsEmpty
;
15 using ui::test::MockMotionEvent
;
20 const int kDefaultTapTimeoutMs
= 200;
21 const float kDefaulTapSlop
= 10.f
;
22 const gfx::PointF
kIgnoredPoint(0, 0);
24 class MockTouchHandleDrawable
: public TouchHandleDrawable
{
26 explicit MockTouchHandleDrawable(bool* contains_point
)
27 : intersects_rect_(contains_point
) {}
28 ~MockTouchHandleDrawable() override
{}
29 void SetEnabled(bool enabled
) override
{}
30 void SetOrientation(TouchHandleOrientation orientation
) override
{}
31 void SetAlpha(float alpha
) override
{}
32 void SetFocus(const gfx::PointF
& position
) override
{}
33 gfx::RectF
GetVisibleBounds() const override
{
34 return *intersects_rect_
? gfx::RectF(-1000, -1000, 2000, 2000)
35 : gfx::RectF(-1000, -1000, 0, 0);
39 bool* intersects_rect_
;
41 DISALLOW_COPY_AND_ASSIGN(MockTouchHandleDrawable
);
46 class TouchSelectionControllerTest
: public testing::Test
,
47 public TouchSelectionControllerClient
{
49 TouchSelectionControllerTest()
50 : caret_moved_(false),
51 selection_moved_(false),
52 selection_points_swapped_(false),
53 needs_animate_(false),
54 animation_enabled_(true),
55 dragging_enabled_(false) {}
57 ~TouchSelectionControllerTest() override
{}
59 // testing::Test implementation.
61 void SetUp() override
{
62 // Default touch selection controller is created with
63 // |show_on_tap_for_empty_editable| flag set to false. Use
64 // |AllowShowingOnTapForEmptyEditable()| function to override it.
65 bool show_on_tap_for_empty_editable
= false;
66 controller_
.reset(new TouchSelectionController(
68 base::TimeDelta::FromMilliseconds(kDefaultTapTimeoutMs
),
70 show_on_tap_for_empty_editable
));
73 void TearDown() override
{ controller_
.reset(); }
75 // TouchSelectionControllerClient implementation.
77 bool SupportsAnimation() const override
{ return animation_enabled_
; }
79 void SetNeedsAnimate() override
{ needs_animate_
= true; }
81 void MoveCaret(const gfx::PointF
& position
) override
{
83 caret_position_
= position
;
86 void SelectBetweenCoordinates(const gfx::PointF
& base
,
87 const gfx::PointF
& extent
) override
{
88 if (base
== selection_end_
&& extent
== selection_start_
)
89 selection_points_swapped_
= true;
91 selection_start_
= base
;
92 selection_end_
= extent
;
95 void MoveRangeSelectionExtent(const gfx::PointF
& extent
) override
{
96 selection_moved_
= true;
97 selection_end_
= extent
;
100 void OnSelectionEvent(SelectionEventType event
) override
{
101 events_
.push_back(event
);
102 last_event_start_
= controller_
->GetStartPosition();
103 last_event_end_
= controller_
->GetEndPosition();
106 scoped_ptr
<TouchHandleDrawable
> CreateDrawable() override
{
107 return make_scoped_ptr(new MockTouchHandleDrawable(&dragging_enabled_
));
110 void AllowShowingOnTapForEmptyEditable() {
111 bool show_on_tap_for_empty_editable
= true;
112 controller_
.reset(new TouchSelectionController(
114 base::TimeDelta::FromMilliseconds(kDefaultTapTimeoutMs
),
116 show_on_tap_for_empty_editable
));
119 void SetAnimationEnabled(bool enabled
) { animation_enabled_
= enabled
; }
120 void SetDraggingEnabled(bool enabled
) { dragging_enabled_
= enabled
; }
122 void ClearSelection() {
123 controller_
->OnSelectionBoundsChanged(SelectionBound(),
127 void ClearInsertion() { ClearSelection(); }
129 void ChangeInsertion(const gfx::RectF
& rect
, bool visible
) {
130 SelectionBound bound
;
131 bound
.set_type(SelectionBound::CENTER
);
132 bound
.SetEdge(rect
.origin(), rect
.bottom_left());
133 bound
.set_visible(visible
);
134 controller_
->OnSelectionBoundsChanged(bound
, bound
);
137 void ChangeSelection(const gfx::RectF
& start_rect
,
139 const gfx::RectF
& end_rect
,
141 SelectionBound start_bound
, end_bound
;
142 start_bound
.set_type(SelectionBound::LEFT
);
143 end_bound
.set_type(SelectionBound::RIGHT
);
144 start_bound
.SetEdge(start_rect
.origin(), start_rect
.bottom_left());
145 end_bound
.SetEdge(end_rect
.origin(), end_rect
.bottom_left());
146 start_bound
.set_visible(start_visible
);
147 end_bound
.set_visible(end_visible
);
148 controller_
->OnSelectionBoundsChanged(start_bound
, end_bound
);
151 void OnLongPressEvent() {
152 ASSERT_FALSE(controller().WillHandleLongPressEvent(kIgnoredPoint
));
156 ASSERT_FALSE(controller().WillHandleTapEvent(kIgnoredPoint
));
160 base::TimeTicks now
= base::TimeTicks::Now();
161 while (needs_animate_
) {
162 needs_animate_
= controller_
->Animate(now
);
163 now
+= base::TimeDelta::FromMilliseconds(16);
167 bool GetAndResetNeedsAnimate() {
168 bool needs_animate
= needs_animate_
;
170 return needs_animate
;
173 bool GetAndResetCaretMoved() {
174 bool moved
= caret_moved_
;
175 caret_moved_
= false;
179 bool GetAndResetSelectionMoved() {
180 bool moved
= selection_moved_
;
181 selection_moved_
= false;
185 bool GetAndResetSelectionPointsSwapped() {
186 bool swapped
= selection_points_swapped_
;
187 selection_points_swapped_
= false;
191 const gfx::PointF
& GetLastCaretPosition() const { return caret_position_
; }
192 const gfx::PointF
& GetLastSelectionStart() const { return selection_start_
; }
193 const gfx::PointF
& GetLastSelectionEnd() const { return selection_end_
; }
194 const gfx::PointF
& GetLastEventStart() const { return last_event_start_
; }
195 const gfx::PointF
& GetLastEventEnd() const { return last_event_end_
; }
197 std::vector
<SelectionEventType
> GetAndResetEvents() {
198 std::vector
<SelectionEventType
> events
;
199 events
.swap(events_
);
203 TouchSelectionController
& controller() { return *controller_
; }
206 gfx::PointF last_event_start_
;
207 gfx::PointF last_event_end_
;
208 gfx::PointF caret_position_
;
209 gfx::PointF selection_start_
;
210 gfx::PointF selection_end_
;
211 std::vector
<SelectionEventType
> events_
;
213 bool selection_moved_
;
214 bool selection_points_swapped_
;
216 bool animation_enabled_
;
217 bool dragging_enabled_
;
218 scoped_ptr
<TouchSelectionController
> controller_
;
220 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerTest
);
223 TEST_F(TouchSelectionControllerTest
, InsertionBasic
) {
224 gfx::RectF
insertion_rect(5, 5, 0, 10);
227 // Insertion events are ignored until automatic showing is enabled.
228 ChangeInsertion(insertion_rect
, visible
);
229 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
230 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
233 // Insertion events are ignored until the selection region is marked editable.
234 ChangeInsertion(insertion_rect
, visible
);
235 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
236 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
239 controller().OnSelectionEditable(true);
240 ChangeInsertion(insertion_rect
, visible
);
241 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
242 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
244 insertion_rect
.Offset(1, 0);
245 ChangeInsertion(insertion_rect
, visible
);
246 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_MOVED
));
247 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
249 insertion_rect
.Offset(0, 1);
250 ChangeInsertion(insertion_rect
, visible
);
251 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_MOVED
));
252 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
255 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
));
258 TEST_F(TouchSelectionControllerTest
, InsertionClearedWhenNoLongerEditable
) {
259 gfx::RectF
insertion_rect(5, 5, 0, 10);
262 controller().OnSelectionEditable(true);
264 ChangeInsertion(insertion_rect
, visible
);
265 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
266 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
268 controller().OnSelectionEditable(false);
269 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
));
272 TEST_F(TouchSelectionControllerTest
, InsertionWithNoShowOnTapForEmptyEditable
) {
273 gfx::RectF
insertion_rect(5, 5, 0, 10);
275 controller().OnSelectionEditable(true);
277 // Taps on an empty editable region should be ignored if the controller is
278 // created with |show_on_tap_for_empty_editable| set to false.
280 controller().OnSelectionEmpty(true);
281 ChangeInsertion(insertion_rect
, visible
);
282 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
284 // Once the region becomes non-empty, taps should show the insertion handle.
286 controller().OnSelectionEmpty(false);
287 ChangeInsertion(insertion_rect
, visible
);
288 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
289 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
291 // Reset the selection.
292 controller().HideAndDisallowShowingAutomatically();
293 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
));
295 // Long-pressing should show the handle even if the editable region is empty.
296 insertion_rect
.Offset(2, -2);
298 controller().OnSelectionEmpty(true);
299 ChangeInsertion(insertion_rect
, visible
);
300 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
301 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
303 // Single Tap on an empty edit field should clear insertion handle.
305 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
));
308 TEST_F(TouchSelectionControllerTest
, InsertionWithShowOnTapForEmptyEditable
) {
309 AllowShowingOnTapForEmptyEditable();
311 gfx::RectF
insertion_rect(5, 5, 0, 10);
313 controller().OnSelectionEditable(true);
315 // Taps on an empty editable region should show the insertion handle if the
316 // controller is created with |show_on_tap_for_empty_editable| set to true.
318 controller().OnSelectionEmpty(true);
319 ChangeInsertion(insertion_rect
, visible
);
320 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
321 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
323 // Additional taps should not hide the insertion handle in this case.
325 ChangeInsertion(insertion_rect
, visible
);
326 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
329 TEST_F(TouchSelectionControllerTest
, InsertionAppearsAfterTapFollowingTyping
) {
330 gfx::RectF
insertion_rect(5, 5, 0, 10);
333 // Simulate the user tapping an empty text field.
335 controller().OnSelectionEditable(true);
336 controller().OnSelectionEmpty(true);
337 ChangeInsertion(insertion_rect
, visible
);
338 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
340 // Simulate the cursor moving while a user is typing.
341 insertion_rect
.Offset(10, 0);
342 controller().OnSelectionEmpty(false);
343 ChangeInsertion(insertion_rect
, visible
);
344 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
346 // If the user taps the *same* position as the cursor at the end of the text
347 // entry, the handle should appear.
349 ChangeInsertion(insertion_rect
, visible
);
350 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
351 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
354 TEST_F(TouchSelectionControllerTest
, InsertionToSelectionTransition
) {
356 controller().OnSelectionEditable(true);
358 gfx::RectF
start_rect(5, 5, 0, 10);
359 gfx::RectF
end_rect(50, 5, 0, 10);
362 ChangeInsertion(start_rect
, visible
);
363 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
364 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
366 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
367 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
,
369 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
371 ChangeInsertion(end_rect
, visible
);
372 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_CLEARED
,
374 EXPECT_EQ(end_rect
.bottom_left(), GetLastEventStart());
376 controller().HideAndDisallowShowingAutomatically();
377 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
));
380 ChangeInsertion(end_rect
, visible
);
381 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
382 EXPECT_EQ(end_rect
.bottom_left(), GetLastEventStart());
385 TEST_F(TouchSelectionControllerTest
, InsertionDragged
) {
386 base::TimeTicks event_time
= base::TimeTicks::Now();
388 controller().OnSelectionEditable(true);
390 // The touch sequence should not be handled if insertion is not active.
391 MockMotionEvent
event(MockMotionEvent::ACTION_DOWN
, event_time
, 0, 0);
392 EXPECT_FALSE(controller().WillHandleTouchEvent(event
));
394 float line_height
= 10.f
;
395 gfx::RectF
start_rect(10, 0, 0, line_height
);
397 ChangeInsertion(start_rect
, visible
);
398 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
399 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
401 // The touch sequence should be handled only if the drawable reports a hit.
402 EXPECT_FALSE(controller().WillHandleTouchEvent(event
));
403 SetDraggingEnabled(true);
404 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
405 EXPECT_FALSE(GetAndResetCaretMoved());
406 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_DRAG_STARTED
));
408 // The MoveCaret() result should reflect the movement.
409 // The reported position is offset from the center of |start_rect|.
410 gfx::PointF start_offset
= start_rect
.CenterPoint();
411 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
, 0, 5);
412 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
413 EXPECT_TRUE(GetAndResetCaretMoved());
414 EXPECT_EQ(start_offset
+ gfx::Vector2dF(0, 5), GetLastCaretPosition());
416 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
, 5, 5);
417 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
418 EXPECT_TRUE(GetAndResetCaretMoved());
419 EXPECT_EQ(start_offset
+ gfx::Vector2dF(5, 5), GetLastCaretPosition());
421 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
, 10, 10);
422 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
423 EXPECT_TRUE(GetAndResetCaretMoved());
424 EXPECT_EQ(start_offset
+ gfx::Vector2dF(10, 10), GetLastCaretPosition());
426 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 10, 5);
427 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
428 EXPECT_FALSE(GetAndResetCaretMoved());
429 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_DRAG_STOPPED
));
431 // Once the drag is complete, no more touch events should be consumed until
432 // the next ACTION_DOWN.
433 EXPECT_FALSE(controller().WillHandleTouchEvent(event
));
436 TEST_F(TouchSelectionControllerTest
, InsertionTapped
) {
437 base::TimeTicks event_time
= base::TimeTicks::Now();
439 controller().OnSelectionEditable(true);
440 SetDraggingEnabled(true);
442 gfx::RectF
start_rect(10, 0, 0, 10);
444 ChangeInsertion(start_rect
, visible
);
445 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
447 MockMotionEvent
event(MockMotionEvent::ACTION_DOWN
, event_time
, 0, 0);
448 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
449 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_DRAG_STARTED
));
451 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 0, 0);
452 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
453 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_TAPPED
,
454 INSERTION_DRAG_STOPPED
));
456 // Reset the insertion.
459 ChangeInsertion(start_rect
, visible
);
460 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
,
463 // No tap should be signalled if the time between DOWN and UP was too long.
464 event
= MockMotionEvent(MockMotionEvent::ACTION_DOWN
, event_time
, 0, 0);
465 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
466 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
,
467 event_time
+ base::TimeDelta::FromSeconds(1),
470 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
471 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_DRAG_STARTED
,
472 INSERTION_DRAG_STOPPED
));
474 // Reset the insertion.
477 ChangeInsertion(start_rect
, visible
);
478 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
,
481 // No tap should be signalled if the drag was too long.
482 event
= MockMotionEvent(MockMotionEvent::ACTION_DOWN
, event_time
, 0, 0);
483 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
484 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
, 100, 0);
485 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
486 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 100, 0);
487 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
488 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_DRAG_STARTED
,
489 INSERTION_DRAG_STOPPED
));
491 // Reset the insertion.
494 ChangeInsertion(start_rect
, visible
);
495 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_CLEARED
,
498 // No tap should be signalled if the touch sequence is cancelled.
499 event
= MockMotionEvent(MockMotionEvent::ACTION_DOWN
, event_time
, 0, 0);
500 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
501 event
= MockMotionEvent(MockMotionEvent::ACTION_CANCEL
, event_time
, 0, 0);
502 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
503 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_DRAG_STARTED
,
504 INSERTION_DRAG_STOPPED
));
507 TEST_F(TouchSelectionControllerTest
, InsertionNotResetByRepeatedTapOrPress
) {
508 base::TimeTicks event_time
= base::TimeTicks::Now();
510 controller().OnSelectionEditable(true);
511 SetDraggingEnabled(true);
513 gfx::RectF
anchor_rect(10, 0, 0, 10);
515 ChangeInsertion(anchor_rect
, visible
);
516 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
517 EXPECT_EQ(anchor_rect
.bottom_left(), GetLastEventStart());
519 // Tapping again shouldn't reset the active insertion point.
521 MockMotionEvent
event(MockMotionEvent::ACTION_DOWN
, event_time
, 0, 0);
522 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
523 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_DRAG_STARTED
));
524 EXPECT_EQ(anchor_rect
.bottom_left(), GetLastEventStart());
526 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 0, 0);
527 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
528 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_TAPPED
,
529 INSERTION_DRAG_STOPPED
));
530 EXPECT_EQ(anchor_rect
.bottom_left(), GetLastEventStart());
532 anchor_rect
.Offset(5, 15);
533 ChangeInsertion(anchor_rect
, visible
);
534 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_MOVED
));
535 EXPECT_EQ(anchor_rect
.bottom_left(), GetLastEventStart());
537 // Pressing shouldn't reset the active insertion point.
539 controller().OnSelectionEmpty(true);
540 event
= MockMotionEvent(MockMotionEvent::ACTION_DOWN
, event_time
, 0, 0);
541 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
542 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_DRAG_STARTED
));
543 EXPECT_EQ(anchor_rect
.bottom_left(), GetLastEventStart());
545 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 0, 0);
546 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
547 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_TAPPED
,
548 INSERTION_DRAG_STOPPED
));
549 EXPECT_EQ(anchor_rect
.bottom_left(), GetLastEventStart());
552 TEST_F(TouchSelectionControllerTest
, SelectionBasic
) {
553 gfx::RectF
start_rect(5, 5, 0, 10);
554 gfx::RectF
end_rect(50, 5, 0, 10);
557 // Selection events are ignored until automatic showing is enabled.
558 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
559 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
562 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
563 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
564 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
566 start_rect
.Offset(1, 0);
567 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
568 // Selection movement does not currently trigger a separate event.
569 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_MOVED
));
570 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
571 EXPECT_EQ(end_rect
.bottom_left(), GetLastEventEnd());
574 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_CLEARED
));
575 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
578 TEST_F(TouchSelectionControllerTest
, SelectionRepeatedLongPress
) {
579 gfx::RectF
start_rect(5, 5, 0, 10);
580 gfx::RectF
end_rect(50, 5, 0, 10);
584 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
585 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
586 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
587 EXPECT_EQ(end_rect
.bottom_left(), GetLastEventEnd());
589 // A long press triggering a new selection should re-send the SELECTION_SHOWN
590 // event notification.
591 start_rect
.Offset(10, 10);
593 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
594 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
595 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
596 EXPECT_EQ(end_rect
.bottom_left(), GetLastEventEnd());
599 TEST_F(TouchSelectionControllerTest
, SelectionDragged
) {
600 base::TimeTicks event_time
= base::TimeTicks::Now();
603 // The touch sequence should not be handled if selection is not active.
604 MockMotionEvent
event(MockMotionEvent::ACTION_DOWN
, event_time
, 0, 0);
605 EXPECT_FALSE(controller().WillHandleTouchEvent(event
));
607 float line_height
= 10.f
;
608 gfx::RectF
start_rect(0, 0, 0, line_height
);
609 gfx::RectF
end_rect(50, 0, 0, line_height
);
611 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
612 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
613 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
615 // The touch sequence should be handled only if the drawable reports a hit.
616 EXPECT_FALSE(controller().WillHandleTouchEvent(event
));
617 SetDraggingEnabled(true);
618 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
619 EXPECT_FALSE(GetAndResetSelectionMoved());
621 // The SelectBetweenCoordinates() result should reflect the movement. Note
622 // that the start coordinate will always reflect the "fixed" handle's
623 // position, in this case the position from |end_rect|.
624 // Note that the reported position is offset from the center of the
625 // input rects (i.e., the middle of the corresponding text line).
626 gfx::PointF fixed_offset
= end_rect
.CenterPoint();
627 gfx::PointF start_offset
= start_rect
.CenterPoint();
628 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
, 0, 5);
629 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
630 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STARTED
));
631 EXPECT_TRUE(GetAndResetSelectionMoved());
632 EXPECT_EQ(fixed_offset
, GetLastSelectionStart());
633 EXPECT_EQ(start_offset
+ gfx::Vector2dF(0, 5), GetLastSelectionEnd());
635 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
, 5, 5);
636 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
637 EXPECT_TRUE(GetAndResetSelectionMoved());
638 EXPECT_EQ(fixed_offset
, GetLastSelectionStart());
639 EXPECT_EQ(start_offset
+ gfx::Vector2dF(5, 5), GetLastSelectionEnd());
641 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
, 10, 5);
642 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
643 EXPECT_TRUE(GetAndResetSelectionMoved());
644 EXPECT_EQ(fixed_offset
, GetLastSelectionStart());
645 EXPECT_EQ(start_offset
+ gfx::Vector2dF(10, 5), GetLastSelectionEnd());
647 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 10, 5);
648 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
649 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STOPPED
));
650 EXPECT_FALSE(GetAndResetSelectionMoved());
652 // Once the drag is complete, no more touch events should be consumed until
653 // the next ACTION_DOWN.
654 EXPECT_FALSE(controller().WillHandleTouchEvent(event
));
657 TEST_F(TouchSelectionControllerTest
, SelectionDraggedWithOverlap
) {
658 base::TimeTicks event_time
= base::TimeTicks::Now();
661 float line_height
= 10.f
;
662 gfx::RectF
start_rect(0, 0, 0, line_height
);
663 gfx::RectF
end_rect(50, 0, 0, line_height
);
665 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
666 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
667 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
669 // The ACTION_DOWN should lock to the closest handle.
670 gfx::PointF end_offset
= end_rect
.CenterPoint();
671 gfx::PointF fixed_offset
= start_rect
.CenterPoint();
672 float touch_down_x
= (end_offset
.x() + fixed_offset
.x()) / 2 + 1.f
;
673 MockMotionEvent
event(
674 MockMotionEvent::ACTION_DOWN
, event_time
, touch_down_x
, 0);
675 SetDraggingEnabled(true);
676 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
677 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STARTED
));
678 EXPECT_FALSE(GetAndResetSelectionMoved());
680 // Even though the ACTION_MOVE is over the start handle, it should continue
681 // targetting the end handle that consumed the ACTION_DOWN.
682 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
, 0, 0);
683 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
684 EXPECT_TRUE(GetAndResetSelectionMoved());
685 EXPECT_EQ(fixed_offset
, GetLastSelectionStart());
686 EXPECT_EQ(end_offset
- gfx::Vector2dF(touch_down_x
, 0),
687 GetLastSelectionEnd());
689 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 0, 0);
690 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
691 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STOPPED
));
692 EXPECT_FALSE(GetAndResetSelectionMoved());
695 TEST_F(TouchSelectionControllerTest
, SelectionDraggedToSwitchBaseAndExtent
) {
696 base::TimeTicks event_time
= base::TimeTicks::Now();
699 float line_height
= 10.f
;
700 gfx::RectF
start_rect(50, line_height
, 0, line_height
);
701 gfx::RectF
end_rect(100, line_height
, 0, line_height
);
703 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
704 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
705 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
707 SetDraggingEnabled(true);
709 // Move the extent, not triggering a swap of points.
710 MockMotionEvent
event(MockMotionEvent::ACTION_DOWN
, event_time
,
711 end_rect
.x(), end_rect
.bottom());
712 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
713 EXPECT_FALSE(GetAndResetSelectionMoved());
714 EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
716 gfx::PointF base_offset
= start_rect
.CenterPoint();
717 gfx::PointF extent_offset
= end_rect
.CenterPoint();
718 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
,
719 end_rect
.x(), end_rect
.bottom() + 5);
720 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
721 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STARTED
));
722 EXPECT_TRUE(GetAndResetSelectionMoved());
723 EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
724 EXPECT_EQ(base_offset
, GetLastSelectionStart());
725 EXPECT_EQ(extent_offset
+ gfx::Vector2dF(0, 5), GetLastSelectionEnd());
727 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 10, 5);
728 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
729 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STOPPED
));
730 EXPECT_FALSE(GetAndResetSelectionMoved());
732 end_rect
+= gfx::Vector2dF(0, 5);
733 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
734 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_MOVED
));
736 // Move the base, triggering a swap of points.
737 event
= MockMotionEvent(MockMotionEvent::ACTION_DOWN
, event_time
,
738 start_rect
.x(), start_rect
.bottom());
739 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
740 EXPECT_FALSE(GetAndResetSelectionMoved());
741 EXPECT_TRUE(GetAndResetSelectionPointsSwapped());
743 base_offset
= end_rect
.CenterPoint();
744 extent_offset
= start_rect
.CenterPoint();
745 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
,
746 start_rect
.x(), start_rect
.bottom() + 5);
747 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
748 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STARTED
));
749 EXPECT_TRUE(GetAndResetSelectionMoved());
750 EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
751 EXPECT_EQ(base_offset
, GetLastSelectionStart());
752 EXPECT_EQ(extent_offset
+ gfx::Vector2dF(0, 5), GetLastSelectionEnd());
754 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 10, 5);
755 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
756 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STOPPED
));
757 EXPECT_FALSE(GetAndResetSelectionMoved());
759 start_rect
+= gfx::Vector2dF(0, 5);
760 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
761 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_MOVED
));
763 // Move the same point again, not triggering a swap of points.
764 event
= MockMotionEvent(MockMotionEvent::ACTION_DOWN
, event_time
,
765 start_rect
.x(), start_rect
.bottom());
766 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
767 EXPECT_FALSE(GetAndResetSelectionMoved());
768 EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
770 base_offset
= end_rect
.CenterPoint();
771 extent_offset
= start_rect
.CenterPoint();
772 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
,
773 start_rect
.x(), start_rect
.bottom() + 5);
774 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
775 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STARTED
));
776 EXPECT_TRUE(GetAndResetSelectionMoved());
777 EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
778 EXPECT_EQ(base_offset
, GetLastSelectionStart());
779 EXPECT_EQ(extent_offset
+ gfx::Vector2dF(0, 5), GetLastSelectionEnd());
781 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 10, 5);
782 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
783 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STOPPED
));
784 EXPECT_FALSE(GetAndResetSelectionMoved());
786 start_rect
+= gfx::Vector2dF(0, 5);
787 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
788 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_MOVED
));
790 // Move the base, triggering a swap of points.
791 event
= MockMotionEvent(MockMotionEvent::ACTION_DOWN
, event_time
,
792 end_rect
.x(), end_rect
.bottom());
793 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
794 EXPECT_FALSE(GetAndResetSelectionMoved());
795 EXPECT_TRUE(GetAndResetSelectionPointsSwapped());
797 base_offset
= start_rect
.CenterPoint();
798 extent_offset
= end_rect
.CenterPoint();
799 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
,
800 end_rect
.x(), end_rect
.bottom() + 5);
801 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
802 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STARTED
));
803 EXPECT_TRUE(GetAndResetSelectionMoved());
804 EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
805 EXPECT_EQ(base_offset
, GetLastSelectionStart());
806 EXPECT_EQ(extent_offset
+ gfx::Vector2dF(0, 5), GetLastSelectionEnd());
808 event
= MockMotionEvent(MockMotionEvent::ACTION_UP
, event_time
, 10, 5);
809 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
810 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STOPPED
));
811 EXPECT_FALSE(GetAndResetSelectionMoved());
814 TEST_F(TouchSelectionControllerTest
, SelectionDragExtremeLineSize
) {
815 base::TimeTicks event_time
= base::TimeTicks::Now();
818 float small_line_height
= 1.f
;
819 float large_line_height
= 50.f
;
820 gfx::RectF
small_line_rect(0, 0, 0, small_line_height
);
821 gfx::RectF
large_line_rect(50, 50, 0, large_line_height
);
823 ChangeSelection(small_line_rect
, visible
, large_line_rect
, visible
);
824 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
825 EXPECT_EQ(small_line_rect
.bottom_left(), GetLastEventStart());
827 // Start dragging the handle on the small line.
828 MockMotionEvent
event(MockMotionEvent::ACTION_DOWN
, event_time
,
829 small_line_rect
.x(), small_line_rect
.y());
830 SetDraggingEnabled(true);
831 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
832 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_DRAG_STARTED
));
833 // The drag coordinate for large lines should be capped to a reasonable
834 // offset, allowing seamless transition to neighboring lines with different
835 // sizes. The drag coordinate for small lines should have an offset
836 // commensurate with the small line size.
837 EXPECT_EQ(large_line_rect
.bottom_left() - gfx::Vector2dF(0, 5.f
),
838 GetLastSelectionStart());
839 EXPECT_EQ(small_line_rect
.CenterPoint(), GetLastSelectionEnd());
841 small_line_rect
+= gfx::Vector2dF(25.f
, 0);
842 event
= MockMotionEvent(MockMotionEvent::ACTION_MOVE
, event_time
,
843 small_line_rect
.x(), small_line_rect
.y());
844 EXPECT_TRUE(controller().WillHandleTouchEvent(event
));
845 EXPECT_TRUE(GetAndResetSelectionMoved());
846 EXPECT_EQ(small_line_rect
.CenterPoint(), GetLastSelectionEnd());
849 TEST_F(TouchSelectionControllerTest
, Animation
) {
851 controller().OnSelectionEditable(true);
853 gfx::RectF
insertion_rect(5, 5, 0, 10);
856 ChangeInsertion(insertion_rect
, visible
);
857 EXPECT_FALSE(GetAndResetNeedsAnimate());
860 ChangeInsertion(insertion_rect
, visible
);
861 EXPECT_TRUE(GetAndResetNeedsAnimate());
864 ChangeInsertion(insertion_rect
, visible
);
865 EXPECT_TRUE(GetAndResetNeedsAnimate());
867 // If the handles are explicity hidden, no animation should be triggered.
868 controller().HideAndDisallowShowingAutomatically();
869 EXPECT_FALSE(GetAndResetNeedsAnimate());
871 // If the client doesn't support animation, no animation should be triggered.
872 SetAnimationEnabled(false);
875 ChangeInsertion(insertion_rect
, visible
);
876 EXPECT_FALSE(GetAndResetNeedsAnimate());
879 TEST_F(TouchSelectionControllerTest
, TemporarilyHidden
) {
881 controller().OnSelectionEditable(true);
883 gfx::RectF
insertion_rect(5, 5, 0, 10);
886 ChangeInsertion(insertion_rect
, visible
);
887 EXPECT_FALSE(GetAndResetNeedsAnimate());
889 controller().SetTemporarilyHidden(true);
890 EXPECT_TRUE(GetAndResetNeedsAnimate());
893 ChangeInsertion(insertion_rect
, visible
);
894 EXPECT_FALSE(GetAndResetNeedsAnimate());
897 ChangeInsertion(insertion_rect
, visible
);
898 EXPECT_FALSE(GetAndResetNeedsAnimate());
900 controller().SetTemporarilyHidden(false);
901 EXPECT_TRUE(GetAndResetNeedsAnimate());
904 TEST_F(TouchSelectionControllerTest
, SelectionClearOnTap
) {
905 gfx::RectF
start_rect(5, 5, 0, 10);
906 gfx::RectF
end_rect(50, 5, 0, 10);
910 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
911 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
913 // Selection should not be cleared if the selection bounds have not changed.
915 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
916 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
920 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_CLEARED
));
921 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
924 TEST_F(TouchSelectionControllerTest
, NoSelectionAfterLongpressThenTap
) {
925 gfx::RectF
start_rect(5, 5, 0, 10);
926 gfx::RectF
end_rect(50, 5, 0, 10);
929 // Tap-triggered selections should not be allowed.
932 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
933 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
935 // Subsequent longpress selections will be allowed.
937 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
938 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
940 // Tapping again shouldn't have any effect on subsequent selection events.
942 end_rect
.Offset(10, 10);
943 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
944 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_MOVED
));
946 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_CLEARED
));
949 TEST_F(TouchSelectionControllerTest
, AllowShowingFromCurrentSelection
) {
950 gfx::RectF
start_rect(5, 5, 0, 10);
951 gfx::RectF
end_rect(50, 5, 0, 10);
954 // The selection should not be activated, as it wasn't yet allowed.
955 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
956 EXPECT_EQ(gfx::PointF(), GetLastEventStart());
958 // A longpress should have no immediate effect.
961 // Now explicitly allow showing from the previously supplied bounds.
962 controller().AllowShowingFromCurrentSelection();
963 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
964 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
966 // Repeated calls to show from the current selection should be ignored.
967 controller().AllowShowingFromCurrentSelection();
968 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
969 EXPECT_EQ(start_rect
.bottom_left(), GetLastEventStart());
971 // Trying to show from an empty selection will have no result.
973 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_CLEARED
));
974 controller().AllowShowingFromCurrentSelection();
975 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
977 // Showing the insertion handle should also be supported.
978 controller().OnSelectionEditable(true);
979 controller().OnSelectionEmpty(false);
980 controller().HideAndDisallowShowingAutomatically();
981 gfx::RectF
insertion_rect(5, 5, 0, 10);
982 ChangeInsertion(insertion_rect
, visible
);
983 controller().AllowShowingFromCurrentSelection();
984 EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_SHOWN
));
985 EXPECT_EQ(insertion_rect
.bottom_left(), GetLastEventStart());
988 TEST_F(TouchSelectionControllerTest
, HandlesShowOnTapInsideRect
) {
989 bool visible
= false;
990 gfx::RectF
start_rect(5, 5, 0, 10);
991 gfx::RectF
end_rect(50, 5, 0, 10);
992 gfx::PointF
inner_point(25, 10);
993 gfx::PointF
outer_point(100, 100);
995 // Establish a selection without handles from 5 to 50 with height 10.
996 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
997 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
999 // A point outside the rect should not be handled.
1000 EXPECT_FALSE(controller().WillHandleTapEvent(outer_point
));
1001 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
1003 // A point inside the rect should be handled.
1004 EXPECT_TRUE(controller().WillHandleTapEvent(inner_point
));
1005 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));
1008 TEST_F(TouchSelectionControllerTest
, HandlesShowOnLongPressInsideRect
) {
1009 bool visible
= false;
1010 gfx::RectF
start_rect(5, 5, 0, 10);
1011 gfx::RectF
end_rect(50, 5, 0, 10);
1012 gfx::PointF
inner_point(25, 10);
1013 gfx::PointF
outer_point(100, 100);
1015 // Establish a selection without handles from 5 to 50 with height 10.
1016 ChangeSelection(start_rect
, visible
, end_rect
, visible
);
1017 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
1019 // A point outside the rect should not be handled.
1020 EXPECT_FALSE(controller().WillHandleLongPressEvent(outer_point
));
1021 EXPECT_THAT(GetAndResetEvents(), IsEmpty());
1023 // A point inside the rect should be handled.
1024 EXPECT_TRUE(controller().WillHandleLongPressEvent(inner_point
));
1025 EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_SHOWN
));