Commit 7e8fb35e authored by chaopeng's avatar chaopeng Committed by Commit Bot

Add a feature flag for not exposing key board event to web

Chrome does not expose key events to pages for spatnav. This is to prevent
pages from accidentally interfering with the built-in behavior.

Bug: 920818
Change-Id: I9476b4b5b5d8aa2ff53c07c64ce50c2a9a7812b1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1500599
Commit-Queue: Jianpeng Chao <chaopeng@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#644176}
parent 31fdfe99
......@@ -90,6 +90,7 @@
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display_switches.h"
#include "ui/events/blink/blink_features.h"
#include "ui/gfx/animation/animation.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/image/image_skia.h"
......@@ -518,6 +519,9 @@ const WebPreferences RenderViewHostImpl::ComputeWebPreferences() {
NOTREACHED();
}
prefs.dont_send_key_events_to_javascript =
base::FeatureList::IsEnabled(features::kDontSendKeyEventsToJavascript);
// TODO(dtapuska): Enable barrel button selection drag support on Android.
// crbug.com/758042
#if defined(OS_WIN)
......
......@@ -205,6 +205,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(text_track_font_variant)
IPC_STRUCT_TRAITS_MEMBER(text_autosizing_enabled)
IPC_STRUCT_TRAITS_MEMBER(double_tap_to_zoom_enabled)
IPC_STRUCT_TRAITS_MEMBER(dont_send_key_events_to_javascript)
IPC_STRUCT_TRAITS_MEMBER(web_app_scope)
#if defined(OS_ANDROID)
IPC_STRUCT_TRAITS_MEMBER(font_scale_factor)
......
......@@ -129,6 +129,7 @@ WebPreferences::WebPreferences()
primary_pointer_type(ui::POINTER_TYPE_NONE),
available_hover_types(0),
primary_hover_type(ui::HOVER_TYPE_NONE),
dont_send_key_events_to_javascript(false),
sync_xhr_in_documents_enabled(true),
should_respect_image_orientation(false),
number_of_cpu_cores(1),
......
......@@ -161,6 +161,7 @@ struct CONTENT_EXPORT WebPreferences {
ui::PointerType primary_pointer_type;
int available_hover_types;
ui::HoverType primary_hover_type;
bool dont_send_key_events_to_javascript;
bool barrel_button_for_drag_enabled = false;
bool sync_xhr_in_documents_enabled;
bool should_respect_image_orientation;
......
......@@ -842,6 +842,8 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
static_cast<blink::WebEffectiveConnectionType>(
prefs.network_quality_estimator_web_holdback));
settings->SetDontSendKeyEventsToJavascript(
prefs.dont_send_key_events_to_javascript);
settings->SetWebAppScope(WebString::FromASCII(prefs.web_app_scope.spec()));
#if defined(OS_ANDROID)
......
......@@ -148,6 +148,7 @@ class WebSettings {
void SetDeferred2dCanvasEnabled(bool) {} // temporary stub
virtual void SetDeviceScaleAdjustment(float) = 0;
virtual void SetDisableReadingFromCanvas(bool) = 0;
virtual void SetDontSendKeyEventsToJavascript(bool) = 0;
virtual void SetDoubleTapToZoomEnabled(bool) = 0;
virtual void SetDownloadableBinaryFontsEnabled(bool) = 0;
virtual void SetEditingBehavior(EditingBehavior) = 0;
......
......@@ -322,6 +322,12 @@ void WebSettingsImpl::SetUseWideViewport(bool use_wide_viewport) {
settings_->SetUseWideViewport(use_wide_viewport);
}
void WebSettingsImpl::SetDontSendKeyEventsToJavascript(
bool dont_send_key_events_to_javascript) {
settings_->SetDontSendKeyEventsToJavascript(
dont_send_key_events_to_javascript);
}
void WebSettingsImpl::SetDoubleTapToZoomEnabled(
bool double_tap_to_zoom_enabled) {
dev_tools_emulator_->SetDoubleTapToZoomEnabled(double_tap_to_zoom_enabled);
......
......@@ -78,6 +78,7 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
void SetDeviceScaleAdjustment(float) override;
void SetDisableReadingFromCanvas(bool) override;
void SetDontSendKeyEventsToJavascript(bool) override;
void SetDoubleTapToZoomEnabled(bool) override;
void SetDownloadableBinaryFontsEnabled(bool) override;
void SetEditingBehavior(EditingBehavior) override;
......
......@@ -1018,5 +1018,9 @@
initial: false,
invalidate: "MediaQuery",
},
{
name: "DontSendKeyEventsToJavascript",
initial: false,
},
],
}
......@@ -7,6 +7,7 @@
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_keyboard_event.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/editing/editing_behavior.h"
......@@ -1556,4 +1557,41 @@ TEST_F(EventHandlerSimTest, SmallCustomCursorIntersectsViewport) {
}
}
TEST_F(EventHandlerSimTest, NotExposeKeyboardEvent) {
GetDocument().GetSettings()->SetDontSendKeyEventsToJavascript(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
<!DOCTYPE html>
Last event: <br>
<p id='log'>no event</p>
<script>
document.addEventListener('keydown', (e) => {
let log = document.getElementById('log');
log.innerText = 'keydown';
});
document.addEventListener('keyup', (e) => {
let log = document.getElementById('log');
log.innerText = 'keyup';
});
</script>
)HTML");
Compositor().BeginFrame();
WebElement element = GetDocument().getElementById("log");
WebKeyboardEvent e{WebInputEvent::kRawKeyDown, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests()};
GetDocument().GetFrame()->GetEventHandler().KeyEvent(e);
EXPECT_EQ("no event", element.InnerHTML().Utf8());
e.SetType(WebInputEvent::kKeyUp);
GetDocument().GetFrame()->GetEventHandler().KeyEvent(e);
EXPECT_EQ("no event", element.InnerHTML().Utf8());
e.SetType(WebInputEvent::kKeyDown);
GetDocument().GetFrame()->GetEventHandler().KeyEvent(e);
EXPECT_EQ("no event", element.InnerHTML().Utf8());
}
} // namespace blink
......@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/html_dialog_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/input/event_handling_util.h"
......@@ -201,29 +202,50 @@ WebInputEventResult KeyboardEventManager::KeyEvent(
if (initial_key_event.GetType() == WebInputEvent::kKeyDown)
matched_an_access_key = HandleAccessKey(initial_key_event);
// FIXME: it would be fair to let an input method handle KeyUp events before
// DOM dispatch.
if (initial_key_event.GetType() == WebInputEvent::kKeyUp ||
initial_key_event.GetType() == WebInputEvent::kChar) {
KeyboardEvent* dom_event = KeyboardEvent::Create(
initial_key_event, frame_->GetDocument()->domWindow());
// Don't expose key events to pages while browsing on the drive-by web. This
// is to prevent pages from accidentally interfering with the built-in
// behavior eg. spatial-navigation. Installed PWAs are a signal from the user
// that they trust the app more than a random page on the drive-by web so we
// allow PWAs to receive and override key events. The only exception is the
// browser display mode since it must always behave like the the drive-by web.
bool should_send_key_events_to_js =
!frame_->GetSettings()->GetDontSendKeyEventsToJavascript();
if (!should_send_key_events_to_js &&
frame_->GetDocument()->IsInWebAppScope()) {
DCHECK(frame_->View());
WebDisplayMode display_mode = frame_->View()->DisplayMode();
should_send_key_events_to_js = display_mode == kWebDisplayModeMinimalUi ||
display_mode == kWebDisplayModeStandalone ||
display_mode == kWebDisplayModeFullscreen;
}
if (should_send_key_events_to_js) {
// FIXME: it would be fair to let an input method handle KeyUp events before
// DOM dispatch.
if (initial_key_event.GetType() == WebInputEvent::kKeyUp ||
initial_key_event.GetType() == WebInputEvent::kChar) {
KeyboardEvent* dom_event = KeyboardEvent::Create(
initial_key_event, frame_->GetDocument()->domWindow());
return event_handling_util::ToWebInputEventResult(
node->DispatchEvent(*dom_event));
}
return event_handling_util::ToWebInputEventResult(
node->DispatchEvent(*dom_event));
WebKeyboardEvent key_down_event = initial_key_event;
if (key_down_event.GetType() != WebInputEvent::kRawKeyDown)
key_down_event.SetType(WebInputEvent::kRawKeyDown);
KeyboardEvent* keydown = KeyboardEvent::Create(
key_down_event, frame_->GetDocument()->domWindow());
if (matched_an_access_key)
keydown->SetDefaultPrevented(true);
keydown->SetTarget(node);
DispatchEventResult dispatch_result = node->DispatchEvent(*keydown);
if (dispatch_result != DispatchEventResult::kNotCanceled)
return event_handling_util::ToWebInputEventResult(dispatch_result);
}
WebKeyboardEvent key_down_event = initial_key_event;
if (key_down_event.GetType() != WebInputEvent::kRawKeyDown)
key_down_event.SetType(WebInputEvent::kRawKeyDown);
KeyboardEvent* keydown =
KeyboardEvent::Create(key_down_event, frame_->GetDocument()->domWindow());
if (matched_an_access_key)
keydown->SetDefaultPrevented(true);
keydown->SetTarget(node);
DispatchEventResult dispatch_result = node->DispatchEvent(*keydown);
if (dispatch_result != DispatchEventResult::kNotCanceled)
return event_handling_util::ToWebInputEventResult(dispatch_result);
// If frame changed as a result of keydown dispatch, then return early to
// avoid sending a subsequent keypress message to the new frame.
bool changed_focused_frame =
......
......@@ -30,4 +30,7 @@ const base::Feature kCompositorTouchAction{"CompositorTouchAction",
const base::Feature kFallbackCursorMode{"FallbackCursorMode",
base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kDontSendKeyEventsToJavascript{
"DontSendKeyEventsToJavascript", base::FEATURE_DISABLED_BY_DEFAULT};
}
......@@ -44,6 +44,10 @@ extern const base::Feature kCompositorTouchAction;
// Enables fallback cursor mode for dpad devices.
extern const base::Feature kFallbackCursorMode;
// When enabled, this feature prevent blink sending key event to web unless it
// is on installed PWA.
extern const base::Feature kDontSendKeyEventsToJavascript;
}
#endif // UI_EVENTS_BLINK_BLINK_FEATURES_H_
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