From 4a10006a0baeb74011e938668e896fc18adafcd1 Mon Sep 17 00:00:00 2001 From: "jyasskin@chromium.org" Date: Fri, 17 May 2013 23:18:35 +0000 Subject: Add a non-blocking "OneShotEvent" class to simplify code that needs to run after something has happened, and start using it for the ExtensionService's READY notification. This change doesn't, in itself replace any uses of NOTIFICATION_EXTENSIONS_READY, but it paves the way for doing so. BUG=240968 R=atwilson@chromium.org, kalman@chromium.org, mpcomplete@chromium.org Review URL: https://codereview.chromium.org/14757022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200918 0039d316-1c4b-4281-b951-d872f2087c98 --- .../background_application_list_model_unittest.cc | 2 +- chrome/browser/extensions/extension_service.cc | 20 +++++++++++--------- chrome/browser/extensions/extension_service.h | 11 ++++++----- chrome/browser/extensions/extension_system.cc | 7 ++++++- chrome/browser/extensions/extension_system.h | 9 +++++++++ chrome/browser/extensions/test_extension_system.cc | 7 ++++++- chrome/browser/extensions/test_extension_system.h | 2 ++ 7 files changed, 41 insertions(+), 17 deletions(-) (limited to 'chrome/browser') diff --git a/chrome/browser/background/background_application_list_model_unittest.cc b/chrome/browser/background/background_application_list_model_unittest.cc index 1723e6b..1b632d5 100644 --- a/chrome/browser/background/background_application_list_model_unittest.cc +++ b/chrome/browser/background/background_application_list_model_unittest.cc @@ -47,7 +47,7 @@ class BackgroundApplicationListModelTest : public ExtensionServiceTestBase { protected: void InitializeAndLoadEmptyExtensionService() { InitializeEmptyExtensionService(); - service_->OnLoadedInstalledExtensions(); /* Sends EXTENSIONS_READY */ + service_->Init(); /* Sends EXTENSIONS_READY */ } bool IsBackgroundApp(const Extension& app) { diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 71dd2fa..30f2deb 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -337,7 +337,8 @@ ExtensionService::ExtensionService(Profile* profile, extensions::ExtensionPrefs* extension_prefs, extensions::Blacklist* blacklist, bool autoupdate_enabled, - bool extensions_enabled) + bool extensions_enabled, + extensions::OneShotEvent* ready) : extensions::Blacklist::Observer(blacklist), profile_(profile), system_(extensions::ExtensionSystem::Get(profile)), @@ -349,7 +350,7 @@ ExtensionService::ExtensionService(Profile* profile, extensions_enabled_(extensions_enabled), show_extensions_prompts_(true), install_updates_when_idle_(true), - ready_(false), + ready_(ready), toolbar_model_(this), menu_manager_(profile), event_routers_initialized_(false), @@ -561,7 +562,7 @@ const Extension* ExtensionService::GetExtensionById( void ExtensionService::Init() { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!ready_); // Can't redo init. + DCHECK(!is_ready()); // Can't redo init. DCHECK_EQ(extensions_.size(), 0u); const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); @@ -584,12 +585,13 @@ void ExtensionService::Init() { // import process. extensions::InstalledLoader(this).LoadAllExtensions(); + SetReadyAndNotifyListeners(); RegisterForImportFinished(); } else { - // In this case, LoadAllExtensions() calls OnLoadedInstalledExtensions(), - // which calls SetReadyAndNotifyListeners(). + // In this case, LoadAllExtensions() calls OnLoadedInstalledExtensions(). component_loader_->LoadAll(); extensions::InstalledLoader(this).LoadAllExtensions(); + SetReadyAndNotifyListeners(); // TODO(erikkay) this should probably be deferred to a future point // rather than running immediately at startup. @@ -1238,7 +1240,7 @@ extensions::ContentSettingsStore* ExtensionService::GetContentSettingsStore() { } bool ExtensionService::is_ready() { - return ready_; + return ready_->is_signaled(); } base::SequencedTaskRunner* ExtensionService::GetFileTaskRunner() { @@ -1962,6 +1964,8 @@ void ExtensionService::ReloadExtensions() { UnloadAllExtensions(); component_loader_->LoadAll(); extensions::InstalledLoader(this).LoadAllExtensions(); + // Don't call SetReadyAndNotifyListeners() since tests call this multiple + // times. } void ExtensionService::GarbageCollectExtensions() { @@ -2020,7 +2024,7 @@ void ExtensionService::SyncExtensionChangeIfNeeded(const Extension& extension) { } void ExtensionService::SetReadyAndNotifyListeners() { - ready_ = true; + ready_->Signal(); content::NotificationService::current()->Notify( chrome::NOTIFICATION_EXTENSIONS_READY, content::Source(profile_), @@ -2032,8 +2036,6 @@ void ExtensionService::OnLoadedInstalledExtensions() { updater_->Start(); OnBlacklistUpdated(); - - SetReadyAndNotifyListeners(); } void ExtensionService::AddExtension(const Extension* extension) { diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 3f0408a2..e11e6cc 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -38,6 +38,7 @@ #include "chrome/common/extensions/manifest.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "extensions/common/one_shot_event.h" #include "sync/api/string_ordinal.h" #include "sync/api/sync_change.h" #include "sync/api/syncable_service.h" @@ -199,7 +200,8 @@ class ExtensionService extensions::ExtensionPrefs* extension_prefs, extensions::Blacklist* blacklist, bool autoupdate_enabled, - bool extensions_enabled); + bool extensions_enabled, + extensions::OneShotEvent* ready); virtual ~ExtensionService(); @@ -704,7 +706,7 @@ class ExtensionService }; typedef std::list NaClModuleInfoList; - // Sets the ready_ flag and sends a notification to the listeners. + // Signals *ready_ and sends a notification to the listeners. void SetReadyAndNotifyListeners(); // Return true if the sync type of |extension| matches |type|. @@ -899,9 +901,8 @@ class ExtensionService // Used by dispatchers to limit API quota for individual extensions. ExtensionsQuotaService quota_service_; - // Record that Init() has been called, and chrome::EXTENSIONS_READY - // has fired. - bool ready_; + // Signaled when all extensions are loaded. + extensions::OneShotEvent* const ready_; // Our extension updater, if updates are turned on. scoped_ptr updater_; diff --git a/chrome/browser/extensions/extension_system.cc b/chrome/browser/extensions/extension_system.cc index f7eec58..9ceb4d4 100644 --- a/chrome/browser/extensions/extension_system.cc +++ b/chrome/browser/extensions/extension_system.cc @@ -137,7 +137,8 @@ void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) { ExtensionPrefs::Get(profile_), blacklist_.get(), autoupdate_enabled, - extensions_enabled)); + extensions_enabled, + &ready_)); // These services must be registered before the ExtensionService tries to // load any extensions. @@ -392,6 +393,10 @@ Blacklist* ExtensionSystemImpl::blacklist() { return shared_->blacklist(); } +const OneShotEvent& ExtensionSystemImpl::ready() const { + return shared_->ready(); +} + void ExtensionSystemImpl::RegisterExtensionWithRequestContexts( const Extension* extension) { base::Time install_time; diff --git a/chrome/browser/extensions/extension_system.h b/chrome/browser/extensions/extension_system.h index 331570e8..5b663b5 100644 --- a/chrome/browser/extensions/extension_system.h +++ b/chrome/browser/extensions/extension_system.h @@ -15,6 +15,7 @@ #include "chrome/browser/extensions/api/usb/usb_device_resource.h" #include "chrome/browser/profiles/profile_keyed_service.h" #include "chrome/common/extensions/extension_constants.h" +#include "extensions/common/one_shot_event.h" class ExtensionInfoMap; class ExtensionProcessManager; @@ -128,6 +129,9 @@ class ExtensionSystem : public ProfileKeyedService { virtual void UnregisterExtensionWithRequestContexts( const std::string& extension_id, const extension_misc::UnloadedExtensionReason reason) {} + + // Signaled when the extension system has completed its startup tasks. + virtual const OneShotEvent& ready() const = 0; }; // The ExtensionSystem for ProfileImpl and OffTheRecordProfileImpl. @@ -173,6 +177,8 @@ class ExtensionSystemImpl : public ExtensionSystem { const std::string& extension_id, const extension_misc::UnloadedExtensionReason reason) OVERRIDE; + virtual const OneShotEvent& ready() const OVERRIDE; + private: friend class ExtensionSystemSharedFactory; @@ -202,6 +208,7 @@ class ExtensionSystemImpl : public ExtensionSystem { LazyBackgroundTaskQueue* lazy_background_task_queue(); EventRouter* event_router(); ExtensionWarningService* warning_service(); + const OneShotEvent& ready() const { return ready_; } private: Profile* profile_; @@ -227,6 +234,8 @@ class ExtensionSystemImpl : public ExtensionSystem { scoped_refptr extension_info_map_; scoped_ptr extension_warning_service_; scoped_ptr extension_warning_badge_service_; + + OneShotEvent ready_; }; Profile* profile_; diff --git a/chrome/browser/extensions/test_extension_system.cc b/chrome/browser/extensions/test_extension_system.cc index 4450ff3..938e6b3 100644 --- a/chrome/browser/extensions/test_extension_system.cc +++ b/chrome/browser/extensions/test_extension_system.cc @@ -97,7 +97,8 @@ ExtensionService* TestExtensionSystem::CreateExtensionService( ExtensionPrefs::Get(profile_), blacklist_.get(), autoupdate_enabled, - true)); + true, + &ready_)); extension_service_->ClearProvidersForTesting(); return extension_service_.get(); } @@ -169,6 +170,10 @@ Blacklist* TestExtensionSystem::blacklist() { return blacklist_.get(); } +const OneShotEvent& TestExtensionSystem::ready() const { + return ready_; +} + // static ProfileKeyedService* TestExtensionSystem::Build( content::BrowserContext* profile) { diff --git a/chrome/browser/extensions/test_extension_system.h b/chrome/browser/extensions/test_extension_system.h index debd400..cc57886 100644 --- a/chrome/browser/extensions/test_extension_system.h +++ b/chrome/browser/extensions/test_extension_system.h @@ -69,6 +69,7 @@ class TestExtensionSystem : public ExtensionSystem { OVERRIDE; virtual ExtensionWarningService* warning_service() OVERRIDE; virtual Blacklist* blacklist() OVERRIDE; + virtual const OneShotEvent& ready() const OVERRIDE; // Factory method for tests to use with SetTestingProfile. static ProfileKeyedService* Build(content::BrowserContext* profile); @@ -86,6 +87,7 @@ class TestExtensionSystem : public ExtensionSystem { scoped_ptr extension_process_manager_; scoped_refptr info_map_; scoped_ptr > socket_manager_; + OneShotEvent ready_; }; } // namespace extensions -- cgit v1.1