diff options
author | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-05 04:26:16 +0000 |
---|---|---|
committer | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-05 04:26:16 +0000 |
commit | 7f47421705a2075ac304e9e9f25020a1f8669fc8 (patch) | |
tree | 9dbd00a5b672bb218943cc6823cd4c9f640a261c | |
parent | 434e3bad563f4a4ceac3fb7a4c05eb5d21b1dd3c (diff) | |
download | chromium_src-7f47421705a2075ac304e9e9f25020a1f8669fc8.zip chromium_src-7f47421705a2075ac304e9e9f25020a1f8669fc8.tar.gz chromium_src-7f47421705a2075ac304e9e9f25020a1f8669fc8.tar.bz2 |
Reland: Convert ExtensionProcessManager to BrowserContext, part 1
Reland of https://codereview.chromium.org/52983004/ which failed due to
timeouts on Windows XP.
Part of moving ExtensionProcessManager to src/extensions.
* Introduce more test coverage
* Convert most usage of Profile to BrowserContext
* Separate out "master" vs. incognito profiles/contexts
* Move switches into extensions/common/switches.h
BUG=313481
TEST=unit_tests ExtensionProcessManager* and browser_tests ExtensionProcessManager*
TBR=miket@chromium.org
Review URL: https://codereview.chromium.org/57813003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232904 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 398 insertions, 127 deletions
diff --git a/chrome/browser/apps/app_browsertest_util.cc b/chrome/browser/apps/app_browsertest_util.cc index 24a161c..9a04d3c 100644 --- a/chrome/browser/apps/app_browsertest_util.cc +++ b/chrome/browser/apps/app_browsertest_util.cc @@ -14,7 +14,6 @@ #include "chrome/browser/ui/apps/chrome_shell_window_delegate.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/extensions/application_launch.h" -#include "chrome/common/chrome_switches.h" #include "content/public/browser/notification_service.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -37,8 +36,8 @@ void PlatformAppBrowserTest::SetUpCommandLine(CommandLine* command_line) { ExtensionBrowserTest::SetUpCommandLine(command_line); // Make event pages get suspended quicker. - command_line->AppendSwitchASCII(::switches::kEventPageIdleTime, "1"); - command_line->AppendSwitchASCII(::switches::kEventPageSuspendingTime, "1"); + command_line->AppendSwitchASCII(switches::kEventPageIdleTime, "1"); + command_line->AppendSwitchASCII(switches::kEventPageSuspendingTime, "1"); } // static diff --git a/chrome/browser/extensions/api/runtime/runtime_api.cc b/chrome/browser/extensions/api/runtime/runtime_api.cc index 185c2ce..3411a03 100644 --- a/chrome/browser/extensions/api/runtime/runtime_api.cc +++ b/chrome/browser/extensions/api/runtime/runtime_api.cc @@ -132,7 +132,9 @@ std::string GetUninstallUrl(ExtensionPrefs* prefs, // static void RuntimeEventRouter::DispatchOnStartupEvent( - Profile* profile, const std::string& extension_id) { + content::BrowserContext* context, const std::string& extension_id) { + // TODO(jamescook): Convert to BrowserContext all the way down. + Profile* profile = static_cast<Profile*>(context); DispatchOnStartupEventImpl(profile, extension_id, true, NULL); } diff --git a/chrome/browser/extensions/api/runtime/runtime_api.h b/chrome/browser/extensions/api/runtime/runtime_api.h index b917ba4..8884984 100644 --- a/chrome/browser/extensions/api/runtime/runtime_api.h +++ b/chrome/browser/extensions/api/runtime/runtime_api.h @@ -18,6 +18,10 @@ namespace base { class Version; } +namespace content { +class BrowserContext; +} + namespace extensions { class Extension; class ExtensionHost; @@ -25,7 +29,7 @@ class ExtensionHost; class RuntimeEventRouter { public: // Dispatches the onStartup event to all currently-loaded extensions. - static void DispatchOnStartupEvent(Profile* profile, + static void DispatchOnStartupEvent(content::BrowserContext* context, const std::string& extension_id); // Dispatches the onInstalled event to the given extension. diff --git a/chrome/browser/extensions/api/system_indicator/system_indicator_apitest.cc b/chrome/browser/extensions/api/system_indicator/system_indicator_apitest.cc index 5b923ca..4268a39 100644 --- a/chrome/browser/extensions/api/system_indicator/system_indicator_apitest.cc +++ b/chrome/browser/extensions/api/system_indicator/system_indicator_apitest.cc @@ -11,8 +11,8 @@ #include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/extensions/lazy_background_page_test_util.h" #include "chrome/browser/ui/browser.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" +#include "extensions/common/switches.h" class SystemIndicatorApiTest : public ExtensionApiTest { public: @@ -20,8 +20,10 @@ class SystemIndicatorApiTest : public ExtensionApiTest { ExtensionApiTest::SetUpCommandLine(command_line); // Set shorter delays to prevent test timeouts in tests that need to wait // for the event page to unload. - command_line->AppendSwitchASCII(switches::kEventPageIdleTime, "1"); - command_line->AppendSwitchASCII(switches::kEventPageSuspendingTime, "1"); + command_line->AppendSwitchASCII( + extensions::switches::kEventPageIdleTime, "1"); + command_line->AppendSwitchASCII( + extensions::switches::kEventPageSuspendingTime, "1"); } const extensions::Extension* LoadExtensionAndWait( diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc index e2ba427..f2d2c8f 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.cc +++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc @@ -4,8 +4,12 @@ #include "chrome/browser/extensions/chrome_extensions_browser_client.h" +#include "base/command_line.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/common/chrome_switches.h" namespace extensions { @@ -41,6 +45,31 @@ content::BrowserContext* ChromeExtensionsBrowserClient::GetOffTheRecordContext( return static_cast<Profile*>(context)->GetOffTheRecordProfile(); } +content::BrowserContext* ChromeExtensionsBrowserClient::GetOriginalContext( + content::BrowserContext* context) { + return static_cast<Profile*>(context)->GetOriginalProfile(); +} + +bool ChromeExtensionsBrowserClient::DeferLoadingBackgroundHosts( + content::BrowserContext* context) const { + Profile* profile = static_cast<Profile*>(context); + + // 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(profile)) + return true; + +#if defined(OS_ANDROID) + return false; +#else + // There are no browser windows open and the browser process was + // started to show the app launcher. + return chrome::GetTotalBrowserCountForProfile(profile) == 0 && + CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowAppList); +#endif +} + // static ChromeExtensionsBrowserClient* ChromeExtensionsBrowserClient::GetInstance() { return g_client.Pointer(); diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.h b/chrome/browser/extensions/chrome_extensions_browser_client.h index ddcc4d7..13cd64d 100644 --- a/chrome/browser/extensions/chrome_extensions_browser_client.h +++ b/chrome/browser/extensions/chrome_extensions_browser_client.h @@ -35,6 +35,10 @@ class ChromeExtensionsBrowserClient : public ExtensionsBrowserClient { content::BrowserContext* context) OVERRIDE; virtual content::BrowserContext* GetOffTheRecordContext( content::BrowserContext* context) OVERRIDE; + virtual content::BrowserContext* GetOriginalContext( + content::BrowserContext* context) OVERRIDE; + virtual bool DeferLoadingBackgroundHosts( + content::BrowserContext* context) const OVERRIDE; // Get the LazyInstance for ChromeBrowserClient. static ChromeExtensionsBrowserClient* GetInstance(); diff --git a/chrome/browser/extensions/extension_context_menu_browsertest.cc b/chrome/browser/extensions/extension_context_menu_browsertest.cc index 5c00310..8120edf 100644 --- a/chrome/browser/extensions/extension_context_menu_browsertest.cc +++ b/chrome/browser/extensions/extension_context_menu_browsertest.cc @@ -14,9 +14,9 @@ #include "chrome/browser/tab_contents/render_view_context_menu.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/common/context_menu_params.h" +#include "extensions/common/switches.h" #include "net/dns/mock_host_resolver.h" #include "ui/base/models/menu_model.h" @@ -608,8 +608,10 @@ class ExtensionContextMenuBrowserLazyTest : virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { ExtensionContextMenuBrowserTest::SetUpCommandLine(command_line); // Set shorter delays to prevent test timeouts. - command_line->AppendSwitchASCII(switches::kEventPageIdleTime, "0"); - command_line->AppendSwitchASCII(switches::kEventPageSuspendingTime, "0"); + command_line->AppendSwitchASCII( + extensions::switches::kEventPageIdleTime, "0"); + command_line->AppendSwitchASCII( + extensions::switches::kEventPageSuspendingTime, "0"); } }; diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc index a4b2374..bb44539 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(); } diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h index 3239bee..c24a74b 100644 --- a/chrome/browser/extensions/extension_process_manager.h +++ b/chrome/browser/extensions/extension_process_manager.h @@ -23,6 +23,7 @@ class GURL; class Profile; namespace content { +class BrowserContext; class DevToolsAgentHost; class RenderViewHost; class SiteInstance; @@ -41,7 +42,7 @@ class ExtensionProcessManager : public content::NotificationObserver { typedef std::set<extensions::ExtensionHost*> ExtensionHostSet; typedef ExtensionHostSet::const_iterator const_iterator; - static ExtensionProcessManager* Create(Profile* profile); + static ExtensionProcessManager* Create(content::BrowserContext* context); virtual ~ExtensionProcessManager(); const ExtensionHostSet& background_hosts() const { @@ -141,7 +142,10 @@ class ExtensionProcessManager : public content::NotificationObserver { void DeferBackgroundHostCreation(bool defer); protected: - explicit ExtensionProcessManager(Profile* profile); + // If |context| is incognito pass the master context as |original_context|. + // Otherwise pass the same context for both. + ExtensionProcessManager(content::BrowserContext* context, + content::BrowserContext* original_context); // Called just after |host| is created so it can be registered in our lists. void OnExtensionHostCreated(extensions::ExtensionHost* host, @@ -163,6 +167,9 @@ class ExtensionProcessManager : public content::NotificationObserver { // related SiteInstances. Profile* GetProfile() const; + // Returns the same value as GetProfile() as a BrowserContext. + content::BrowserContext* GetBrowserContext() const; + content::NotificationRegistrar registrar_; // The set of ExtensionHosts running viewless background extensions. @@ -174,6 +181,8 @@ class ExtensionProcessManager : public content::NotificationObserver { scoped_refptr<content::SiteInstance> site_instance_; private: + friend class ExtensionProcessManagerTest; + // Extra information we keep for each extension's background page. struct BackgroundPageData; typedef std::string ExtensionId; @@ -207,10 +216,7 @@ class ExtensionProcessManager : public content::NotificationObserver { // Clears background page data for this extension. void ClearBackgroundPageData(const std::string& extension_id); - // Returns true if loading background pages should be deferred. This is - // true if there are no browser windows open and the browser process was - // started to show the app launcher, or if DeferBackgroundHostCreation was - // called with true, or if the profile is not yet valid. + // Returns true if loading background pages should be deferred. bool DeferLoadingBackgroundHosts() const; void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached); @@ -233,10 +239,10 @@ class ExtensionProcessManager : public content::NotificationObserver { // If true, then creation of background hosts is suspended. bool defer_background_host_creation_; - base::WeakPtrFactory<ExtensionProcessManager> weak_ptr_factory_; - base::Callback<void(content::DevToolsAgentHost*, bool)> devtools_callback_; + base::WeakPtrFactory<ExtensionProcessManager> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ExtensionProcessManager); }; diff --git a/chrome/browser/extensions/extension_process_manager_browsertest.cc b/chrome/browser/extensions/extension_process_manager_browsertest.cc new file mode 100644 index 0000000..02f02cd --- /dev/null +++ b/chrome/browser/extensions/extension_process_manager_browsertest.cc @@ -0,0 +1,111 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/extension_process_manager.h" + +#include "chrome/browser/extensions/browser_action_test_util.h" +#include "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_system.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "content/public/browser/notification_service.h" +#include "content/public/test/test_utils.h" + +using extensions::Extension; +using extensions::ExtensionSystem; + +// Exists as a browser test because ExtensionHosts are hard to create without +// a real browser. +typedef ExtensionBrowserTest ExtensionProcessManagerBrowserTest; + +// Test that basic extension loading creates the appropriate ExtensionHosts +// and background pages. +IN_PROC_BROWSER_TEST_F(ExtensionProcessManagerBrowserTest, + ExtensionHostCreation) { + ExtensionProcessManager* pm = + ExtensionSystem::Get(profile())->process_manager(); + + // We start with no background hosts. + ASSERT_EQ(0u, pm->background_hosts().size()); + ASSERT_EQ(0u, pm->GetAllViews().size()); + + // Load an extension with a background page. + scoped_refptr<const Extension> extension = + LoadExtension(test_data_dir_.AppendASCII("api_test") + .AppendASCII("browser_action") + .AppendASCII("none")); + ASSERT_TRUE(extension.get()); + + // Process manager gains a background host. + EXPECT_EQ(1u, pm->background_hosts().size()); + EXPECT_EQ(1u, pm->GetAllViews().size()); + EXPECT_TRUE(pm->GetBackgroundHostForExtension(extension->id())); + EXPECT_TRUE(pm->GetSiteInstanceForURL(extension->url())); + EXPECT_EQ(1u, pm->GetRenderViewHostsForExtension(extension->id()).size()); + EXPECT_FALSE(pm->IsBackgroundHostClosing(extension->id())); + EXPECT_EQ(0, pm->GetLazyKeepaliveCount(extension.get())); + + // Unload the extension. + UnloadExtension(extension->id()); + + // Background host disappears. + EXPECT_EQ(0u, pm->background_hosts().size()); + EXPECT_EQ(0u, pm->GetAllViews().size()); + EXPECT_FALSE(pm->GetBackgroundHostForExtension(extension->id())); + EXPECT_TRUE(pm->GetSiteInstanceForURL(extension->url())); + EXPECT_EQ(0u, pm->GetRenderViewHostsForExtension(extension->id()).size()); + EXPECT_FALSE(pm->IsBackgroundHostClosing(extension->id())); + EXPECT_EQ(0, pm->GetLazyKeepaliveCount(extension.get())); +} + +// Times out on Windows. +#if defined(OS_WIN) +#define MAYBE_PopupHostCreation DISABLED_PopupHostCreation +#else +#define MAYBE_PopupHostCreation PopupHostCreation +#endif +// Test that loading an extension with a browser action does not create a +// background page and that clicking on the action creates the appropriate +// ExtensionHost. +IN_PROC_BROWSER_TEST_F(ExtensionProcessManagerBrowserTest, + MAYBE_PopupHostCreation) { + ExtensionProcessManager* pm = + ExtensionSystem::Get(profile())->process_manager(); + + // Load an extension with the ability to open a popup but no background + // page. + scoped_refptr<const Extension> popup = + LoadExtension(test_data_dir_.AppendASCII("api_test") + .AppendASCII("browser_action") + .AppendASCII("popup")); + ASSERT_TRUE(popup); + + // No background host was added. + EXPECT_EQ(0u, pm->background_hosts().size()); + EXPECT_EQ(0u, pm->GetAllViews().size()); + EXPECT_FALSE(pm->GetBackgroundHostForExtension(popup->id())); + EXPECT_EQ(0u, pm->GetRenderViewHostsForExtension(popup->id()).size()); + EXPECT_TRUE(pm->GetSiteInstanceForURL(popup->url())); + EXPECT_FALSE(pm->IsBackgroundHostClosing(popup->id())); + EXPECT_EQ(0, pm->GetLazyKeepaliveCount(popup.get())); + + // Simulate clicking on the action to open a popup. + BrowserActionTestUtil test_util(browser()); + content::WindowedNotificationObserver frame_observer( + content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, + content::NotificationService::AllSources()); + // Open popup in the first extension. + test_util.Press(0); + frame_observer.Wait(); + ASSERT_TRUE(test_util.HasPopup()); + + // We now have a view, but still no background hosts. + EXPECT_EQ(0u, pm->background_hosts().size()); + EXPECT_EQ(1u, pm->GetAllViews().size()); + EXPECT_FALSE(pm->GetBackgroundHostForExtension(popup->id())); + EXPECT_EQ(1u, pm->GetRenderViewHostsForExtension(popup->id()).size()); + EXPECT_TRUE(pm->GetSiteInstanceForURL(popup->url())); + EXPECT_FALSE(pm->IsBackgroundHostClosing(popup->id())); + EXPECT_EQ(0, pm->GetLazyKeepaliveCount(popup.get())); +} diff --git a/chrome/browser/extensions/extension_process_manager_unittest.cc b/chrome/browser/extensions/extension_process_manager_unittest.cc index bdd8d96..70a01f8 100644 --- a/chrome/browser/extensions/extension_process_manager_unittest.cc +++ b/chrome/browser/extensions/extension_process_manager_unittest.cc @@ -3,8 +3,11 @@ // found in the LICENSE file. #include "chrome/browser/extensions/extension_process_manager.h" + +#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/test/base/testing_profile.h" +#include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/site_instance.h" #include "testing/gtest/include/gtest/gtest.h" @@ -12,8 +15,6 @@ using content::SiteInstance; -namespace { - // make the test a PlatformTest to setup autorelease pools properly on mac class ExtensionProcessManagerTest : public testing::Test { public: @@ -24,9 +25,89 @@ class ExtensionProcessManagerTest : public testing::Test { virtual void SetUp() { ExtensionErrorReporter::GetInstance()->ClearErrors(); } + + // Returns true if the notification |type| is registered for |manager| with + // source |profile|. Pass NULL for |profile| for all sources. + static bool IsRegistered(ExtensionProcessManager* manager, + int type, + TestingProfile* profile) { + return manager->registrar_.IsRegistered( + manager, type, content::Source<Profile>(profile)); + } + + // Allows access to a protected method. + static Profile* GetProfile(ExtensionProcessManager* manager) { + return manager->GetProfile(); + } }; -} // namespace +// Test that notification registration works properly. +TEST_F(ExtensionProcessManagerTest, ExtensionNotificationRegistration) { + // Test for a normal profile. + scoped_ptr<TestingProfile> original_profile(new TestingProfile); + scoped_ptr<ExtensionProcessManager> manager1( + ExtensionProcessManager::Create(original_profile.get())); + + EXPECT_EQ(original_profile.get(), GetProfile(manager1.get())); + EXPECT_EQ(0u, manager1->background_hosts().size()); + + // It observes some notifications from all sources. + EXPECT_TRUE(IsRegistered( + manager1.get(), chrome::NOTIFICATION_BROWSER_WINDOW_READY, NULL)); + + // It observes other notifications from this profile. + EXPECT_TRUE(IsRegistered(manager1.get(), + chrome::NOTIFICATION_EXTENSIONS_READY, + original_profile.get())); + EXPECT_TRUE(IsRegistered(manager1.get(), + chrome::NOTIFICATION_EXTENSION_LOADED, + original_profile.get())); + EXPECT_TRUE(IsRegistered(manager1.get(), + chrome::NOTIFICATION_EXTENSION_UNLOADED, + original_profile.get())); + EXPECT_TRUE(IsRegistered(manager1.get(), + chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, + original_profile.get())); + + // Now add an incognito profile associated with the master above. + TestingProfile::Builder builder; + builder.SetIncognito(); + scoped_ptr<TestingProfile> incognito_profile = builder.Build(); + incognito_profile->SetOriginalProfile(original_profile.get()); + scoped_ptr<ExtensionProcessManager> manager2( + ExtensionProcessManager::Create(incognito_profile.get())); + + EXPECT_EQ(incognito_profile.get(), GetProfile(manager2.get())); + EXPECT_EQ(0u, manager2->background_hosts().size()); + + // Some notifications are observed for the original profile. + EXPECT_TRUE(IsRegistered(manager2.get(), + chrome::NOTIFICATION_EXTENSION_LOADED, + original_profile.get())); + + // Some notifications are observed for the incognito profile. + EXPECT_TRUE(IsRegistered(manager2.get(), + chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, + incognito_profile.get())); + + // Some notifications are observed for both incognito and original. + EXPECT_TRUE(IsRegistered(manager2.get(), + chrome::NOTIFICATION_PROFILE_DESTROYED, + original_profile.get())); + EXPECT_TRUE(IsRegistered(manager2.get(), + chrome::NOTIFICATION_PROFILE_DESTROYED, + incognito_profile.get())); + + // Some are not observed at all. + EXPECT_FALSE(IsRegistered(manager2.get(), + chrome::NOTIFICATION_EXTENSIONS_READY, + original_profile.get())); + + // This notification is observed for incognito profiles only. + EXPECT_TRUE(IsRegistered(manager2.get(), + chrome::NOTIFICATION_PROFILE_DESTROYED, + incognito_profile.get())); +} // Test that extensions get grouped in the right SiteInstance (and therefore // process) based on their URLs. diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index df1bf3d..bb99cf1 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc @@ -23,13 +23,13 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/omnibox/location_bar.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" +#include "extensions/common/switches.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "url/gurl.h" @@ -81,8 +81,10 @@ class LazyBackgroundPageApiTest : public ExtensionApiTest { virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { ExtensionApiTest::SetUpCommandLine(command_line); // Set shorter delays to prevent test timeouts. - command_line->AppendSwitchASCII(switches::kEventPageIdleTime, "1"); - command_line->AppendSwitchASCII(switches::kEventPageSuspendingTime, "1"); + command_line->AppendSwitchASCII( + extensions::switches::kEventPageIdleTime, "1"); + command_line->AppendSwitchASCII( + extensions::switches::kEventPageSuspendingTime, "1"); } // Loads the extension, which temporarily starts the lazy background page diff --git a/chrome/browser/extensions/notifications_apitest.cc b/chrome/browser/extensions/notifications_apitest.cc index 10d95b6..dab664a 100644 --- a/chrome/browser/extensions/notifications_apitest.cc +++ b/chrome/browser/extensions/notifications_apitest.cc @@ -10,8 +10,8 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/lazy_background_page_test_util.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" +#include "extensions/common/switches.h" #include "ui/message_center/message_center_switches.h" #include "ui/message_center/message_center_util.h" @@ -20,8 +20,10 @@ class NotificationIdleTest : public ExtensionApiTest { virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { ExtensionApiTest::SetUpCommandLine(command_line); - command_line->AppendSwitchASCII(switches::kEventPageIdleTime, "1"); - command_line->AppendSwitchASCII(switches::kEventPageSuspendingTime, "1"); + command_line->AppendSwitchASCII( + extensions::switches::kEventPageIdleTime, "1"); + command_line->AppendSwitchASCII( + extensions::switches::kEventPageSuspendingTime, "1"); } const extensions::Extension* LoadExtensionAndWait( diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 3592ab9..a773487 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1252,6 +1252,7 @@ 'browser/extensions/extension_loading_browsertest.cc', 'browser/extensions/extension_messages_apitest.cc', 'browser/extensions/extension_override_apitest.cc', + 'browser/extensions/extension_process_manager_browsertest.cc', 'browser/extensions/extension_resource_request_policy_apitest.cc', 'browser/extensions/extension_startup_browsertest.cc', 'browser/extensions/extension_storage_apitest.cc', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 20d49e6..a75946f 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -813,14 +813,6 @@ const char kEnableWebSocketOverSpdy[] = "enable-websocket-over-spdy"; // numbers. const char kExplicitlyAllowedPorts[] = "explicitly-allowed-ports"; -// The time in seconds that an extension event page can be idle before it -// is shut down. -const char kEventPageIdleTime[] = "event-page-idle-time"; - -// The time in seconds that an extension event page has between being notified -// of its impending unload and that unload happening. -const char kEventPageSuspendingTime[] = "event-page-unloading-time"; - // Marks a renderer as extension process. const char kExtensionProcess[] = "extension-process"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index bf64f6d..2e0d881 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -229,8 +229,6 @@ extern const char kEnableUnrestrictedSSL3Fallback[]; extern const char kEnableUserAlternateProtocolPorts[]; extern const char kEnableWatchdog[]; extern const char kEnableWebSocketOverSpdy[]; -extern const char kEventPageIdleTime[]; -extern const char kEventPageSuspendingTime[]; extern const char kExplicitlyAllowedPorts[]; extern const char kExtensionProcess[]; extern const char kExtensionsUpdateFrequency[]; diff --git a/extensions/browser/extensions_browser_client.h b/extensions/browser/extensions_browser_client.h index 4810836..dd78811 100644 --- a/extensions/browser/extensions_browser_client.h +++ b/extensions/browser/extensions_browser_client.h @@ -29,7 +29,7 @@ class ExtensionsBrowserClient { virtual bool IsSameContext(content::BrowserContext* first, content::BrowserContext* second) = 0; - // Returns true if |context| has an off-the-record content associated with it. + // Returns true if |context| has an off-the-record context associated with it. virtual bool HasOffTheRecordContext(content::BrowserContext* context) = 0; // Returns the off-the-record context associated with |context|. If |context| @@ -39,6 +39,15 @@ class ExtensionsBrowserClient { virtual content::BrowserContext* GetOffTheRecordContext( content::BrowserContext* context) = 0; + // Return the original "recording" context. This method returns |context| if + // |context| is not incognito. + virtual content::BrowserContext* GetOriginalContext( + content::BrowserContext* context) = 0; + + // Returns true if loading background pages should be deferred. + virtual bool DeferLoadingBackgroundHosts( + content::BrowserContext* context) const = 0; + // Returns the single instance of |this|. static ExtensionsBrowserClient* Get(); diff --git a/extensions/browser/lazy_background_task_queue_unittest.cc b/extensions/browser/lazy_background_task_queue_unittest.cc index 27d8471..da2e5bc 100644 --- a/extensions/browser/lazy_background_task_queue_unittest.cc +++ b/extensions/browser/lazy_background_task_queue_unittest.cc @@ -21,7 +21,7 @@ namespace extensions { class TestExtensionProcessManager : public ExtensionProcessManager { public: explicit TestExtensionProcessManager(Profile* profile) - : ExtensionProcessManager(profile), + : ExtensionProcessManager(profile, profile->GetOriginalProfile()), create_count_(0) {} virtual ~TestExtensionProcessManager() {} diff --git a/extensions/common/switches.cc b/extensions/common/switches.cc index 3c8ab10..674bb03 100644 --- a/extensions/common/switches.cc +++ b/extensions/common/switches.cc @@ -26,6 +26,14 @@ const char kEnableExperimentalExtensionApis[] = // them in the chrome:extensions page. const char kErrorConsole[] = "error-console"; +// The time in seconds that an extension event page can be idle before it +// is shut down. +const char kEventPageIdleTime[] = "event-page-idle-time"; + +// The time in seconds that an extension event page has between being notified +// of its impending unload and that unload happening. +const char kEventPageSuspendingTime[] = "event-page-unloading-time"; + // Enables extensions running scripts on chrome:// URLs. // Extensions still need to explicitly request access to chrome:// URLs in the // manifest. diff --git a/extensions/common/switches.h b/extensions/common/switches.h index 43cc0f1..e6ff310 100644 --- a/extensions/common/switches.h +++ b/extensions/common/switches.h @@ -15,6 +15,8 @@ extern const char kAllowLegacyExtensionManifests[]; extern const char kAllowScriptingGallery[]; extern const char kEnableExperimentalExtensionApis[]; extern const char kErrorConsole[]; +extern const char kEventPageIdleTime[]; +extern const char kEventPageSuspendingTime[]; extern const char kExtensionsOnChromeURLs[]; extern const char kShowComponentExtensionOptions[]; |