Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(767)

Side by Side Diff: content/renderer/browser_plugin/browser_plugin.cc

Issue 250063002: Browser Plugin: Simplified guest attachment (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed New Window API test Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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/browser_plugin/browser_plugin.h" 5 #include "content/renderer/browser_plugin/browser_plugin.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/json/json_string_value_serializer.h" 8 #include "base/json/json_string_value_serializer.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 namespace content { 54 namespace content {
55 55
56 namespace { 56 namespace {
57 57
58 const char* kCustomPersistPartition = "persist:custom_plugin"; 58 const char* kCustomPersistPartition = "persist:custom_plugin";
59 59
60 static std::string GetInternalEventName(const char* event_name) { 60 static std::string GetInternalEventName(const char* event_name) {
61 return base::StringPrintf("-internal-%s", event_name); 61 return base::StringPrintf("-internal-%s", event_name);
62 } 62 }
63 63
64 typedef std::map<blink::WebPluginContainer*,
65 BrowserPlugin*> PluginContainerMap;
66 static base::LazyInstance<PluginContainerMap> g_plugin_container_map =
67 LAZY_INSTANCE_INITIALIZER;
68
69 } // namespace 64 } // namespace
70 65
71 BrowserPlugin::BrowserPlugin(RenderViewImpl* render_view, 66 BrowserPlugin::BrowserPlugin(RenderViewImpl* render_view,
72 blink::WebFrame* frame, 67 blink::WebFrame* frame,
73 bool auto_navigate) 68 bool auto_navigate)
74 : guest_instance_id_(browser_plugin::kInstanceIDNone), 69 : guest_instance_id_(browser_plugin::kInstanceIDNone),
75 attached_(false), 70 attached_(false),
76 render_view_(render_view->AsWeakPtr()), 71 render_view_(render_view->AsWeakPtr()),
77 render_view_routing_id_(render_view->GetRoutingID()), 72 render_view_routing_id_(render_view->GetRoutingID()),
78 container_(NULL), 73 container_(NULL),
(...skipping 22 matching lines...) Expand all
101 // BrowserPluginManager don't know about it and so there is nothing to do 96 // BrowserPluginManager don't know about it and so there is nothing to do
102 // here. 97 // here.
103 if (!HasGuestInstanceID()) 98 if (!HasGuestInstanceID())
104 return; 99 return;
105 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_); 100 browser_plugin_manager()->RemoveBrowserPlugin(guest_instance_id_);
106 browser_plugin_manager()->Send( 101 browser_plugin_manager()->Send(
107 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_, 102 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_,
108 guest_instance_id_)); 103 guest_instance_id_));
109 } 104 }
110 105
111 /*static*/
112 BrowserPlugin* BrowserPlugin::FromContainer(
113 blink::WebPluginContainer* container) {
114 PluginContainerMap* browser_plugins = g_plugin_container_map.Pointer();
115 PluginContainerMap::iterator it = browser_plugins->find(container);
116 return it == browser_plugins->end() ? NULL : it->second;
117 }
118
119 bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) { 106 bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
120 bool handled = true; 107 bool handled = true;
121 IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message) 108 IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message)
122 IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus) 109 IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus)
123 IPC_MESSAGE_HANDLER(BrowserPluginMsg_Attach_ACK, OnAttachACK) 110 IPC_MESSAGE_HANDLER(BrowserPluginMsg_Attach_ACK, OnAttachACK)
124 IPC_MESSAGE_HANDLER(BrowserPluginMsg_BuffersSwapped, OnBuffersSwapped) 111 IPC_MESSAGE_HANDLER(BrowserPluginMsg_BuffersSwapped, OnBuffersSwapped)
125 IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginMsg_CompositorFrameSwapped, 112 IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginMsg_CompositorFrameSwapped,
126 OnCompositorFrameSwapped(message)) 113 OnCompositorFrameSwapped(message))
127 IPC_MESSAGE_HANDLER(BrowserPluginMsg_CopyFromCompositingSurface, 114 IPC_MESSAGE_HANDLER(BrowserPluginMsg_CopyFromCompositingSurface,
128 OnCopyFromCompositingSurface) 115 OnCopyFromCompositingSurface)
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 360
374 bool BrowserPlugin::UsesPendingDamageBuffer( 361 bool BrowserPlugin::UsesPendingDamageBuffer(
375 const BrowserPluginMsg_UpdateRect_Params& params) { 362 const BrowserPluginMsg_UpdateRect_Params& params) {
376 if (!pending_damage_buffer_) 363 if (!pending_damage_buffer_)
377 return false; 364 return false;
378 return damage_buffer_sequence_id_ == params.damage_buffer_sequence_id; 365 return damage_buffer_sequence_id_ == params.damage_buffer_sequence_id;
379 } 366 }
380 367
381 void BrowserPlugin::OnInstanceIDAllocated(int guest_instance_id) { 368 void BrowserPlugin::OnInstanceIDAllocated(int guest_instance_id) {
382 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone); 369 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone);
383 before_first_navigation_ = false;
384 guest_instance_id_ = guest_instance_id;
385 browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this);
386 370
387 if (auto_navigate_) { 371 if (auto_navigate_) {
388 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue()); 372 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
389 Attach(params.Pass()); 373 Attach(guest_instance_id, params.Pass());
390 return; 374 return;
391 } 375 }
392 376
393 std::map<std::string, base::Value*> props; 377 std::map<std::string, base::Value*> props;
394 props[browser_plugin::kWindowID] = 378 props[browser_plugin::kWindowID] =
395 new base::FundamentalValue(guest_instance_id); 379 new base::FundamentalValue(guest_instance_id);
396 TriggerEvent(browser_plugin::kEventInternalInstanceIDAllocated, &props); 380 TriggerEvent(browser_plugin::kEventInternalInstanceIDAllocated, &props);
397 } 381 }
398 382
399 void BrowserPlugin::Attach(scoped_ptr<base::DictionaryValue> extra_params) { 383 void BrowserPlugin::Attach(int guest_instance_id,
384 scoped_ptr<base::DictionaryValue> extra_params) {
385 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone);
386
387 // If this BrowserPlugin is already attached to a guest, then do nothing.
388 if (HasGuestInstanceID())
389 return;
390
391 // This API may be called directly without setting the src attribute.
392 // In that case, we need to make sure we don't allocate another instance ID.
393 before_first_navigation_ = false;
394 guest_instance_id_ = guest_instance_id;
395 browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this);
396
400 BrowserPluginHostMsg_Attach_Params attach_params; 397 BrowserPluginHostMsg_Attach_Params attach_params;
401 attach_params.focused = ShouldGuestBeFocused(); 398 attach_params.focused = ShouldGuestBeFocused();
402 attach_params.visible = visible_; 399 attach_params.visible = visible_;
403 attach_params.opaque = !GetAllowTransparencyAttribute(); 400 attach_params.opaque = !GetAllowTransparencyAttribute();
404 attach_params.name = GetNameAttribute(); 401 attach_params.name = GetNameAttribute();
405 attach_params.storage_partition_id = storage_partition_id_; 402 attach_params.storage_partition_id = storage_partition_id_;
406 attach_params.persist_storage = persist_storage_; 403 attach_params.persist_storage = persist_storage_;
407 attach_params.src = GetSrcAttribute(); 404 attach_params.src = GetSrcAttribute();
408 attach_params.embedder_frame_url = embedder_frame_url_; 405 attach_params.embedder_frame_url = embedder_frame_url_;
409 GetDamageBufferWithSizeParams(&attach_params.auto_size_params, 406 GetDamageBufferWithSizeParams(&attach_params.auto_size_params,
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 if (content_window_routing_id_ == MSG_ROUTING_NONE) 683 if (content_window_routing_id_ == MSG_ROUTING_NONE)
687 return NULL; 684 return NULL;
688 RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID( 685 RenderViewImpl* guest_render_view = RenderViewImpl::FromRoutingID(
689 content_window_routing_id_); 686 content_window_routing_id_);
690 if (!guest_render_view) 687 if (!guest_render_view)
691 return NULL; 688 return NULL;
692 blink::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame(); 689 blink::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame();
693 return guest_frame->windowObject(); 690 return guest_frame->windowObject();
694 } 691 }
695 692
696 // static
697 bool BrowserPlugin::AttachWindowTo(const blink::WebNode& node, int window_id) {
698 if (node.isNull())
699 return false;
700
701 if (!node.isElementNode())
702 return false;
703
704 blink::WebElement shim_element = node.toConst<blink::WebElement>();
705 // The shim containing the BrowserPlugin must be attached to a document.
706 if (shim_element.document().isNull())
707 return false;
708
709 blink::WebNode shadow_root = shim_element.shadowRoot();
710 if (shadow_root.isNull() || !shadow_root.hasChildNodes())
711 return false;
712
713 blink::WebNode plugin_element = shadow_root.firstChild();
714 blink::WebPluginContainer* plugin_container =
715 plugin_element.pluginContainer();
716 if (!plugin_container)
717 return false;
718
719 BrowserPlugin* browser_plugin =
720 BrowserPlugin::FromContainer(plugin_container);
721 if (!browser_plugin)
722 return false;
723
724 // If the BrowserPlugin has already begun to navigate then we shouldn't allow
725 // attaching a different guest.
726 //
727 // Navigation happens in two stages.
728 // 1. BrowserPlugin requests an instance ID from the browser process.
729 // 2. The browser process returns an instance ID and BrowserPlugin is
730 // "Attach"ed to that instance ID.
731 // If the instance ID is new then a new guest will be created.
732 // If the instance ID corresponds to an unattached guest then BrowserPlugin
733 // is attached to that guest.
734 //
735 // Between step 1, and step 2, BrowserPlugin::AttachWindowTo may be called.
736 // The check below ensures that BrowserPlugin:Attach does not get called with
737 // a different instance ID after step 1 has happened.
738 // TODO(fsamuel): We may wish to support reattaching guests in the future:
739 // http://crbug.com/156219.
740 if (browser_plugin->HasNavigated())
741 return false;
742
743 browser_plugin->OnInstanceIDAllocated(window_id);
744 return true;
745 }
746
747 bool BrowserPlugin::HasNavigated() const { 693 bool BrowserPlugin::HasNavigated() const {
748 return !before_first_navigation_; 694 return !before_first_navigation_;
749 } 695 }
750 696
751 bool BrowserPlugin::HasGuestInstanceID() const { 697 bool BrowserPlugin::HasGuestInstanceID() const {
752 return guest_instance_id_ != browser_plugin::kInstanceIDNone; 698 return guest_instance_id_ != browser_plugin::kInstanceIDNone;
753 } 699 }
754 700
755 bool BrowserPlugin::ParsePartitionAttribute(std::string* error_message) { 701 bool BrowserPlugin::ParsePartitionAttribute(std::string* error_message) {
756 if (HasNavigated()) { 702 if (HasNavigated()) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 return false; 853 return false;
908 854
909 // Tell |container| to allow this plugin to use script objects. 855 // Tell |container| to allow this plugin to use script objects.
910 npp_.reset(new NPP_t); 856 npp_.reset(new NPP_t);
911 container->allowScriptObjects(); 857 container->allowScriptObjects();
912 858
913 bindings_.reset(new BrowserPluginBindings(this)); 859 bindings_.reset(new BrowserPluginBindings(this));
914 container_ = container; 860 container_ = container;
915 container_->setWantsWheelEvents(true); 861 container_->setWantsWheelEvents(true);
916 ParseAttributes(); 862 ParseAttributes();
917 g_plugin_container_map.Get().insert(std::make_pair(container_, this));
918 return true; 863 return true;
919 } 864 }
920 865
921 void BrowserPlugin::EnableCompositing(bool enable) { 866 void BrowserPlugin::EnableCompositing(bool enable) {
922 if (compositing_enabled_ == enable) 867 if (compositing_enabled_ == enable)
923 return; 868 return;
924 869
925 compositing_enabled_ = enable; 870 compositing_enabled_ = enable;
926 if (enable) { 871 if (enable) {
927 // No need to keep the backing store and damage buffer around if we're now 872 // No need to keep the backing store and damage buffer around if we're now
(...skipping 26 matching lines...) Expand all
954 compositing_helper_->SetContentsOpaque(!GetAllowTransparencyAttribute()); 899 compositing_helper_->SetContentsOpaque(!GetAllowTransparencyAttribute());
955 } 900 }
956 901
957 void BrowserPlugin::destroy() { 902 void BrowserPlugin::destroy() {
958 // If the plugin was initialized then it has a valid |npp_| identifier, and 903 // If the plugin was initialized then it has a valid |npp_| identifier, and
959 // the |container_| must clear references to the plugin's script objects. 904 // the |container_| must clear references to the plugin's script objects.
960 DCHECK(!npp_ || container_); 905 DCHECK(!npp_ || container_);
961 if (container_) 906 if (container_)
962 container_->clearScriptObjects(); 907 container_->clearScriptObjects();
963 908
964 // The BrowserPlugin's WebPluginContainer is deleted immediately after this
965 // call returns, so let's not keep a reference to it around.
966 g_plugin_container_map.Get().erase(container_);
967 if (compositing_helper_.get()) 909 if (compositing_helper_.get())
968 compositing_helper_->OnContainerDestroy(); 910 compositing_helper_->OnContainerDestroy();
969 container_ = NULL; 911 container_ = NULL;
970 // Will be a no-op if the mouse is not currently locked. 912 // Will be a no-op if the mouse is not currently locked.
971 if (render_view_.get()) 913 if (render_view_.get())
972 render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this); 914 render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
973 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 915 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
974 } 916 }
975 917
976 NPObject* BrowserPlugin::scriptableObject() { 918 NPObject* BrowserPlugin::scriptableObject() {
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 const blink::WebMouseEvent& event) { 1342 const blink::WebMouseEvent& event) {
1401 browser_plugin_manager()->Send( 1343 browser_plugin_manager()->Send(
1402 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, 1344 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_,
1403 guest_instance_id_, 1345 guest_instance_id_,
1404 plugin_rect_, 1346 plugin_rect_,
1405 &event)); 1347 &event));
1406 return true; 1348 return true;
1407 } 1349 }
1408 1350
1409 } // namespace content 1351 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/browser_plugin/browser_plugin.h ('k') | content/renderer/browser_plugin/browser_plugin_bindings.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698