diff options
18 files changed, 260 insertions, 139 deletions
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc index 1fd0a57..1338514 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.cc +++ b/content/browser/browser_plugin/browser_plugin_embedder.cc @@ -161,7 +161,7 @@ void BrowserPluginEmbedder::CreateGuest( static_cast<WebContentsImpl*>(guest->GetWebContents())-> CreateSwappedOutRenderView(web_contents()->GetSiteInstance()); render_view_host->Send(new BrowserPluginMsg_GuestContentWindowReady( - instance_id, guest_routing_id)); + render_view_host->GetRoutingID(), instance_id, guest_routing_id)); } void BrowserPluginEmbedder::NavigateGuest( diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index 89df1d92..3af1c7a 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc @@ -112,7 +112,9 @@ void BrowserPluginGuest::Observe(int type, bool BrowserPluginGuest::ViewTakeFocus(bool reverse) { SendMessageToEmbedder( - new BrowserPluginMsg_AdvanceFocus(instance_id(), reverse)); + new BrowserPluginMsg_AdvanceFocus(embedder_routing_id(), + instance_id(), + reverse)); return true; } @@ -158,7 +160,9 @@ bool BrowserPluginGuest::ShouldFocusPageAfterCrash() { void BrowserPluginGuest::SetIsAcceptingTouchEvents(bool accept) { SendMessageToEmbedder( - new BrowserPluginMsg_ShouldAcceptTouchEvents(instance_id(), accept)); + new BrowserPluginMsg_ShouldAcceptTouchEvents(embedder_routing_id(), + instance_id(), + accept)); } void BrowserPluginGuest::SetVisibility(bool embedder_visible, bool visible) { @@ -301,6 +305,10 @@ void BrowserPluginGuest::SetDamageBuffer( damage_buffer_scale_factor_ = scale_factor; } +int BrowserPluginGuest::embedder_routing_id() const { + return embedder_web_contents_->GetRoutingID(); +} + bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const { return size.width() <= max_auto_size_.width() && size.height() <= max_auto_size_.height(); @@ -364,7 +372,8 @@ void BrowserPluginGuest::UpdateRect( gfx::Size param_size = gfx::Size(params.view_size.width(), params.view_size.height()); - SendMessageToEmbedder(new BrowserPluginMsg_UpdateRect(instance_id(), + SendMessageToEmbedder(new BrowserPluginMsg_UpdateRect(embedder_routing_id(), + instance_id(), message_id, relay_params)); } @@ -469,7 +478,9 @@ void BrowserPluginGuest::ShowWidget(RenderViewHost* render_view_host, } void BrowserPluginGuest::SetCursor(const WebCursor& cursor) { - SendMessageToEmbedder(new BrowserPluginMsg_SetCursor(instance_id(), cursor)); + SendMessageToEmbedder(new BrowserPluginMsg_SetCursor(embedder_routing_id(), + instance_id(), + cursor)); } void BrowserPluginGuest::DidStartProvisionalLoadForFrame( @@ -481,7 +492,8 @@ void BrowserPluginGuest::DidStartProvisionalLoadForFrame( RenderViewHost* render_view_host) { // Inform the embedder of the loadStart. SendMessageToEmbedder( - new BrowserPluginMsg_LoadStart(instance_id(), + new BrowserPluginMsg_LoadStart(embedder_routing_id(), + instance_id(), validated_url, is_main_frame)); } @@ -498,7 +510,8 @@ void BrowserPluginGuest::DidFailProvisionalLoad( RemoveChars(net::ErrorToString(error_code), "net::", &error_type); // Inform the embedder of the loadAbort. SendMessageToEmbedder( - new BrowserPluginMsg_LoadAbort(instance_id(), + new BrowserPluginMsg_LoadAbort(embedder_routing_id(), + instance_id(), validated_url, is_main_frame, error_type)); @@ -509,8 +522,11 @@ void BrowserPluginGuest::LoadRedirect( const GURL& new_url, bool is_top_level) { SendMessageToEmbedder( - new BrowserPluginMsg_LoadRedirect( - instance_id(), old_url, new_url, is_top_level)); + new BrowserPluginMsg_LoadRedirect(embedder_routing_id(), + instance_id(), + old_url, + new_url, + is_top_level)); } void BrowserPluginGuest::DidCommitProvisionalLoadForFrame( @@ -529,12 +545,15 @@ void BrowserPluginGuest::DidCommitProvisionalLoadForFrame( params.entry_count = web_contents()->GetController().GetEntryCount(); SendMessageToEmbedder( - new BrowserPluginMsg_LoadCommit(instance_id(), params)); + new BrowserPluginMsg_LoadCommit(embedder_routing_id(), + instance_id(), + params)); RecordAction(UserMetricsAction("BrowserPlugin.Guest.DidNavigate")); } void BrowserPluginGuest::DidStopLoading(RenderViewHost* render_view_host) { - SendMessageToEmbedder(new BrowserPluginMsg_LoadStop(instance_id())); + SendMessageToEmbedder(new BrowserPluginMsg_LoadStop(embedder_routing_id(), + instance_id())); } void BrowserPluginGuest::RenderViewReady() { @@ -562,7 +581,8 @@ void BrowserPluginGuest::RenderViewGone(base::TerminationStatus status) { SendMessageToEmbedder(reply_message); } int process_id = web_contents()->GetRenderProcessHost()->GetID(); - SendMessageToEmbedder(new BrowserPluginMsg_GuestGone(instance_id(), + SendMessageToEmbedder(new BrowserPluginMsg_GuestGone(embedder_routing_id(), + instance_id(), process_id, status)); IDMap<RenderViewHost>::const_iterator iter(&pending_updates_); diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index f4a3661..d92a2d319 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h @@ -247,6 +247,9 @@ class CONTENT_EXPORT BrowserPluginGuest : public NotificationObserver, RenderViewHost* embedder_rvh, const BrowserPluginHostMsg_ResizeGuest_Params& params); + // Returns the embedder's routing ID. + int embedder_routing_id() const; + // Helper to send messages to embedder. Overridden in test implementation // since we want to intercept certain messages for testing. virtual void SendMessageToEmbedder(IPC::Message* msg); diff --git a/content/common/browser_plugin_messages.h b/content/common/browser_plugin_messages.h index 7267b13..782b9a3 100644 --- a/content/common/browser_plugin_messages.h +++ b/content/common/browser_plugin_messages.h @@ -227,82 +227,81 @@ IPC_SYNC_MESSAGE_ROUTED2_0(BrowserPluginHostMsg_ResizeGuest, // Once the swapped out guest RenderView has been created in the embedder render // process, the browser process informs the embedder of its routing ID. -IPC_MESSAGE_CONTROL2(BrowserPluginMsg_GuestContentWindowReady, - int /* instance_id */, - int /* source_routing_id */) +IPC_MESSAGE_ROUTED2(BrowserPluginMsg_GuestContentWindowReady, + int /* instance_id */, + int /* source_routing_id */) // When the guest begins to load a page, the browser process informs the // embedder through the BrowserPluginMsg_LoadStart message. -IPC_MESSAGE_CONTROL3(BrowserPluginMsg_LoadStart, - int /* instance_id */, - GURL /* url */, - bool /* is_top_level */) +IPC_MESSAGE_ROUTED3(BrowserPluginMsg_LoadStart, + int /* instance_id */, + GURL /* url */, + bool /* is_top_level */) // If the guest fails to commit a page load then it will inform the // embedder through the BrowserPluginMsg_LoadAbort. A description // of the error will be stored in |type|. The list of known error // types can be found in net/base/net_error_list.h. -IPC_MESSAGE_CONTROL4(BrowserPluginMsg_LoadAbort, - int /* instance_id */, - GURL /* url */, - bool /* is_top_level */, - std::string /* type */) +IPC_MESSAGE_ROUTED4(BrowserPluginMsg_LoadAbort, + int /* instance_id */, + GURL /* url */, + bool /* is_top_level */, + std::string /* type */) // When the guest redirects a navigation, the browser process informs the // embedder through the BrowserPluginMsg_LoadRedirect message. -IPC_MESSAGE_CONTROL4(BrowserPluginMsg_LoadRedirect, - int /* instance_id */, - GURL /* old_url */, - GURL /* new_url */, - bool /* is_top_level */) +IPC_MESSAGE_ROUTED4(BrowserPluginMsg_LoadRedirect, + int /* instance_id */, + GURL /* old_url */, + GURL /* new_url */, + bool /* is_top_level */) // When the guest commits a navigation, the browser process informs // the embedder through the BrowserPluginMsg_DidCommit message. -IPC_MESSAGE_CONTROL2(BrowserPluginMsg_LoadCommit, - int /* instance_id */, - BrowserPluginMsg_LoadCommit_Params) +IPC_MESSAGE_ROUTED2(BrowserPluginMsg_LoadCommit, + int /* instance_id */, + BrowserPluginMsg_LoadCommit_Params) // When the guest page has completed loading (including subframes), the browser // process informs the embedder through the BrowserPluginMsg_LoadStop message. -IPC_MESSAGE_CONTROL1(BrowserPluginMsg_LoadStop, - int /* instance_id */) +IPC_MESSAGE_ROUTED1(BrowserPluginMsg_LoadStop, + int /* instance_id */) // When the guest crashes, the browser process informs the embedder through this // message. -IPC_MESSAGE_CONTROL3(BrowserPluginMsg_GuestGone, - int /* instance_id */, - int /* process_id */, - int /* This is really base::TerminationStatus */) +IPC_MESSAGE_ROUTED3(BrowserPluginMsg_GuestGone, + int /* instance_id */, + int /* process_id */, + int /* This is really base::TerminationStatus */) // When the user tabs to the end of the tab stops of a guest, the browser // process informs the embedder to tab out of the browser plugin. -IPC_MESSAGE_CONTROL2(BrowserPluginMsg_AdvanceFocus, - int /* instance_id */, - bool /* reverse */) +IPC_MESSAGE_ROUTED2(BrowserPluginMsg_AdvanceFocus, + int /* instance_id */, + bool /* reverse */) // When the guest starts/stops listening to touch events, it needs to notify the // plugin in the embedder about it. -IPC_MESSAGE_CONTROL2(BrowserPluginMsg_ShouldAcceptTouchEvents, - int /* instance_id */, - bool /* accept */) +IPC_MESSAGE_ROUTED2(BrowserPluginMsg_ShouldAcceptTouchEvents, + int /* instance_id */, + bool /* accept */) // Inform the embedder of the cursor the guest wishes to display. -IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetCursor, - int /* instance_id */, - WebCursor /* cursor */) +IPC_MESSAGE_ROUTED2(BrowserPluginMsg_SetCursor, + int /* instance_id */, + WebCursor /* cursor */) // The guest has damage it wants to convey to the embedder so that it can // update its backing store. -IPC_MESSAGE_CONTROL3(BrowserPluginMsg_UpdateRect, - int /* instance_id */, - int /* message_id */, - BrowserPluginMsg_UpdateRect_Params) +IPC_MESSAGE_ROUTED3(BrowserPluginMsg_UpdateRect, + int /* instance_id */, + int /* message_id */, + BrowserPluginMsg_UpdateRect_Params) // Requests the renderer to find out if a browser plugin is at position // (|x|, |y|) within the embedder. // The response message is BrowserPluginHostMsg_PluginAtPositionResponse. // The |request_id| uniquely identifies a request from an embedder. -IPC_MESSAGE_CONTROL3(BrowserPluginMsg_PluginAtPositionRequest, - int /* source_routing_id */, - int /* request_id */, - gfx::Point /* position */) +IPC_MESSAGE_ROUTED2(BrowserPluginMsg_PluginAtPositionRequest, + int /* request_id */, + gfx::Point /* position */) diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index efc9e4a..a0dde73 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -216,6 +216,7 @@ 'renderer/browser_plugin/browser_plugin_bindings.cc', 'renderer/browser_plugin/browser_plugin_manager.h', 'renderer/browser_plugin/browser_plugin_manager.cc', + 'renderer/browser_plugin/browser_plugin_manager_factory.h', 'renderer/browser_plugin/browser_plugin_manager_impl.h', 'renderer/browser_plugin/browser_plugin_manager_impl.cc', 'renderer/render_process.h', diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index b63d735..d8696ed 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc @@ -121,9 +121,10 @@ BrowserPlugin::BrowserPlugin( embedder_focused_(false), visible_(true), size_changed_in_flight_(false), + browser_plugin_manager_(render_view->browser_plugin_manager()), current_nav_entry_index_(0), nav_entry_count_(0) { - BrowserPluginManager::Get()->AddBrowserPlugin(instance_id, this); + browser_plugin_manager()->AddBrowserPlugin(instance_id, this); bindings_.reset(new BrowserPluginBindings(this)); ParseAttributes(params); @@ -132,8 +133,8 @@ BrowserPlugin::BrowserPlugin( BrowserPlugin::~BrowserPlugin() { if (damage_buffer_) FreeDamageBuffer(); - BrowserPluginManager::Get()->RemoveBrowserPlugin(instance_id_); - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->RemoveBrowserPlugin(instance_id_); + browser_plugin_manager()->Send( new BrowserPluginHostMsg_PluginDestroyed( render_view_routing_id_, instance_id_)); @@ -164,7 +165,7 @@ bool BrowserPlugin::SetSrcAttribute(const std::string& src, params.focused = ShouldGuestBeFocused(); params.visible = visible_; PopulateAutoSizeParameters(¶ms.auto_size); - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_CreateGuest( render_view_routing_id_, instance_id_, @@ -175,7 +176,7 @@ bool BrowserPlugin::SetSrcAttribute(const std::string& src, GetPendingResizeParams()); DCHECK(!params->resize_pending); - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_NavigateGuest( render_view_routing_id_, instance_id_, @@ -229,7 +230,7 @@ void BrowserPlugin::UpdateGuestAutoSizeState() { // we just want to make sure the damage buffer has been updated. resize_params.resize_pending = true; DCHECK(new_damage_buffer); - BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SetAutoSize( + browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetAutoSize( render_view_routing_id_, instance_id_, auto_size_params, @@ -417,7 +418,7 @@ void BrowserPlugin::TriggerEvent(const std::string& event_name, void BrowserPlugin::Back() { if (!navigate_src_sent_) return; - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_Go(render_view_routing_id_, instance_id_, -1)); } @@ -425,7 +426,7 @@ void BrowserPlugin::Back() { void BrowserPlugin::Forward() { if (!navigate_src_sent_) return; - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_Go(render_view_routing_id_, instance_id_, 1)); } @@ -433,7 +434,7 @@ void BrowserPlugin::Forward() { void BrowserPlugin::Go(int relative_index) { if (!navigate_src_sent_) return; - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_Go(render_view_routing_id_, instance_id_, relative_index)); @@ -442,7 +443,7 @@ void BrowserPlugin::Go(int relative_index) { void BrowserPlugin::TerminateGuest() { if (!navigate_src_sent_) return; - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_TerminateGuest(render_view_routing_id_, instance_id_)); } @@ -450,7 +451,7 @@ void BrowserPlugin::TerminateGuest() { void BrowserPlugin::Stop() { if (!navigate_src_sent_) return; - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_Stop(render_view_routing_id_, instance_id_)); } @@ -458,7 +459,7 @@ void BrowserPlugin::Stop() { void BrowserPlugin::Reload() { if (!navigate_src_sent_) return; - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_Reload(render_view_routing_id_, instance_id_)); } @@ -474,7 +475,7 @@ void BrowserPlugin::UpdateRect( (width() != params.view_size.width() || height() != params.view_size.height())) || (auto_size_ && (!InAutoSizeBounds(params.view_size)))) { - BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( + browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( render_view_routing_id_, instance_id_, message_id, @@ -537,7 +538,7 @@ void BrowserPlugin::UpdateRect( // NULL so we shouldn't attempt to access it. if (container_) container_->invalidate(); - BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( + browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( render_view_routing_id_, instance_id_, message_id, @@ -637,7 +638,7 @@ void BrowserPlugin::UpdateGuestFocus() { if (!navigate_src_sent_) return; bool should_be_focused = ShouldGuestBeFocused(); - BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SetFocus( + browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetFocus( render_view_routing_id_, instance_id_, should_be_focused)); @@ -758,7 +759,7 @@ void BrowserPlugin::updateGeometry( DCHECK(new_damage_buffer); if (navigate_src_sent_) { - BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_ResizeGuest( + browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( render_view_routing_id_, instance_id_, *params)); @@ -850,7 +851,7 @@ TransportDIB* BrowserPlugin::CreateTransportDIB(const size_t size) { false, // cache in browser. &handle); TransportDIB* new_damage_buffer = NULL; - if (BrowserPluginManager::Get()->Send(msg) && handle.fd >= 0) + if (browser_plugin_manager()->Send(msg) && handle.fd >= 0) new_damage_buffer = TransportDIB::Map(handle); #else TransportDIB* new_damage_buffer = @@ -887,7 +888,7 @@ void BrowserPlugin::updateVisibility(bool visible) { if (!navigate_src_sent_) return; - BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SetVisibility( + browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetVisibility( render_view_routing_id_, instance_id_, visible)); @@ -911,7 +912,7 @@ bool BrowserPlugin::handleInputEvent(const WebKit::WebInputEvent& event, message->WriteData(reinterpret_cast<const char*>(&plugin_rect_), sizeof(gfx::Rect)); message->WriteData(reinterpret_cast<const char*>(&event), event.size); - BrowserPluginManager::Get()->Send(message); + browser_plugin_manager()->Send(message); cursor_.GetCursorInfo(&cursor_info); return handled; } @@ -923,7 +924,7 @@ bool BrowserPlugin::handleDragStatusUpdate(WebKit::WebDragStatus drag_status, const WebKit::WebPoint& screen) { if (guest_crashed_ || !navigate_src_sent_) return false; - BrowserPluginManager::Get()->Send( + browser_plugin_manager()->Send( new BrowserPluginHostMsg_DragStatusUpdate( render_view_routing_id_, instance_id_, diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index 6abd3e2..caf1c28 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h @@ -203,6 +203,9 @@ class CONTENT_EXPORT BrowserPlugin : int height() const { return plugin_rect_.height(); } int instance_id() const { return instance_id_; } int render_view_routing_id() const { return render_view_routing_id_; } + BrowserPluginManager* browser_plugin_manager() const { + return browser_plugin_manager_; + } // Virtual to allow for mocking in tests. virtual float GetDeviceScaleFactor() const; @@ -290,6 +293,11 @@ class CONTENT_EXPORT BrowserPlugin : gfx::Size last_view_size_; bool size_changed_in_flight_; + // BrowserPlugin outlives RenderViewImpl in Chrome Apps and so we need to + // store the BrowserPlugin's BrowserPluginManager in a member variable to + // avoid accessing the RenderViewImpl. + scoped_refptr<BrowserPluginManager> browser_plugin_manager_; + // Important: Do not add more history state here. // We strongly discourage storing additional history state (such as page IDs) // in the embedder process, at the risk of having incorrect information that diff --git a/content/renderer/browser_plugin/browser_plugin_browsertest.cc b/content/renderer/browser_plugin/browser_plugin_browsertest.cc index 4692305..4904da8 100644 --- a/content/renderer/browser_plugin/browser_plugin_browsertest.cc +++ b/content/renderer/browser_plugin/browser_plugin_browsertest.cc @@ -6,10 +6,12 @@ #include "base/file_path.h" #include "base/file_util.h" +#include "base/memory/singleton.h" #include "base/path_service.h" #include "content/common/browser_plugin_messages.h" #include "content/public/common/content_constants.h" #include "content/renderer/browser_plugin/browser_plugin.h" +#include "content/renderer/browser_plugin/browser_plugin_manager_factory.h" #include "content/renderer/browser_plugin/mock_browser_plugin.h" #include "content/renderer/browser_plugin/mock_browser_plugin_manager.h" #include "content/renderer/render_thread_impl.h" @@ -48,18 +50,46 @@ std::string GetHTMLForBrowserPluginObject() { namespace content { +// Test factory for creating test instances of BrowserPluginManager. +class TestBrowserPluginManagerFactory : public BrowserPluginManagerFactory { + public: + virtual MockBrowserPluginManager* CreateBrowserPluginManager( + RenderViewImpl* render_view) OVERRIDE { + return new MockBrowserPluginManager(render_view); + } + + // Singleton getter. + static TestBrowserPluginManagerFactory* GetInstance() { + return Singleton<TestBrowserPluginManagerFactory>::get(); + } + + protected: + TestBrowserPluginManagerFactory() {} + virtual ~TestBrowserPluginManagerFactory() {} + + private: + // For Singleton. + friend struct DefaultSingletonTraits<TestBrowserPluginManagerFactory>; + + DISALLOW_COPY_AND_ASSIGN(TestBrowserPluginManagerFactory); +}; + BrowserPluginTest::BrowserPluginTest() {} BrowserPluginTest::~BrowserPluginTest() {} void BrowserPluginTest::SetUp() { GetContentClient()->set_renderer_for_testing(&content_renderer_client_); + BrowserPluginManager::set_factory_for_testing( + TestBrowserPluginManagerFactory::GetInstance()); content::RenderViewTest::SetUp(); - browser_plugin_manager_.reset(new MockBrowserPluginManager()); + } void BrowserPluginTest::TearDown() { - browser_plugin_manager_->Cleanup(); + browser_plugin_manager()->Cleanup(); + BrowserPluginManager::set_factory_for_testing( + TestBrowserPluginManagerFactory::GetInstance()); content::RenderViewTest::TearDown(); } diff --git a/content/renderer/browser_plugin/browser_plugin_browsertest.h b/content/renderer/browser_plugin/browser_plugin_browsertest.h index 90cc636..13f0215 100644 --- a/content/renderer/browser_plugin/browser_plugin_browsertest.h +++ b/content/renderer/browser_plugin/browser_plugin_browsertest.h @@ -28,12 +28,12 @@ class BrowserPluginTest : public RenderViewTest { virtual void SetUp() OVERRIDE; virtual void TearDown() OVERRIDE; MockBrowserPluginManager* browser_plugin_manager() const { - return browser_plugin_manager_.get(); + return static_cast<MockBrowserPluginManager*>( + static_cast<RenderViewImpl*>(view_)->browser_plugin_manager()); } std::string ExecuteScriptAndReturnString(const std::string& script); int ExecuteScriptAndReturnInt(const std::string& script); private: - scoped_ptr<MockBrowserPluginManager> browser_plugin_manager_; ContentRendererClient content_renderer_client_; }; diff --git a/content/renderer/browser_plugin/browser_plugin_manager.cc b/content/renderer/browser_plugin/browser_plugin_manager.cc index 35169ec..4cc3426 100644 --- a/content/renderer/browser_plugin/browser_plugin_manager.cc +++ b/content/renderer/browser_plugin/browser_plugin_manager.cc @@ -8,46 +8,41 @@ #include "base/threading/thread_local.h" #include "content/public/renderer/render_thread.h" #include "content/renderer/browser_plugin/browser_plugin.h" +#include "content/renderer/browser_plugin/browser_plugin_manager_factory.h" #include "content/renderer/browser_plugin/browser_plugin_manager_impl.h" namespace content { -static base::LazyInstance<base::ThreadLocalPointer< - BrowserPluginManager> > lazy_tls = LAZY_INSTANCE_INITIALIZER; +// static +BrowserPluginManagerFactory* BrowserPluginManager::factory_ = NULL; -BrowserPluginManager* BrowserPluginManager::Get() { - BrowserPluginManager* manager = lazy_tls.Pointer()->Get(); - if (!manager) { - manager = new BrowserPluginManagerImpl(); - lazy_tls.Pointer()->Set(manager); - } - return manager; +BrowserPluginManager* BrowserPluginManager::Create( + RenderViewImpl* render_view) { + if (factory_) + return factory_->CreateBrowserPluginManager(render_view); + return new BrowserPluginManagerImpl(render_view); } -BrowserPluginManager::BrowserPluginManager() - : browser_plugin_counter_(0) { - lazy_tls.Pointer()->Set(this); - RenderThread::Get()->AddObserver(this); +BrowserPluginManager::BrowserPluginManager(RenderViewImpl* render_view) + : RenderViewObserver(render_view), + render_view_(render_view->AsWeakPtr()), + browser_plugin_counter_(0) { } BrowserPluginManager::~BrowserPluginManager() { - lazy_tls.Pointer()->Set(NULL); } void BrowserPluginManager::AddBrowserPlugin( int instance_id, BrowserPlugin* browser_plugin) { - DCHECK(CalledOnValidThread()); instances_.AddWithID(browser_plugin, instance_id); } void BrowserPluginManager::RemoveBrowserPlugin(int instance_id) { - DCHECK(CalledOnValidThread()); instances_.Remove(instance_id); } BrowserPlugin* BrowserPluginManager::GetBrowserPlugin(int instance_id) const { - DCHECK(CalledOnValidThread()); return instances_.Lookup(instance_id); } diff --git a/content/renderer/browser_plugin/browser_plugin_manager.h b/content/renderer/browser_plugin/browser_plugin_manager.h index af950fa..b6dab83 100644 --- a/content/renderer/browser_plugin/browser_plugin_manager.h +++ b/content/renderer/browser_plugin/browser_plugin_manager.h @@ -6,8 +6,10 @@ #define CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_MANAGER_H_ #include "base/id_map.h" -#include "base/threading/non_thread_safe.h" -#include "content/public/renderer/render_process_observer.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "content/public/renderer/render_view_observer.h" #include "ipc/ipc_sender.h" namespace WebKit { @@ -18,21 +20,25 @@ struct WebPluginParams; namespace content { class BrowserPlugin; +class BrowserPluginManagerFactory; class RenderViewImpl; // BrowserPluginManager manages the routing of messages to the appropriate -// BrowserPlugin object based on its instance ID. There is only one -// BrowserPluginManager per renderer process, and it should only be accessed -// by the render thread. -class CONTENT_EXPORT BrowserPluginManager : public IPC::Sender, - public RenderProcessObserver, - public base::NonThreadSafe { +// BrowserPlugin object based on its instance ID. +class CONTENT_EXPORT BrowserPluginManager + : public RenderViewObserver, + public base::RefCounted<BrowserPluginManager> { public: // Returns the one BrowserPluginManager for this process. - static BrowserPluginManager* Get(); + static BrowserPluginManager* Create(RenderViewImpl* render_view); - BrowserPluginManager(); - virtual ~BrowserPluginManager(); + // Overrides factory for testing. Default (NULL) value indicates regular + // (non-test) environment. + static void set_factory_for_testing(BrowserPluginManagerFactory* factory) { + BrowserPluginManager::factory_ = factory; + } + + BrowserPluginManager(RenderViewImpl* render_view); // Creates a new BrowserPlugin object with a unique identifier. // BrowserPlugin is responsible for associating itself with the @@ -47,9 +53,29 @@ class CONTENT_EXPORT BrowserPluginManager : public IPC::Sender, void RemoveBrowserPlugin(int instance_id); BrowserPlugin* GetBrowserPlugin(int instance_id) const; void SetEmbedderFocus(const RenderViewImpl* embedder, bool focused); + RenderViewImpl* render_view() const { return render_view_; } + + // RenderViewObserver implementation. + + // BrowserPluginManager must override the default Send behavior. + virtual bool Send(IPC::Message* msg) OVERRIDE = 0; + + // Don't destroy the BrowserPluginManager when the RenderViewImpl goes away. + // BrowserPluginManager's lifetime is managed by a reference count. Once + // the host RenderViewImpl and all BrowserPlugins release their references, + // then the BrowserPluginManager will be destroyed. + virtual void OnDestruct() OVERRIDE {} protected: + // Friend RefCounted so that the dtor can be non-public. + friend class base::RefCounted<BrowserPluginManager>; + + // Static factory instance (always NULL for non-test). + static BrowserPluginManagerFactory* factory_; + + virtual ~BrowserPluginManager(); IDMap<BrowserPlugin> instances_; + base::WeakPtr<RenderViewImpl> render_view_; int browser_plugin_counter_; }; diff --git a/content/renderer/browser_plugin/browser_plugin_manager_factory.h b/content/renderer/browser_plugin/browser_plugin_manager_factory.h new file mode 100644 index 0000000..3178fed --- /dev/null +++ b/content/renderer/browser_plugin/browser_plugin_manager_factory.h @@ -0,0 +1,21 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_MANAGER_FACTORY_H_ +#define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_MANAGER_FACTORY_H_ + +namespace content { + +class CONTENT_EXPORT BrowserPluginManagerFactory { + public: + virtual BrowserPluginManager* CreateBrowserPluginManager( + RenderViewImpl* render_view) = 0; + + protected: + virtual ~BrowserPluginManagerFactory() {} +}; + +} // namespace content + +#endif // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_MANAGER_FACTORY_H_ diff --git a/content/renderer/browser_plugin/browser_plugin_manager_impl.cc b/content/renderer/browser_plugin/browser_plugin_manager_impl.cc index 63143da..bfca48a 100644 --- a/content/renderer/browser_plugin/browser_plugin_manager_impl.cc +++ b/content/renderer/browser_plugin/browser_plugin_manager_impl.cc @@ -12,7 +12,9 @@ namespace content { -BrowserPluginManagerImpl::BrowserPluginManagerImpl() { +BrowserPluginManagerImpl::BrowserPluginManagerImpl( + RenderViewImpl* render_view) + : BrowserPluginManager(render_view) { } BrowserPluginManagerImpl::~BrowserPluginManagerImpl() { @@ -32,9 +34,8 @@ bool BrowserPluginManagerImpl::Send(IPC::Message* msg) { return RenderThread::Get()->Send(msg); } -bool BrowserPluginManagerImpl::OnControlMessageReceived( +bool BrowserPluginManagerImpl::OnMessageReceived( const IPC::Message& message) { - DCHECK(CalledOnValidThread()); bool handled = true; IPC_BEGIN_MESSAGE_MAP(BrowserPluginManagerImpl, message) IPC_MESSAGE_HANDLER(BrowserPluginMsg_UpdateRect, OnUpdateRect) @@ -58,16 +59,17 @@ bool BrowserPluginManagerImpl::OnControlMessageReceived( } void BrowserPluginManagerImpl::OnPluginAtPositionRequest( - int source_routing_id, int request_id, const gfx::Point& position) { + int request_id, const gfx::Point& position) { int instance_id = -1; IDMap<BrowserPlugin>::iterator it(&instances_); gfx::Point local_position = position; + int source_routing_id = -1; while (!it.IsAtEnd()) { const BrowserPlugin* plugin = it.GetCurrentValue(); // We need to check the plugin's routing id too since BrowserPluginManager // can manage plugins from other embedder (in the same process). - if (plugin->render_view_routing_id() == source_routing_id && - plugin->InBounds(position)) { + if (plugin->InBounds(position)) { + source_routing_id = plugin->render_view_routing_id(); instance_id = plugin->instance_id(); local_position = plugin->ToLocalCoordinates(position); break; @@ -76,10 +78,10 @@ void BrowserPluginManagerImpl::OnPluginAtPositionRequest( } Send(new BrowserPluginHostMsg_PluginAtPositionResponse( - source_routing_id, - instance_id, - request_id, - local_position)); + source_routing_id, + instance_id, + request_id, + local_position)); } void BrowserPluginManagerImpl::OnUpdateRect( diff --git a/content/renderer/browser_plugin/browser_plugin_manager_impl.h b/content/renderer/browser_plugin/browser_plugin_manager_impl.h index 73d7c3b..b472e57 100644 --- a/content/renderer/browser_plugin/browser_plugin_manager_impl.h +++ b/content/renderer/browser_plugin/browser_plugin_manager_impl.h @@ -20,8 +20,7 @@ namespace content { class BrowserPluginManagerImpl : public BrowserPluginManager { public: - BrowserPluginManagerImpl(); - virtual ~BrowserPluginManagerImpl(); + BrowserPluginManagerImpl(RenderViewImpl* render_view); // BrowserPluginManager implementation. virtual BrowserPlugin* CreateBrowserPlugin( @@ -32,9 +31,11 @@ class BrowserPluginManagerImpl : public BrowserPluginManager { // IPC::Sender implementation. virtual bool Send(IPC::Message* msg) OVERRIDE; - // RenderProcessObserver override. Call on render thread. - virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE; + // RenderViewObserver override. Call on render thread. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; private: + virtual ~BrowserPluginManagerImpl(); + void OnUpdateRect(int instance_id, int message_id, const BrowserPluginMsg_UpdateRect_Params& params); @@ -58,8 +59,7 @@ class BrowserPluginManagerImpl : public BrowserPluginManager { bool is_top_level); void OnSetCursor(int instance_id, const WebCursor& cursor); - void OnPluginAtPositionRequest(int source_routing_id, - int request_id, + void OnPluginAtPositionRequest(int request_id, const gfx::Point& position); DISALLOW_COPY_AND_ASSIGN(BrowserPluginManagerImpl); diff --git a/content/renderer/browser_plugin/mock_browser_plugin_manager.cc b/content/renderer/browser_plugin/mock_browser_plugin_manager.cc index 9544635..3522cc4 100644 --- a/content/renderer/browser_plugin/mock_browser_plugin_manager.cc +++ b/content/renderer/browser_plugin/mock_browser_plugin_manager.cc @@ -9,7 +9,9 @@ namespace content { -MockBrowserPluginManager::MockBrowserPluginManager() { +MockBrowserPluginManager::MockBrowserPluginManager( + RenderViewImpl* render_view) + : BrowserPluginManager(render_view) { } MockBrowserPluginManager::~MockBrowserPluginManager() { @@ -50,13 +52,13 @@ bool MockBrowserPluginManager::Send(IPC::Message* msg) { reply_deserializer_.reset( static_cast<IPC::SyncMessage*>(msg)->GetReplyDeserializer()); } - OnControlMessageReceived(*msg); + OnMessageReceived(*msg); } delete msg; return true; } -bool MockBrowserPluginManager::OnControlMessageReceived( +bool MockBrowserPluginManager::OnMessageReceived( const IPC::Message& message) { // Save the message in the sink. sink_.OnMessageReceived(message); diff --git a/content/renderer/browser_plugin/mock_browser_plugin_manager.h b/content/renderer/browser_plugin/mock_browser_plugin_manager.h index 90be1cd..46c4578 100644 --- a/content/renderer/browser_plugin/mock_browser_plugin_manager.h +++ b/content/renderer/browser_plugin/mock_browser_plugin_manager.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_MANAGER_IMPL_H_ -#define CONTENT_RENDERER_BROWSER_PLUGIN_BROWSER_PLUGIN_MANAGER_IMPL_H_ +#ifndef CONTENT_RENDERER_BROWSER_PLUGIN_MOCK_BROWSER_PLUGIN_MANAGER_H_ +#define CONTENT_RENDERER_BROWSER_PLUGIN_MOCK_BROWSER_PLUGIN_MANAGER_H_ #include "content/renderer/browser_plugin/browser_plugin_manager.h" @@ -15,8 +15,7 @@ namespace content { class MockBrowserPluginManager : public BrowserPluginManager { public: - MockBrowserPluginManager(); - virtual ~MockBrowserPluginManager(); + MockBrowserPluginManager(RenderViewImpl* render_view); // BrowserPluginManager implementation. virtual BrowserPlugin* CreateBrowserPlugin( @@ -31,12 +30,11 @@ class MockBrowserPluginManager : public BrowserPluginManager { // Provides access to the messages that have been received by this thread. IPC::TestSink& sink() { return sink_; } - // IPC::Sender implementation. + // RenderViewObserver override. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual bool Send(IPC::Message* msg) OVERRIDE; - - // RenderProcessObserver override. - virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE; - private: + protected: + virtual ~MockBrowserPluginManager(); IPC::TestSink sink_; // The last known good deserializer for sync messages. @@ -47,4 +45,4 @@ class MockBrowserPluginManager : public BrowserPluginManager { } // namespace content -#endif // CONTENT_RENDERER_BROWSER_PLUGIN_TESTS_BROWSER_PLUGIN_MANAGER_IMPL_H_ +#endif // CONTENT_RENDERER_BROWSER_PLUGIN_MOCK_BROWSER_PLUGIN_MANAGER_H_ diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 9f617a1..aca4987 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -63,6 +63,7 @@ #include "content/public/renderer/render_view_visitor.h" #include "content/renderer/browser_plugin/browser_plugin.h" #include "content/renderer/browser_plugin/browser_plugin_manager.h" +#include "content/renderer/browser_plugin/browser_plugin_manager_impl.h" #include "content/renderer/device_orientation_dispatcher.h" #include "content/renderer/devtools_agent.h" #include "content/renderer/disambiguation_popup_helper.h" @@ -577,6 +578,7 @@ RenderViewImpl::RenderViewImpl(RenderViewImplParams* params) speech_recognition_dispatcher_(NULL), device_orientation_dispatcher_(NULL), media_stream_dispatcher_(NULL), + browser_plugin_manager_(NULL), media_stream_impl_(NULL), devtools_agent_(NULL), accessibility_mode_(AccessibilityModeOff), @@ -2455,8 +2457,7 @@ WebPlugin* RenderViewImpl::createPlugin(WebFrame* frame, } if (UTF16ToASCII(params.mimeType) == kBrowserPluginMimeType) { - return BrowserPluginManager::Get()-> - CreateBrowserPlugin(this, frame, params); + return browser_plugin_manager()->CreateBrowserPlugin(this, frame, params); } webkit::WebPluginInfo info; @@ -3865,6 +3866,12 @@ void RenderViewImpl::SendUpdatedFrameTree( // in place. } +BrowserPluginManager* RenderViewImpl::browser_plugin_manager() { + if (!browser_plugin_manager_) + browser_plugin_manager_ = BrowserPluginManager::Create(this); + return browser_plugin_manager_; +} + void RenderViewImpl::CreateFrameTree(WebKit::WebFrame* frame, DictionaryValue* frame_tree) { // TODO(nasko): Remove once http://crbug.com/153701 is fixed. @@ -5830,7 +5837,8 @@ void RenderViewImpl::OnSetFocus(bool enable) { // Notify all Pepper plugins. pepper_delegate_.OnSetFocus(enable); // Notify all BrowserPlugins of the RenderView's focus state. - BrowserPluginManager::Get()->SetEmbedderFocus(this, enable); + if (browser_plugin_manager_) + browser_plugin_manager()->SetEmbedderFocus(this, enable); } void RenderViewImpl::PpapiPluginFocusChanged() { diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index b0b2f33..54425be 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -137,6 +137,7 @@ class WebHitTestResult; } namespace content { +class BrowserPluginManager; class DeviceOrientationDispatcher; class DevToolsAgent; class DocumentState; @@ -264,6 +265,9 @@ class CONTENT_EXPORT RenderViewImpl } #endif + // Lazily initialize this view's BrowserPluginManager and return it. + BrowserPluginManager* browser_plugin_manager(); + // Functions to add and remove observers for this object. void AddObserver(RenderViewObserver* observer); void RemoveObserver(RenderViewObserver* observer); @@ -1378,6 +1382,9 @@ class CONTENT_EXPORT RenderViewImpl // MediaStream dispatcher attached to this view; lazily initialized. MediaStreamDispatcher* media_stream_dispatcher_; + // BrowserPluginManager attached to this view; lazily initialized. + scoped_refptr<BrowserPluginManager> browser_plugin_manager_; + // MediaStreamImpl attached to this view; lazily initialized. MediaStreamImpl* media_stream_impl_; |