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

Unified Diff: content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc

Issue 2883653002: Implement TouchSelectionEditing controls for OOPIF. (Closed)
Patch Set: Rebase to master@{#474649}. Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
index 3cda5fbb787a553ca785b0b8e46b14bd019abdc9..2dccf4b98eb765acd0a8972f752d3fa6ed840250 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -9,13 +9,20 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
+#include "base/test/test_timeouts.h"
+#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/renderer_host/render_widget_host_view_event_handler.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/display/display_switches.h"
@@ -170,13 +177,14 @@ class TouchSelectionControllerClientAuraTest : public ContentBrowserTest {
rwhva->event_handler()->disable_input_event_router_for_testing();
}
- private:
+ protected:
void SetUpOnMainThread() override {
ContentBrowserTest::SetUpOnMainThread();
if (!ui::TouchSelectionMenuRunner::GetInstance())
menu_runner_.reset(new TestTouchSelectionMenuRunner);
}
+ private:
void TearDownOnMainThread() override {
menu_runner_ = nullptr;
selection_controller_client_ = nullptr;
@@ -223,6 +231,207 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicSelection) {
EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
}
+class TouchSelectionControllerClientAuraSiteIsolationTest
+ : public TouchSelectionControllerClientAuraTest,
+ public testing::WithParamInterface<bool> {
+ public:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ IsolateAllSitesForTesting(command_line);
+ }
+
+ void SetUpOnMainThread() override {
+ TouchSelectionControllerClientAuraTest::SetUpOnMainThread();
+ host_resolver()->AddRule("*", "127.0.0.1");
+ SetupCrossSiteRedirector(embedded_test_server());
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+
+ void SelectWithLongPress(gfx::Point point) {
+ // Get main frame view for event insertion.
+ RenderWidgetHostViewAura* main_view = GetRenderWidgetHostViewAura();
+
+ SendTouch(main_view, ui::ET_TOUCH_PRESSED, point);
+ SendTouch(main_view, ui::ET_TOUCH_RELEASED, point);
+ SendGestureTap(main_view, point);
+ SendGestureLongPress(main_view, point);
+ }
+
+ void SimpleTap(gfx::Point point) {
+ // Get main frame view for event insertion.
+ RenderWidgetHostViewAura* main_view = GetRenderWidgetHostViewAura();
+
+ SendTouch(main_view, ui::ET_TOUCH_PRESSED, point);
+ SendTouch(main_view, ui::ET_TOUCH_RELEASED, point);
+ SendGestureTap(main_view, point);
+ }
+
+ private:
+ void SendTouch(RenderWidgetHostViewAura* view,
+ ui::EventType type,
+ gfx::Point point) {
+ DCHECK(type >= ui::ET_TOUCH_RELEASED && type << ui::ET_TOUCH_CANCELLED);
+ ui::TouchEvent touch(
+ type, point, ui::EventTimeForNow(),
+ ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
+ view->OnTouchEvent(&touch);
+ }
+
+ void SendGestureTap(RenderWidgetHostViewAura* view, gfx::Point point) {
+ ui::GestureEventDetails tap_down_details(ui::ET_GESTURE_TAP_DOWN);
+ tap_down_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
+ ui::GestureEvent gesture_tap_down(point.x(), point.y(), 0,
+ ui::EventTimeForNow(), tap_down_details);
+ view->OnGestureEvent(&gesture_tap_down);
+ ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP);
+ tap_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
+ tap_details.set_tap_count(1);
+ ui::GestureEvent gesture_tap(point.x(), point.y(), 0, ui::EventTimeForNow(),
+ tap_details);
+ view->OnGestureEvent(&gesture_tap);
+ }
+
+ void SendGestureLongPress(RenderWidgetHostViewAura* view, gfx::Point point) {
+ ui::GestureEventDetails long_press_details(ui::ET_GESTURE_LONG_PRESS);
+ long_press_details.set_device_type(
+ ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
+ ui::GestureEvent gesture_long_press(
+ point.x(), point.y(), 0, ui::EventTimeForNow(), long_press_details);
+ view->OnGestureEvent(&gesture_long_press);
+ }
+};
+
+class FrameStableObserver {
+ public:
+ FrameStableObserver(RenderWidgetHostViewBase* view, base::TimeDelta delta)
+ : view_(view), delta_(delta) {}
+ virtual ~FrameStableObserver() {}
+
+ void WaitUntilStable() {
+ uint32_t current_frame_number = view_->RendererFrameNumber();
+ uint32_t previous_frame_number;
+
+ do {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(), delta_);
+ run_loop.Run();
+ previous_frame_number = current_frame_number;
+ current_frame_number = view_->RendererFrameNumber();
+ } while (current_frame_number != previous_frame_number);
+ }
+
+ private:
+ RenderWidgetHostViewBase* view_;
+ base::TimeDelta delta_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameStableObserver);
+};
+
+INSTANTIATE_TEST_CASE_P(TouchSelectionForCrossProcessFramesTests,
+ TouchSelectionControllerClientAuraSiteIsolationTest,
+ testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
+ BasicSelectionIsolatedIframe) {
+ GURL test_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(a)"));
+ EXPECT_TRUE(NavigateToURL(shell(), test_url));
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ EXPECT_EQ(
+ " Site A\n"
+ " +--Site A\n"
+ "Where A = http://a.com/",
+ FrameTreeVisualizer().DepictFrameTree(root));
+ TestNavigationObserver observer(shell()->web_contents());
+ EXPECT_EQ(1u, root->child_count());
+ FrameTreeNode* child = root->child_at(0);
+
+ RenderWidgetHostViewAura* parent_view =
+ static_cast<RenderWidgetHostViewAura*>(
+ root->current_frame_host()->GetRenderWidgetHost()->GetView());
+ TestTouchSelectionControllerClientAura* parent_selection_controller_client =
+ new TestTouchSelectionControllerClientAura(parent_view);
+ parent_view->SetSelectionControllerClientForTest(
+ base::WrapUnique(parent_selection_controller_client));
+
+ // We need to load the desired subframe and then wait until it's stable, i.e.
+ // generates no new frames for some reasonable time period: a stray frame
+ // between touch selection's pre-handling of GestureLongPress and the
+ // expected frame containing the selected region can confuse the
+ // TouchSelectionController, causing it to fail to show selection handles.
+ // Note this is an issue with the TouchSelectionController in general, and
+ // not a property of this test.
+ GURL child_url(
+ embedded_test_server()->GetURL("b.com", "/touch_selection.html"));
+ NavigateFrameToURL(child, child_url);
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/",
+ FrameTreeVisualizer().DepictFrameTree(root));
+
+ // The child will change with the cross-site navigation. It shouldn't change
+ // after this.
+ child = root->child_at(0);
+ WaitForChildFrameSurfaceReady(child->current_frame_host());
+
+ RenderWidgetHostViewChildFrame* child_view =
+ static_cast<RenderWidgetHostViewChildFrame*>(
+ child->current_frame_host()->GetRenderWidgetHost()->GetView());
+
+ EXPECT_EQ(child_url, observer.last_navigation_url());
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ FrameStableObserver child_frame_stable_observer(child_view,
+ TestTimeouts::tiny_timeout());
+ child_frame_stable_observer.WaitUntilStable();
+
+ EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
+ parent_view->selection_controller()->active_status());
+
+ // Find the location of some text to select.
+ gfx::PointF point_f;
+ std::string str;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(child->current_frame_host(),
+ "get_point_inside_text()", &str));
+ JSONToPoint(str, &point_f);
+ gfx::Point origin = child_view->GetViewOriginInRoot();
+ gfx::Vector2dF origin_vec(origin.x(), origin.y());
+ point_f += origin_vec;
+
+ // Initiate selection with a sequence of events that go through the targeting
+ // system.
+ parent_selection_controller_client->InitWaitForSelectionEvent(
+ ui::SELECTION_HANDLES_SHOWN);
+
+ SelectWithLongPress(gfx::Point(point_f.x(), point_f.y()));
+
+ parent_selection_controller_client->Wait();
+
+ // Check that selection is active and the quick menu is showing.
+ EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
+ parent_view->selection_controller()->active_status());
+ EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+
+ // Tap inside/outside the iframe and make sure the selection handles go away.
+ parent_selection_controller_client->InitWaitForSelectionEvent(
+ ui::SELECTION_HANDLES_CLEARED);
+ if (GetParam()) {
+ gfx::PointF point_outside_iframe = gfx::PointF(-1.f, -1.f) + origin_vec;
+ SimpleTap(gfx::Point(point_outside_iframe.x(), point_outside_iframe.y()));
+ } else {
+ gfx::PointF point_inside_iframe = gfx::PointF(+1.f, +1.f) + origin_vec;
+ SimpleTap(gfx::Point(point_inside_iframe.x(), point_inside_iframe.y()));
+ }
+ parent_selection_controller_client->Wait();
+
+ EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
+ parent_view->selection_controller()->active_status());
+ EXPECT_FALSE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
+}
+
// Tests that tapping in a textfield brings up the insertion handle, but not the
// quick menu, initially. Then, successive taps on the insertion handle toggle
// the quick menu visibility.

Powered by Google App Engine
This is Rietveld 408576698