Skip to content

Commit

Permalink
Forward tab events to PDF plugin from blink
Browse files Browse the repository at this point in the history
Blink brings plugin to focus but does not forward the tab event to
plugin. Simulating tab to enable seamless tabbing across UI and plugin.

Bug: 989046
Change-Id: Ie156c66a25a87afe9b56083f98876cc6e75917e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2061636
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: Kevin Babbitt <kbabbitt@microsoft.com>
Commit-Queue: Ankit Kumar 🌪️ <ankk@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#761853}
  • Loading branch information
ankk0294 authored and Commit Bot committed Apr 23, 2020
1 parent 1372a6c commit 1104bcf
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 2 deletions.
38 changes: 38 additions & 0 deletions chrome/browser/pdf/pdf_extension_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2418,6 +2418,44 @@ IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Metrics) {
EXPECT_EQ(1, actions.GetActionCount("PDF.LoadSuccess"));
}

IN_PROC_BROWSER_TEST_F(PDFExtensionTest, TabInAndOutOfPDFPlugin) {
GURL test_pdf_url(embedded_test_server()->GetURL("/pdf/test.pdf"));
content::WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url);
ASSERT_TRUE(guest_contents);

// Set focus on PDF document.
ASSERT_TRUE(content::ExecuteScript(
guest_contents, "document.getElementById('plugin').focus();"));

// The script will ensure we return the id of the focused element on focus.
std::string script =
"function onFocus(e) {"
" domAutomationController.send(e.target.id);"
"}"
"const plugin = document.getElementById('plugin');"
"const button = "
"document.getElementById('zoom-toolbar').$['zoom-out-button'];"
"plugin.addEventListener('focus', onFocus);"
"button.addEventListener('focus', onFocus);";
ASSERT_TRUE(content::ExecuteScript(guest_contents, script));

// Helper to simulate a tab press and wait for a focus message.
auto press_tab_and_wait_for_message = [guest_contents](bool reverse) {
content::DOMMessageQueue msg_queue;
std::string reply;
SimulateKeyPress(guest_contents, ui::DomKey::TAB, ui::DomCode::TAB,
ui::VKEY_TAB, false, /*shift=*/reverse, false, false);
EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
return reply;
};

// Press <shift-tab> and ensure that last toolbar element (zoom-out-button)
// receives focus.
EXPECT_EQ("\"zoom-out-button\"", press_tab_and_wait_for_message(true));
// Press <tab> and ensure that PDF document receives focus.
EXPECT_EQ("\"plugin\"", press_tab_and_wait_for_message(false));
}

// This test suite does a simple text-extraction based on the accessibility
// internals, breaking lines & paragraphs where appropriate. Unlike
// TreeDumpTests, this allows us to verify the kNextOnLine and kPreviousOnLine
Expand Down
1 change: 1 addition & 0 deletions content/renderer/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ include_rules = [
"+third_party/hyphen/hyphen.h",
"+third_party/webrtc_overrides",
"+third_party/blink/public/common",
"+third_party/blink/public/mojom",
"+v8/include",
"+v8/src/third_party/vtune",
]
Expand Down
1 change: 1 addition & 0 deletions content/renderer/pepper/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ include_rules = [
"+third_party/opus",
"+ui/base/ime",
"+ui/base/range",
"+ui/events/keycodes/keyboard_codes.h",
]
5 changes: 5 additions & 0 deletions content/renderer/pepper/pepper_plugin_instance_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2229,6 +2229,11 @@ void PepperPluginInstanceImpl::OnHiddenForPlaceholder(bool hidden) {
UpdateLayer(false /* device_changed */);
}

bool PepperPluginInstanceImpl::SupportsKeyboardFocus() {
// Only PDF plugin supports keyboard focus.
return LoadPdfInterface();
}

void PepperPluginInstanceImpl::AddPluginObject(PluginObject* plugin_object) {
DCHECK(live_plugin_objects_.find(plugin_object) ==
live_plugin_objects_.end());
Expand Down
2 changes: 2 additions & 0 deletions content/renderer/pepper/pepper_plugin_instance_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// Should be used only for logging.
bool is_flash_plugin() const { return is_flash_plugin_; }

bool SupportsKeyboardFocus();

private:
friend class base::RefCounted<PepperPluginInstanceImpl>;
friend class PpapiPluginInstanceTest;
Expand Down
27 changes: 26 additions & 1 deletion content/renderer/pepper/pepper_webplugin_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/pepper/message_channel.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
Expand All @@ -23,7 +24,10 @@
#include "content/renderer/renderer_blink_platform_impl.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/var_tracker.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_rect.h"
Expand All @@ -37,6 +41,8 @@
#include "third_party/blink/public/web/web_print_params.h"
#include "third_party/blink/public/web/web_print_preset_options.h"
#include "third_party/blink/public/web/web_print_scaling_option.h"
#include "ui/base/cursor/cursor.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "url/gurl.h"

using ppapi::V8ObjectVar;
Expand Down Expand Up @@ -187,6 +193,10 @@ v8::Local<v8::Object> PepperWebPluginImpl::V8ScriptableObject(
return result;
}

bool PepperWebPluginImpl::SupportsKeyboardFocus() const {
return instance_ && instance_->SupportsKeyboardFocus();
}

void PepperWebPluginImpl::Paint(cc::PaintCanvas* canvas, const WebRect& rect) {
// Re-entrancy may cause JS to try to execute script on the plugin before it
// is fully initialized. See: crbug.com/715747.
Expand All @@ -208,8 +218,23 @@ void PepperWebPluginImpl::UpdateFocus(bool focused,
blink::mojom::FocusType focus_type) {
// Re-entrancy may cause JS to try to execute script on the plugin before it
// is fully initialized. See: crbug.com/715747.
if (instance_)
if (instance_) {
instance_->SetWebKitFocus(focused);

if (focused && instance_->SupportsKeyboardFocus()) {
int modifiers = blink::WebInputEvent::kNoModifiers;
if (focus_type == blink::mojom::FocusType::kBackward)
modifiers |= blink::WebInputEvent::kShiftKey;
// As part of focus management for plugin, blink brings plugin to focus
// but does not forward the tab event to plugin. Hence simulating tab
// event here to enable seamless tabbing across UI & plugin.
blink::WebKeyboardEvent simulated_event(blink::WebInputEvent::kKeyDown,
modifiers, base::TimeTicks());
simulated_event.windows_key_code = ui::KeyboardCode::VKEY_TAB;
ui::Cursor cursor;
instance_->HandleInputEvent(simulated_event, &cursor);
}
}
}

void PepperWebPluginImpl::UpdateVisibility(bool visible) {}
Expand Down
1 change: 1 addition & 0 deletions content/renderer/pepper/pepper_webplugin_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class PepperWebPluginImpl : public blink::WebPlugin {
bool Initialize(blink::WebPluginContainer* container) override;
void Destroy() override;
v8::Local<v8::Object> V8ScriptableObject(v8::Isolate* isolate) override;
bool SupportsKeyboardFocus() const override;
void UpdateAllLifecyclePhases(blink::DocumentUpdateReason) override {}
void Paint(cc::PaintCanvas* canvas, const blink::WebRect& rect) override;
void UpdateGeometry(const blink::WebRect& window_rect,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ bool HTMLPlugInElement::IsKeyboardFocusable() const {
if (HTMLFrameOwnerElement::IsKeyboardFocusable())
return true;
return GetDocument().IsActive() && PluginEmbeddedContentView() &&
PluginEmbeddedContentView()->SupportsKeyboardFocus();
PluginEmbeddedContentView()->SupportsKeyboardFocus() && IsFocusable();
}

bool HTMLPlugInElement::HasCustomFocusLogic() const {
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/web_tests/plugins/focus-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ CONSOLE MESSAGE: Blink Test Plugin: initializing
CONSOLE MESSAGE: Blink Test Plugin: initializing
CONSOLE MESSAGE: Blink Test Plugin: initializing
CONSOLE MESSAGE: Blink Test Plugin: initializing
CONSOLE MESSAGE: Blink Test Plugin: DidChangeFocus(true)
Test for Embed and Object for bug 32292: Unable to focus on embedded plugins such as Flash via javascript focus().

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Expand Down

0 comments on commit 1104bcf

Please sign in to comment.