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

Side by Side Diff: content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.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 blink issue fixed: r200194 Created 5 years, 4 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 "content/browser/renderer_host/input/touch_selection_controller_client_ aura.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/run_loop.h"
9 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
10 #include "content/browser/web_contents/web_contents_impl.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "content/public/test/content_browser_test.h"
13 #include "content/public/test/content_browser_test_utils.h"
14 #include "content/shell/browser/shell.h"
15 #include "ui/aura/window.h"
16 #include "ui/aura/window_tree_host.h"
17 #include "ui/events/event_utils.h"
18 #include "ui/events/test/event_generator.h"
19 #include "ui/touch_selection/touch_selection_controller_test_api.h"
20
21 namespace content {
22 namespace {
23
24 bool JSONToPoint(const std::string& str, gfx::PointF* point) {
25 scoped_ptr<base::Value> value = base::JSONReader::Read(str);
26 if (!value)
27 return false;
28 base::DictionaryValue* root;
29 if (!value->GetAsDictionary(&root))
30 return false;
31 double x, y;
32 if (!root->GetDouble("x", &x))
33 return false;
34 if (!root->GetDouble("y", &y))
35 return false;
36 point->set_x(x);
37 point->set_y(y);
38 return true;
39 }
40
41 // A mock touch selection menu runner to use whenever a default one is not
42 // installed.
43 class TestTouchSelectionMenuRunner : public ui::TouchSelectionMenuRunner {
44 public:
45 TestTouchSelectionMenuRunner() : menu_opened_(false) {}
46 ~TestTouchSelectionMenuRunner() override {}
47
48 private:
49 void OpenMenu(ui::TouchSelectionMenuClient* client,
50 const gfx::Rect& anchor_rect,
51 const gfx::Size& handle_image_size,
52 aura::Window* context) override {
53 menu_opened_ = true;
54 }
55
56 void CloseMenu() override { menu_opened_ = false; }
57
58 bool IsRunning() const override { return menu_opened_; }
59
60 bool menu_opened_;
61
62 DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionMenuRunner);
63 };
64
65 } // namespace
66
67 class TestTouchSelectionControllerClientAura
68 : public TouchSelectionControllerClientAura {
69 public:
70 explicit TestTouchSelectionControllerClientAura(
71 RenderWidgetHostViewAura* rwhva)
72 : TouchSelectionControllerClientAura(rwhva),
73 expected_event_(ui::SELECTION_HANDLES_SHOWN) {
74 show_quick_menu_immediately_for_test_ = true;
75 }
76
77 ~TestTouchSelectionControllerClientAura() override {}
78
79 void InitWaitForSelectionEvent(ui::SelectionEventType expected_event) {
80 DCHECK(!run_loop_);
81 expected_event_ = expected_event;
82 run_loop_.reset(new base::RunLoop());
83 }
84
85 void Wait() {
86 DCHECK(run_loop_);
87 run_loop_->Run();
88 run_loop_.reset();
89 }
90
91 private:
92 // TouchSelectionControllerClientAura:
93 void OnSelectionEvent(ui::SelectionEventType event) override {
94 TouchSelectionControllerClientAura::OnSelectionEvent(event);
95 if (run_loop_ && event == expected_event_)
96 run_loop_->Quit();
97 }
98
99 bool IsCommandIdEnabled(int command_id) const override {
100 // Return true so that quick menu has something to show.
101 return true;
102 }
103
104 ui::SelectionEventType expected_event_;
105 scoped_ptr<base::RunLoop> run_loop_;
106
107 DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionControllerClientAura);
108 };
109
110 class TouchSelectionControllerClientAuraTest : public ContentBrowserTest {
111 public:
112 TouchSelectionControllerClientAuraTest() {}
113 ~TouchSelectionControllerClientAuraTest() override {}
114
115 protected:
116 // Starts the test server and navigates to the given url. Sets a large enough
117 // size to the root window. Returns after the navigation to the url is
118 // complete.
119 void StartTestWithPage(const std::string& url) {
120 ASSERT_TRUE(test_server()->Start());
121 GURL test_url(test_server()->GetURL(url));
122 NavigateToURL(shell(), test_url);
123 aura::Window* content = shell()->web_contents()->GetContentNativeView();
124 content->GetHost()->SetBounds(gfx::Rect(800, 600));
125 }
126
127 bool GetPointInsideText(gfx::PointF* point) {
128 std::string str;
129 if (ExecuteScriptAndExtractString(shell()->web_contents()->GetMainFrame(),
130 "get_point_inside_text()", &str)) {
131 return JSONToPoint(str, point);
132 }
133 return false;
134 }
135
136 bool GetPointInsideTextfield(gfx::PointF* point) {
137 std::string str;
138 if (ExecuteScriptAndExtractString(shell()->web_contents()->GetMainFrame(),
139 "get_point_inside_textfield()", &str)) {
140 return JSONToPoint(str, point);
141 }
142 return false;
143 }
144
145 private:
146 void SetUpOnMainThread() override {
147 ContentBrowserTest::SetUpOnMainThread();
148 if (!ui::TouchSelectionMenuRunner::GetInstance())
149 menu_runner_.reset(new TestTouchSelectionMenuRunner);
150 }
151
152 void TearDownOnMainThread() override {
153 menu_runner_ = nullptr;
154 ContentBrowserTest::TearDownOnMainThread();
155 }
156
157 scoped_ptr<TestTouchSelectionMenuRunner> menu_runner_;
158
159 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerClientAuraTest);
160 };
161
162 // Tests if long-pressing on a text brings up selection handles and the quick
163 // menu properly.
164 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicSelection) {
165 // Set the test page up.
166 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
167 WebContents* web_contents =
168 static_cast<WebContentsImpl*>(shell()->web_contents());
169 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
170 web_contents->GetRenderWidgetHostView());
171 TestTouchSelectionControllerClientAura* selection_controller_client =
172 new TestTouchSelectionControllerClientAura(rwhva);
173 rwhva->SetSelectionControllerClientForTest(
174 make_scoped_ptr(selection_controller_client));
175
176 EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
177 rwhva->selection_controller()->active_status());
178 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
179
180 // Long-press on the text and wait for handles to appear.
181 selection_controller_client->InitWaitForSelectionEvent(
182 ui::SELECTION_HANDLES_SHOWN);
183
184 gfx::PointF point;
185 ASSERT_TRUE(GetPointInsideText(&point));
186 ui::GestureEvent long_press(
187 point.x(), point.y(), 0, ui::EventTimeForNow(),
188 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
189 rwhva->OnGestureEvent(&long_press);
190
191 selection_controller_client->Wait();
192
193 // Check if selection is active and the quick menu is showing.
194 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
195 rwhva->selection_controller()->active_status());
196 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
197 }
198
199 // Tests if tapping in a textfield brings up the insertion handle and the quick
200 // menu properly.
201 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicInsertion) {
202 // Set the test page up.
203 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
204 WebContents* web_contents =
205 static_cast<WebContentsImpl*>(shell()->web_contents());
206 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
207 web_contents->GetRenderWidgetHostView());
208 TestTouchSelectionControllerClientAura* selection_controller_client =
209 new TestTouchSelectionControllerClientAura(rwhva);
210 rwhva->SetSelectionControllerClientForTest(
211 make_scoped_ptr(selection_controller_client));
212
213 EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
214 rwhva->selection_controller()->active_status());
215 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
216
217 // Tap inside the textfield and wait for the insertion handle to appear.
218 selection_controller_client->InitWaitForSelectionEvent(
219 ui::INSERTION_HANDLE_SHOWN);
220
221 gfx::PointF point;
222 ASSERT_TRUE(GetPointInsideTextfield(&point));
223 ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP);
224 tap_details.set_tap_count(1);
225 ui::GestureEvent tap(point.x(), point.y(), 0, ui::EventTimeForNow(),
226 tap_details);
227 rwhva->OnGestureEvent(&tap);
228
229 selection_controller_client->Wait();
230
231 // Check if insertion is active and the quick menu is showing.
232 EXPECT_EQ(ui::TouchSelectionController::INSERTION_ACTIVE,
233 rwhva->selection_controller()->active_status());
234 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
235 }
236
237 // Tests if the quick menu is hidden whenever a touch point is active.
238 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
239 QuickMenuHiddenOnTouch) {
240 // Set the test page up.
241 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
242 WebContents* web_contents =
243 static_cast<WebContentsImpl*>(shell()->web_contents());
244 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
245 web_contents->GetRenderWidgetHostView());
246 TestTouchSelectionControllerClientAura* selection_controller_client =
247 new TestTouchSelectionControllerClientAura(rwhva);
248 rwhva->SetSelectionControllerClientForTest(
249 make_scoped_ptr(selection_controller_client));
250
251 EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
252 rwhva->selection_controller()->active_status());
253 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
254
255 // Long-press on the text and wait for selection handles to appear.
256 selection_controller_client->InitWaitForSelectionEvent(
257 ui::SELECTION_HANDLES_SHOWN);
258
259 gfx::PointF point;
260 ASSERT_TRUE(GetPointInsideText(&point));
261 ui::GestureEvent long_press(
262 point.x(), point.y(), 0, ui::EventTimeForNow(),
263 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
264 rwhva->OnGestureEvent(&long_press);
265
266 selection_controller_client->Wait();
267
268 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
269 rwhva->selection_controller()->active_status());
270 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
271
272 ui::test::EventGenerator generator(
273 web_contents->GetContentNativeView()->GetRootWindow(),
274 web_contents->GetContentNativeView());
275
276 // Put the first finger down: the quick menu should get hidden.
277 generator.PressTouchId(0);
278 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
279 rwhva->selection_controller()->active_status());
280 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
281
282 // Put a second finger down: the quick menu should remain hidden.
283 generator.PressTouchId(1);
284 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
285 rwhva->selection_controller()->active_status());
286 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
287
288 // Lift the first finger up: the quick menu should still remain hidden.
289 generator.ReleaseTouchId(0);
290 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
291 rwhva->selection_controller()->active_status());
292 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
293
294 // Lift the second finger up: the quick menu should re-appear.
295 generator.ReleaseTouchId(1);
296 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
297 rwhva->selection_controller()->active_status());
298 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
299 }
300
301 // Tests if the quick menu and touch handles are hidden during an scroll.
302 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, HiddenOnScroll) {
303 // Set the test page up.
304 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
305 WebContents* web_contents =
306 static_cast<WebContentsImpl*>(shell()->web_contents());
307 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
308 web_contents->GetRenderWidgetHostView());
309 TestTouchSelectionControllerClientAura* selection_controller_client =
310 new TestTouchSelectionControllerClientAura(rwhva);
311 rwhva->SetSelectionControllerClientForTest(
312 make_scoped_ptr(selection_controller_client));
313 ui::TouchSelectionControllerTestApi selection_controller_test_api(
314 rwhva->selection_controller());
315
316 EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
317 rwhva->selection_controller()->active_status());
318 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
319
320 // Long-press on the text and wait for selection handles to appear.
321 selection_controller_client->InitWaitForSelectionEvent(
322 ui::SELECTION_HANDLES_SHOWN);
323
324 gfx::PointF point;
325 ASSERT_TRUE(GetPointInsideText(&point));
326 ui::GestureEvent long_press(
327 point.x(), point.y(), 0, ui::EventTimeForNow(),
328 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
329 rwhva->OnGestureEvent(&long_press);
330
331 selection_controller_client->Wait();
332
333 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
334 rwhva->selection_controller()->active_status());
335 EXPECT_FALSE(selection_controller_test_api.temporarily_hidden());
336 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
337
338 // Put a finger down: the quick menu should go away, while touch handles stay
339 // there.
340 ui::TouchEvent touch_down(ui::ET_TOUCH_PRESSED, gfx::PointF(10, 10), 0,
341 ui::EventTimeForNow());
342 rwhva->OnTouchEvent(&touch_down);
343 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
344 rwhva->selection_controller()->active_status());
345 EXPECT_FALSE(selection_controller_test_api.temporarily_hidden());
346 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
347
348 // Start scrolling: touch handles should get hidden, while touch selection is
349 // still active.
350 ui::GestureEvent scroll_begin(
351 10, 10, 0, ui::EventTimeForNow(),
352 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN));
353 rwhva->OnGestureEvent(&scroll_begin);
354 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
355 rwhva->selection_controller()->active_status());
356 EXPECT_TRUE(selection_controller_test_api.temporarily_hidden());
357 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
358
359 // End scrolling: touch handles should re-appear.
360 ui::GestureEvent scroll_end(
361 10, 10, 0, ui::EventTimeForNow(),
362 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END));
363 rwhva->OnGestureEvent(&scroll_end);
364 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
365 rwhva->selection_controller()->active_status());
366 EXPECT_FALSE(selection_controller_test_api.temporarily_hidden());
367 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
368
369 // Lift the finger up: the quick menu should re-appear.
370 ui::TouchEvent touch_up(ui::ET_TOUCH_RELEASED, gfx::PointF(10, 10), 0,
371 ui::EventTimeForNow());
372 rwhva->OnTouchEvent(&touch_up);
373 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
374 rwhva->selection_controller()->active_status());
375 EXPECT_FALSE(selection_controller_test_api.temporarily_hidden());
376 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
377 }
378
379 // Tests if touch selection gets deactivated after an overscroll completes.
380 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest,
381 HiddenAfterOverscroll) {
382 // Set the page up.
383 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
384 WebContents* web_contents =
385 static_cast<WebContentsImpl*>(shell()->web_contents());
386 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
387 web_contents->GetRenderWidgetHostView());
388 TestTouchSelectionControllerClientAura* selection_controller_client =
389 new TestTouchSelectionControllerClientAura(rwhva);
390 rwhva->SetSelectionControllerClientForTest(
391 make_scoped_ptr(selection_controller_client));
392
393 EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
394 rwhva->selection_controller()->active_status());
395 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
396
397 // Long-press on the text and wait for touch handles to appear.
398 selection_controller_client->InitWaitForSelectionEvent(
399 ui::SELECTION_HANDLES_SHOWN);
400
401 gfx::PointF point;
402 ASSERT_TRUE(GetPointInsideText(&point));
403 ui::GestureEvent long_press(
404 point.x(), point.y(), 0, ui::EventTimeForNow(),
405 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
406 rwhva->OnGestureEvent(&long_press);
407
408 selection_controller_client->Wait();
409
410 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
411 rwhva->selection_controller()->active_status());
412 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
413
414 // Scroll such that an overscroll is initiated and wait for it to complete:
415 // touch selection should not be active at the end.
416 selection_controller_client->InitWaitForSelectionEvent(
417 ui::SELECTION_HANDLES_CLEARED);
418
419 ui::GestureEvent scroll_begin(
420 10, 10, 0, ui::EventTimeForNow(),
421 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN));
422 rwhva->OnGestureEvent(&scroll_begin);
423
424 ui::GestureEvent scroll_update(
425 210, 10, 0, ui::EventTimeForNow(),
426 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 200, 0));
427 rwhva->OnGestureEvent(&scroll_update);
428
429 ui::GestureEvent scroll_end(
430 210, 10, 0, ui::EventTimeForNow(),
431 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END));
432 rwhva->OnGestureEvent(&scroll_end);
433
434 selection_controller_client->Wait();
435
436 EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
437 rwhva->selection_controller()->active_status());
438 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
439 }
440
441 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698