OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/npapi/webplugin_delegate_proxy.h" | 5 #include "content/renderer/npapi/webplugin_delegate_proxy.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <utility> | 10 #include <utility> |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 WebPluginImpl* plugin, | 101 WebPluginImpl* plugin, |
102 const std::string& mime_type, | 102 const std::string& mime_type, |
103 const base::WeakPtr<RenderViewImpl>& render_view, | 103 const base::WeakPtr<RenderViewImpl>& render_view, |
104 RenderFrameImpl* render_frame) | 104 RenderFrameImpl* render_frame) |
105 : render_view_(render_view), | 105 : render_view_(render_view), |
106 render_frame_(render_frame), | 106 render_frame_(render_frame), |
107 plugin_(plugin), | 107 plugin_(plugin), |
108 uses_shared_bitmaps_(true), | 108 uses_shared_bitmaps_(true), |
109 #if defined(OS_MACOSX) | 109 #if defined(OS_MACOSX) |
110 uses_compositor_(false), | 110 uses_compositor_(false), |
| 111 #elif defined(OS_WIN) |
| 112 dummy_activation_window_(NULL), |
111 #endif | 113 #endif |
112 mime_type_(mime_type), | 114 mime_type_(mime_type), |
113 instance_id_(MSG_ROUTING_NONE), | 115 instance_id_(MSG_ROUTING_NONE), |
114 npobject_(NULL), | 116 npobject_(NULL), |
115 npp_(new NPP_t), | 117 npp_(new NPP_t), |
116 sad_plugin_(NULL), | 118 sad_plugin_(NULL), |
117 invalidate_pending_(false), | 119 invalidate_pending_(false), |
118 transparent_(false), | 120 transparent_(false), |
119 front_buffer_index_(0), | 121 front_buffer_index_(0), |
120 page_url_(render_view_->webview()->mainFrame()->document().url()) { | 122 page_url_(render_view_->webview()->mainFrame()->document().url()) { |
121 } | 123 } |
122 | 124 |
123 WebPluginDelegateProxy::~WebPluginDelegateProxy() { | 125 WebPluginDelegateProxy::~WebPluginDelegateProxy() { |
124 if (npobject_) | 126 if (npobject_) |
125 WebBindings::releaseObject(npobject_); | 127 WebBindings::releaseObject(npobject_); |
126 } | 128 } |
127 | 129 |
128 WebPluginDelegateProxy::SharedBitmap::SharedBitmap() {} | 130 WebPluginDelegateProxy::SharedBitmap::SharedBitmap() {} |
129 | 131 |
130 WebPluginDelegateProxy::SharedBitmap::~SharedBitmap() {} | 132 WebPluginDelegateProxy::SharedBitmap::~SharedBitmap() {} |
131 | 133 |
132 void WebPluginDelegateProxy::PluginDestroyed() { | 134 void WebPluginDelegateProxy::PluginDestroyed() { |
133 #if defined(OS_MACOSX) | 135 #if defined(OS_MACOSX) || defined(OS_WIN) |
134 // Ensure that the renderer doesn't think the plugin still has focus. | 136 // Ensure that the renderer doesn't think the plugin still has focus. |
135 if (render_view_) | 137 if (render_view_) |
136 render_view_->PluginFocusChanged(false, instance_id_); | 138 render_view_->PluginFocusChanged(false, instance_id_); |
137 #endif | 139 #endif |
138 | 140 |
| 141 #if defined(OS_WIN) |
| 142 if (dummy_activation_window_ && render_view_) { |
| 143 render_view_->Send(new ViewHostMsg_WindowlessPluginDummyWindowDestroyed( |
| 144 render_view_->GetRoutingID(), dummy_activation_window_)); |
| 145 } |
| 146 dummy_activation_window_ = NULL; |
| 147 #endif |
| 148 |
139 if (render_view_.get()) | 149 if (render_view_.get()) |
140 render_view_->UnregisterPluginDelegate(this); | 150 render_view_->UnregisterPluginDelegate(this); |
141 | 151 |
142 if (channel_host_.get()) { | 152 if (channel_host_.get()) { |
143 Send(new PluginMsg_DestroyInstance(instance_id_)); | 153 Send(new PluginMsg_DestroyInstance(instance_id_)); |
144 | 154 |
145 // Must remove the route after sending the destroy message, rather than | 155 // Must remove the route after sending the destroy message, rather than |
146 // before, since RemoveRoute can lead to all the outstanding NPObjects | 156 // before, since RemoveRoute can lead to all the outstanding NPObjects |
147 // being told the channel went away if this was the last instance. | 157 // being told the channel went away if this was the last instance. |
148 channel_host_->RemoveRoute(instance_id_); | 158 channel_host_->RemoveRoute(instance_id_); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 IPC_MESSAGE_HANDLER(PluginHostMsg_InvalidateRect, OnInvalidateRect) | 297 IPC_MESSAGE_HANDLER(PluginHostMsg_InvalidateRect, OnInvalidateRect) |
288 IPC_MESSAGE_HANDLER(PluginHostMsg_GetWindowScriptNPObject, | 298 IPC_MESSAGE_HANDLER(PluginHostMsg_GetWindowScriptNPObject, |
289 OnGetWindowScriptNPObject) | 299 OnGetWindowScriptNPObject) |
290 IPC_MESSAGE_HANDLER(PluginHostMsg_GetPluginElement, OnGetPluginElement) | 300 IPC_MESSAGE_HANDLER(PluginHostMsg_GetPluginElement, OnGetPluginElement) |
291 IPC_MESSAGE_HANDLER(PluginHostMsg_ResolveProxy, OnResolveProxy) | 301 IPC_MESSAGE_HANDLER(PluginHostMsg_ResolveProxy, OnResolveProxy) |
292 IPC_MESSAGE_HANDLER(PluginHostMsg_SetCookie, OnSetCookie) | 302 IPC_MESSAGE_HANDLER(PluginHostMsg_SetCookie, OnSetCookie) |
293 IPC_MESSAGE_HANDLER(PluginHostMsg_GetCookies, OnGetCookies) | 303 IPC_MESSAGE_HANDLER(PluginHostMsg_GetCookies, OnGetCookies) |
294 IPC_MESSAGE_HANDLER(PluginHostMsg_CancelDocumentLoad, OnCancelDocumentLoad) | 304 IPC_MESSAGE_HANDLER(PluginHostMsg_CancelDocumentLoad, OnCancelDocumentLoad) |
295 IPC_MESSAGE_HANDLER(PluginHostMsg_DidStartLoading, OnDidStartLoading) | 305 IPC_MESSAGE_HANDLER(PluginHostMsg_DidStartLoading, OnDidStartLoading) |
296 IPC_MESSAGE_HANDLER(PluginHostMsg_DidStopLoading, OnDidStopLoading) | 306 IPC_MESSAGE_HANDLER(PluginHostMsg_DidStopLoading, OnDidStopLoading) |
| 307 #if defined(OS_WIN) |
| 308 IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindowlessData, OnSetWindowlessData) |
| 309 IPC_MESSAGE_HANDLER(PluginHostMsg_NotifyIMEStatus, OnNotifyIMEStatus) |
| 310 #endif |
297 #if defined(OS_MACOSX) | 311 #if defined(OS_MACOSX) |
298 IPC_MESSAGE_HANDLER(PluginHostMsg_FocusChanged, | 312 IPC_MESSAGE_HANDLER(PluginHostMsg_FocusChanged, |
299 OnFocusChanged); | 313 OnFocusChanged); |
300 IPC_MESSAGE_HANDLER(PluginHostMsg_StartIme, | 314 IPC_MESSAGE_HANDLER(PluginHostMsg_StartIme, |
301 OnStartIme); | 315 OnStartIme); |
302 IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginEnabledRendering, | 316 IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginEnabledRendering, |
303 OnAcceleratedPluginEnabledRendering) | 317 OnAcceleratedPluginEnabledRendering) |
304 IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginAllocatedIOSurface, | 318 IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginAllocatedIOSurface, |
305 OnAcceleratedPluginAllocatedIOSurface) | 319 OnAcceleratedPluginAllocatedIOSurface) |
306 IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginSwappedIOSurface, | 320 IPC_MESSAGE_HANDLER(PluginHostMsg_AcceleratedPluginSwappedIOSurface, |
307 OnAcceleratedPluginSwappedIOSurface) | 321 OnAcceleratedPluginSwappedIOSurface) |
308 #endif | 322 #endif |
309 IPC_MESSAGE_UNHANDLED(handled = false) | 323 IPC_MESSAGE_UNHANDLED(handled = false) |
310 IPC_END_MESSAGE_MAP() | 324 IPC_END_MESSAGE_MAP() |
311 DCHECK(handled); | 325 DCHECK(handled); |
312 return handled; | 326 return handled; |
313 } | 327 } |
314 | 328 |
315 void WebPluginDelegateProxy::OnChannelError() { | 329 void WebPluginDelegateProxy::OnChannelError() { |
316 if (plugin_) { | 330 if (plugin_) { |
317 plugin_->Invalidate(); | 331 plugin_->Invalidate(); |
318 } | 332 } |
319 if (channel_host_.get() && !channel_host_->expecting_shutdown()) { | 333 if (channel_host_.get() && !channel_host_->expecting_shutdown()) { |
320 render_view_->GetMainRenderFrame()->PluginCrashed( | 334 render_view_->GetMainRenderFrame()->PluginCrashed( |
321 info_.path, channel_host_->peer_pid()); | 335 info_.path, channel_host_->peer_pid()); |
322 } | 336 } |
323 | 337 |
324 #if defined(OS_MACOSX) | 338 #if defined(OS_MACOSX) || defined(OS_WIN) |
325 // Ensure that the renderer doesn't think the plugin still has focus. | 339 // Ensure that the renderer doesn't think the plugin still has focus. |
326 if (render_view_) | 340 if (render_view_) |
327 render_view_->PluginFocusChanged(false, instance_id_); | 341 render_view_->PluginFocusChanged(false, instance_id_); |
328 #endif | 342 #endif |
329 } | 343 } |
330 | 344 |
331 static void CopySharedMemoryHandleForMessage( | 345 static void CopySharedMemoryHandleForMessage( |
332 const base::SharedMemoryHandle& handle_in, | 346 const base::SharedMemoryHandle& handle_in, |
333 base::SharedMemoryHandle* handle_out, | 347 base::SharedMemoryHandle* handle_out, |
334 base::ProcessId peer_pid) { | 348 base::ProcessId peer_pid) { |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 } | 584 } |
571 | 585 |
572 bool WebPluginDelegateProxy::GetFormValue(base::string16* value) { | 586 bool WebPluginDelegateProxy::GetFormValue(base::string16* value) { |
573 bool success = false; | 587 bool success = false; |
574 Send(new PluginMsg_GetFormValue(instance_id_, value, &success)); | 588 Send(new PluginMsg_GetFormValue(instance_id_, value, &success)); |
575 return success; | 589 return success; |
576 } | 590 } |
577 | 591 |
578 void WebPluginDelegateProxy::SetFocus(bool focused) { | 592 void WebPluginDelegateProxy::SetFocus(bool focused) { |
579 Send(new PluginMsg_SetFocus(instance_id_, focused)); | 593 Send(new PluginMsg_SetFocus(instance_id_, focused)); |
| 594 #if defined(OS_WIN) |
| 595 if (render_view_) |
| 596 render_view_->PluginFocusChanged(focused, instance_id_); |
| 597 #endif |
580 } | 598 } |
581 | 599 |
582 bool WebPluginDelegateProxy::HandleInputEvent( | 600 bool WebPluginDelegateProxy::HandleInputEvent( |
583 const WebInputEvent& event, | 601 const WebInputEvent& event, |
584 WebCursor::CursorInfo* cursor_info) { | 602 WebCursor::CursorInfo* cursor_info) { |
585 bool handled = false; | 603 bool handled = false; |
586 WebCursor cursor; | 604 WebCursor cursor; |
587 Send(new PluginMsg_HandleInputEvent(instance_id_, &event, &handled, &cursor)); | 605 // A windowless plugin can enter a modal loop in the context of a |
| 606 // NPP_HandleEvent call, in which case we need to pump messages to |
| 607 // the plugin. We pass of the corresponding event handle to the |
| 608 // plugin process, which is set if the plugin does enter a modal loop. |
| 609 IPC::SyncMessage* message = new PluginMsg_HandleInputEvent( |
| 610 instance_id_, &event, &handled, &cursor); |
| 611 message->set_pump_messages_event(modal_loop_pump_messages_event_.get()); |
| 612 Send(message); |
588 return handled; | 613 return handled; |
589 } | 614 } |
590 | 615 |
591 int WebPluginDelegateProxy::GetProcessId() { | 616 int WebPluginDelegateProxy::GetProcessId() { |
592 return channel_host_->peer_pid(); | 617 return channel_host_->peer_pid(); |
593 } | 618 } |
594 | 619 |
595 void WebPluginDelegateProxy::SetContentAreaFocus(bool has_focus) { | 620 void WebPluginDelegateProxy::SetContentAreaFocus(bool has_focus) { |
596 IPC::Message* msg = new PluginMsg_SetContentAreaFocus(instance_id_, | 621 IPC::Message* msg = new PluginMsg_SetContentAreaFocus(instance_id_, |
597 has_focus); | 622 has_focus); |
598 // Make sure focus events are delivered in the right order relative to | 623 // Make sure focus events are delivered in the right order relative to |
599 // sync messages they might interact with (Paint, HandleEvent, etc.). | 624 // sync messages they might interact with (Paint, HandleEvent, etc.). |
600 msg->set_unblock(true); | 625 msg->set_unblock(true); |
601 Send(msg); | 626 Send(msg); |
602 } | 627 } |
603 | 628 |
| 629 #if defined(OS_WIN) |
| 630 void WebPluginDelegateProxy::ImeCompositionUpdated( |
| 631 const base::string16& text, |
| 632 const std::vector<int>& clauses, |
| 633 const std::vector<int>& target, |
| 634 int cursor_position, |
| 635 int plugin_id) { |
| 636 // Dispatch the raw IME data if this plugin is the focused one. |
| 637 if (instance_id_ != plugin_id) |
| 638 return; |
| 639 |
| 640 IPC::Message* msg = new PluginMsg_ImeCompositionUpdated(instance_id_, |
| 641 text, clauses, target, cursor_position); |
| 642 msg->set_unblock(true); |
| 643 Send(msg); |
| 644 } |
| 645 |
| 646 void WebPluginDelegateProxy::ImeCompositionCompleted(const base::string16& text, |
| 647 int plugin_id) { |
| 648 // Dispatch the IME text if this plugin is the focused one. |
| 649 if (instance_id_ != plugin_id) |
| 650 return; |
| 651 |
| 652 IPC::Message* msg = new PluginMsg_ImeCompositionCompleted(instance_id_, text); |
| 653 msg->set_unblock(true); |
| 654 Send(msg); |
| 655 } |
| 656 #endif |
| 657 |
604 #if defined(OS_MACOSX) | 658 #if defined(OS_MACOSX) |
605 void WebPluginDelegateProxy::SetWindowFocus(bool window_has_focus) { | 659 void WebPluginDelegateProxy::SetWindowFocus(bool window_has_focus) { |
606 IPC::Message* msg = new PluginMsg_SetWindowFocus(instance_id_, | 660 IPC::Message* msg = new PluginMsg_SetWindowFocus(instance_id_, |
607 window_has_focus); | 661 window_has_focus); |
608 // Make sure focus events are delivered in the right order relative to | 662 // Make sure focus events are delivered in the right order relative to |
609 // sync messages they might interact with (Paint, HandleEvent, etc.). | 663 // sync messages they might interact with (Paint, HandleEvent, etc.). |
610 msg->set_unblock(true); | 664 msg->set_unblock(true); |
611 Send(msg); | 665 Send(msg); |
612 } | 666 } |
613 | 667 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 return; | 699 return; |
646 | 700 |
647 IPC::Message* msg = new PluginMsg_ImeCompositionCompleted(instance_id_, | 701 IPC::Message* msg = new PluginMsg_ImeCompositionCompleted(instance_id_, |
648 text); | 702 text); |
649 // Order relative to other key events is important. | 703 // Order relative to other key events is important. |
650 msg->set_unblock(true); | 704 msg->set_unblock(true); |
651 Send(msg); | 705 Send(msg); |
652 } | 706 } |
653 #endif // OS_MACOSX | 707 #endif // OS_MACOSX |
654 | 708 |
| 709 #if defined(OS_WIN) |
| 710 void WebPluginDelegateProxy::OnSetWindowlessData( |
| 711 HANDLE modal_loop_pump_messages_event_handle, |
| 712 gfx::NativeViewId dummy_activation_window) { |
| 713 DCHECK(!modal_loop_pump_messages_event_.get()); |
| 714 DCHECK(!dummy_activation_window_); |
| 715 base::win::ScopedHandle modal_loop_pump_messages_event( |
| 716 modal_loop_pump_messages_event_handle); |
| 717 |
| 718 dummy_activation_window_ = dummy_activation_window; |
| 719 render_view_->Send(new ViewHostMsg_WindowlessPluginDummyWindowCreated( |
| 720 render_view_->GetRoutingID(), dummy_activation_window_)); |
| 721 |
| 722 // Bug 25583: this can be null because some "virus scanners" block the |
| 723 // DuplicateHandle call in the plugin process. |
| 724 if (!modal_loop_pump_messages_event.IsValid()) |
| 725 return; |
| 726 |
| 727 modal_loop_pump_messages_event_.reset( |
| 728 new base::WaitableEvent(std::move(modal_loop_pump_messages_event))); |
| 729 } |
| 730 |
| 731 void WebPluginDelegateProxy::OnNotifyIMEStatus(int input_type, |
| 732 const gfx::Rect& caret_rect) { |
| 733 if (!render_view_) |
| 734 return; |
| 735 |
| 736 ViewHostMsg_TextInputState_Params params; |
| 737 params.type = static_cast<ui::TextInputType>(input_type); |
| 738 params.mode = ui::TEXT_INPUT_MODE_DEFAULT; |
| 739 params.can_compose_inline = true; |
| 740 render_view_->Send(new ViewHostMsg_TextInputStateChanged( |
| 741 render_view_->GetRoutingID(), params)); |
| 742 |
| 743 ViewHostMsg_SelectionBounds_Params bounds_params; |
| 744 bounds_params.anchor_rect = bounds_params.focus_rect = caret_rect; |
| 745 bounds_params.anchor_dir = bounds_params.focus_dir = |
| 746 blink::WebTextDirectionLeftToRight; |
| 747 bounds_params.is_anchor_first = true; |
| 748 render_view_->Send(new ViewHostMsg_SelectionBoundsChanged( |
| 749 render_view_->GetRoutingID(), bounds_params)); |
| 750 } |
| 751 #endif |
| 752 |
655 void WebPluginDelegateProxy::OnInvalidateRect(const gfx::Rect& rect) { | 753 void WebPluginDelegateProxy::OnInvalidateRect(const gfx::Rect& rect) { |
656 if (!plugin_) | 754 if (!plugin_) |
657 return; | 755 return; |
658 | 756 |
659 // Clip the invalidation rect to the plugin bounds; the plugin may have been | 757 // Clip the invalidation rect to the plugin bounds; the plugin may have been |
660 // resized since the invalidate message was sent. | 758 // resized since the invalidate message was sent. |
661 gfx::Rect clipped_rect = | 759 gfx::Rect clipped_rect = |
662 gfx::IntersectRects(rect, gfx::Rect(plugin_rect_.size())); | 760 gfx::IntersectRects(rect, gfx::Rect(plugin_rect_.size())); |
663 | 761 |
664 invalidate_pending_ = true; | 762 invalidate_pending_ = true; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 index->mime_type == "application/x-vnd.movenetworks.qm" || | 940 index->mime_type == "application/x-vnd.movenetworks.qm" || |
843 index->mime_type == "application/x-vnd.mnplayer.qm") { | 941 index->mime_type == "application/x-vnd.mnplayer.qm") { |
844 return true; | 942 return true; |
845 } | 943 } |
846 } | 944 } |
847 return false; | 945 return false; |
848 } | 946 } |
849 #endif | 947 #endif |
850 | 948 |
851 } // namespace content | 949 } // namespace content |
OLD | NEW |