X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fextensions%2Fbrowser%2Fprocess_manager.cc;h=5e2e3aa0dcd1397ff692e3fc3ce3c25cdf671ad3;hb=1afa4dd80ef85af7c90efaea6959db1d92330844;hp=1b6a45a2e65584557d1e78121f1236c45def0028;hpb=90762837333c13ccf56f2ad88e4481fc71e8d281;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/extensions/browser/process_manager.cc b/src/extensions/browser/process_manager.cc index 1b6a45a..5e2e3aa 100644 --- a/src/extensions/browser/process_manager.cc +++ b/src/extensions/browser/process_manager.cc @@ -33,6 +33,7 @@ #include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/notification_types.h" #include "extensions/browser/process_manager_delegate.h" +#include "extensions/browser/process_manager_factory.h" #include "extensions/browser/process_manager_observer.h" #include "extensions/browser/view_type_utils.h" #include "extensions/common/constants.h" @@ -114,16 +115,13 @@ class IncognitoProcessManager : public ProcessManager { public: IncognitoProcessManager(BrowserContext* incognito_context, BrowserContext* original_context, - ProcessManager* original_manager, ExtensionRegistry* extension_registry); - virtual ~IncognitoProcessManager() {} - virtual bool CreateBackgroundHost(const Extension* extension, - const GURL& url) OVERRIDE; - virtual SiteInstance* GetSiteInstanceForURL(const GURL& url) OVERRIDE; + ~IncognitoProcessManager() override {} + bool CreateBackgroundHost(const Extension* extension, + const GURL& url) override; + SiteInstance* GetSiteInstanceForURL(const GURL& url) override; private: - ProcessManager* original_manager_; - DISALLOW_COPY_AND_ASSIGN(IncognitoProcessManager); }; @@ -141,19 +139,19 @@ class RenderViewHostDestructionObserver : public content::WebContentsObserver, public content::WebContentsUserData { public: - virtual ~RenderViewHostDestructionObserver() {} + ~RenderViewHostDestructionObserver() override {} private: explicit RenderViewHostDestructionObserver(WebContents* web_contents) : WebContentsObserver(web_contents) { BrowserContext* context = web_contents->GetBrowserContext(); - process_manager_ = ExtensionSystem::Get(context)->process_manager(); + process_manager_ = ProcessManager::Get(context); } friend class content::WebContentsUserData; // content::WebContentsObserver overrides. - virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE { + void RenderViewDeleted(RenderViewHost* render_view_host) override { process_manager_->UnregisterRenderViewHost(render_view_host); } @@ -194,11 +192,50 @@ struct ProcessManager::BackgroundPageData { close_sequence_id(0) {} }; +// Data of a RenderViewHost associated with an extension. +struct ProcessManager::ExtensionRenderViewData { + // The type of the view. + extensions::ViewType view_type; + + // Whether the view is keeping the lazy background page alive or not. + bool has_keepalive; + + ExtensionRenderViewData() + : view_type(VIEW_TYPE_INVALID), has_keepalive(false) {} + + // Returns whether the view can keep the lazy background page alive or not. + bool CanKeepalive() const { + switch (view_type) { + case VIEW_TYPE_APP_WINDOW: + case VIEW_TYPE_BACKGROUND_CONTENTS: + case VIEW_TYPE_EXTENSION_DIALOG: + case VIEW_TYPE_EXTENSION_INFOBAR: + case VIEW_TYPE_EXTENSION_POPUP: + case VIEW_TYPE_LAUNCHER_PAGE: + case VIEW_TYPE_PANEL: + case VIEW_TYPE_TAB_CONTENTS: + case VIEW_TYPE_VIRTUAL_KEYBOARD: + return true; + + case VIEW_TYPE_INVALID: + case VIEW_TYPE_EXTENSION_BACKGROUND_PAGE: + return false; + } + NOTREACHED(); + return false; + } +}; + // // ProcessManager // // static +ProcessManager* ProcessManager::Get(BrowserContext* context) { + return ProcessManagerFactory::GetForBrowserContext(context); +} + +// static ProcessManager* ProcessManager::Create(BrowserContext* context) { ExtensionRegistry* extension_registry = ExtensionRegistry::Get(context); ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); @@ -213,10 +250,8 @@ ProcessManager* ProcessManager::Create(BrowserContext* context) { if (context->IsOffTheRecord()) { BrowserContext* original_context = client->GetOriginalContext(context); - ProcessManager* original_manager = - ExtensionSystem::Get(original_context)->process_manager(); return new IncognitoProcessManager( - context, original_context, original_manager, extension_registry); + context, original_context, extension_registry); } return new ProcessManager(context, context, extension_registry); @@ -234,13 +269,11 @@ ProcessManager* ProcessManager::CreateForTesting( ProcessManager* ProcessManager::CreateIncognitoForTesting( BrowserContext* incognito_context, BrowserContext* original_context, - ProcessManager* original_manager, ExtensionRegistry* extension_registry) { DCHECK(incognito_context->IsOffTheRecord()); DCHECK(!original_context->IsOffTheRecord()); return new IncognitoProcessManager(incognito_context, original_context, - original_manager, extension_registry); } @@ -369,6 +402,40 @@ const Extension* ProcessManager::GetExtensionForRenderViewHost( GetExtensionID(render_view_host)); } +void ProcessManager::AcquireLazyKeepaliveCountForView( + content::RenderViewHost* render_view_host) { + auto it = all_extension_views_.find(render_view_host); + if (it == all_extension_views_.end()) + return; + + ExtensionRenderViewData* data = &it->second; + if (data->CanKeepalive() && !data->has_keepalive) { + const Extension* extension = + GetExtensionForRenderViewHost(render_view_host); + if (extension) { + IncrementLazyKeepaliveCount(extension); + data->has_keepalive = true; + } + } +} + +void ProcessManager::ReleaseLazyKeepaliveCountForView( + content::RenderViewHost* render_view_host) { + auto it = all_extension_views_.find(render_view_host); + if (it == all_extension_views_.end()) + return; + + ExtensionRenderViewData* data = &it->second; + if (data->CanKeepalive() && data->has_keepalive) { + const Extension* extension = + GetExtensionForRenderViewHost(render_view_host); + if (extension) { + DecrementLazyKeepaliveCount(extension); + data->has_keepalive = false; + } + } +} + void ProcessManager::UnregisterRenderViewHost( RenderViewHost* render_view_host) { ExtensionRenderViews::iterator view = @@ -377,17 +444,10 @@ void ProcessManager::UnregisterRenderViewHost( return; OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host); - ViewType view_type = view->second; - all_extension_views_.erase(view); // Keepalive count, balanced in RegisterRenderViewHost. - if (view_type != VIEW_TYPE_INVALID && - view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { - const Extension* extension = GetExtensionForRenderViewHost( - render_view_host); - if (extension) - DecrementLazyKeepaliveCount(extension); - } + ReleaseLazyKeepaliveCountForView(render_view_host); + all_extension_views_.erase(view); } bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) { @@ -397,12 +457,13 @@ bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) { return false; WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); - all_extension_views_[render_view_host] = GetViewType(web_contents); + ExtensionRenderViewData* data = &all_extension_views_[render_view_host]; + data->view_type = GetViewType(web_contents); // Keep the lazy background page alive as long as any non-background-page // extension views are visible. Keepalive count balanced in // UnregisterRenderViewHost. - IncrementLazyKeepaliveCountForView(render_view_host); + AcquireLazyKeepaliveCountForView(render_view_host); return true; } @@ -460,20 +521,6 @@ void ProcessManager::DecrementLazyKeepaliveCount( } } -void ProcessManager::IncrementLazyKeepaliveCountForView( - RenderViewHost* render_view_host) { - WebContents* web_contents = - WebContents::FromRenderViewHost(render_view_host); - ViewType view_type = GetViewType(web_contents); - if (view_type != VIEW_TYPE_INVALID && - view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { - const Extension* extension = GetExtensionForRenderViewHost( - render_view_host); - if (extension) - IncrementLazyKeepaliveCount(extension); - } -} - // This implementation layers on top of the keepalive count. An impulse sets // a per extension flag. On a regular interval that flag is checked. Changes // from the flag not being set to set cause an IncrementLazyKeepaliveCount. @@ -517,11 +564,7 @@ void ProcessManager::OnKeepaliveFromPlugin(int render_process_id, if (!extension) return; - ProcessManager* pm = ExtensionSystem::Get(browser_context)->process_manager(); - if (!pm) - return; - - pm->KeepaliveImpulse(extension); + ProcessManager::Get(browser_context)->KeepaliveImpulse(extension); } // DecrementLazyKeepaliveCount is called when no calls to KeepaliveImpulse @@ -611,6 +654,24 @@ void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id, ExtensionHost* host = GetBackgroundHostForExtension(extension_id); if (host && sequence_id == background_page_data_[extension_id].close_sequence_id) { + // Close remaining views. + std::vector views_to_close; + for (const auto& view : all_extension_views_) { + if (view.second.CanKeepalive() && + GetExtensionID(view.first) == extension_id) { + DCHECK(!view.second.has_keepalive); + views_to_close.push_back(view.first); + } + } + for (auto view : views_to_close) { + view->ClosePage(); + // RenderViewHost::ClosePage() may result in calling + // UnregisterRenderViewHost() asynchronously and may cause race conditions + // when the background page is reloaded. + // To avoid this, unregister the view now. + UnregisterRenderViewHost(view); + } + ExtensionHost* host = GetBackgroundHostForExtension(extension_id); if (host) CloseBackgroundHost(host); @@ -873,11 +934,16 @@ void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) { } void ProcessManager::CloseBackgroundHost(ExtensionHost* host) { + ExtensionId extension_id = host->extension_id(); CHECK(host->extension_host_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); delete host; // |host| should deregister itself from our structures. CHECK(background_hosts_.find(host) == background_hosts_.end()); + + FOR_EACH_OBSERVER(ProcessManagerObserver, + observer_list_, + OnBackgroundHostClose(extension_id)); } void ProcessManager::UnregisterExtension(const std::string& extension_id) { @@ -908,8 +974,15 @@ void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) { // views. for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); it != all_extension_views_.end(); ++it) { - if (GetExtensionID(it->first) == extension_id) - IncrementLazyKeepaliveCountForView(it->first); + RenderViewHost* view = it->first; + const ExtensionRenderViewData& data = it->second; + // Do not increment the count when |has_keepalive| is false + // (i.e. ReleaseLazyKeepaliveCountForView() was called). + if (GetExtensionID(view) == extension_id && data.has_keepalive) { + const Extension* extension = GetExtensionForRenderViewHost(view); + if (extension) + IncrementLazyKeepaliveCount(extension); + } } } @@ -920,10 +993,8 @@ void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) { IncognitoProcessManager::IncognitoProcessManager( BrowserContext* incognito_context, BrowserContext* original_context, - ProcessManager* original_manager, ExtensionRegistry* extension_registry) - : ProcessManager(incognito_context, original_context, extension_registry), - original_manager_(original_manager) { + : ProcessManager(incognito_context, original_context, extension_registry) { DCHECK(incognito_context->IsOffTheRecord()); // The original profile will have its own ProcessManager to @@ -951,8 +1022,11 @@ bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension, SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) { const Extension* extension = extension_registry_->enabled_extensions().GetExtensionOrAppByURL(url); - if (extension && !IncognitoInfo::IsSplitMode(extension)) - return original_manager_->GetSiteInstanceForURL(url); + if (extension && !IncognitoInfo::IsSplitMode(extension)) { + BrowserContext* original_context = + ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); + return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url); + } return ProcessManager::GetSiteInstanceForURL(url); }