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

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

Powered by Google App Engine
This is Rietveld 408576698