Chromium Code Reviews| Index: chrome/browser/extensions/extension_process_manager.cc |
| diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc |
| index a4b23743015f122eeaafe5453e40c64358ae847c..2ba87338f7972d1753c17d1c6892910983f7fab8 100644 |
| --- a/chrome/browser/extensions/extension_process_manager.cc |
| +++ b/chrome/browser/extensions/extension_process_manager.cc |
| @@ -13,7 +13,6 @@ |
| #include "base/stl_util.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/time/time.h" |
| -#include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/extensions/api/runtime/runtime_api.h" |
| #include "chrome/browser/extensions/extension_host.h" |
| @@ -22,10 +21,7 @@ |
| #include "chrome/browser/extensions/extension_system.h" |
| #include "chrome/browser/extensions/extension_util.h" |
| #include "chrome/browser/profiles/profile.h" |
| -#include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/ui/browser.h" |
| -#include "chrome/browser/ui/browser_finder.h" |
| -#include "chrome/common/chrome_switches.h" |
| #include "chrome/common/extensions/background_info.h" |
| #include "chrome/common/extensions/extension.h" |
| #include "chrome/common/extensions/extension_messages.h" |
| @@ -44,12 +40,15 @@ |
| #include "content/public/browser/web_contents_observer.h" |
| #include "content/public/browser/web_contents_user_data.h" |
| #include "content/public/common/renderer_preferences.h" |
| +#include "extensions/browser/extensions_browser_client.h" |
| #include "extensions/browser/view_type_utils.h" |
| +#include "extensions/common/switches.h" |
| #if defined(OS_MACOSX) |
| #include "chrome/browser/extensions/extension_host_mac.h" |
| #endif |
| +using content::BrowserContext; |
| using content::RenderViewHost; |
| using content::SiteInstance; |
| using content::WebContents; |
| @@ -57,6 +56,8 @@ using extensions::BackgroundInfo; |
| using extensions::BackgroundManifestHandler; |
| using extensions::Extension; |
| using extensions::ExtensionHost; |
| +using extensions::ExtensionsBrowserClient; |
| +using extensions::ExtensionSystem; |
| class RenderViewHostDestructionObserver; |
| DEFINE_WEB_CONTENTS_USER_DATA_KEY(RenderViewHostDestructionObserver); |
| @@ -72,11 +73,11 @@ std::string GetExtensionID(RenderViewHost* render_view_host) { |
| return render_view_host->GetSiteInstance()->GetSiteURL().host(); |
| } |
| -void OnRenderViewHostUnregistered(Profile* profile, |
| +void OnRenderViewHostUnregistered(BrowserContext* context, |
| RenderViewHost* render_view_host) { |
| content::NotificationService::current()->Notify( |
| chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED, |
| - content::Source<Profile>(profile), |
| + content::Source<BrowserContext>(context), |
| content::Details<RenderViewHost>(render_view_host)); |
| } |
| @@ -85,7 +86,8 @@ void OnRenderViewHostUnregistered(Profile* profile, |
| // on whether a given extension uses "split" or "spanning" incognito behavior. |
| class IncognitoExtensionProcessManager : public ExtensionProcessManager { |
| public: |
| - explicit IncognitoExtensionProcessManager(Profile* profile); |
| + IncognitoExtensionProcessManager(BrowserContext* incognito_context, |
| + BrowserContext* original_context); |
| virtual ~IncognitoExtensionProcessManager(); |
| virtual ExtensionHost* CreateViewHost( |
| const Extension* extension, |
| @@ -110,6 +112,7 @@ class IncognitoExtensionProcessManager : public ExtensionProcessManager { |
| static void CreateBackgroundHostForExtensionLoad( |
| ExtensionProcessManager* manager, const Extension* extension) { |
| + DVLOG(1) << "CreateBackgroundHostForExtensionLoad"; |
|
miket_OOO
2013/10/31 23:04:53
OK to keep, but did you mean this?
James Cook
2013/11/01 00:08:32
Yeah, I need these DVLOG lines to keep working on
|
| if (BackgroundInfo::HasPersistentBackgroundPage(extension)) |
| manager->CreateBackgroundHost(extension, |
| BackgroundInfo::GetBackgroundURL(extension)); |
| @@ -170,57 +173,63 @@ struct ExtensionProcessManager::BackgroundPageData { |
| // |
| // static |
| -ExtensionProcessManager* ExtensionProcessManager::Create(Profile* profile) { |
| - return (profile->IsOffTheRecord()) ? |
| - new IncognitoExtensionProcessManager(profile) : |
| - new ExtensionProcessManager(profile); |
| +ExtensionProcessManager* ExtensionProcessManager::Create( |
| + BrowserContext* context) { |
| + if (context->IsOffTheRecord()) { |
| + BrowserContext* original_context = |
| + ExtensionsBrowserClient::Get()->GetOriginalContext(context); |
| + return new IncognitoExtensionProcessManager(context, original_context); |
| + } |
| + return new ExtensionProcessManager(context, context); |
| } |
| -ExtensionProcessManager::ExtensionProcessManager(Profile* profile) |
| - : site_instance_(SiteInstance::Create(profile)), |
| +ExtensionProcessManager::ExtensionProcessManager( |
| + BrowserContext* context, |
| + BrowserContext* original_context) |
| + : site_instance_(SiteInstance::Create(context)), |
| defer_background_host_creation_(false), |
| - weak_ptr_factory_(this), |
| devtools_callback_(base::Bind( |
| &ExtensionProcessManager::OnDevToolsStateChanged, |
| - base::Unretained(this))) { |
| - Profile* original_profile = profile->GetOriginalProfile(); |
| + base::Unretained(this))), |
| + weak_ptr_factory_(this) { |
| registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, |
| content::NotificationService::AllSources()); |
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| - content::Source<Profile>(original_profile)); |
| + content::Source<BrowserContext>(original_context)); |
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| - content::Source<Profile>(original_profile)); |
| + content::Source<BrowserContext>(original_context)); |
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| - content::Source<Profile>(original_profile)); |
| + content::Source<BrowserContext>(original_context)); |
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| - content::Source<Profile>(profile)); |
| + content::Source<BrowserContext>(context)); |
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
| - content::Source<Profile>(profile)); |
| + content::Source<BrowserContext>(context)); |
| registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
| content::NotificationService::AllSources()); |
| registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, |
| content::NotificationService::AllSources()); |
| registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, |
| - content::Source<Profile>(original_profile)); |
| + content::Source<BrowserContext>(original_context)); |
| registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| - content::Source<Profile>(profile)); |
| - if (profile->IsOffTheRecord()) { |
| + content::Source<BrowserContext>(context)); |
| + if (context->IsOffTheRecord()) { |
| registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| - content::Source<Profile>(original_profile)); |
| + content::Source<BrowserContext>(original_context)); |
| } |
| event_page_idle_time_ = base::TimeDelta::FromSeconds(10); |
| unsigned idle_time_sec = 0; |
| if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| - switches::kEventPageIdleTime), &idle_time_sec)) { |
| + extensions::switches::kEventPageIdleTime), &idle_time_sec)) { |
| event_page_idle_time_ = base::TimeDelta::FromSeconds(idle_time_sec); |
| } |
| event_page_suspending_time_ = base::TimeDelta::FromSeconds(5); |
| unsigned suspending_time_sec = 0; |
| if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| - switches::kEventPageSuspendingTime), &suspending_time_sec)) { |
| - event_page_suspending_time_ = base::TimeDelta::FromSeconds( |
| - suspending_time_sec); |
| + extensions::switches::kEventPageSuspendingTime), |
| + &suspending_time_sec)) { |
| + event_page_suspending_time_ = |
| + base::TimeDelta::FromSeconds(suspending_time_sec); |
| } |
| content::DevToolsManager::GetInstance()->AddAgentStateCallback( |
| @@ -249,17 +258,8 @@ void ExtensionProcessManager::EnsureBrowserWhenRequired( |
| Browser* browser, |
| extensions::ViewType view_type) { |
| if (!browser) { |
| -#if defined (OS_CHROMEOS) |
| - // On ChromeOS we'll only use ExtensionView, which |
| - // does not use the browser parameter. |
| - // TODO(rkc): Remove all this once we create a new host for |
| - // screensaver extensions (crosbug.com/28211). |
| - DCHECK(view_type == extensions::VIEW_TYPE_EXTENSION_POPUP || |
| - view_type == extensions::VIEW_TYPE_EXTENSION_DIALOG); |
| -#else |
| - // A NULL browser may only be given for pop-up views. |
| - DCHECK(view_type == extensions::VIEW_TYPE_EXTENSION_POPUP); |
| -#endif |
| + // A NULL browser may only be given for pop-up views. |
| + DCHECK(view_type == extensions::VIEW_TYPE_EXTENSION_POPUP); |
| } |
| } |
| @@ -268,6 +268,7 @@ ExtensionHost* ExtensionProcessManager::CreateViewHost( |
| const GURL& url, |
| Browser* browser, |
| extensions::ViewType view_type) { |
| + DVLOG(1) << "CreateViewHost"; |
|
miket_OOO
2013/10/31 23:04:53
same
|
| DCHECK(extension); |
| EnsureBrowserWhenRequired(browser, view_type); |
| ExtensionHost* host = |
| @@ -285,7 +286,8 @@ ExtensionHost* ExtensionProcessManager::CreateViewHost( |
| ExtensionHost* ExtensionProcessManager::CreateViewHost( |
| const GURL& url, Browser* browser, extensions::ViewType view_type) { |
| EnsureBrowserWhenRequired(browser, view_type); |
| - ExtensionService* service = GetProfile()->GetExtensionService(); |
| + ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| + GetBrowserContext())->extension_service(); |
| if (service) { |
| std::string extension_id = url.host(); |
| if (url.SchemeIs(chrome::kChromeUIScheme) && |
| @@ -327,6 +329,7 @@ ExtensionHost* ExtensionProcessManager::CreateInfobarHost( |
| ExtensionHost* ExtensionProcessManager::CreateBackgroundHost( |
| const Extension* extension, const GURL& url) { |
| + DVLOG(1) << "CreateBackgroundHost " << url.spec(); |
| // Hosted apps are taken care of from BackgroundContentsService. Ignore them |
| // here. |
| if (extension->is_hosted_app()) |
| @@ -387,8 +390,8 @@ const Extension* ExtensionProcessManager::GetExtensionForRenderViewHost( |
| if (!render_view_host->GetSiteInstance()) |
| return NULL; |
| - ExtensionService* service = |
| - extensions::ExtensionSystem::Get(GetProfile())->extension_service(); |
| + ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| + GetBrowserContext())->extension_service(); |
| if (!service) |
| return NULL; |
| @@ -402,7 +405,7 @@ void ExtensionProcessManager::UnregisterRenderViewHost( |
| if (view == all_extension_views_.end()) |
| return; |
| - OnRenderViewHostUnregistered(GetProfile(), render_view_host); |
| + OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host); |
| extensions::ViewType view_type = view->second; |
| all_extension_views_.erase(view); |
| @@ -613,7 +616,8 @@ void ExtensionProcessManager::Observe( |
| browser->profile() == GetProfile()->GetOffTheRecordProfile())) |
| break; |
| - ExtensionService* service = GetProfile()->GetExtensionService(); |
| + ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| + GetBrowserContext())->extension_service(); |
| if (!service || !service->is_ready()) |
| break; |
| @@ -680,7 +684,7 @@ void ExtensionProcessManager::Observe( |
| // unregister the old RVH so it doesn't count as an active view that would |
| // keep the event page alive. |
| WebContents* contents = content::Source<WebContents>(source).ptr(); |
| - if (contents->GetBrowserContext() != GetProfile()) |
| + if (contents->GetBrowserContext() != GetBrowserContext()) |
| break; |
| typedef std::pair<RenderViewHost*, RenderViewHost*> RVHPair; |
| @@ -698,7 +702,7 @@ void ExtensionProcessManager::Observe( |
| case content::NOTIFICATION_WEB_CONTENTS_CONNECTED: { |
| WebContents* contents = content::Source<WebContents>(source).ptr(); |
| - if (contents->GetBrowserContext() != GetProfile()) |
| + if (contents->GetBrowserContext() != GetBrowserContext()) |
| break; |
| const Extension* extension = GetExtensionForRenderViewHost( |
| contents->GetRenderViewHost()); |
| @@ -709,7 +713,7 @@ void ExtensionProcessManager::Observe( |
| // available), so we need to wait until now to notify. |
| content::NotificationService::current()->Notify( |
| chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED, |
| - content::Source<Profile>(GetProfile()), |
| + content::Source<BrowserContext>(GetBrowserContext()), |
| content::Details<RenderViewHost>(contents->GetRenderViewHost())); |
| break; |
| } |
| @@ -732,7 +736,8 @@ void ExtensionProcessManager::OnDevToolsStateChanged( |
| RenderViewHost* rvh = agent_host->GetRenderViewHost(); |
| // Ignore unrelated notifications. |
| if (!rvh || |
| - rvh->GetSiteInstance()->GetProcess()->GetBrowserContext() != GetProfile()) |
| + rvh->GetSiteInstance()->GetProcess()->GetBrowserContext() != |
| + GetBrowserContext()) |
| return; |
| if (extensions::GetViewType(WebContents::FromRenderViewHost(rvh)) != |
| extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) |
| @@ -750,6 +755,7 @@ void ExtensionProcessManager::OnDevToolsStateChanged( |
| } |
| void ExtensionProcessManager::CreateBackgroundHostsForProfileStartup() { |
| + DVLOG(1) << "CreateBackgroundHostsForProfileStartup"; |
| // Don't load background hosts now if the loading should be deferred. |
| // Instead they will be loaded when a browser window for this profile |
| // (or an incognito profile from this profile) is ready, or when |
| @@ -757,37 +763,52 @@ void ExtensionProcessManager::CreateBackgroundHostsForProfileStartup() { |
| if (DeferLoadingBackgroundHosts()) |
| return; |
| - ExtensionService* service = GetProfile()->GetExtensionService(); |
| + ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| + GetBrowserContext())->extension_service(); |
| + DCHECK(service); |
| for (ExtensionSet::const_iterator extension = service->extensions()->begin(); |
| extension != service->extensions()->end(); ++extension) { |
| CreateBackgroundHostForExtensionLoad(this, extension->get()); |
| extensions::RuntimeEventRouter::DispatchOnStartupEvent( |
| - GetProfile(), (*extension)->id()); |
| + GetBrowserContext(), (*extension)->id()); |
| } |
| // Background pages should only be loaded once. To prevent any further loads |
| // occurring, we remove the notification listeners. |
| - Profile* original_profile = GetProfile()->GetOriginalProfile(); |
| + BrowserContext* original_context = |
| + ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); |
| registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, |
| content::NotificationService::AllSources()); |
| - if (registrar_.IsRegistered(this, chrome::NOTIFICATION_PROFILE_CREATED, |
| - content::Source<Profile>(original_profile))) |
| - registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_CREATED, |
| - content::Source<Profile>(original_profile)); |
| - if (registrar_.IsRegistered(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| - content::Source<Profile>(original_profile))) |
| - registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| - content::Source<Profile>(original_profile)); |
| + if (registrar_.IsRegistered( |
| + this, |
| + chrome::NOTIFICATION_PROFILE_CREATED, |
| + content::Source<BrowserContext>(original_context))) { |
| + registrar_.Remove(this, |
| + chrome::NOTIFICATION_PROFILE_CREATED, |
| + content::Source<BrowserContext>(original_context)); |
| + } |
| + if (registrar_.IsRegistered( |
| + this, |
| + chrome::NOTIFICATION_EXTENSIONS_READY, |
| + content::Source<BrowserContext>(original_context))) { |
| + registrar_.Remove(this, |
| + chrome::NOTIFICATION_EXTENSIONS_READY, |
| + content::Source<BrowserContext>(original_context)); |
| + } |
| } |
| Profile* ExtensionProcessManager::GetProfile() const { |
| return Profile::FromBrowserContext(site_instance_->GetBrowserContext()); |
| } |
| +content::BrowserContext* ExtensionProcessManager::GetBrowserContext() const { |
| + return site_instance_->GetBrowserContext(); |
| +} |
| + |
| void ExtensionProcessManager::OnExtensionHostCreated(ExtensionHost* host, |
| bool is_background) { |
| - DCHECK_EQ(site_instance_->GetBrowserContext(), host->profile()); |
| + DCHECK_EQ(site_instance_->GetBrowserContext(), host->browser_context()); |
| if (is_background) { |
| background_hosts_.insert(host); |
| @@ -826,11 +847,11 @@ void ExtensionProcessManager::UnregisterExtension( |
| // decrement the lazy_keepalive_count to negative for the new extension |
| // instance when they are destroyed. Since we are erasing the background page |
| // data for the unloaded extension, unregister the RenderViewHosts too. |
| - Profile* profile = GetProfile(); |
| + BrowserContext* context = GetBrowserContext(); |
| for (ExtensionRenderViews::iterator it = all_extension_views_.begin(); |
| it != all_extension_views_.end(); ) { |
| if (GetExtensionID(it->first) == extension_id) { |
| - OnRenderViewHostUnregistered(profile, it->first); |
| + OnRenderViewHostUnregistered(context, it->first); |
| all_extension_views_.erase(it++); |
| } else { |
| ++it; |
| @@ -859,18 +880,9 @@ bool ExtensionProcessManager::DeferLoadingBackgroundHosts() const { |
| if (defer_background_host_creation_) |
| return true; |
| - // The profile may not be valid yet if it is still being initialized. |
| - // In that case, defer loading, since it depends on an initialized profile. |
| - // http://crbug.com/222473 |
| - if (!g_browser_process->profile_manager()->IsValidProfile(GetProfile())) |
| - return true; |
| - |
| -#if defined(OS_ANDROID) |
| - return false; |
| -#else |
| - return chrome::GetTotalBrowserCountForProfile(GetProfile()) == 0 && |
| - CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowAppList); |
| -#endif |
| + // The extensions embedder may have special rules about background hosts. |
| + return ExtensionsBrowserClient::Get()->DeferLoadingBackgroundHosts( |
| + GetBrowserContext()); |
| } |
| // |
| @@ -878,27 +890,28 @@ bool ExtensionProcessManager::DeferLoadingBackgroundHosts() const { |
| // |
| IncognitoExtensionProcessManager::IncognitoExtensionProcessManager( |
| - Profile* profile) |
| - : ExtensionProcessManager(profile), |
| - original_manager_(extensions::ExtensionSystem::Get( |
| - profile->GetOriginalProfile())->process_manager()) { |
| - DCHECK(profile->IsOffTheRecord()); |
| + BrowserContext* incognito_context, |
| + BrowserContext* original_context) |
| + : ExtensionProcessManager(incognito_context, original_context), |
| + original_manager_(extensions::ExtensionSystem::GetForBrowserContext( |
| + original_context)->process_manager()) { |
| + DCHECK(incognito_context->IsOffTheRecord()); |
| // The original profile will have its own ExtensionProcessManager to |
| // load the background pages of the spanning extensions. This process |
| // manager need only worry about the split mode extensions, which is handled |
| // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler. |
| registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| - content::Source<Profile>(profile->GetOriginalProfile())); |
| + content::Source<BrowserContext>(original_context)); |
| registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_CREATED, |
| - content::Source<Profile>(profile->GetOriginalProfile())); |
| + content::Source<BrowserContext>(original_context)); |
| } |
| IncognitoExtensionProcessManager::~IncognitoExtensionProcessManager() { |
| // TODO(yoz): This cleanup code belongs in the MenuManager. |
| // Remove "incognito" "split" mode context menu items. |
| - ExtensionService* service = |
| - extensions::ExtensionSystem::Get(GetProfile())->extension_service(); |
| + ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| + GetBrowserContext())->extension_service(); |
| if (service) |
| service->menu_manager()->RemoveAllIncognitoContextItems(); |
| } |
| @@ -938,7 +951,8 @@ ExtensionHost* IncognitoExtensionProcessManager::CreateBackgroundHost( |
| SiteInstance* IncognitoExtensionProcessManager::GetSiteInstanceForURL( |
| const GURL& url) { |
| - ExtensionService* service = GetProfile()->GetExtensionService(); |
| + ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| + GetBrowserContext())->extension_service(); |
| if (service) { |
| const Extension* extension = |
| service->extensions()->GetExtensionOrAppByURL(url); |
| @@ -953,7 +967,8 @@ SiteInstance* IncognitoExtensionProcessManager::GetSiteInstanceForURL( |
| bool IncognitoExtensionProcessManager::IsIncognitoEnabled( |
| const Extension* extension) { |
| // Keep in sync with duplicate in extension_info_map.cc. |
| - ExtensionService* service = GetProfile()->GetExtensionService(); |
| + ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| + GetBrowserContext())->extension_service(); |
| return extension_util::IsIncognitoEnabled(extension->id(), service); |
| } |
| @@ -973,7 +988,8 @@ void IncognitoExtensionProcessManager::Observe( |
| // On Chrome OS, a login screen is implemented as a browser. |
| // This browser has no extension service. In this case, |
| // service will be NULL. |
| - ExtensionService* service = GetProfile()->GetExtensionService(); |
| + ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| + GetBrowserContext())->extension_service(); |
| if (service && service->is_ready()) |
| CreateBackgroundHostsForProfileStartup(); |
| } |