summaryrefslogtreecommitdiffstats
path: root/content/renderer
diff options
context:
space:
mode:
authordgozman <dgozman@chromium.org>2016-03-22 14:33:13 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-22 21:35:23 +0000
commitc2ec05d98bce21ef672e6775e6f682d41f945f4e (patch)
tree860bb5126b4461f9f7a4d8fb0b3b5d34a6b378d7 /content/renderer
parent1e6a2bc451904125ced0e829f030056b8e2bd8e2 (diff)
downloadchromium_src-c2ec05d98bce21ef672e6775e6f682d41f945f4e.zip
chromium_src-c2ec05d98bce21ef672e6775e6f682d41f945f4e.tar.gz
chromium_src-c2ec05d98bce21ef672e6775e6f682d41f945f4e.tar.bz2
Revert of Remove a bunch of NPAPI quirks and related support code (patchset #1 id:80001 of https://codereview.chromium.org/1813143002/ )
Reason for revert: Speculative revert: could have broken Win8 GN build. See crbug.com/597032 Original issue's description: > Remove a bunch of NPAPI quirks and related support code > > BUG=493212 > CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_site_isolation > > Committed: https://crrev.com/f8396023a9e38d3ec249cdf1f730e4b79cebbc7e > Cr-Commit-Position: refs/heads/master@{#382642} TBR=dcheng@chromium.org,jam@chromium.org,piman@chromium.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=493212 Review URL: https://codereview.chromium.org/1825253002 Cr-Commit-Position: refs/heads/master@{#382684}
Diffstat (limited to 'content/renderer')
-rw-r--r--content/renderer/npapi/webplugin_delegate_proxy.cc104
-rw-r--r--content/renderer/npapi/webplugin_delegate_proxy.h25
-rw-r--r--content/renderer/npapi/webplugin_impl.h6
-rw-r--r--content/renderer/render_view_impl.cc52
-rw-r--r--content/renderer/render_view_impl.h9
5 files changed, 192 insertions, 4 deletions
diff --git a/content/renderer/npapi/webplugin_delegate_proxy.cc b/content/renderer/npapi/webplugin_delegate_proxy.cc
index d69fd40..2e80b85 100644
--- a/content/renderer/npapi/webplugin_delegate_proxy.cc
+++ b/content/renderer/npapi/webplugin_delegate_proxy.cc
@@ -108,6 +108,8 @@ WebPluginDelegateProxy::WebPluginDelegateProxy(
uses_shared_bitmaps_(true),
#if defined(OS_MACOSX)
uses_compositor_(false),
+#elif defined(OS_WIN)
+ dummy_activation_window_(NULL),
#endif
mime_type_(mime_type),
instance_id_(MSG_ROUTING_NONE),
@@ -130,12 +132,20 @@ WebPluginDelegateProxy::SharedBitmap::SharedBitmap() {}
WebPluginDelegateProxy::SharedBitmap::~SharedBitmap() {}
void WebPluginDelegateProxy::PluginDestroyed() {
-#if defined(OS_MACOSX)
+#if defined(OS_MACOSX) || defined(OS_WIN)
// Ensure that the renderer doesn't think the plugin still has focus.
if (render_view_)
render_view_->PluginFocusChanged(false, instance_id_);
#endif
+#if defined(OS_WIN)
+ if (dummy_activation_window_ && render_view_) {
+ render_view_->Send(new ViewHostMsg_WindowlessPluginDummyWindowDestroyed(
+ render_view_->GetRoutingID(), dummy_activation_window_));
+ }
+ dummy_activation_window_ = NULL;
+#endif
+
if (render_view_.get())
render_view_->UnregisterPluginDelegate(this);
@@ -294,6 +304,10 @@ bool WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(PluginHostMsg_CancelDocumentLoad, OnCancelDocumentLoad)
IPC_MESSAGE_HANDLER(PluginHostMsg_DidStartLoading, OnDidStartLoading)
IPC_MESSAGE_HANDLER(PluginHostMsg_DidStopLoading, OnDidStopLoading)
+#if defined(OS_WIN)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindowlessData, OnSetWindowlessData)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_NotifyIMEStatus, OnNotifyIMEStatus)
+#endif
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(PluginHostMsg_FocusChanged,
OnFocusChanged);
@@ -321,7 +335,7 @@ void WebPluginDelegateProxy::OnChannelError() {
info_.path, channel_host_->peer_pid());
}
-#if defined(OS_MACOSX)
+#if defined(OS_MACOSX) || defined(OS_WIN)
// Ensure that the renderer doesn't think the plugin still has focus.
if (render_view_)
render_view_->PluginFocusChanged(false, instance_id_);
@@ -577,6 +591,10 @@ bool WebPluginDelegateProxy::GetFormValue(base::string16* value) {
void WebPluginDelegateProxy::SetFocus(bool focused) {
Send(new PluginMsg_SetFocus(instance_id_, focused));
+#if defined(OS_WIN)
+ if (render_view_)
+ render_view_->PluginFocusChanged(focused, instance_id_);
+#endif
}
bool WebPluginDelegateProxy::HandleInputEvent(
@@ -584,7 +602,14 @@ bool WebPluginDelegateProxy::HandleInputEvent(
WebCursor::CursorInfo* cursor_info) {
bool handled = false;
WebCursor cursor;
- Send(new PluginMsg_HandleInputEvent(instance_id_, &event, &handled, &cursor));
+ // A windowless plugin can enter a modal loop in the context of a
+ // NPP_HandleEvent call, in which case we need to pump messages to
+ // the plugin. We pass of the corresponding event handle to the
+ // plugin process, which is set if the plugin does enter a modal loop.
+ IPC::SyncMessage* message = new PluginMsg_HandleInputEvent(
+ instance_id_, &event, &handled, &cursor);
+ message->set_pump_messages_event(modal_loop_pump_messages_event_.get());
+ Send(message);
return handled;
}
@@ -601,6 +626,35 @@ void WebPluginDelegateProxy::SetContentAreaFocus(bool has_focus) {
Send(msg);
}
+#if defined(OS_WIN)
+void WebPluginDelegateProxy::ImeCompositionUpdated(
+ const base::string16& text,
+ const std::vector<int>& clauses,
+ const std::vector<int>& target,
+ int cursor_position,
+ int plugin_id) {
+ // Dispatch the raw IME data if this plugin is the focused one.
+ if (instance_id_ != plugin_id)
+ return;
+
+ IPC::Message* msg = new PluginMsg_ImeCompositionUpdated(instance_id_,
+ text, clauses, target, cursor_position);
+ msg->set_unblock(true);
+ Send(msg);
+}
+
+void WebPluginDelegateProxy::ImeCompositionCompleted(const base::string16& text,
+ int plugin_id) {
+ // Dispatch the IME text if this plugin is the focused one.
+ if (instance_id_ != plugin_id)
+ return;
+
+ IPC::Message* msg = new PluginMsg_ImeCompositionCompleted(instance_id_, text);
+ msg->set_unblock(true);
+ Send(msg);
+}
+#endif
+
#if defined(OS_MACOSX)
void WebPluginDelegateProxy::SetWindowFocus(bool window_has_focus) {
IPC::Message* msg = new PluginMsg_SetWindowFocus(instance_id_,
@@ -652,6 +706,50 @@ void WebPluginDelegateProxy::ImeCompositionCompleted(const base::string16& text,
}
#endif // OS_MACOSX
+#if defined(OS_WIN)
+void WebPluginDelegateProxy::OnSetWindowlessData(
+ HANDLE modal_loop_pump_messages_event_handle,
+ gfx::NativeViewId dummy_activation_window) {
+ DCHECK(!modal_loop_pump_messages_event_.get());
+ DCHECK(!dummy_activation_window_);
+ base::win::ScopedHandle modal_loop_pump_messages_event(
+ modal_loop_pump_messages_event_handle);
+
+ dummy_activation_window_ = dummy_activation_window;
+ render_view_->Send(new ViewHostMsg_WindowlessPluginDummyWindowCreated(
+ render_view_->GetRoutingID(), dummy_activation_window_));
+
+ // Bug 25583: this can be null because some "virus scanners" block the
+ // DuplicateHandle call in the plugin process.
+ if (!modal_loop_pump_messages_event.IsValid())
+ return;
+
+ modal_loop_pump_messages_event_.reset(
+ new base::WaitableEvent(std::move(modal_loop_pump_messages_event)));
+}
+
+void WebPluginDelegateProxy::OnNotifyIMEStatus(int input_type,
+ const gfx::Rect& caret_rect) {
+ if (!render_view_)
+ return;
+
+ ViewHostMsg_TextInputState_Params params;
+ params.type = static_cast<ui::TextInputType>(input_type);
+ params.mode = ui::TEXT_INPUT_MODE_DEFAULT;
+ params.can_compose_inline = true;
+ render_view_->Send(new ViewHostMsg_TextInputStateChanged(
+ render_view_->GetRoutingID(), params));
+
+ ViewHostMsg_SelectionBounds_Params bounds_params;
+ bounds_params.anchor_rect = bounds_params.focus_rect = caret_rect;
+ bounds_params.anchor_dir = bounds_params.focus_dir =
+ blink::WebTextDirectionLeftToRight;
+ bounds_params.is_anchor_first = true;
+ render_view_->Send(new ViewHostMsg_SelectionBoundsChanged(
+ render_view_->GetRoutingID(), bounds_params));
+}
+#endif
+
void WebPluginDelegateProxy::OnInvalidateRect(const gfx::Rect& rect) {
if (!plugin_)
return;
diff --git a/content/renderer/npapi/webplugin_delegate_proxy.h b/content/renderer/npapi/webplugin_delegate_proxy.h
index d980de8..9e3643e 100644
--- a/content/renderer/npapi/webplugin_delegate_proxy.h
+++ b/content/renderer/npapi/webplugin_delegate_proxy.h
@@ -80,6 +80,19 @@ class WebPluginDelegateProxy
// Informs the plugin that its containing content view has gained or lost
// first responder status.
virtual void SetContentAreaFocus(bool has_focus);
+#if defined(OS_WIN)
+ // Informs the plugin that plugin IME has updated its status.
+ virtual void ImeCompositionUpdated(
+ const base::string16& text,
+ const std::vector<int>& clauses,
+ const std::vector<int>& target,
+ int cursor_position,
+ int plugin_id);
+ // Informs the plugin that plugin IME has completed.
+ // If |text| is empty, composition was cancelled.
+ virtual void ImeCompositionCompleted(const base::string16& text,
+ int plugin_id);
+#endif
#if defined(OS_MACOSX)
// Informs the plugin that its enclosing window has gained or lost focus.
virtual void SetWindowFocus(bool window_has_focus);
@@ -143,6 +156,11 @@ class WebPluginDelegateProxy
uint32_t surface_id);
void OnAcceleratedPluginSwappedIOSurface();
#endif
+#if defined(OS_WIN)
+ void OnSetWindowlessData(HANDLE modal_loop_pump_messages_event_handle,
+ gfx::NativeViewId dummy_activation_window);
+ void OnNotifyIMEStatus(const int input_mode, const gfx::Rect& caret_rect);
+#endif
// Helper function that sends the UpdateGeometry message.
void SendUpdateGeometry(bool bitmaps_changed);
@@ -208,6 +226,9 @@ class WebPluginDelegateProxy
bool uses_shared_bitmaps_;
#if defined(OS_MACOSX)
bool uses_compositor_;
+#elif defined(OS_WIN)
+ // Used for windowless plugins so that keyboard activation works.
+ gfx::NativeViewId dummy_activation_window_;
#endif
scoped_refptr<PluginChannelHost> channel_host_;
std::string mime_type_;
@@ -222,6 +243,10 @@ class WebPluginDelegateProxy
// Dummy NPP used to uniquely identify this plugin.
scoped_ptr<NPP_t> npp_;
+ // Event passed in by the plugin process and is used to decide if messages
+ // need to be pumped in the NPP_HandleEvent sync call.
+ scoped_ptr<base::WaitableEvent> modal_loop_pump_messages_event_;
+
// Bitmap for crashed plugin
SkBitmap* sad_plugin_;
diff --git a/content/renderer/npapi/webplugin_impl.h b/content/renderer/npapi/webplugin_impl.h
index 8d54cc3..3e695e6 100644
--- a/content/renderer/npapi/webplugin_impl.h
+++ b/content/renderer/npapi/webplugin_impl.h
@@ -110,6 +110,12 @@ class WebPluginImpl : public WebPlugin,
void DidStartLoading() override;
void DidStopLoading() override;
bool IsOffTheRecord() override;
+#if defined(OS_WIN)
+ void SetWindowlessData(HANDLE pump_messages_event,
+ gfx::NativeViewId dummy_activation_window) override {}
+ void ReparentPluginWindow(HWND window, HWND parent) { }
+ void ReportExecutableMemory(size_t size) { }
+#endif
#if defined(OS_MACOSX)
WebPluginAcceleratedSurface* GetAcceleratedSurface(
gfx::GpuPreference gpu_preference) override;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index a88549a..e5052e8 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -638,6 +638,9 @@ RenderViewImpl::RenderViewImpl(CompositorDependencies* compositor_deps,
#if defined(OS_ANDROID)
expected_content_intent_id_(0),
#endif
+#if defined(OS_WIN)
+ focused_plugin_id_(-1),
+#endif
#if defined(ENABLE_PLUGINS)
focused_pepper_plugin_(NULL),
pepper_last_mouse_event_target_(NULL),
@@ -1207,6 +1210,15 @@ void RenderViewImpl::UnregisterPluginDelegate(
plugin_delegates_.erase(delegate);
}
+#if defined(OS_WIN)
+void RenderViewImpl::PluginFocusChanged(bool focused, int plugin_id) {
+ if (focused)
+ focused_plugin_id_ = plugin_id;
+ else
+ focused_plugin_id_ = -1;
+}
+#endif
+
#if defined(OS_MACOSX)
void RenderViewImpl::PluginFocusChanged(bool focused, int plugin_id) {
Send(new ViewHostMsg_PluginFocusChanged(GetRoutingID(), focused, plugin_id));
@@ -2914,6 +2926,32 @@ void RenderViewImpl::OnImeSetComposition(
text, underlines, selection_start, selection_end);
return;
}
+
+#if defined(OS_WIN)
+ // When a plugin has focus, we create platform-specific IME data used by
+ // our IME emulator and send it directly to the focused plugin, i.e. we
+ // bypass WebKit. (WebPluginDelegate dispatches this IME data only when its
+ // instance ID is the same one as the specified ID.)
+ if (focused_plugin_id_ >= 0) {
+ std::vector<int> clauses;
+ std::vector<int> target;
+ for (size_t i = 0; i < underlines.size(); ++i) {
+ clauses.push_back(underlines[i].startOffset);
+ clauses.push_back(underlines[i].endOffset);
+ if (underlines[i].thick) {
+ target.clear();
+ target.push_back(underlines[i].startOffset);
+ target.push_back(underlines[i].endOffset);
+ }
+ }
+ std::set<WebPluginDelegateProxy*>::iterator it;
+ for (it = plugin_delegates_.begin(); it != plugin_delegates_.end(); ++it) {
+ (*it)->ImeCompositionUpdated(text, clauses, target, selection_end,
+ focused_plugin_id_);
+ }
+ return;
+ }
+#endif // OS_WIN
#endif // ENABLE_PLUGINS
if (replacement_range.IsValid() && webview()) {
// Select the text in |replacement_range|, it will then be replaced by
@@ -2942,6 +2980,20 @@ void RenderViewImpl::OnImeConfirmComposition(
text, replacement_range, keep_selection);
return;
}
+#if defined(OS_WIN)
+ // Same as OnImeSetComposition(), we send the text from IMEs directly to
+ // plugins. When we send IME text directly to plugins, we should not send
+ // it to WebKit to prevent WebKit from controlling IMEs.
+ // TODO(thakis): Honor |replacement_range| for plugins?
+ if (focused_plugin_id_ >= 0) {
+ std::set<WebPluginDelegateProxy*>::iterator it;
+ for (it = plugin_delegates_.begin();
+ it != plugin_delegates_.end(); ++it) {
+ (*it)->ImeCompositionCompleted(text, focused_plugin_id_);
+ }
+ return;
+ }
+#endif // OS_WIN
#endif // ENABLE_PLUGINS
if (replacement_range.IsValid() && webview()) {
// Select the text in |replacement_range|, it will then be replaced by
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index b8df750..d508b9f 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -258,10 +258,12 @@ class CONTENT_EXPORT RenderViewImpl
pepper_last_mouse_event_target_ = plugin;
}
-#if defined(OS_MACOSX)
+#if defined(OS_MACOSX) || defined(OS_WIN)
// Informs the render view that the given plugin has gained or lost focus.
void PluginFocusChanged(bool focused, int plugin_id);
+#endif
+#if defined(OS_MACOSX)
// Starts plugin IME.
void StartPluginIme();
#endif
@@ -940,6 +942,11 @@ class CONTENT_EXPORT RenderViewImpl
// location or tab focus and visibily. These are non-owning references.
std::set<WebPluginDelegateProxy*> plugin_delegates_;
+#if defined(OS_WIN)
+ // The ID of the focused NPAPI plugin.
+ int focused_plugin_id_;
+#endif
+
#if defined(ENABLE_PLUGINS)
typedef std::set<PepperPluginInstanceImpl*> PepperPluginSet;
PepperPluginSet active_pepper_instances_;