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..bb445396894589120289eb4d07b714552df7a271 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"; |
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,9 @@ 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 and dialogs. |
+ DCHECK(view_type == extensions::VIEW_TYPE_EXTENSION_POPUP || |
+ view_type == extensions::VIEW_TYPE_EXTENSION_DIALOG); |
} |
} |
@@ -268,6 +269,7 @@ ExtensionHost* ExtensionProcessManager::CreateViewHost( |
const GURL& url, |
Browser* browser, |
extensions::ViewType view_type) { |
+ DVLOG(1) << "CreateViewHost"; |
DCHECK(extension); |
EnsureBrowserWhenRequired(browser, view_type); |
ExtensionHost* host = |
@@ -285,7 +287,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 +330,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 +391,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 +406,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 +617,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 +685,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 +703,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 +714,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 +737,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 +756,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 +764,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 +848,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 +881,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 +891,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 +952,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 +968,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 +989,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(); |
} |