From 200c9187bd8029de9a6d4665082c7bf358c62829 Mon Sep 17 00:00:00 2001 From: "scheib@chromium.org" Date: Wed, 18 Dec 2013 23:37:11 +0000 Subject: Keep NaCl plugins used in app background pages alive when active. Activity in Native Client plugins results in IPC messages sent to the BrowserPpapiHostImpl and routed to call extensions::ProcessManager::KeepaliveImpulse. Implementation patch, to be followed by tests. See: https://codereview.chromium.org/111563006/ Tests. https://codereview.chromium.org/105873003/ Cumulative patch. Design doc: https://docs.google.com/a/chromium.org/document/d/1mI0lS1rfAf-BAGLmWAEcWy37Xq9dOvgfMx8OqeUMXts/edit# BUG=298339 Review URL: https://codereview.chromium.org/61063003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241702 0039d316-1c4b-4281-b951-d872f2087c98 --- .../pepper/browser_ppapi_host_impl.cc | 58 +++++++++++++++++++--- .../renderer_host/pepper/browser_ppapi_host_impl.h | 20 ++++++-- content/public/browser/browser_ppapi_host.h | 15 ++++++ 3 files changed, 84 insertions(+), 9 deletions(-) (limited to 'content') diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc index c3c2c6f3..fd2c82e 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc @@ -7,9 +7,9 @@ #include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/browser/tracing/trace_message_filter.h" #include "content/common/pepper_renderer_instance_data.h" -#include "content/public/browser/render_view_host.h" #include "content/public/common/process_type.h" #include "ipc/ipc_message_macros.h" +#include "ppapi/proxy/ppapi_messages.h" namespace content { @@ -55,7 +55,7 @@ BrowserPpapiHostImpl::BrowserPpapiHostImpl( in_process_(in_process), external_plugin_(external_plugin), ssl_context_helper_(new SSLContextHelper()) { - message_filter_ = new HostMessageFilter(ppapi_host_.get()); + message_filter_ = new HostMessageFilter(ppapi_host_.get(), this); ppapi_host_->AddHostFactoryFilter(scoped_ptr( new ContentBrowserPepperHostFactory(this))); } @@ -126,6 +126,11 @@ GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) { return found->second.plugin_url; } +void BrowserPpapiHostImpl::SetOnKeepaliveCallback( + const BrowserPpapiHost::OnKeepaliveCallback& callback) { + on_keepalive_callback_ = callback; +} + void BrowserPpapiHostImpl::AddInstance( PP_Instance instance, const PepperRendererInstanceData& instance_data) { @@ -142,26 +147,67 @@ void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) { instance_map_.erase(found); } +BrowserPpapiHostImpl::HostMessageFilter::HostMessageFilter( + ppapi::host::PpapiHost* ppapi_host, + BrowserPpapiHostImpl* browser_ppapi_host_impl) + : ppapi_host_(ppapi_host), + browser_ppapi_host_impl_(browser_ppapi_host_impl) { +} + bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived( const IPC::Message& msg) { // Don't forward messages if our owner object has been destroyed. if (!ppapi_host_) return false; - /* TODO(brettw) when we add messages, here, the code should look like this: bool handled = true; - IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl, msg) + IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl::HostMessageFilter, msg) // Add necessary message handlers here. + IPC_MESSAGE_HANDLER(PpapiHostMsg_Keepalive, OnKeepalive) IPC_MESSAGE_UNHANDLED(handled = ppapi_host_->OnMessageReceived(msg)) IPC_END_MESSAGE_MAP(); return handled; - */ - return ppapi_host_->OnMessageReceived(msg); } void BrowserPpapiHostImpl::HostMessageFilter::OnHostDestroyed() { DCHECK(ppapi_host_); ppapi_host_ = NULL; + browser_ppapi_host_impl_ = NULL; +} + +BrowserPpapiHostImpl::HostMessageFilter::~HostMessageFilter() { +} + +void BrowserPpapiHostImpl::HostMessageFilter::OnKeepalive() { + if (browser_ppapi_host_impl_) + browser_ppapi_host_impl_->OnKeepalive(); +} + +void BrowserPpapiHostImpl::OnKeepalive() { + // An instance has been active. The on_keepalive_callback_ will be + // used to permit the content embedder to handle this, e.g. by tracking + // activity and shutting down processes that go idle. + // + // Currently embedders do not need to distinguish between instances having + // different idle state, and thus this implementation handles all instances + // for this module together. + + if (on_keepalive_callback_.is_null()) + return; + + BrowserPpapiHost::OnKeepaliveInstanceData + instance_data(instance_map_.size()); + + InstanceMap::iterator instance = instance_map_.begin(); + int i = 0; + while (instance != instance_map_.end()) { + instance_data[i].render_process_id = instance->second.render_process_id; + instance_data[i].render_view_id = instance->second.render_view_id; + instance_data[i].document_url = instance->second.document_url; + ++instance; + ++i; + } + on_keepalive_callback_.Run(instance_data, profile_data_directory_); } } // namespace content diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h index 5d95342..d987bd4 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h @@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" #include "content/browser/renderer_host/pepper/ssl_context_helper.h" #include "content/common/content_export.h" @@ -52,6 +53,9 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { virtual const base::FilePath& GetProfileDataDirectory() OVERRIDE; virtual GURL GetDocumentURLForInstance(PP_Instance instance) OVERRIDE; virtual GURL GetPluginURLForInstance(PP_Instance instance) OVERRIDE; + virtual void SetOnKeepaliveCallback( + const BrowserPpapiHost::OnKeepaliveCallback& callback) OVERRIDE; + void set_plugin_process_handle(base::ProcessHandle handle) { plugin_process_handle_ = handle; @@ -83,19 +87,27 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { // reference. To avoid that, define a message filter object. class HostMessageFilter : public IPC::ChannelProxy::MessageFilter { public: - explicit HostMessageFilter(ppapi::host::PpapiHost* ppapi_host) - : ppapi_host_(ppapi_host) {} + HostMessageFilter(ppapi::host::PpapiHost* ppapi_host, + BrowserPpapiHostImpl* browser_ppapi_host_impl); + // IPC::ChannelProxy::MessageFilter. virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; void OnHostDestroyed(); private: - virtual ~HostMessageFilter() {} + virtual ~HostMessageFilter(); + + void OnKeepalive(); + // Non owning pointers cleared in OnHostDestroyed() ppapi::host::PpapiHost* ppapi_host_; + BrowserPpapiHostImpl* browser_ppapi_host_impl_; }; + // Reports plugin activity to the callback set with SetOnKeepaliveCallback. + void OnKeepalive(); + scoped_ptr ppapi_host_; base::ProcessHandle plugin_process_handle_; std::string plugin_name_; @@ -118,6 +130,8 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { scoped_refptr message_filter_; + BrowserPpapiHost::OnKeepaliveCallback on_keepalive_callback_; + DISALLOW_COPY_AND_ASSIGN(BrowserPpapiHostImpl); }; diff --git a/content/public/browser/browser_ppapi_host.h b/content/public/browser/browser_ppapi_host.h index 45f997e..ce76d16 100644 --- a/content/public/browser/browser_ppapi_host.h +++ b/content/public/browser/browser_ppapi_host.h @@ -34,6 +34,17 @@ namespace content { // lives entirely on the I/O thread. class CONTENT_EXPORT BrowserPpapiHost { public: + struct OnKeepaliveInstanceStruct { + int render_process_id; + int render_view_id; + GURL document_url; + }; + typedef std::vector OnKeepaliveInstanceData; + typedef base::Callback< + void (const OnKeepaliveInstanceData& instance_data, + const base::FilePath& profile_data_directory)> + OnKeepaliveCallback; + // Creates a browser host and sets up an out-of-process proxy for an external // pepper plugin process. static BrowserPpapiHost* CreateExternalPluginProcess( @@ -81,6 +92,10 @@ class CONTENT_EXPORT BrowserPpapiHost { // Get the Document/Plugin URLs for the given PP_Instance. virtual GURL GetDocumentURLForInstance(PP_Instance instance) = 0; virtual GURL GetPluginURLForInstance(PP_Instance instance) = 0; + + // Sets a callback the BrowserPpapiHost will run when the plugin messages + // that it is active. + virtual void SetOnKeepaliveCallback(const OnKeepaliveCallback& callback) = 0; }; } // namespace content -- cgit v1.1