| Index: chrome/browser/extensions/extension_service.cc
|
| diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
|
| index 2c846550b516ad89109b5e8451675f76e76c2615..d3f1dfbf3bfe4fd986729f83e350ac73166fbcf3 100644
|
| --- a/chrome/browser/extensions/extension_service.cc
|
| +++ b/chrome/browser/extensions/extension_service.cc
|
| @@ -74,6 +74,7 @@
|
| #include "extensions/browser/extension_registry.h"
|
| #include "extensions/browser/extension_system.h"
|
| #include "extensions/browser/extensions_browser_client.h"
|
| +#include "extensions/browser/external_install_info.h"
|
| #include "extensions/browser/install_flag.h"
|
| #include "extensions/browser/runtime_data.h"
|
| #include "extensions/browser/uninstall_reason.h"
|
| @@ -114,6 +115,9 @@ using extensions::ExtensionIdSet;
|
| using extensions::ExtensionInfo;
|
| using extensions::ExtensionRegistry;
|
| using extensions::ExtensionSet;
|
| +using extensions::ExternalInstallInfoFile;
|
| +using extensions::ExternalInstallInfoUpdateUrl;
|
| +using extensions::ExternalProviderInterface;
|
| using extensions::FeatureSwitch;
|
| using extensions::InstallVerifier;
|
| using extensions::ManagementPolicy;
|
| @@ -174,10 +178,10 @@ void ExtensionService::ClearProvidersForTesting() {
|
| }
|
|
|
| void ExtensionService::AddProviderForTesting(
|
| - extensions::ExternalProviderInterface* test_provider) {
|
| + ExternalProviderInterface* test_provider) {
|
| CHECK(test_provider);
|
| external_extension_providers_.push_back(
|
| - linked_ptr<extensions::ExternalProviderInterface>(test_provider));
|
| + linked_ptr<ExternalProviderInterface>(test_provider));
|
| }
|
|
|
| void ExtensionService::BlacklistExtensionForTest(
|
| @@ -189,49 +193,80 @@ void ExtensionService::BlacklistExtensionForTest(
|
| }
|
|
|
| bool ExtensionService::OnExternalExtensionUpdateUrlFound(
|
| - const std::string& id,
|
| - const std::string& install_parameter,
|
| - const GURL& update_url,
|
| - Manifest::Location location,
|
| - int creation_flags,
|
| - bool mark_acknowledged) {
|
| + const ExternalInstallInfoUpdateUrl& info,
|
| + bool is_initial_load) {
|
| CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - CHECK(crx_file::id_util::IdIsValid(id));
|
| + CHECK(crx_file::id_util::IdIsValid(info.extension_id));
|
|
|
| - if (Manifest::IsExternalLocation(location)) {
|
| + if (Manifest::IsExternalLocation(info.download_location)) {
|
| // All extensions that are not user specific can be cached.
|
| - extensions::ExtensionsBrowserClient::Get()->GetExtensionCache()
|
| - ->AllowCaching(id);
|
| + extensions::ExtensionsBrowserClient::Get()
|
| + ->GetExtensionCache()
|
| + ->AllowCaching(info.extension_id);
|
| }
|
|
|
| - const Extension* extension = GetExtensionById(id, true);
|
| + const Extension* extension = GetExtensionById(info.extension_id, true);
|
| if (extension) {
|
| // Already installed. Skip this install if the current location has
|
| - // higher priority than |location|.
|
| + // higher priority than |info.download_location|.
|
| Manifest::Location current = extension->location();
|
| - if (current == Manifest::GetHigherPriorityLocation(current, location))
|
| + if (current ==
|
| + Manifest::GetHigherPriorityLocation(current, info.download_location)) {
|
| return false;
|
| + }
|
| // Otherwise, overwrite the current installation.
|
| }
|
|
|
| - // Add |id| to the set of pending extensions. If it can not be added,
|
| - // then there is already a pending record from a higher-priority install
|
| - // source. In this case, signal that this extension will not be
|
| + // Add |info.extension_id| to the set of pending extensions. If it can not
|
| + // be added, then there is already a pending record from a higher-priority
|
| + // install source. In this case, signal that this extension will not be
|
| // installed by returning false.
|
| if (!pending_extension_manager()->AddFromExternalUpdateUrl(
|
| - id,
|
| - install_parameter,
|
| - update_url,
|
| - location,
|
| - creation_flags,
|
| - mark_acknowledged)) {
|
| + info.extension_id, info.install_parameter, *info.update_url,
|
| + info.download_location, info.creation_flags,
|
| + info.mark_acknowledged)) {
|
| return false;
|
| }
|
|
|
| - update_once_all_providers_are_ready_ = true;
|
| + if (is_initial_load)
|
| + update_once_all_providers_are_ready_ = true;
|
| return true;
|
| }
|
|
|
| +void ExtensionService::OnExternalProviderUpdateComplete(
|
| + const ExternalProviderInterface* provider,
|
| + const ScopedVector<ExternalInstallInfoUpdateUrl>& update_url_extensions,
|
| + const ScopedVector<ExternalInstallInfoFile>& file_extensions,
|
| + const std::set<std::string>& removed_extensions) {
|
| + // Update pending_extension_manager() with the new extensions first.
|
| + for (const auto& extension : update_url_extensions)
|
| + OnExternalExtensionUpdateUrlFound(*extension, false);
|
| + for (const auto& extension : file_extensions)
|
| + OnExternalExtensionFileFound(*extension);
|
| +
|
| +#if DCHECK_IS_ON()
|
| + for (const std::string& id : removed_extensions) {
|
| + for (const auto& extension : update_url_extensions)
|
| + DCHECK_NE(id, extension->extension_id);
|
| + for (const auto& extension : file_extensions)
|
| + DCHECK_NE(id, extension->extension_id);
|
| + }
|
| +#endif
|
| +
|
| + // Then uninstall before running |updater_|.
|
| + for (const std::string& id : removed_extensions)
|
| + CheckExternalUninstall(id);
|
| +
|
| + if (!update_url_extensions.empty() && updater_) {
|
| + // Empty params will cause pending extensions to be updated.
|
| + extensions::ExtensionUpdater::CheckParams empty_params;
|
| + updater_->CheckNow(empty_params);
|
| + }
|
| +
|
| + error_controller_->ShowErrorIfNeeded();
|
| + external_install_manager_->UpdateExternalExtensionAlert();
|
| +}
|
| +
|
| // static
|
| // This function is used to uninstall an extension via sync. The LOG statements
|
| // within this function are used to inform the user if the uninstall cannot be
|
| @@ -370,7 +405,7 @@ ExtensionService::~ExtensionService() {
|
| extensions::ProviderCollection::const_iterator i;
|
| for (i = external_extension_providers_.begin();
|
| i != external_extension_providers_.end(); ++i) {
|
| - extensions::ExternalProviderInterface* provider = i->get();
|
| + ExternalProviderInterface* provider = i->get();
|
| provider->ServiceShutdown();
|
| }
|
| }
|
| @@ -1274,7 +1309,7 @@ void ExtensionService::CheckForExternalUpdates() {
|
| extensions::ProviderCollection::const_iterator i;
|
| for (i = external_extension_providers_.begin();
|
| i != external_extension_providers_.end(); ++i) {
|
| - extensions::ExternalProviderInterface* provider = i->get();
|
| + ExternalProviderInterface* provider = i->get();
|
| provider->VisitRegisteredExtension();
|
| }
|
|
|
| @@ -1285,7 +1320,7 @@ void ExtensionService::CheckForExternalUpdates() {
|
| }
|
|
|
| void ExtensionService::OnExternalProviderReady(
|
| - const extensions::ExternalProviderInterface* provider) {
|
| + const ExternalProviderInterface* provider) {
|
| CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| CHECK(provider->IsReady());
|
|
|
| @@ -2008,22 +2043,16 @@ const Extension* ExtensionService::GetInstalledExtension(
|
| }
|
|
|
| bool ExtensionService::OnExternalExtensionFileFound(
|
| - const std::string& id,
|
| - const Version* version,
|
| - const base::FilePath& path,
|
| - Manifest::Location location,
|
| - int creation_flags,
|
| - bool mark_acknowledged,
|
| - bool install_immediately) {
|
| + const ExternalInstallInfoFile& info) {
|
| CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - CHECK(crx_file::id_util::IdIsValid(id));
|
| - if (extension_prefs_->IsExternalExtensionUninstalled(id))
|
| + CHECK(crx_file::id_util::IdIsValid(info.extension_id));
|
| + if (extension_prefs_->IsExternalExtensionUninstalled(info.extension_id))
|
| return false;
|
|
|
| // Before even bothering to unpack, check and see if we already have this
|
| // version. This is important because these extensions are going to get
|
| // installed on every startup.
|
| - const Extension* existing = GetExtensionById(id, true);
|
| + const Extension* existing = GetExtensionById(info.extension_id, true);
|
|
|
| if (existing) {
|
| // The default apps will have the location set as INTERNAL. Since older
|
| @@ -2031,22 +2060,23 @@ bool ExtensionService::OnExternalExtensionFileFound(
|
| // app is already installed as internal, then do the version check.
|
| // TODO(grv) : Remove after Q1-2013.
|
| bool is_default_apps_migration =
|
| - (location == Manifest::INTERNAL &&
|
| + (info.crx_location == Manifest::INTERNAL &&
|
| Manifest::IsExternalLocation(existing->location()));
|
|
|
| if (!is_default_apps_migration) {
|
| - DCHECK(version);
|
| + DCHECK(info.version.get());
|
|
|
| - switch (existing->version()->CompareTo(*version)) {
|
| + switch (existing->version()->CompareTo(*info.version)) {
|
| case -1: // existing version is older, we should upgrade
|
| break;
|
| case 0: // existing version is same, do nothing
|
| return false;
|
| case 1: // existing version is newer, uh-oh
|
| - LOG(WARNING) << "Found external version of extension " << id
|
| + LOG(WARNING) << "Found external version of extension "
|
| + << info.extension_id
|
| << "that is older than current version. Current version "
|
| << "is: " << existing->VersionString() << ". New "
|
| - << "version is: " << version->GetString()
|
| + << "version is: " << info.version->GetString()
|
| << ". Keeping current version.";
|
| return false;
|
| }
|
| @@ -2055,30 +2085,31 @@ bool ExtensionService::OnExternalExtensionFileFound(
|
|
|
| // If the extension is already pending, don't start an install.
|
| if (!pending_extension_manager()->AddFromExternalFile(
|
| - id, location, *version, creation_flags, mark_acknowledged)) {
|
| + info.extension_id, info.crx_location, *info.version,
|
| + info.creation_flags, info.mark_acknowledged)) {
|
| return false;
|
| }
|
|
|
| // no client (silent install)
|
| scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(this));
|
| - installer->set_install_source(location);
|
| - installer->set_expected_id(id);
|
| - installer->set_expected_version(*version,
|
| + installer->set_install_source(info.crx_location);
|
| + installer->set_expected_id(info.extension_id);
|
| + installer->set_expected_version(*info.version,
|
| true /* fail_install_if_unexpected */);
|
| installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE);
|
| - installer->set_install_immediately(install_immediately);
|
| - installer->set_creation_flags(creation_flags);
|
| + installer->set_install_immediately(info.install_immediately);
|
| + installer->set_creation_flags(info.creation_flags);
|
| #if defined(OS_CHROMEOS)
|
| - extensions::InstallLimiter::Get(profile_)->Add(installer, path);
|
| + extensions::InstallLimiter::Get(profile_)->Add(installer, info.path);
|
| #else
|
| - installer->InstallCrx(path);
|
| + installer->InstallCrx(info.path);
|
| #endif
|
|
|
| // Depending on the source, a new external extension might not need a user
|
| // notification on installation. For such extensions, mark them acknowledged
|
| // now to suppress the notification.
|
| - if (mark_acknowledged)
|
| - external_install_manager_->AcknowledgeExternalExtension(id);
|
| + if (info.mark_acknowledged)
|
| + external_install_manager_->AcknowledgeExternalExtension(info.extension_id);
|
|
|
| return true;
|
| }
|
|
|