Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: ui/touch_selection/touch_selection_controller_aura_unittest.cc

Issue 698253004: Reland: Implement Aura side of unified touch text selection for contents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased after addition of touch_handle_orientation file Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/touch_selection/touch_selection_controller_aura.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/aura/test/aura_test_base.h"
9 #include "ui/aura/window.h"
10 #include "ui/events/test/event_generator.h"
11 #include "ui/touch_selection/touch_handle_drawable_aura.h"
12 #include "ui/touch_selection/touch_selection_menu_runner.h"
13
14 namespace ui {
15 namespace {
16
17 // A mock implementation for TouchSelectionMenuRunner used in tests.
18 class TestTouchSelectionMenuRunner : public TouchSelectionMenuRunner {
19 public:
20 TestTouchSelectionMenuRunner() {}
21 ~TestTouchSelectionMenuRunner() override {}
22
23 bool is_running() const { return is_running_; }
24
25 private:
26 // TouchSelectionMenuRunner:
27 void RunMenu(TouchSelectionMenuClient* client,
28 const gfx::Rect& anchor_rect,
29 const gfx::Size& handle_image_size,
30 aura::Window* context) override {
31 is_running_ = true;
32 }
33
34 void CloseMenu() override {
35 is_running_ = false;
36 }
37
38 bool IsRunning() const override {
39 return is_running_;
40 }
41
42 bool is_running_;
43
44 DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionMenuRunner);
45 };
46
47 // Convenience to make constructing a GestureEvent simpler.
48 class GestureEventForTest : public GestureEvent {
49 public:
50 GestureEventForTest(EventType type, int x, int y)
51 : GestureEvent(x, y, 0, base::TimeDelta(),
52 GestureEventDetails(type)) {}
53 };
54
55 // Convenience to make constructing a TouchEvent simpler.
56 class TouchEventForTest : public TouchEvent {
57 public:
58 TouchEventForTest(EventType type, gfx::Point location)
59 : TouchEvent(type, location, 0, base::TimeDelta()) {}
60 };
61
62 } // namespace
63
64 // A subclass of TouchSelectionControllerAura which adds some test functionality
65 // to it.
66 class TestTouchSelectionControllerAura
67 : public TouchSelectionControllerAura {
68 public:
69 TestTouchSelectionControllerAura(TouchSelectionControllerAuraClient* client)
70 : TouchSelectionControllerAura(client),
71 last_drawable_(nullptr) {
72 set_immediate_quick_menu_for_testing(true);
73 }
74
75 ~TestTouchSelectionControllerAura() override {}
76
77 TouchHandleDrawable* last_drawable() const { return last_drawable_; }
78
79 bool is_insertion_active() const {
80 return is_insertion_active_for_testing();
81 }
82
83 bool is_selection_active() const {
84 return is_selection_active_for_testing();
85 }
86
87 protected:
88 // TouchSelectionControllerAura:
89 scoped_ptr<TouchHandleDrawable> CreateDrawable() override {
90 scoped_ptr<TouchHandleDrawable> drawable =
91 TouchSelectionControllerAura::CreateDrawable();
92 last_drawable_ = drawable.get();
93 return drawable;
94 }
95
96 private:
97 TouchHandleDrawable* last_drawable_;
98
99 DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionControllerAura);
100 };
101
102 class TouchSelectionControllerAuraTest
103 : public aura::test::AuraTestBase,
104 public TouchSelectionControllerAuraClient {
105 public:
106 TouchSelectionControllerAuraTest() {}
107 ~TouchSelectionControllerAuraTest() override {}
108
109 protected:
110 void ChangeSelection(const gfx::PointF& start_top,
111 const gfx::PointF& start_bottom,
112 const gfx::PointF& end_top,
113 const gfx::PointF& end_bottom) {
114 SelectionBound start_bound, end_bound;
115 start_bound.set_type(SelectionBound::LEFT);
116 end_bound.set_type(SelectionBound::RIGHT);
117 start_bound.SetEdge(start_top, start_bottom);
118 end_bound.SetEdge(end_top, end_bottom);
119 start_bound.set_visible(true);
120 end_bound.set_visible(true);
121 controller_->OnSelectionBoundsUpdated(start_bound, end_bound);
122 }
123
124 void ChangeInsertion(const gfx::Point& top,
125 const gfx::Point& bottom) {
126 SelectionBound bound;
127 bound.set_type(SelectionBound::CENTER);
128 bound.SetEdge(top, bottom);
129 bound.set_visible(true);
130 controller_->OnSelectionBoundsUpdated(bound, bound);
131 }
132
133 void ClearSelection() {
134 controller_->OnSelectionBoundsUpdated(SelectionBound(), SelectionBound());
135 }
136
137 void ClearInsertion() { ClearSelection(); }
138
139 aura::Window* parent_window() const { return parent_window_.get(); }
140
141 TestTouchSelectionMenuRunner* menu_runner() const {
142 return menu_runner_.get();
143 }
144
145 TestTouchSelectionControllerAura* controller() const {
146 return controller_.get();
147 }
148
149 private:
150 // aura::test::AuraTestBase:
151 void SetUp() override {
152 AuraTestBase::SetUp();
153
154 menu_runner_.reset(new TestTouchSelectionMenuRunner());
155
156 parent_window_.reset(CreateNormalWindow(0, root_window(), nullptr));
157 parent_window_->SetBounds(gfx::Rect(0, 0, 400, 400));
158
159 controller_.reset(new TestTouchSelectionControllerAura(this));
160 }
161
162 void TearDown() override {
163 controller_.reset();
164 parent_window_.reset();
165 menu_runner_.reset();
166
167 AuraTestBase::TearDown();
168 }
169
170 // TouchSelectionControllerAuraClient:
171 void MoveCaret(const gfx::PointF& position) override {}
172
173 void MoveRangeSelectionExtent(const gfx::PointF& extent) override {}
174
175 void SelectBetweenCoordinates(const gfx::PointF& base,
176 const gfx::PointF& extent) override {}
177
178 aura::Window* GetParentWindow() const override {
179 return parent_window_.get();
180 }
181
182 gfx::Rect GetClientBounds() const override {
183 return parent_window_->bounds();
184 }
185
186 bool IsCommandIdEnabled(int command_id) const override { return true; }
187
188 void ExecuteCommand(int command_id, int event_flags) override {}
189
190 void OpenContextMenu(const gfx::PointF& point) override {}
191
192 scoped_ptr<aura::Window> parent_window_;
193 scoped_ptr<TestTouchSelectionControllerAura> controller_;
194 scoped_ptr<TestTouchSelectionMenuRunner> menu_runner_;
195
196 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerAuraTest);
197 };
198
199 // Tests if touch selection quick menu is shown when touch selection is
200 // activated and hidden when touch selection is deactivated.
201 TEST_F(TouchSelectionControllerAuraTest, QuickMenuShowHide) {
202 gfx::Point top(5, 5);
203 gfx::Point bottom(5, 15);
204
205 controller()->OnSelectionEditable(true);
206 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
207 controller()->HandleGestureEvent(&tap);
208 ChangeInsertion(top, bottom);
209 EXPECT_TRUE(controller()->is_insertion_active());
210 EXPECT_FALSE(controller()->is_selection_active());
211 EXPECT_TRUE(menu_runner()->is_running());
212
213 ClearInsertion();
214 EXPECT_FALSE(controller()->is_insertion_active());
215 EXPECT_FALSE(controller()->is_selection_active());
216 EXPECT_FALSE(menu_runner()->is_running());
217 }
218
219 // Tests if touch selection quick menu is hidden during a scroll.
220 TEST_F(TouchSelectionControllerAuraTest, QuickMenuHiddenOnScroll) {
221 gfx::Point top(5, 5);
222 gfx::Point bottom(5, 15);
223
224 controller()->OnSelectionEditable(true);
225 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
226 controller()->HandleGestureEvent(&tap);
227 ChangeInsertion(top, bottom);
228 EXPECT_TRUE(controller()->is_insertion_active());
229 EXPECT_FALSE(controller()->is_selection_active());
230 EXPECT_TRUE(menu_runner()->is_running());
231
232 GestureEventForTest scroll_begin(ET_GESTURE_SCROLL_BEGIN, top.x(), top.y());
233 controller()->HandleGestureEvent(&scroll_begin);
234 EXPECT_TRUE(controller()->is_insertion_active());
235 EXPECT_FALSE(controller()->is_selection_active());
236 EXPECT_FALSE(menu_runner()->is_running());
237
238 GestureEventForTest scroll_end(ET_GESTURE_SCROLL_END, top.x(), top.y());
239 controller()->HandleGestureEvent(&scroll_end);
240 EXPECT_TRUE(controller()->is_insertion_active());
241 EXPECT_FALSE(controller()->is_selection_active());
242 EXPECT_TRUE(menu_runner()->is_running());
243
244 ClearInsertion();
245 EXPECT_FALSE(controller()->is_insertion_active());
246 EXPECT_FALSE(controller()->is_selection_active());
247 EXPECT_FALSE(menu_runner()->is_running());
248 }
249
250 // Tests if touch selection quick menu is hidden while a handle is being
251 // dragged.
252 TEST_F(TouchSelectionControllerAuraTest, QuickMenuHiddenOnHandleDrag) {
253 gfx::Point top(5, 5);
254 gfx::Point bottom(5, 15);
255
256 controller()->OnSelectionEditable(true);
257 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
258 controller()->HandleGestureEvent(&tap);
259 ChangeInsertion(top, bottom);
260 EXPECT_TRUE(controller()->is_insertion_active());
261 EXPECT_FALSE(controller()->is_selection_active());
262 EXPECT_TRUE(menu_runner()->is_running());
263
264 gfx::RectF handle_bounds = controller()->last_drawable()->GetVisibleBounds();
265 gfx::Point drag_point = gfx::ToRoundedPoint(handle_bounds.CenterPoint());
266
267 TouchEventForTest touch_pressed(ET_TOUCH_PRESSED, drag_point);
268 controller()->HandleTouchEvent(&touch_pressed);
269 EXPECT_TRUE(controller()->is_insertion_active());
270 EXPECT_FALSE(controller()->is_selection_active());
271 EXPECT_FALSE(menu_runner()->is_running());
272
273 TouchEventForTest touch_released(ET_TOUCH_RELEASED, drag_point);
274 controller()->HandleTouchEvent(&touch_released);
275 EXPECT_TRUE(controller()->is_insertion_active());
276 EXPECT_FALSE(controller()->is_selection_active());
277 EXPECT_TRUE(menu_runner()->is_running());
278
279 ClearInsertion();
280 EXPECT_FALSE(controller()->is_insertion_active());
281 EXPECT_FALSE(controller()->is_selection_active());
282 EXPECT_FALSE(menu_runner()->is_running());
283 }
284
285 // Tests if taps on selection in an editable text are handled properly.
286 TEST_F(TouchSelectionControllerAuraTest, TapOnEditableSelection) {
287 gfx::Point start_top(5, 5);
288 gfx::Point start_bottom(5, 15);
289 gfx::Point middle(15, 10);
290 gfx::Point end_top(25, 5);
291 gfx::Point end_bottom(25, 15);
292
293 controller()->OnSelectionEditable(true);
294 ChangeSelection(start_top, start_bottom, end_top, end_bottom);
295 EXPECT_FALSE(controller()->is_insertion_active());
296 EXPECT_FALSE(controller()->is_selection_active());
297
298 // When touch selection is inactive, tapping on selection should consume the
299 // event and activate touch selection.
300 GestureEventForTest tap1(ET_GESTURE_TAP, middle.x(), middle.y());
301 controller()->HandleGestureEvent(&tap1);
302 EXPECT_TRUE(tap1.handled());
303 EXPECT_FALSE(controller()->is_insertion_active());
304 EXPECT_TRUE(controller()->is_selection_active());
305
306 // When touch selection is active, tapping on selection should leave the event
307 // unhandled, so that the event can be forwarded to the renderer.
308 GestureEventForTest tap2(ET_GESTURE_TAP, middle.x(), middle.y());
309 controller()->HandleGestureEvent(&tap2);
310 EXPECT_FALSE(tap2.handled());
311 EXPECT_FALSE(controller()->is_insertion_active());
312 EXPECT_TRUE(controller()->is_selection_active());
313
314 ClearSelection();
315 EXPECT_FALSE(controller()->is_insertion_active());
316 EXPECT_FALSE(controller()->is_selection_active());
317 }
318
319 // Tests if taps on selection in a non-editable text are handled properly.
320 TEST_F(TouchSelectionControllerAuraTest, TapOnNonEditableSelection) {
321 gfx::Point start_top(5, 5);
322 gfx::Point start_bottom(5, 15);
323 gfx::Point middle(15, 10);
324 gfx::Point end_top(25, 5);
325 gfx::Point end_bottom(25, 15);
326
327 controller()->OnSelectionEditable(false);
328 ChangeSelection(start_top, start_bottom, end_top, end_bottom);
329 EXPECT_FALSE(controller()->is_insertion_active());
330 EXPECT_FALSE(controller()->is_selection_active());
331
332 // When touch selection is inactive, tapping on selection should consume the
333 // event and activate touch selection.
334 GestureEventForTest tap1(ET_GESTURE_TAP, middle.x(), middle.y());
335 controller()->HandleGestureEvent(&tap1);
336 EXPECT_TRUE(tap1.handled());
337 EXPECT_FALSE(controller()->is_insertion_active());
338 EXPECT_TRUE(controller()->is_selection_active());
339
340 // When touch selection is active, tapping on selection should consume the
341 // event to prevent it from being forwarded to the renderer.
342 GestureEventForTest tap2(ET_GESTURE_TAP, middle.x(), middle.y());
343 controller()->HandleGestureEvent(&tap2);
344 EXPECT_TRUE(tap2.handled());
345 EXPECT_FALSE(controller()->is_insertion_active());
346 EXPECT_TRUE(controller()->is_selection_active());
347
348 ClearSelection();
349 EXPECT_FALSE(controller()->is_insertion_active());
350 EXPECT_FALSE(controller()->is_selection_active());
351 }
352
353 // Tests if touch selection is deactivated on a key event.
354 TEST_F(TouchSelectionControllerAuraTest, DeactivatedOnKeyEvent) {
355 gfx::Point top(5, 5);
356 gfx::Point bottom(5, 15);
357
358 RunAllPendingInMessageLoop();
359 controller()->OnSelectionEditable(true);
360 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
361 controller()->HandleGestureEvent(&tap);
362 ChangeInsertion(top, bottom);
363 EXPECT_TRUE(controller()->is_insertion_active());
364 EXPECT_FALSE(controller()->is_selection_active());
365
366 test::EventGenerator generator(root_window());
367 generator.PressKey(VKEY_A, 0);
368 RunAllPendingInMessageLoop();
369 EXPECT_FALSE(controller()->is_insertion_active());
370 EXPECT_FALSE(controller()->is_selection_active());
371 }
372
373 // Tests if touch selection is deactivated on a mouse event.
374 TEST_F(TouchSelectionControllerAuraTest, DeactivatedOnMouseEvent) {
375 gfx::Point top(5, 5);
376 gfx::Point bottom(5, 15);
377
378 RunAllPendingInMessageLoop();
379 controller()->OnSelectionEditable(true);
380 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
381 controller()->HandleGestureEvent(&tap);
382 ChangeInsertion(top, bottom);
383 EXPECT_TRUE(controller()->is_insertion_active());
384 EXPECT_FALSE(controller()->is_selection_active());
385
386 test::EventGenerator generator(root_window());
387 generator.set_current_location(top);
388 RunAllPendingInMessageLoop();
389 generator.MoveMouseTo(bottom);
390 RunAllPendingInMessageLoop();
391 EXPECT_FALSE(controller()->is_insertion_active());
392 EXPECT_FALSE(controller()->is_selection_active());
393 }
394
395 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698