diff options
-rw-r--r-- | chrome/browser/nacl_host/nacl_browser_delegate_impl.cc | 82 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_browser_delegate_impl.h | 2 | ||||
-rw-r--r-- | components/nacl/browser/nacl_browser_delegate.h | 9 | ||||
-rw-r--r-- | components/nacl/browser/nacl_process_host.cc | 3 | ||||
-rw-r--r-- | components/nacl/browser/test_nacl_browser_delegate.cc | 5 | ||||
-rw-r--r-- | components/nacl/browser/test_nacl_browser_delegate.h | 2 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc | 58 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/browser_ppapi_host_impl.h | 20 | ||||
-rw-r--r-- | content/public/browser/browser_ppapi_host.h | 15 | ||||
-rw-r--r-- | extensions/browser/process_manager.cc | 2 | ||||
-rw-r--r-- | ppapi/proxy/plugin_globals.cc | 47 | ||||
-rw-r--r-- | ppapi/proxy/plugin_globals.h | 21 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 3 | ||||
-rw-r--r-- | ppapi/shared_impl/ppapi_globals.cc | 3 | ||||
-rw-r--r-- | ppapi/shared_impl/ppapi_globals.h | 6 | ||||
-rw-r--r-- | ppapi/thunk/enter.cc | 5 |
16 files changed, 268 insertions, 15 deletions
diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc index a0e92bd..96e0c1f 100644 --- a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc +++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc @@ -9,15 +9,20 @@ #include "base/strings/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h" +#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/nacl_host/nacl_infobar_delegate.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/logging_chrome.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/site_instance.h" #include "extensions/browser/info_map.h" +#include "extensions/browser/process_manager.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/manifest_handlers/shared_module_info.h" @@ -26,6 +31,78 @@ using extensions::SharedModuleInfo; +namespace { + +// Handles an extension's NaCl process transitioning in or out of idle state by +// relaying the state to the extension's process manager. +// +// A NaCl instance, when active (making PPAPI calls or receiving callbacks), +// sends keepalive IPCs to the browser process BrowserPpapiHost at a throttled +// rate. The content::BrowserPpapiHost passes context information up to the +// chrome level NaClProcessHost where we use the instance's context to find the +// associated extension process manager. +// +// There is a 1:many relationship for extension:nacl-embeds, but only a +// 1:1 relationship for NaClProcessHost:PP_Instance. The content layer doesn't +// rely on this knowledge because it routes messages for ppapi non-nacl +// instances as well, though they won't have callbacks set. Here the 1:1 +// assumption is made and DCHECKed. +void OnKeepaliveOnUIThread( + const content::BrowserPpapiHost::OnKeepaliveInstanceData& instance_data, + const base::FilePath& profile_data_directory) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + // Only one instance will exist for NaCl embeds, even when more than one + // embed of the same plugin exists on the same page. + DCHECK(instance_data.size() == 1); + if (instance_data.size() < 1) + return; + + content::RenderViewHost* render_view_host = content::RenderViewHost::FromID( + instance_data[0].render_process_id, instance_data[0].render_view_id); + if (!render_view_host) + return; + + content::SiteInstance* site_instance = render_view_host->GetSiteInstance(); + if (!site_instance) + return; + + extensions::ExtensionSystem* extension_system = + extensions::ExtensionSystem::GetForBrowserContext( + site_instance->GetBrowserContext()); + if (!extension_system) + return; + + const ExtensionService* extension_service = + extension_system->extension_service(); + if (!extension_service) + return; + + const extensions::Extension* extension = extension_service->GetExtensionById( + instance_data[0].document_url.host(), false); + if (!extension) + return; + + extensions::ProcessManager* pm = extension_system->process_manager(); + if (!pm) + return; + + pm->KeepaliveImpulse(extension); +} + +// Calls OnKeepaliveOnUIThread on UI thread. +void OnKeepalive( + const content::BrowserPpapiHost::OnKeepaliveInstanceData& instance_data, + const base::FilePath& profile_data_directory) { + DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&OnKeepaliveOnUIThread, + instance_data, + profile_data_directory)); +} + +} // namespace + NaClBrowserDelegateImpl::NaClBrowserDelegateImpl( extensions::InfoMap* extension_info_map) : extension_info_map_(extension_info_map), inverse_debug_patterns_(false) {} @@ -181,3 +258,8 @@ bool NaClBrowserDelegateImpl::MapUrlToLocalFilePath( *file_path = resource_file_path; return true; } + +content::BrowserPpapiHost::OnKeepaliveCallback +NaClBrowserDelegateImpl::GetOnKeepaliveCallback() { + return base::Bind(&OnKeepalive); +} diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.h b/chrome/browser/nacl_host/nacl_browser_delegate_impl.h index c23fefc..674d517 100644 --- a/chrome/browser/nacl_host/nacl_browser_delegate_impl.h +++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.h @@ -29,6 +29,8 @@ class NaClBrowserDelegateImpl : public NaClBrowserDelegate { base::FilePath* file_path) OVERRIDE; virtual void SetDebugPatterns(std::string debug_patterns) OVERRIDE; virtual bool URLMatchesDebugPatterns(const GURL& manifest_url) OVERRIDE; + virtual content::BrowserPpapiHost::OnKeepaliveCallback + GetOnKeepaliveCallback() OVERRIDE; private: scoped_refptr<extensions::InfoMap> extension_info_map_; diff --git a/components/nacl/browser/nacl_browser_delegate.h b/components/nacl/browser/nacl_browser_delegate.h index 0540f60..30bf467 100644 --- a/components/nacl/browser/nacl_browser_delegate.h +++ b/components/nacl/browser/nacl_browser_delegate.h @@ -8,6 +8,7 @@ #include <string> #include "base/callback_forward.h" +#include "content/public/browser/browser_ppapi_host.h" class GURL; @@ -21,10 +22,6 @@ class HostFactory; } } -namespace content { -class BrowserPpapiHost; -} - // Encapsulates the dependencies of NaCl code on chrome/, to avoid a direct // dependency on chrome/. class NaClBrowserDelegate { @@ -73,6 +70,10 @@ class NaClBrowserDelegate { // Returns whether NaCl application with this manifest URL should be debugged. virtual bool URLMatchesDebugPatterns(const GURL& manifest_url) = 0; + + // Returns a callback that handles NaCl idle state transitions. + virtual content::BrowserPpapiHost::OnKeepaliveCallback + GetOnKeepaliveCallback() = 0; }; #endif // COMPONENTS_NACL_BROWSER_NACL_BROWSER_DELEGATE_H_ diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index 2d154f3..a0868b8 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc @@ -49,6 +49,7 @@ #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/ppapi_nacl_channel_args.h" +#include "ppapi/shared_impl/ppapi_switches.h" #if defined(OS_POSIX) #include <fcntl.h> @@ -799,6 +800,8 @@ void NaClProcessHost::OnPpapiChannelCreated( nacl_host_message_filter_->render_process_id(), render_view_id_, profile_directory_)); + ppapi_host_->SetOnKeepaliveCallback( + NaClBrowser::GetDelegate()->GetOnKeepaliveCallback()); ppapi::PpapiNaClChannelArgs args; args.off_the_record = nacl_host_message_filter_->off_the_record(); diff --git a/components/nacl/browser/test_nacl_browser_delegate.cc b/components/nacl/browser/test_nacl_browser_delegate.cc index 2cd0bba..d0b5607 100644 --- a/components/nacl/browser/test_nacl_browser_delegate.cc +++ b/components/nacl/browser/test_nacl_browser_delegate.cc @@ -53,3 +53,8 @@ bool TestNaClBrowserDelegate::URLMatchesDebugPatterns( const GURL& manifest_url) { return false; } + +content::BrowserPpapiHost::OnKeepaliveCallback +TestNaClBrowserDelegate::GetOnKeepaliveCallback() { + return content::BrowserPpapiHost::OnKeepaliveCallback(); +} diff --git a/components/nacl/browser/test_nacl_browser_delegate.h b/components/nacl/browser/test_nacl_browser_delegate.h index fc0444f..2e8e5f6 100644 --- a/components/nacl/browser/test_nacl_browser_delegate.h +++ b/components/nacl/browser/test_nacl_browser_delegate.h @@ -38,6 +38,8 @@ class TestNaClBrowserDelegate : public NaClBrowserDelegate { base::FilePath* file_path) OVERRIDE; virtual void SetDebugPatterns(std::string debug_patterns) OVERRIDE; virtual bool URLMatchesDebugPatterns(const GURL& manifest_url) OVERRIDE; + virtual content::BrowserPpapiHost::OnKeepaliveCallback + GetOnKeepaliveCallback() OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(TestNaClBrowserDelegate); 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<ppapi::host::HostFactory>( 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::PpapiHost> ppapi_host_; base::ProcessHandle plugin_process_handle_; std::string plugin_name_; @@ -118,6 +130,8 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { scoped_refptr<HostMessageFilter> 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<OnKeepaliveInstanceStruct> 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 diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc index 6a57d8e..e49d990 100644 --- a/extensions/browser/process_manager.cc +++ b/extensions/browser/process_manager.cc @@ -203,6 +203,8 @@ ProcessManager::ProcessManager(BrowserContext* context, content::Source<BrowserContext>(original_context)); } + // Note: event_page_idle_time_ must be sufficiently larger (e.g. 2x) than + // kKeepaliveThrottleIntervalInSeconds in ppapi/proxy/plugin_globals. event_page_idle_time_ = base::TimeDelta::FromSeconds(10); unsigned idle_time_msec = 0; if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( diff --git a/ppapi/proxy/plugin_globals.cc b/ppapi/proxy/plugin_globals.cc index 59b5191..d34adf1 100644 --- a/ppapi/proxy/plugin_globals.cc +++ b/ppapi/proxy/plugin_globals.cc @@ -10,11 +10,18 @@ #include "ipc/ipc_sender.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_proxy_delegate.h" +#include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_message_loop_proxy.h" #include "ppapi/proxy/resource_reply_thread_registrar.h" #include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/thunk/enter.h" +namespace { + +const int kKeepaliveThrottleIntervalDefault = 5000; + +} // namespace + namespace ppapi { namespace proxy { @@ -54,7 +61,11 @@ PluginGlobals::PluginGlobals() plugin_proxy_delegate_(NULL), callback_tracker_(new CallbackTracker), resource_reply_thread_registrar_( - new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())) { + new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())), + plugin_recently_active_(false), + keepalive_throttle_interval_milliseconds_( + kKeepaliveThrottleIntervalDefault), + weak_factory_(this) { DCHECK(!plugin_globals_); plugin_globals_ = this; @@ -71,7 +82,11 @@ PluginGlobals::PluginGlobals(PerThreadForTest per_thread_for_test) plugin_proxy_delegate_(NULL), callback_tracker_(new CallbackTracker), resource_reply_thread_registrar_( - new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())) { + new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())), + plugin_recently_active_(false), + keepalive_throttle_interval_milliseconds_( + kKeepaliveThrottleIntervalDefault), + weak_factory_(this) { DCHECK(!plugin_globals_); } @@ -165,6 +180,21 @@ base::TaskRunner* PluginGlobals::GetFileTaskRunner() { return file_thread_->message_loop_proxy(); } +void PluginGlobals::MarkPluginIsActive() { + if (!plugin_recently_active_) { + plugin_recently_active_ = true; + if (!GetBrowserSender() || !base::MessageLoop::current()) + return; + GetBrowserSender()->Send(new PpapiHostMsg_Keepalive()); + + GetMainThreadMessageLoop()->PostDelayedTask(FROM_HERE, + RunWhileLocked(base::Bind(&PluginGlobals::OnReleaseKeepaliveThrottle, + weak_factory_.GetWeakPtr())), + base::TimeDelta::FromMilliseconds( + keepalive_throttle_interval_milliseconds())); + } +} + IPC::Sender* PluginGlobals::GetBrowserSender() { if (!browser_sender_.get()) { browser_sender_.reset( @@ -195,9 +225,22 @@ MessageLoopResource* PluginGlobals::loop_for_main_thread() { return loop_for_main_thread_.get(); } +int PluginGlobals::keepalive_throttle_interval_milliseconds() const { + return keepalive_throttle_interval_milliseconds_; +} + +void PluginGlobals::set_keepalive_throttle_interval_milliseconds(int i) { + keepalive_throttle_interval_milliseconds_ = i; +} + bool PluginGlobals::IsPluginGlobals() const { return true; } +void PluginGlobals::OnReleaseKeepaliveThrottle() { + ppapi::ProxyLock::AssertAcquiredDebugOnly(); + plugin_recently_active_ = false; +} + } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/plugin_globals.h b/ppapi/proxy/plugin_globals.h index 029e2d2..dac33b6 100644 --- a/ppapi/proxy/plugin_globals.h +++ b/ppapi/proxy/plugin_globals.h @@ -74,6 +74,7 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { const std::string& value) OVERRIDE; virtual MessageLoopShared* GetCurrentMessageLoop() OVERRIDE; base::TaskRunner* GetFileTaskRunner() OVERRIDE; + virtual void MarkPluginIsActive() OVERRIDE; // Returns the channel for sending to the browser. IPC::Sender* GetBrowserSender(); @@ -133,12 +134,21 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { return resource_reply_thread_registrar_.get(); } + // Interval to limit how many IPC messages are sent indicating that the plugin + // is active and should be kept alive. The value must be smaller than any + // threshold used to kill inactive plugins by the embedder host. + int keepalive_throttle_interval_milliseconds() const; + void set_keepalive_throttle_interval_milliseconds(int i); + private: class BrowserSender; // PpapiGlobals overrides. virtual bool IsPluginGlobals() const OVERRIDE; + // Locks the proxy lock and releases the throttle on keepalive IPC messages. + void OnReleaseKeepaliveThrottle(); + static PluginGlobals* plugin_globals_; PluginProxyDelegate* plugin_proxy_delegate_; @@ -167,6 +177,17 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_; + // Indicates activity by the plugin. Used to monitor when a plugin can be + // shutdown due to idleness. Current needs do not require differentiating + // between idle state between multiple instances, if any are active they are + // all considered active. + bool plugin_recently_active_; + + int keepalive_throttle_interval_milliseconds_; + + // Member variables should appear before the WeakPtrFactory, see weak_ptr.h. + base::WeakPtrFactory<PluginGlobals> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(PluginGlobals); }; diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 4b4fed8..086d42a 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -726,6 +726,9 @@ IPC_MESSAGE_ROUTED2(PpapiMsg_PPPVideoDecoder_NotifyError, PP_VideoDecodeError_Dev /* error */) #endif // !defined(OS_NACL) && !defined(NACL_WIN64) +// Reports to the browser that a plugin has been active. +IPC_MESSAGE_CONTROL0(PpapiHostMsg_Keepalive) + // ----------------------------------------------------------------------------- // These are from the plugin to the renderer. diff --git a/ppapi/shared_impl/ppapi_globals.cc b/ppapi/shared_impl/ppapi_globals.cc index 28ed2cf..f652f15 100644 --- a/ppapi/shared_impl/ppapi_globals.cc +++ b/ppapi/shared_impl/ppapi_globals.cc @@ -69,6 +69,9 @@ bool PpapiGlobals::IsPluginGlobals() const { return false; } +void PpapiGlobals::MarkPluginIsActive() { +} + // static PpapiGlobals* PpapiGlobals::GetThreadLocalPointer() { return tls_ppapi_globals_for_test.Pointer()->Get(); diff --git a/ppapi/shared_impl/ppapi_globals.h b/ppapi/shared_impl/ppapi_globals.h index 93ab299..d9be0387 100644 --- a/ppapi/shared_impl/ppapi_globals.h +++ b/ppapi/shared_impl/ppapi_globals.h @@ -128,6 +128,12 @@ class PPAPI_SHARED_EXPORT PpapiGlobals { virtual bool IsHostGlobals() const; virtual bool IsPluginGlobals() const; + // Records that the plugin is active. The plugin reports that it is active to + // containers that monitor and shutdown idle content such as background apps. + // This method only has an effect on the plugin process, calls from the + // renderer process will have no effect. + virtual void MarkPluginIsActive(); + private: // Return the thread-local pointer which is used only for unit testing. It // should always be NULL when running in production. It allows separate diff --git a/ppapi/thunk/enter.cc b/ppapi/thunk/enter.cc index 47889dd..2adc7f2 100644 --- a/ppapi/thunk/enter.cc +++ b/ppapi/thunk/enter.cc @@ -32,16 +32,19 @@ namespace subtle { EnterBase::EnterBase() : resource_(NULL), retval_(PP_OK) { + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::EnterBase(PP_Resource resource) : resource_(GetResource(resource)), retval_(PP_OK) { + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id) : resource_(GetSingletonResource(instance, resource_id)), retval_(PP_OK) { + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::EnterBase(PP_Resource resource, @@ -49,6 +52,7 @@ EnterBase::EnterBase(PP_Resource resource, : resource_(GetResource(resource)), retval_(PP_OK) { callback_ = new TrackedCallback(resource_, callback); + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id, @@ -59,6 +63,7 @@ EnterBase::EnterBase(PP_Instance instance, SingletonResourceID resource_id, if (!resource_) retval_ = PP_ERROR_BADARGUMENT; callback_ = new TrackedCallback(resource_, callback); + PpapiGlobals::Get()->MarkPluginIsActive(); } EnterBase::~EnterBase() { |