diff options
author | dgozman <dgozman@chromium.org> | 2016-03-22 14:33:13 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-22 21:35:23 +0000 |
commit | c2ec05d98bce21ef672e6775e6f682d41f945f4e (patch) | |
tree | 860bb5126b4461f9f7a4d8fb0b3b5d34a6b378d7 /content/renderer | |
parent | 1e6a2bc451904125ced0e829f030056b8e2bd8e2 (diff) | |
download | chromium_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.cc | 104 | ||||
-rw-r--r-- | content/renderer/npapi/webplugin_delegate_proxy.h | 25 | ||||
-rw-r--r-- | content/renderer/npapi/webplugin_impl.h | 6 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 52 | ||||
-rw-r--r-- | content/renderer/render_view_impl.h | 9 |
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_; |