Commit ec552f22 authored by Xida Chen's avatar Xida Chen Committed by Commit Bot

Set touch action Auto in MaybeSendSyntheticTapGesture

The MaybeSendSyntheticTapGesture can be called in PreProcessMouseEvent,
in which case the TouchActionFilter::allowed_touch_action_ has no value
and will result in a crash.

This CL set the allowed_touch_action_ to auto to fix the issue. A
browser test is added.

Bug: 873211
Change-Id: If776a93fe2c8f7a311a10bc0fec42cda15d0ae9a
Reviewed-on: https://chromium-review.googlesource.com/1169585
Commit-Queue: Xida Chen <xidachen@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583369}
parent f9cdaf5d
......@@ -397,6 +397,23 @@ class ChromeSitePerProcessPDFTest : public ChromeSitePerProcessTest {
}
void ResendGestureToEmbedder(const std::string& host_name) {
content::WebContents* guest_web_contents = SetupGuestWebContents(host_name);
blink::WebGestureEvent event(blink::WebInputEvent::kGestureScrollUpdate,
blink::WebInputEvent::kNoModifiers,
ui::EventTimeForNow(),
blink::kWebGestureDeviceTouchscreen);
// This should not crash.
content::ResendGestureScrollUpdateToEmbedder(guest_web_contents, event);
}
void SendSyntheticTapGesture(const std::string& host_name) {
content::WebContents* guest_web_contents = SetupGuestWebContents(host_name);
// This should not crash
MaybeSendSyntheticTapGesture(guest_web_contents);
}
private:
content::WebContents* SetupGuestWebContents(const std::string& host_name) {
// Navigate to a page with an <iframe>.
GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
ui_test_utils::NavigateToURL(browser(), main_url);
......@@ -420,15 +437,9 @@ class ChromeSitePerProcessPDFTest : public ChromeSitePerProcessTest {
ResetTouchAction(
guest_view::GuestViewBase::FromWebContents(guest_web_contents)
->GetOwnerRenderWidgetHost());
blink::WebGestureEvent event(blink::WebInputEvent::kGestureScrollUpdate,
blink::WebInputEvent::kNoModifiers,
ui::EventTimeForNow(),
blink::kWebGestureDeviceTouchscreen);
// This should not crash.
content::ResendGestureScrollUpdateToEmbedder(guest_web_contents, event);
return guest_web_contents;
}
private:
guest_view::TestGuestViewManagerFactory factory_;
guest_view::TestGuestViewManager* test_guest_view_manager_;
......@@ -449,6 +460,19 @@ IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessPDFTest,
ResendGestureToEmbedder("a.com");
}
// Regression test for https://crbug.com/873211. MaybeSendSyntheticTapGesture
// can be called with no touch action set in TouchActionFilter and results in
// a crash.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessPDFTest,
SendSyntheticTapGestureOOPIF) {
SendSyntheticTapGesture("b.com");
}
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessPDFTest,
SendSyntheticTapGestureNonOOPIF) {
SendSyntheticTapGesture("a.com");
}
// This test verifies that when navigating an OOPIF to a page with <embed>-ed
// PDF, the guest is properly created, and by removing the embedder frame, the
// guest is properly destroyed (https://crbug.com/649856).
......
......@@ -620,6 +620,12 @@ RenderWidgetHostViewGuest::GetOwnerRenderWidgetHostView() const {
: nullptr;
}
void RenderWidgetHostViewGuest::MaybeSendSyntheticTapGestureForTest(
const blink::WebFloatPoint& position,
const blink::WebFloatPoint& screenPosition) const {
MaybeSendSyntheticTapGesture(position, screenPosition);
}
// TODO(wjmaclean): When we remove BrowserPlugin, delete this code.
// http://crbug.com/533069
void RenderWidgetHostViewGuest::MaybeSendSyntheticTapGesture(
......@@ -641,6 +647,13 @@ void RenderWidgetHostViewGuest::MaybeSendSyntheticTapGesture(
gesture_tap_event.SetPositionInWidget(
blink::WebFloatPoint(position.x + offset.x(), position.y + offset.y()));
gesture_tap_event.SetPositionInScreen(screenPosition);
// The touch action may not be set yet because this is still at the
// Pre-processing stage of a mouse or a touch event. In this case, set the
// touch action to Auto to prevent crashing.
static_cast<RenderWidgetHostImpl*>(
GetOwnerRenderWidgetHostView()->GetRenderWidgetHost())
->input_router()
->ForceSetTouchActionAuto();
GetOwnerRenderWidgetHostView()->ProcessGestureEvent(
gesture_tap_event, ui::LatencyInfo(ui::SourceEventType::TOUCH));
......
......@@ -162,6 +162,10 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
const cc::RenderFrameMetadata& metadata) override;
void MaybeSendSyntheticTapGestureForTest(
const blink::WebFloatPoint& position,
const blink::WebFloatPoint& screenPosition) const;
private:
friend class RenderWidgetHostView;
......
......@@ -42,6 +42,7 @@
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
......@@ -607,6 +608,15 @@ void ResendGestureScrollUpdateToEmbedder(WebContents* guest_web_contents,
guest_web_contents->GetBrowserPluginGuest()->ResendEventToEmbedder(event);
}
void MaybeSendSyntheticTapGesture(WebContents* guest_web_contents) {
content::RenderWidgetHostViewGuest* rwhv =
static_cast<content::RenderWidgetHostViewGuest*>(
guest_web_contents->GetRenderWidgetHostView());
DCHECK(rwhv);
rwhv->MaybeSendSyntheticTapGestureForTest(blink::WebFloatPoint(1, 1),
blink::WebFloatPoint(1, 1));
}
void WaitForLoadStopWithoutSuccessCheck(WebContents* web_contents) {
// In many cases, the load may have finished before we get here. Only wait if
// the tab still has a pending navigation.
......
......@@ -270,6 +270,10 @@ void ResetTouchAction(RenderWidgetHost* host);
void ResendGestureScrollUpdateToEmbedder(WebContents* guest_web_contents,
const blink::WebInputEvent& event);
// When a guest view is pre-processing a mouse/touch event, send a synthetic
// tap gesture to its RenderWidgetHostView.
void MaybeSendSyntheticTapGesture(WebContents* guest_web_contents);
// Holds down modifier keys for the duration of its lifetime and releases them
// upon destruction. This allows simulating multiple input events without
// simulating modifier key releases in between.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment