1 // Copyright (c) 2012 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 "content/browser/web_contents/touch_editable_impl_aura.h"
7 #include "base/command_line.h"
8 #include "base/run_loop.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/test/test_timeouts.h"
11 #include "base/values.h"
12 #include "content/browser/web_contents/web_contents_impl.h"
13 #include "content/browser/web_contents/web_contents_view_aura.h"
14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/public/test/browser_test_utils.h"
17 #include "content/public/test/content_browser_test.h"
18 #include "content/public/test/content_browser_test_utils.h"
19 #include "content/public/test/test_utils.h"
20 #include "content/shell/browser/shell.h"
21 #include "third_party/WebKit/public/web/WebInputEvent.h"
22 #include "ui/aura/window.h"
23 #include "ui/aura/window_tree_host.h"
24 #include "ui/base/ui_base_switches.h"
25 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
26 #include "ui/events/event_utils.h"
27 #include "ui/events/test/event_generator.h"
28 #include "ui/wm/core/default_screen_position_client.h"
30 using blink::WebInputEvent
;
34 class TestTouchEditableImplAura
: public TouchEditableImplAura
{
36 TestTouchEditableImplAura()
37 : overscroll_started_callback_arrived_(false),
38 waiting_for_overscroll_started_callback_(false),
39 overscroll_completed_callback_arrived_(false),
40 waiting_for_overscroll_completed_callback_(false),
41 selection_changed_callback_arrived_(false),
42 waiting_for_selection_changed_callback_(false),
43 waiting_for_gesture_ack_type_(WebInputEvent::Undefined
),
44 last_gesture_ack_type_(WebInputEvent::Undefined
),
45 fling_stop_callback_arrived_(false),
46 waiting_for_fling_stop_callback_(false) {}
48 virtual void Reset() {
49 overscroll_started_callback_arrived_
= false;
50 waiting_for_overscroll_started_callback_
= false;
51 overscroll_completed_callback_arrived_
= false;
52 waiting_for_overscroll_completed_callback_
= false;
53 selection_changed_callback_arrived_
= false;
54 waiting_for_selection_changed_callback_
= false;
55 waiting_for_gesture_ack_type_
= WebInputEvent::Undefined
;
56 last_gesture_ack_type_
= WebInputEvent::Undefined
;
57 fling_stop_callback_arrived_
= false;
58 waiting_for_fling_stop_callback_
= false;
61 void OverscrollStarted() override
{
62 overscroll_started_callback_arrived_
= true;
63 TouchEditableImplAura::OverscrollStarted();
64 if (waiting_for_overscroll_started_callback_
)
65 overscroll_started_wait_run_loop_
->Quit();
68 void WaitForOverscrollStartedCallback() {
69 // Doesn't make sense to call more that once without resetting.
70 CHECK(!waiting_for_overscroll_started_callback_
);
71 waiting_for_overscroll_started_callback_
= true;
72 if (overscroll_started_callback_arrived_
)
74 overscroll_started_wait_run_loop_
.reset(new base::RunLoop());
75 overscroll_started_wait_run_loop_
->Run();
78 void OverscrollCompleted() override
{
79 overscroll_completed_callback_arrived_
= true;
80 TouchEditableImplAura::OverscrollCompleted();
81 if (waiting_for_overscroll_completed_callback_
)
82 overscroll_completed_wait_run_loop_
->Quit();
85 void WaitForOverscrollCompletedCallback() {
86 // Doesn't make sense to call more that once without resetting.
87 CHECK(!waiting_for_overscroll_completed_callback_
);
88 waiting_for_overscroll_completed_callback_
= true;
89 if (overscroll_completed_callback_arrived_
)
91 overscroll_completed_wait_run_loop_
.reset(new base::RunLoop());
92 overscroll_completed_wait_run_loop_
->Run();
95 void OnSelectionOrCursorChanged(const ui::SelectionBound
& anchor
,
96 const ui::SelectionBound
& focus
) override
{
97 selection_changed_callback_arrived_
= true;
98 TouchEditableImplAura::OnSelectionOrCursorChanged(anchor
, focus
);
99 if (waiting_for_selection_changed_callback_
)
100 selection_changed_wait_run_loop_
->Quit();
103 void GestureEventAck(int gesture_event_type
) override
{
104 last_gesture_ack_type_
=
105 static_cast<WebInputEvent::Type
>(gesture_event_type
);
106 TouchEditableImplAura::GestureEventAck(gesture_event_type
);
107 if (waiting_for_gesture_ack_type_
== gesture_event_type
)
108 gesture_ack_wait_run_loop_
->Quit();
111 void DidStopFlinging() override
{
112 fling_stop_callback_arrived_
= true;
113 TouchEditableImplAura::DidStopFlinging();
114 if (waiting_for_fling_stop_callback_
)
115 fling_stop_wait_run_loop_
->Quit();
118 void WaitForSelectionChangeCallback() {
119 // Doesn't make sense to call more that once without resetting.
120 CHECK(!waiting_for_selection_changed_callback_
);
121 waiting_for_selection_changed_callback_
= true;
122 if (selection_changed_callback_arrived_
)
124 selection_changed_wait_run_loop_
.reset(new base::RunLoop());
125 selection_changed_wait_run_loop_
->Run();
128 void WaitForGestureAck(WebInputEvent::Type gesture_event_type
) {
129 // Doesn't make sense to call more that once without resetting.
130 CHECK_EQ(waiting_for_gesture_ack_type_
, WebInputEvent::Undefined
);
131 waiting_for_gesture_ack_type_
= gesture_event_type
;
132 if (last_gesture_ack_type_
== gesture_event_type
)
134 gesture_ack_wait_run_loop_
.reset(new base::RunLoop());
135 gesture_ack_wait_run_loop_
->Run();
138 void WaitForFlingStopCallback() {
139 // Doesn't make sense to call more that once without resetting.
140 CHECK(!waiting_for_fling_stop_callback_
);
141 waiting_for_fling_stop_callback_
= true;
142 if (fling_stop_callback_arrived_
)
144 fling_stop_wait_run_loop_
.reset(new base::RunLoop());
145 fling_stop_wait_run_loop_
->Run();
149 ~TestTouchEditableImplAura() override
{}
152 bool overscroll_started_callback_arrived_
;
153 bool waiting_for_overscroll_started_callback_
;
154 bool overscroll_completed_callback_arrived_
;
155 bool waiting_for_overscroll_completed_callback_
;
156 bool selection_changed_callback_arrived_
;
157 bool waiting_for_selection_changed_callback_
;
158 WebInputEvent::Type waiting_for_gesture_ack_type_
;
159 WebInputEvent::Type last_gesture_ack_type_
;
160 bool fling_stop_callback_arrived_
;
161 bool waiting_for_fling_stop_callback_
;
162 scoped_ptr
<base::RunLoop
> overscroll_started_wait_run_loop_
;
163 scoped_ptr
<base::RunLoop
> overscroll_completed_wait_run_loop_
;
164 scoped_ptr
<base::RunLoop
> selection_changed_wait_run_loop_
;
165 scoped_ptr
<base::RunLoop
> gesture_ack_wait_run_loop_
;
166 scoped_ptr
<base::RunLoop
> fling_stop_wait_run_loop_
;
168 DISALLOW_COPY_AND_ASSIGN(TestTouchEditableImplAura
);
171 class TouchEditableImplAuraTest
: public ContentBrowserTest
{
173 TouchEditableImplAuraTest() {}
176 void SetUpOnMainThread() override
{
177 ContentBrowserTest::SetUpOnMainThread();
178 aura::client::SetScreenPositionClient(shell()->window()->GetRootWindow(),
179 &screen_position_client_
);
182 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
183 command_line
->AppendSwitch(switches::kEnableTouchEditing
);
186 // Executes the javascript synchronously and makes sure the returned value is
188 void ExecuteSyncJSFunction(RenderFrameHost
* rfh
, const std::string
& jscript
) {
189 scoped_ptr
<base::Value
> value
=
190 content::ExecuteScriptAndGetValue(rfh
, jscript
);
193 // Starts the test server and navigates to the given url. Sets a large enough
194 // size to the root window. Returns after the navigation to the url is
196 void StartTestWithPage(const std::string
& url
) {
197 ASSERT_TRUE(test_server()->Start());
198 GURL
test_url(test_server()->GetURL(url
));
199 NavigateToURL(shell(), test_url
);
200 aura::Window
* content
= shell()->web_contents()->GetContentNativeView();
201 content
->GetHost()->SetBounds(gfx::Rect(800, 600));
204 RenderWidgetHostViewAura
* GetRenderWidgetHostViewAura(
205 TouchEditableImplAura
* touch_editable
) {
206 return touch_editable
->rwhva_
;
209 ui::TouchEditingControllerDeprecated
* GetTouchSelectionController(
210 TouchEditableImplAura
* touch_editable
) {
211 return touch_editable
->touch_selection_controller_
.get();
214 ui::TextInputType
GetTextInputType(TouchEditableImplAura
* touch_editable
) {
215 return touch_editable
->text_input_type_
;
219 wm::DefaultScreenPositionClient screen_position_client_
;
221 DISALLOW_COPY_AND_ASSIGN(TouchEditableImplAuraTest
);
224 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest
,
225 TouchSelectionOriginatingFromWebpageTest
) {
226 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
227 WebContentsImpl
* web_contents
=
228 static_cast<WebContentsImpl
*>(shell()->web_contents());
229 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
230 WebContentsViewAura
* view_aura
= static_cast<WebContentsViewAura
*>(
231 web_contents
->GetView());
232 TestTouchEditableImplAura
* touch_editable
= new TestTouchEditableImplAura
;
233 view_aura
->SetTouchEditableForTest(touch_editable
);
234 RenderWidgetHostViewAura
* rwhva
= static_cast<RenderWidgetHostViewAura
*>(
235 web_contents
->GetRenderWidgetHostView());
236 aura::Window
* content
= web_contents
->GetContentNativeView();
237 ui::test::EventGenerator
generator(content
->GetRootWindow(), content
);
238 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
240 touch_editable
->Reset();
241 ExecuteSyncJSFunction(main_frame
, "select_all_text()");
242 touch_editable
->WaitForSelectionChangeCallback();
244 // Tap inside selection to bring up selection handles.
245 generator
.GestureTapAt(gfx::Point(bounds
.x() + 10, bounds
.y() + 10));
246 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable
), rwhva
);
248 scoped_ptr
<base::Value
> value
=
249 content::ExecuteScriptAndGetValue(main_frame
, "get_selection()");
250 std::string selection
;
251 value
->GetAsString(&selection
);
253 // Check if selection handles are showing.
254 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
255 EXPECT_STREQ("Some text we can select", selection
.c_str());
257 // Lets move the handles a bit to modify the selection
258 touch_editable
->Reset();
259 ui::SelectionBound anchor
, focus
;
260 touch_editable
->GetSelectionEndPoints(&anchor
, &focus
);
261 // The distance by which a handle image is offset from the bottom of the
262 // selection/text baseline.
263 const int kSelectionHandleVerticalVisualOffset
= 2;
264 int handle_grab_x
= bounds
.x() + anchor
.edge_bottom_rounded().x();
265 int handle_grab_y
= bounds
.y() + anchor
.edge_bottom_rounded().y() +
266 kSelectionHandleVerticalVisualOffset
+ 1;
267 generator
.GestureScrollSequence(
268 gfx::Point(handle_grab_x
, handle_grab_y
),
269 gfx::Point(handle_grab_x
+ 20, handle_grab_y
),
270 base::TimeDelta::FromMilliseconds(20),
272 touch_editable
->WaitForSelectionChangeCallback();
274 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
275 value
= content::ExecuteScriptAndGetValue(main_frame
, "get_selection()");
276 value
->GetAsString(&selection
);
278 // It is hard to tell what exactly the selection would be now. But it would
279 // definitely be less than whatever was selected before.
280 EXPECT_GT(std::strlen("Some text we can select"), selection
.size());
283 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest
,
284 TestTouchSelectionHiddenWhenScrolling
) {
285 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
286 WebContentsImpl
* web_contents
=
287 static_cast<WebContentsImpl
*>(shell()->web_contents());
288 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
289 WebContentsViewAura
* view_aura
= static_cast<WebContentsViewAura
*>(
290 web_contents
->GetView());
291 TestTouchEditableImplAura
* touch_editable
= new TestTouchEditableImplAura
;
292 view_aura
->SetTouchEditableForTest(touch_editable
);
293 RenderWidgetHostViewAura
* rwhva
= static_cast<RenderWidgetHostViewAura
*>(
294 web_contents
->GetRenderWidgetHostView());
295 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable
), rwhva
);
297 // Long press to select word.
298 ui::GestureEvent
long_press(
302 ui::EventTimeForNow(),
303 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS
));
304 touch_editable
->Reset();
305 rwhva
->OnGestureEvent(&long_press
);
306 touch_editable
->WaitForSelectionChangeCallback();
308 // Check if selection handles are showing.
309 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
311 scoped_ptr
<base::Value
> value
=
312 content::ExecuteScriptAndGetValue(main_frame
, "get_selection()");
313 std::string selection
;
314 value
->GetAsString(&selection
);
315 EXPECT_STREQ("Some", selection
.c_str());
317 // Start scrolling. Handles should get hidden.
318 ui::GestureEvent
scroll_begin(
322 ui::EventTimeForNow(),
323 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN
));
324 rwhva
->OnGestureEvent(&scroll_begin
);
325 EXPECT_FALSE(GetTouchSelectionController(touch_editable
));
327 // Handles should come back after scroll ends.
328 ui::GestureEvent
scroll_end(
332 ui::EventTimeForNow(),
333 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END
));
334 rwhva
->OnGestureEvent(&scroll_end
);
335 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
338 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest
,
339 TestTouchSelectionReshownAfterFling
) {
340 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
341 WebContentsImpl
* web_contents
=
342 static_cast<WebContentsImpl
*>(shell()->web_contents());
343 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
344 WebContentsViewAura
* view_aura
= static_cast<WebContentsViewAura
*>(
345 web_contents
->GetView());
346 TestTouchEditableImplAura
* touch_editable
= new TestTouchEditableImplAura
;
347 view_aura
->SetTouchEditableForTest(touch_editable
);
348 RenderWidgetHostViewAura
* rwhva
= static_cast<RenderWidgetHostViewAura
*>(
349 web_contents
->GetRenderWidgetHostView());
350 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable
), rwhva
);
352 // Long press to select word.
353 ui::GestureEvent
long_press(
357 ui::EventTimeForNow(),
358 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS
));
359 touch_editable
->Reset();
360 rwhva
->OnGestureEvent(&long_press
);
361 touch_editable
->WaitForSelectionChangeCallback();
363 // Check if selection handles are showing.
364 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
366 scoped_ptr
<base::Value
> value
=
367 content::ExecuteScriptAndGetValue(main_frame
, "get_selection()");
368 std::string selection
;
369 value
->GetAsString(&selection
);
370 EXPECT_STREQ("Some", selection
.c_str());
372 // Start scrolling. Handles should get hidden.
373 ui::GestureEvent
scroll_begin(
377 ui::EventTimeForNow(),
378 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN
, 0, 0));
379 rwhva
->OnGestureEvent(&scroll_begin
);
380 EXPECT_FALSE(GetTouchSelectionController(touch_editable
));
382 // Start a fling. Handles should come back after fling stops.
383 ui::GestureEvent
fling_start(
387 ui::EventTimeForNow(),
388 ui::GestureEventDetails(ui::ET_SCROLL_FLING_START
, 1, 0));
389 rwhva
->OnGestureEvent(&fling_start
);
390 touch_editable
->WaitForFlingStopCallback();
391 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
394 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest
,
395 TestTouchSelectionWhenOverscrolling
) {
396 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
397 WebContentsImpl
* web_contents
=
398 static_cast<WebContentsImpl
*>(shell()->web_contents());
399 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
400 WebContentsViewAura
* view_aura
= static_cast<WebContentsViewAura
*>(
401 web_contents
->GetView());
402 TestTouchEditableImplAura
* touch_editable
= new TestTouchEditableImplAura
;
403 view_aura
->SetTouchEditableForTest(touch_editable
);
404 RenderWidgetHostViewAura
* rwhva
= static_cast<RenderWidgetHostViewAura
*>(
405 web_contents
->GetRenderWidgetHostView());
406 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable
), rwhva
);
408 // Long press to select word.
409 ui::GestureEvent
long_press(
413 ui::EventTimeForNow(),
414 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS
));
415 touch_editable
->Reset();
416 rwhva
->OnGestureEvent(&long_press
);
417 touch_editable
->WaitForSelectionChangeCallback();
419 // Check if selection handles are showing.
420 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
422 scoped_ptr
<base::Value
> value
=
423 content::ExecuteScriptAndGetValue(main_frame
, "get_selection()");
424 std::string selection
;
425 value
->GetAsString(&selection
);
426 EXPECT_STREQ("Some", selection
.c_str());
428 ui::GestureEvent
scroll_begin(
432 ui::EventTimeForNow(),
433 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN
, 0, 0));
434 rwhva
->OnGestureEvent(&scroll_begin
);
435 EXPECT_FALSE(GetTouchSelectionController(touch_editable
));
437 // Then overscroll starts. OverscrollStarted callback should be called and
438 // handles should remain hidden.
439 ui::GestureEvent
scroll_update(
443 ui::EventTimeForNow(),
444 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE
, 200, 0));
445 rwhva
->OnGestureEvent(&scroll_update
);
446 touch_editable
->WaitForOverscrollStartedCallback();
447 EXPECT_FALSE(GetTouchSelectionController(touch_editable
));
449 // We might have multiple overscroll-starts in one overscroll session. Handles
450 // should still remain hidden.
451 touch_editable
->OverscrollStarted();
452 EXPECT_FALSE(GetTouchSelectionController(touch_editable
));
454 // And, finally a scroll-end. An OverscrollCompleted callback should be
455 // called and handles should come back.
456 ui::GestureEvent
scroll_end(
460 ui::EventTimeForNow(),
461 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END
));
462 rwhva
->OnGestureEvent(&scroll_end
);
463 touch_editable
->WaitForOverscrollCompletedCallback();
464 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
466 // Now repeat the same sequence, but abort the overscroll by scrolling back
467 // before ending the scroll.
468 touch_editable
->Reset();
469 scroll_begin
= ui::GestureEvent(
473 ui::EventTimeForNow(),
474 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN
, 0, 0));
475 rwhva
->OnGestureEvent(&scroll_begin
);
477 scroll_update
= ui::GestureEvent(
481 ui::EventTimeForNow(),
482 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE
, 200, 0));
483 rwhva
->OnGestureEvent(&scroll_update
);
484 touch_editable
->WaitForOverscrollStartedCallback();
487 ui::GestureEvent
scroll_update2(
491 ui::EventTimeForNow(),
492 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE
, -200, 0));
493 rwhva
->OnGestureEvent(&scroll_update2
);
494 // Handles should remain hidden.
495 EXPECT_FALSE(GetTouchSelectionController(touch_editable
));
497 // End the scroll - the overscroll should be cancelled, and we should still
498 // receive OverscrollCompleted callback
499 scroll_end
= ui::GestureEvent(
503 ui::EventTimeForNow(),
504 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END
));
505 rwhva
->OnGestureEvent(&scroll_end
);
506 touch_editable
->WaitForOverscrollCompletedCallback();
507 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
510 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest
,
511 TouchSelectionOnLongPressTest
) {
512 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
513 WebContentsImpl
* web_contents
=
514 static_cast<WebContentsImpl
*>(shell()->web_contents());
515 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
516 WebContentsViewAura
* view_aura
= static_cast<WebContentsViewAura
*>(
517 web_contents
->GetView());
518 TestTouchEditableImplAura
* touch_editable
= new TestTouchEditableImplAura
;
519 view_aura
->SetTouchEditableForTest(touch_editable
);
520 RenderWidgetHostViewAura
* rwhva
= static_cast<RenderWidgetHostViewAura
*>(
521 web_contents
->GetRenderWidgetHostView());
522 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable
), rwhva
);
524 // Long press to select word.
525 ui::GestureEvent
long_press(
529 ui::EventTimeForNow(),
530 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS
));
531 touch_editable
->Reset();
532 rwhva
->OnGestureEvent(&long_press
);
533 touch_editable
->WaitForSelectionChangeCallback();
535 // Check if selection handles are showing.
536 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
538 scoped_ptr
<base::Value
> value
=
539 content::ExecuteScriptAndGetValue(main_frame
, "get_selection()");
540 std::string selection
;
541 value
->GetAsString(&selection
);
542 EXPECT_STREQ("Some", selection
.c_str());
545 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest
,
546 NoTouchSelectionOnDoubleTapTest
) {
547 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
548 WebContentsImpl
* web_contents
=
549 static_cast<WebContentsImpl
*>(shell()->web_contents());
550 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
551 WebContentsViewAura
* view_aura
=
552 static_cast<WebContentsViewAura
*>(web_contents
->GetView());
553 TestTouchEditableImplAura
* touch_editable
= new TestTouchEditableImplAura
;
554 view_aura
->SetTouchEditableForTest(touch_editable
);
555 RenderWidgetHostViewAura
* rwhva
= static_cast<RenderWidgetHostViewAura
*>(
556 web_contents
->GetRenderWidgetHostView());
557 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable
), rwhva
);
559 // Double-tap to select word.
560 ui::GestureEventDetails
details(ui::ET_GESTURE_TAP
);
561 details
.set_tap_count(2);
562 ui::GestureEvent
double_tap(10, 10, 0, ui::EventTimeForNow(), details
);
563 touch_editable
->Reset();
564 rwhva
->OnGestureEvent(&double_tap
);
565 touch_editable
->WaitForSelectionChangeCallback();
567 // Make sure touch selection handles are not showing.
568 EXPECT_FALSE(GetTouchSelectionController(touch_editable
));
570 scoped_ptr
<base::Value
> value
=
571 content::ExecuteScriptAndGetValue(main_frame
, "get_selection()");
572 std::string selection
;
573 value
->GetAsString(&selection
);
574 EXPECT_STREQ("Some", selection
.c_str());
577 #if defined(OS_CHROMEOS)
578 // http://crbug.com/396509
579 #define MAYBE_TouchCursorInTextfieldTest DISABLED_TouchCursorInTextfieldTest
581 #define MAYBE_TouchCursorInTextfieldTest TouchCursorInTextfieldTest
583 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest
,
584 MAYBE_TouchCursorInTextfieldTest
) {
585 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
586 WebContentsImpl
* web_contents
=
587 static_cast<WebContentsImpl
*>(shell()->web_contents());
588 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
589 WebContentsViewAura
* view_aura
= static_cast<WebContentsViewAura
*>(
590 web_contents
->GetView());
591 TestTouchEditableImplAura
* touch_editable
= new TestTouchEditableImplAura
;
592 view_aura
->SetTouchEditableForTest(touch_editable
);
593 RenderWidgetHostViewAura
* rwhva
= static_cast<RenderWidgetHostViewAura
*>(
594 web_contents
->GetRenderWidgetHostView());
595 aura::Window
* content
= web_contents
->GetContentNativeView();
596 ui::test::EventGenerator
generator(content
->GetRootWindow(), content
);
597 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
598 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable
), rwhva
);
600 ExecuteSyncJSFunction(main_frame
, "focus_textfield()");
601 touch_editable
->WaitForSelectionChangeCallback();
604 touch_editable
->Reset();
605 generator
.GestureTapAt(gfx::Point(bounds
.x() + 50, bounds
.y() + 40));
606 // Tap Down acks are sent synchronously, while Tap acks are asynchronous.
607 touch_editable
->WaitForGestureAck(WebInputEvent::GestureTap
);
608 touch_editable
->WaitForSelectionChangeCallback();
609 touch_editable
->Reset();
611 // Check if cursor handle is showing.
612 EXPECT_NE(ui::TEXT_INPUT_TYPE_NONE
, GetTextInputType(touch_editable
));
613 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
615 scoped_ptr
<base::Value
> value
=
616 content::ExecuteScriptAndGetValue(main_frame
, "get_cursor_position()");
618 value
->GetAsInteger(&cursor_pos
);
619 EXPECT_NE(-1, cursor_pos
);
621 // Move the cursor handle.
622 generator
.GestureScrollSequence(
625 base::TimeDelta::FromMilliseconds(20),
627 touch_editable
->WaitForSelectionChangeCallback();
628 EXPECT_TRUE(GetTouchSelectionController(touch_editable
));
629 value
= content::ExecuteScriptAndGetValue(main_frame
,
630 "get_cursor_position()");
631 int new_cursor_pos
= -1;
632 value
->GetAsInteger(&new_cursor_pos
);
633 EXPECT_NE(-1, new_cursor_pos
);
634 // Cursor should have moved.
635 EXPECT_NE(new_cursor_pos
, cursor_pos
);
638 } // namespace content