OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/input/touch_selection_controller_client_ aura.h" | 5 #include "content/browser/renderer_host/input/touch_selection_controller_client_ aura.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "base/test/test_timeouts.h" | |
13 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" | |
12 #include "content/browser/renderer_host/render_widget_host_view_aura.h" | 14 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
13 #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" | 15 #include "content/browser/renderer_host/render_widget_host_view_event_handler.h" |
14 #include "content/browser/web_contents/web_contents_impl.h" | 16 #include "content/browser/web_contents/web_contents_impl.h" |
15 #include "content/public/test/browser_test_utils.h" | 17 #include "content/public/test/browser_test_utils.h" |
16 #include "content/public/test/content_browser_test.h" | 18 #include "content/public/test/content_browser_test.h" |
17 #include "content/public/test/content_browser_test_utils.h" | 19 #include "content/public/test/content_browser_test_utils.h" |
20 #include "content/public/test/test_navigation_observer.h" | |
21 #include "content/public/test/test_utils.h" | |
18 #include "content/shell/browser/shell.h" | 22 #include "content/shell/browser/shell.h" |
23 #include "content/test/content_browser_test_utils_internal.h" | |
24 #include "net/dns/mock_host_resolver.h" | |
25 #include "net/test/embedded_test_server/embedded_test_server.h" | |
19 #include "ui/aura/window.h" | 26 #include "ui/aura/window.h" |
20 #include "ui/aura/window_tree_host.h" | 27 #include "ui/aura/window_tree_host.h" |
21 #include "ui/display/display_switches.h" | 28 #include "ui/display/display_switches.h" |
22 #include "ui/events/event_utils.h" | 29 #include "ui/events/event_utils.h" |
23 #include "ui/events/test/event_generator.h" | 30 #include "ui/events/test/event_generator.h" |
24 #include "ui/touch_selection/touch_selection_controller_test_api.h" | 31 #include "ui/touch_selection/touch_selection_controller_test_api.h" |
25 | 32 |
26 namespace content { | 33 namespace content { |
27 namespace { | 34 namespace { |
28 | 35 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 | 170 |
164 void InitSelectionController() { | 171 void InitSelectionController() { |
165 RenderWidgetHostViewAura* rwhva = GetRenderWidgetHostViewAura(); | 172 RenderWidgetHostViewAura* rwhva = GetRenderWidgetHostViewAura(); |
166 selection_controller_client_ = | 173 selection_controller_client_ = |
167 new TestTouchSelectionControllerClientAura(rwhva); | 174 new TestTouchSelectionControllerClientAura(rwhva); |
168 rwhva->SetSelectionControllerClientForTest( | 175 rwhva->SetSelectionControllerClientForTest( |
169 base::WrapUnique(selection_controller_client_)); | 176 base::WrapUnique(selection_controller_client_)); |
170 rwhva->event_handler()->disable_input_event_router_for_testing(); | 177 rwhva->event_handler()->disable_input_event_router_for_testing(); |
171 } | 178 } |
172 | 179 |
173 private: | 180 protected: |
174 void SetUpOnMainThread() override { | 181 void SetUpOnMainThread() override { |
175 ContentBrowserTest::SetUpOnMainThread(); | 182 ContentBrowserTest::SetUpOnMainThread(); |
176 if (!ui::TouchSelectionMenuRunner::GetInstance()) | 183 if (!ui::TouchSelectionMenuRunner::GetInstance()) |
177 menu_runner_.reset(new TestTouchSelectionMenuRunner); | 184 menu_runner_.reset(new TestTouchSelectionMenuRunner); |
178 } | 185 } |
179 | 186 |
187 private: | |
180 void TearDownOnMainThread() override { | 188 void TearDownOnMainThread() override { |
181 menu_runner_ = nullptr; | 189 menu_runner_ = nullptr; |
182 selection_controller_client_ = nullptr; | 190 selection_controller_client_ = nullptr; |
183 ContentBrowserTest::TearDownOnMainThread(); | 191 ContentBrowserTest::TearDownOnMainThread(); |
184 } | 192 } |
185 | 193 |
186 std::unique_ptr<TestTouchSelectionMenuRunner> menu_runner_; | 194 std::unique_ptr<TestTouchSelectionMenuRunner> menu_runner_; |
187 | 195 |
188 TestTouchSelectionControllerClientAura* selection_controller_client_ = | 196 TestTouchSelectionControllerClientAura* selection_controller_client_ = |
189 nullptr; | 197 nullptr; |
(...skipping 26 matching lines...) Expand all Loading... | |
216 rwhva->OnGestureEvent(&long_press); | 224 rwhva->OnGestureEvent(&long_press); |
217 | 225 |
218 selection_controller_client()->Wait(); | 226 selection_controller_client()->Wait(); |
219 | 227 |
220 // Check that selection is active and the quick menu is showing. | 228 // Check that selection is active and the quick menu is showing. |
221 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE, | 229 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE, |
222 rwhva->selection_controller()->active_status()); | 230 rwhva->selection_controller()->active_status()); |
223 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); | 231 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); |
224 } | 232 } |
225 | 233 |
234 class TouchSelectionControllerClientAuraSiteIsolationTest | |
235 : public TouchSelectionControllerClientAuraTest { | |
236 public: | |
237 void SetUpCommandLine(base::CommandLine* command_line) override { | |
238 IsolateAllSitesForTesting(command_line); | |
239 } | |
240 | |
241 void SetUpOnMainThread() override { | |
242 TouchSelectionControllerClientAuraTest::SetUpOnMainThread(); | |
243 host_resolver()->AddRule("*", "127.0.0.1"); | |
244 SetupCrossSiteRedirector(embedded_test_server()); | |
245 ASSERT_TRUE(embedded_test_server()->Start()); | |
246 } | |
247 | |
248 void SelectWithLongPress(gfx::Point point) { | |
249 // Get main frame view for event insertion. | |
250 RenderWidgetHostViewAura* main_view = GetRenderWidgetHostViewAura(); | |
251 | |
252 SendTouch(main_view, ui::ET_TOUCH_PRESSED, point); | |
253 SendTouch(main_view, ui::ET_TOUCH_RELEASED, point); | |
254 SendGestureTap(main_view, point); | |
255 SendGestureLongPress(main_view, point); | |
256 } | |
257 | |
258 void SimpleTap(gfx::Point point) { | |
259 // Get main frame view for event insertion. | |
260 RenderWidgetHostViewAura* main_view = GetRenderWidgetHostViewAura(); | |
261 | |
262 SendTouch(main_view, ui::ET_TOUCH_PRESSED, point); | |
263 SendTouch(main_view, ui::ET_TOUCH_RELEASED, point); | |
264 SendGestureTap(main_view, point); | |
265 } | |
266 | |
267 private: | |
268 void SendTouch(RenderWidgetHostViewAura* view, | |
269 ui::EventType type, | |
270 gfx::Point point) { | |
271 DCHECK(type >= ui::ET_TOUCH_RELEASED && type << ui::ET_TOUCH_CANCELLED); | |
272 ui::TouchEvent touch( | |
273 type, point, ui::EventTimeForNow(), | |
274 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); | |
275 view->OnTouchEvent(&touch); | |
276 } | |
277 | |
278 void SendGestureTap(RenderWidgetHostViewAura* view, gfx::Point point) { | |
279 ui::GestureEventDetails tap_down_details(ui::ET_GESTURE_TAP_DOWN); | |
280 tap_down_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHSCREEN); | |
281 ui::GestureEvent gesture_tap_down(point.x(), point.y(), 0, | |
282 ui::EventTimeForNow(), tap_down_details); | |
283 view->OnGestureEvent(&gesture_tap_down); | |
284 ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP); | |
285 tap_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHSCREEN); | |
286 tap_details.set_tap_count(1); | |
287 ui::GestureEvent gesture_tap(point.x(), point.y(), 0, ui::EventTimeForNow(), | |
288 tap_details); | |
289 view->OnGestureEvent(&gesture_tap); | |
290 } | |
291 | |
292 void SendGestureLongPress(RenderWidgetHostViewAura* view, gfx::Point point) { | |
293 ui::GestureEventDetails long_press_details(ui::ET_GESTURE_LONG_PRESS); | |
294 long_press_details.set_device_type( | |
295 ui::GestureDeviceType::DEVICE_TOUCHSCREEN); | |
296 ui::GestureEvent gesture_long_press( | |
297 point.x(), point.y(), 0, ui::EventTimeForNow(), long_press_details); | |
298 view->OnGestureEvent(&gesture_long_press); | |
299 } | |
300 }; | |
301 | |
302 class FrameStableObserver { | |
303 public: | |
304 FrameStableObserver(RenderWidgetHostViewBase* view, base::TimeDelta delta) | |
305 : view_(view), delta_(delta) {} | |
306 virtual ~FrameStableObserver() {} | |
307 | |
308 void WaitUntilStable() { | |
309 uint32_t current_frame_number = view_->RendererFrameNumber(); | |
310 uint32_t previous_frame_number; | |
311 | |
312 do { | |
313 base::RunLoop run_loop; | |
314 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
315 FROM_HERE, run_loop.QuitClosure(), delta_); | |
316 run_loop.Run(); | |
317 previous_frame_number = current_frame_number; | |
318 current_frame_number = view_->RendererFrameNumber(); | |
319 } while (current_frame_number != previous_frame_number); | |
320 } | |
321 | |
322 private: | |
323 RenderWidgetHostViewBase* view_; | |
324 base::TimeDelta delta_; | |
325 | |
326 DISALLOW_COPY_AND_ASSIGN(FrameStableObserver); | |
327 }; | |
328 | |
329 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraSiteIsolationTest, | |
330 BasicSelectionIsolatedIframe) { | |
331 GURL test_url(embedded_test_server()->GetURL( | |
332 "a.com", "/cross_site_iframe_factory.html?a(a)")); | |
333 EXPECT_TRUE(NavigateToURL(shell(), test_url)); | |
334 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | |
335 ->GetFrameTree() | |
336 ->root(); | |
337 EXPECT_EQ( | |
338 " Site A\n" | |
339 " +--Site A\n" | |
340 "Where A = http://a.com/", | |
341 FrameTreeVisualizer().DepictFrameTree(root)); | |
342 TestNavigationObserver observer(shell()->web_contents()); | |
343 EXPECT_EQ(1u, root->child_count()); | |
344 FrameTreeNode* child = root->child_at(0); | |
345 | |
346 RenderWidgetHostViewAura* parent_view = | |
347 static_cast<RenderWidgetHostViewAura*>( | |
348 root->current_frame_host()->GetRenderWidgetHost()->GetView()); | |
349 TestTouchSelectionControllerClientAura* parent_selection_controller_client = | |
350 new TestTouchSelectionControllerClientAura(parent_view); | |
351 parent_view->SetSelectionControllerClientForTest( | |
352 base::WrapUnique(parent_selection_controller_client)); | |
353 | |
354 // We need to load the desired subframe and then wait until it's stable, i.e. | |
355 // generates no new frames for some reasonable time period: a stray frame | |
356 // between touch selection's pre-handling of GestureLongPress and the | |
357 // expected frame containing the selected region can confuse the | |
358 // TouchSelectionController, causing it to fail to show selection handles. | |
359 // Note this is an issue with the TouchSelectionController in general, and | |
360 // not a property of this test. | |
361 GURL child_url( | |
362 embedded_test_server()->GetURL("b.com", "/touch_selection.html")); | |
363 NavigateFrameToURL(child, child_url); | |
364 EXPECT_EQ( | |
365 " Site A ------------ proxies for B\n" | |
366 " +--Site B ------- proxies for A\n" | |
367 "Where A = http://a.com/\n" | |
368 " B = http://b.com/", | |
369 FrameTreeVisualizer().DepictFrameTree(root)); | |
370 | |
371 // The child will change with the cross-site navigation. It shouldn't change | |
372 // after this. | |
373 child = root->child_at(0); | |
374 WaitForChildFrameSurfaceReady(child->current_frame_host()); | |
375 | |
376 RenderWidgetHostViewChildFrame* child_view = | |
377 static_cast<RenderWidgetHostViewChildFrame*>( | |
378 child->current_frame_host()->GetRenderWidgetHost()->GetView()); | |
379 | |
380 EXPECT_EQ(child_url, observer.last_navigation_url()); | |
381 EXPECT_TRUE(observer.last_navigation_succeeded()); | |
382 FrameStableObserver child_frame_stable_observer(child_view, | |
383 TestTimeouts::tiny_timeout()); | |
384 child_frame_stable_observer.WaitUntilStable(); | |
385 | |
386 EXPECT_EQ(ui::TouchSelectionController::INACTIVE, | |
387 parent_view->selection_controller()->active_status()); | |
388 | |
389 // Find the location of some text to select. | |
390 gfx::PointF point_f; | |
391 std::string str; | |
392 EXPECT_TRUE(ExecuteScriptAndExtractString(child->current_frame_host(), | |
393 "get_point_inside_text()", &str)); | |
394 JSONToPoint(str, &point_f); | |
395 gfx::Point origin = child_view->GetViewOriginInRoot(); | |
396 gfx::Vector2dF origin_vec(origin.x(), origin.y()); | |
397 point_f += origin_vec; | |
398 | |
399 // Initiate selection with a sequence of events that go through the targeting | |
400 // system. | |
401 parent_selection_controller_client->InitWaitForSelectionEvent( | |
402 ui::SELECTION_HANDLES_SHOWN); | |
403 | |
404 SelectWithLongPress(gfx::Point(point_f.x(), point_f.y())); | |
405 | |
406 parent_selection_controller_client->Wait(); | |
407 | |
408 // Check that selection is active and the quick menu is showing. | |
409 EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE, | |
410 parent_view->selection_controller()->active_status()); | |
411 EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); | |
412 | |
413 // Tap outside the iframe and make sure the selection handles go away. | |
414 // TODO(wjmaclean): As we expand test coverage, also add one where we tap | |
415 // *inside* the oopif, but not on the text, to clear. | |
Charlie Reis
2017/05/25 02:29:43
I would recommend adding a test for this now, if p
| |
416 parent_selection_controller_client->InitWaitForSelectionEvent( | |
417 ui::SELECTION_HANDLES_CLEARED); | |
418 gfx::PointF point_outside_iframe = gfx::PointF(-1.f, -1.f) + origin_vec; | |
419 SimpleTap(gfx::Point(point_outside_iframe.x(), point_outside_iframe.y())); | |
420 parent_selection_controller_client->Wait(); | |
421 | |
422 EXPECT_EQ(ui::TouchSelectionController::INACTIVE, | |
423 parent_view->selection_controller()->active_status()); | |
424 EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()); | |
425 } | |
426 | |
226 // Tests that tapping in a textfield brings up the insertion handle, but not the | 427 // Tests that tapping in a textfield brings up the insertion handle, but not the |
227 // quick menu, initially. Then, successive taps on the insertion handle toggle | 428 // quick menu, initially. Then, successive taps on the insertion handle toggle |
228 // the quick menu visibility. | 429 // the quick menu visibility. |
229 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, | 430 IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, |
230 BasicInsertionFollowedByTapsOnHandle) { | 431 BasicInsertionFollowedByTapsOnHandle) { |
231 // Set the test page up. | 432 // Set the test page up. |
232 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html")); | 433 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("/touch_selection.html")); |
233 InitSelectionController(); | 434 InitSelectionController(); |
234 | 435 |
235 RenderWidgetHostViewAura* rwhva = GetRenderWidgetHostViewAura(); | 436 RenderWidgetHostViewAura* rwhva = GetRenderWidgetHostViewAura(); |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
644 | 845 |
645 // The handle should have moved to right. | 846 // The handle should have moved to right. |
646 EXPECT_EQ(initial_handle_rect.y(), moved_handle_rect.y()); | 847 EXPECT_EQ(initial_handle_rect.y(), moved_handle_rect.y()); |
647 EXPECT_LT(initial_handle_rect.x(), moved_handle_rect.x()); | 848 EXPECT_LT(initial_handle_rect.x(), moved_handle_rect.x()); |
648 | 849 |
649 EXPECT_EQ(ui::TouchSelectionController::INSERTION_ACTIVE, | 850 EXPECT_EQ(ui::TouchSelectionController::INSERTION_ACTIVE, |
650 rwhva->selection_controller()->active_status()); | 851 rwhva->selection_controller()->active_status()); |
651 } | 852 } |
652 | 853 |
653 } // namespace content | 854 } // namespace content |
OLD | NEW |