| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 | 330 |
| 331 return true; | 331 return true; |
| 332 } | 332 } |
| 333 | 333 |
| 334 ExtensionService::ExtensionService(Profile* profile, | 334 ExtensionService::ExtensionService(Profile* profile, |
| 335 const CommandLine* command_line, | 335 const CommandLine* command_line, |
| 336 const base::FilePath& install_directory, | 336 const base::FilePath& install_directory, |
| 337 extensions::ExtensionPrefs* extension_prefs, | 337 extensions::ExtensionPrefs* extension_prefs, |
| 338 extensions::Blacklist* blacklist, | 338 extensions::Blacklist* blacklist, |
| 339 bool autoupdate_enabled, | 339 bool autoupdate_enabled, |
| 340 bool extensions_enabled) | 340 bool extensions_enabled, |
| 341 extensions::OneShotEvent* ready) |
| 341 : extensions::Blacklist::Observer(blacklist), | 342 : extensions::Blacklist::Observer(blacklist), |
| 342 profile_(profile), | 343 profile_(profile), |
| 343 system_(extensions::ExtensionSystem::Get(profile)), | 344 system_(extensions::ExtensionSystem::Get(profile)), |
| 344 extension_prefs_(extension_prefs), | 345 extension_prefs_(extension_prefs), |
| 345 blacklist_(blacklist), | 346 blacklist_(blacklist), |
| 346 settings_frontend_(extensions::SettingsFrontend::Create(profile)), | 347 settings_frontend_(extensions::SettingsFrontend::Create(profile)), |
| 347 pending_extension_manager_(*this), | 348 pending_extension_manager_(*this), |
| 348 install_directory_(install_directory), | 349 install_directory_(install_directory), |
| 349 extensions_enabled_(extensions_enabled), | 350 extensions_enabled_(extensions_enabled), |
| 350 show_extensions_prompts_(true), | 351 show_extensions_prompts_(true), |
| 351 install_updates_when_idle_(true), | 352 install_updates_when_idle_(true), |
| 352 ready_(false), | 353 ready_(ready), |
| 353 toolbar_model_(this), | 354 toolbar_model_(this), |
| 354 menu_manager_(profile), | 355 menu_manager_(profile), |
| 355 event_routers_initialized_(false), | 356 event_routers_initialized_(false), |
| 356 update_once_all_providers_are_ready_(false), | 357 update_once_all_providers_are_ready_(false), |
| 357 browser_terminating_(false), | 358 browser_terminating_(false), |
| 358 installs_delayed_(false), | 359 installs_delayed_(false), |
| 359 is_first_run_(false), | 360 is_first_run_(false), |
| 360 app_sync_bundle_(this), | 361 app_sync_bundle_(this), |
| 361 extension_sync_bundle_(this) { | 362 extension_sync_bundle_(this) { |
| 362 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 363 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id); | 555 const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id); |
| 555 if (extension) | 556 if (extension) |
| 556 return extension; | 557 return extension; |
| 557 } | 558 } |
| 558 return NULL; | 559 return NULL; |
| 559 } | 560 } |
| 560 | 561 |
| 561 void ExtensionService::Init() { | 562 void ExtensionService::Init() { |
| 562 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 563 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 563 | 564 |
| 564 DCHECK(!ready_); // Can't redo init. | 565 DCHECK(!is_ready()); // Can't redo init. |
| 565 DCHECK_EQ(extensions_.size(), 0u); | 566 DCHECK_EQ(extensions_.size(), 0u); |
| 566 | 567 |
| 567 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 568 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| 568 | 569 |
| 569 CHECK(!ProfileManager::IsImportProcess(*cmd_line)); | 570 CHECK(!ProfileManager::IsImportProcess(*cmd_line)); |
| 570 | 571 |
| 571 if (cmd_line->HasSwitch(switches::kInstallFromWebstore) || | 572 if (cmd_line->HasSwitch(switches::kInstallFromWebstore) || |
| 572 cmd_line->HasSwitch(switches::kLimitedInstallFromWebstore)) { | 573 cmd_line->HasSwitch(switches::kLimitedInstallFromWebstore)) { |
| 573 // The sole purpose of this launch is to install a new extension from CWS | 574 // The sole purpose of this launch is to install a new extension from CWS |
| 574 // and immediately terminate: loading already installed extensions is | 575 // and immediately terminate: loading already installed extensions is |
| 575 // unnecessary and may interfere with the inline install dialog (e.g. if an | 576 // unnecessary and may interfere with the inline install dialog (e.g. if an |
| 576 // extension listens to onStartup and opens a window). | 577 // extension listens to onStartup and opens a window). |
| 577 SetReadyAndNotifyListeners(); | 578 SetReadyAndNotifyListeners(); |
| 578 } else { | 579 } else { |
| 579 // TODO(mek): It might be cleaner to do the FinishDelayedInstallInfo stuff | 580 // TODO(mek): It might be cleaner to do the FinishDelayedInstallInfo stuff |
| 580 // here instead of in installedloader. | 581 // here instead of in installedloader. |
| 581 if (g_browser_process->profile_manager() && | 582 if (g_browser_process->profile_manager() && |
| 582 g_browser_process->profile_manager()->will_import()) { | 583 g_browser_process->profile_manager()->will_import()) { |
| 583 // Do not load any component extensions, since they may conflict with the | 584 // Do not load any component extensions, since they may conflict with the |
| 584 // import process. | 585 // import process. |
| 585 | 586 |
| 586 extensions::InstalledLoader(this).LoadAllExtensions(); | 587 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 588 SetReadyAndNotifyListeners(); |
| 587 RegisterForImportFinished(); | 589 RegisterForImportFinished(); |
| 588 } else { | 590 } else { |
| 589 // In this case, LoadAllExtensions() calls OnLoadedInstalledExtensions(), | 591 // In this case, LoadAllExtensions() calls OnLoadedInstalledExtensions(). |
| 590 // which calls SetReadyAndNotifyListeners(). | |
| 591 component_loader_->LoadAll(); | 592 component_loader_->LoadAll(); |
| 592 extensions::InstalledLoader(this).LoadAllExtensions(); | 593 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 594 SetReadyAndNotifyListeners(); |
| 593 | 595 |
| 594 // TODO(erikkay) this should probably be deferred to a future point | 596 // TODO(erikkay) this should probably be deferred to a future point |
| 595 // rather than running immediately at startup. | 597 // rather than running immediately at startup. |
| 596 CheckForExternalUpdates(); | 598 CheckForExternalUpdates(); |
| 597 | 599 |
| 598 // TODO(erikkay) this should probably be deferred as well. | 600 // TODO(erikkay) this should probably be deferred as well. |
| 599 GarbageCollectExtensions(); | 601 GarbageCollectExtensions(); |
| 600 } | 602 } |
| 601 | 603 |
| 602 if (extension_prefs_->NeedsStorageGarbageCollection()) { | 604 if (extension_prefs_->NeedsStorageGarbageCollection()) { |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1227 | 1229 |
| 1228 extensions::SettingsFrontend* ExtensionService::settings_frontend() { | 1230 extensions::SettingsFrontend* ExtensionService::settings_frontend() { |
| 1229 return settings_frontend_.get(); | 1231 return settings_frontend_.get(); |
| 1230 } | 1232 } |
| 1231 | 1233 |
| 1232 extensions::ContentSettingsStore* ExtensionService::GetContentSettingsStore() { | 1234 extensions::ContentSettingsStore* ExtensionService::GetContentSettingsStore() { |
| 1233 return extension_prefs()->content_settings_store(); | 1235 return extension_prefs()->content_settings_store(); |
| 1234 } | 1236 } |
| 1235 | 1237 |
| 1236 bool ExtensionService::is_ready() { | 1238 bool ExtensionService::is_ready() { |
| 1237 return ready_; | 1239 return ready_->is_signaled(); |
| 1238 } | 1240 } |
| 1239 | 1241 |
| 1240 base::SequencedTaskRunner* ExtensionService::GetFileTaskRunner() { | 1242 base::SequencedTaskRunner* ExtensionService::GetFileTaskRunner() { |
| 1241 if (file_task_runner_) | 1243 if (file_task_runner_) |
| 1242 return file_task_runner_; | 1244 return file_task_runner_; |
| 1243 | 1245 |
| 1244 // We should be able to interrupt any part of extension install process during | 1246 // We should be able to interrupt any part of extension install process during |
| 1245 // shutdown. SKIP_ON_SHUTDOWN ensures that not started extension install tasks | 1247 // shutdown. SKIP_ON_SHUTDOWN ensures that not started extension install tasks |
| 1246 // will be ignored/deleted while we will block on started tasks. | 1248 // will be ignored/deleted while we will block on started tasks. |
| 1247 std::string token("ext_install-"); | 1249 std::string token("ext_install-"); |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 | 1953 |
| 1952 // TODO(erikkay) should there be a notification for this? We can't use | 1954 // TODO(erikkay) should there be a notification for this? We can't use |
| 1953 // EXTENSION_UNLOADED since that implies that the extension has been disabled | 1955 // EXTENSION_UNLOADED since that implies that the extension has been disabled |
| 1954 // or uninstalled, and UnloadAll is just part of shutdown. | 1956 // or uninstalled, and UnloadAll is just part of shutdown. |
| 1955 } | 1957 } |
| 1956 | 1958 |
| 1957 void ExtensionService::ReloadExtensions() { | 1959 void ExtensionService::ReloadExtensions() { |
| 1958 UnloadAllExtensions(); | 1960 UnloadAllExtensions(); |
| 1959 component_loader_->LoadAll(); | 1961 component_loader_->LoadAll(); |
| 1960 extensions::InstalledLoader(this).LoadAllExtensions(); | 1962 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 1963 // Don't call SetReadyAndNotifyListeners() since tests call this multiple |
| 1964 // times. |
| 1961 } | 1965 } |
| 1962 | 1966 |
| 1963 void ExtensionService::GarbageCollectExtensions() { | 1967 void ExtensionService::GarbageCollectExtensions() { |
| 1964 if (extension_prefs_->pref_service()->ReadOnly()) | 1968 if (extension_prefs_->pref_service()->ReadOnly()) |
| 1965 return; | 1969 return; |
| 1966 | 1970 |
| 1967 if (pending_extension_manager()->HasPendingExtensions()) { | 1971 if (pending_extension_manager()->HasPendingExtensions()) { |
| 1968 // Don't garbage collect while there are pending installations, which may | 1972 // Don't garbage collect while there are pending installations, which may |
| 1969 // be using the temporary installation directory. Try to garbage collect | 1973 // be using the temporary installation directory. Try to garbage collect |
| 1970 // again later. | 1974 // again later. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2009 | 2013 |
| 2010 void ExtensionService::SyncExtensionChangeIfNeeded(const Extension& extension) { | 2014 void ExtensionService::SyncExtensionChangeIfNeeded(const Extension& extension) { |
| 2011 if (app_sync_bundle_.HandlesApp(extension)) { | 2015 if (app_sync_bundle_.HandlesApp(extension)) { |
| 2012 app_sync_bundle_.SyncChangeIfNeeded(extension); | 2016 app_sync_bundle_.SyncChangeIfNeeded(extension); |
| 2013 } else if (extension_sync_bundle_.HandlesExtension(extension)) { | 2017 } else if (extension_sync_bundle_.HandlesExtension(extension)) { |
| 2014 extension_sync_bundle_.SyncChangeIfNeeded(extension); | 2018 extension_sync_bundle_.SyncChangeIfNeeded(extension); |
| 2015 } | 2019 } |
| 2016 } | 2020 } |
| 2017 | 2021 |
| 2018 void ExtensionService::SetReadyAndNotifyListeners() { | 2022 void ExtensionService::SetReadyAndNotifyListeners() { |
| 2019 ready_ = true; | 2023 ready_->Signal(); |
| 2020 content::NotificationService::current()->Notify( | 2024 content::NotificationService::current()->Notify( |
| 2021 chrome::NOTIFICATION_EXTENSIONS_READY, | 2025 chrome::NOTIFICATION_EXTENSIONS_READY, |
| 2022 content::Source<Profile>(profile_), | 2026 content::Source<Profile>(profile_), |
| 2023 content::NotificationService::NoDetails()); | 2027 content::NotificationService::NoDetails()); |
| 2024 } | 2028 } |
| 2025 | 2029 |
| 2026 void ExtensionService::OnLoadedInstalledExtensions() { | 2030 void ExtensionService::OnLoadedInstalledExtensions() { |
| 2027 if (updater_) | 2031 if (updater_) |
| 2028 updater_->Start(); | 2032 updater_->Start(); |
| 2029 | 2033 |
| 2030 OnBlacklistUpdated(); | 2034 OnBlacklistUpdated(); |
| 2031 | |
| 2032 SetReadyAndNotifyListeners(); | |
| 2033 } | 2035 } |
| 2034 | 2036 |
| 2035 void ExtensionService::AddExtension(const Extension* extension) { | 2037 void ExtensionService::AddExtension(const Extension* extension) { |
| 2036 // TODO(jstritar): We may be able to get rid of this branch by overriding the | 2038 // TODO(jstritar): We may be able to get rid of this branch by overriding the |
| 2037 // default extension state to DISABLED when the --disable-extensions flag | 2039 // default extension state to DISABLED when the --disable-extensions flag |
| 2038 // is set (http://crbug.com/29067). | 2040 // is set (http://crbug.com/29067). |
| 2039 if (!extensions_enabled() && | 2041 if (!extensions_enabled() && |
| 2040 !extension->is_theme() && | 2042 !extension->is_theme() && |
| 2041 extension->location() != Manifest::COMPONENT && | 2043 extension->location() != Manifest::COMPONENT && |
| 2042 !Manifest::IsExternalLocation(extension->location())) { | 2044 !Manifest::IsExternalLocation(extension->location())) { |
| (...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3110 } | 3112 } |
| 3111 | 3113 |
| 3112 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { | 3114 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { |
| 3113 update_observers_.AddObserver(observer); | 3115 update_observers_.AddObserver(observer); |
| 3114 } | 3116 } |
| 3115 | 3117 |
| 3116 void ExtensionService::RemoveUpdateObserver( | 3118 void ExtensionService::RemoveUpdateObserver( |
| 3117 extensions::UpdateObserver* observer) { | 3119 extensions::UpdateObserver* observer) { |
| 3118 update_observers_.RemoveObserver(observer); | 3120 update_observers_.RemoveObserver(observer); |
| 3119 } | 3121 } |
| OLD | NEW |