summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extensions_service.cc
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-19 22:27:06 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-19 22:27:06 +0000
commitca3dbf513dde28bb92b0337f87d2ed05c43b75ff (patch)
tree86ee10b963618590ffc9f4590e9a355adbdd8697 /chrome/browser/extensions/extensions_service.cc
parent6a2ba7116c62a97aa0d11af35deba3be6e8589dc (diff)
downloadchromium_src-ca3dbf513dde28bb92b0337f87d2ed05c43b75ff.zip
chromium_src-ca3dbf513dde28bb92b0337f87d2ed05c43b75ff.tar.gz
chromium_src-ca3dbf513dde28bb92b0337f87d2ed05c43b75ff.tar.bz2
Allow extensions to be overinstalled with extensions of same
version. This is useful during development, for switching themes, and for user scripts (since user scripts have no development mode). Since we can't always immediately delete the version directory for an extension after unloading it (because some files might be in use), this required changing the directory layout of the extensions directory to allow multiple copies of the same version of the same extension to be present at once. This was done by adding a counter to the version directory name. Also get rid of all the old "Current Version" cruft, since we no longer use that. BUG=26538 Review URL: http://codereview.chromium.org/1521039 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47740 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extensions_service.cc')
-rw-r--r--chrome/browser/extensions/extensions_service.cc116
1 files changed, 35 insertions, 81 deletions
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 5b9a1e1..849243f 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -57,35 +57,6 @@ namespace errors = extension_manifest_errors;
namespace {
-// Helper class to collect the IDs of every extension listed in the prefs.
-class InstalledExtensionSet {
- public:
- explicit InstalledExtensionSet(ExtensionPrefs* prefs) {
- scoped_ptr<ExtensionPrefs::ExtensionsInfo> info(
- prefs->GetInstalledExtensionsInfo());
-
- for (size_t i = 0; i < info->size(); ++i) {
- std::string version;
- const DictionaryValue* manifest = info->at(i)->extension_manifest.get();
- if (!manifest ||
- !manifest->GetString(extension_manifest_keys::kVersion, &version)) {
- // Without a version, the extension is invalid. Ignoring it here will
- // cause it to get garbage collected.
- continue;
- }
- extensions_.insert(info->at(i)->extension_id);
- versions_[info->at(i)->extension_id] = version;
- }
- }
-
- const std::set<std::string>& extensions() { return extensions_; }
- const std::map<std::string, std::string>& versions() { return versions_; }
-
- private:
- std::set<std::string> extensions_;
- std::map<std::string, std::string> versions_;
-};
-
static bool ShouldReloadExtensionManifest(const ExtensionInfo& info) {
// Always reload LOAD extension manifests, because they can change on disk
// independent of the manifest in our prefs.
@@ -365,8 +336,9 @@ void ExtensionsService::UninstallExtension(const std::string& extension_id,
ChromeThread::PostTask(
ChromeThread::FILE, FROM_HERE,
NewRunnableFunction(
- &extension_file_util::UninstallExtension, extension_id_copy,
- install_directory_));
+ &extension_file_util::UninstallExtension,
+ install_directory_,
+ extension_id_copy));
}
ClearExtensionData(extension_url);
@@ -766,12 +738,18 @@ void ExtensionsService::GarbageCollectExtensions() {
if (extension_prefs_->pref_service()->read_only())
return;
- InstalledExtensionSet installed(extension_prefs_.get());
+ scoped_ptr<ExtensionPrefs::ExtensionsInfo> info(
+ extension_prefs_->GetInstalledExtensionsInfo());
+
+ std::map<std::string, FilePath> extension_paths;
+ for (size_t i = 0; i < info->size(); ++i)
+ extension_paths[info->at(i)->extension_id] = info->at(i)->extension_path;
+
ChromeThread::PostTask(
ChromeThread::FILE, FROM_HERE,
NewRunnableFunction(
&extension_file_util::GarbageCollectExtensions, install_directory_,
- installed.extensions(), installed.versions()));
+ extension_paths));
}
void ExtensionsService::OnLoadedInstalledExtensions() {
@@ -801,39 +779,30 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension,
Extension::IsExternalLocation(extension->location())) {
Extension* old = GetExtensionByIdInternal(extension->id(), true, true);
if (old) {
- if (extension->version()->CompareTo(*(old->version())) > 0) {
- bool allow_silent_upgrade =
- allow_privilege_increase || !Extension::IsPrivilegeIncrease(
- old, extension);
-
- // Extensions get upgraded if silent upgrades are allowed, otherwise
- // they get disabled.
- if (allow_silent_upgrade) {
- old->set_being_upgraded(true);
- extension->set_being_upgraded(true);
- }
-
- // To upgrade an extension in place, unload the old one and
- // then load the new one.
- UnloadExtension(old->id());
- old = NULL;
-
- if (!allow_silent_upgrade) {
- // Extension has changed permissions significantly. Disable it. We
- // send a notification below.
- extension_prefs_->SetExtensionState(extension, Extension::DISABLED);
- extension_prefs_->SetDidExtensionEscalatePermissions(extension, true);
- }
- } else {
- // We already have the extension of the same or older version.
- std::string error_message("Duplicate extension load attempt: ");
- error_message += extension->id();
- LOG(WARNING) << error_message;
- ReportExtensionLoadError(extension->path(),
- error_message,
- NotificationType::EXTENSION_OVERINSTALL_ERROR,
- false);
- return;
+ // CrxInstaller should have guaranteed that we aren't downgrading.
+ CHECK(extension->version()->CompareTo(*(old->version())) >= 0);
+
+ bool allow_silent_upgrade =
+ allow_privilege_increase || !Extension::IsPrivilegeIncrease(
+ old, extension);
+
+ // Extensions get upgraded if silent upgrades are allowed, otherwise
+ // they get disabled.
+ if (allow_silent_upgrade) {
+ old->set_being_upgraded(true);
+ extension->set_being_upgraded(true);
+ }
+
+ // To upgrade an extension in place, unload the old one and
+ // then load the new one.
+ UnloadExtension(old->id());
+ old = NULL;
+
+ if (!allow_silent_upgrade) {
+ // Extension has changed permissions significantly. Disable it. We
+ // send a notification below.
+ extension_prefs_->SetExtensionState(extension, Extension::DISABLED);
+ extension_prefs_->SetDidExtensionEscalatePermissions(extension, true);
}
}
@@ -917,21 +886,6 @@ void ExtensionsService::OnExtensionInstalled(Extension* extension,
}
}
-void ExtensionsService::OnExtensionOverinstallAttempted(const std::string& id) {
- Extension* extension = GetExtensionById(id, false);
- if (extension && extension->IsTheme()) {
- NotificationService::current()->Notify(
- NotificationType::THEME_INSTALLED,
- Source<Profile>(profile_),
- Details<Extension>(extension));
- } else {
- NotificationService::current()->Notify(
- NotificationType::NO_THEME_DETECTED,
- Source<Profile>(profile_),
- NotificationService::NoDetails());
- }
-}
-
Extension* ExtensionsService::GetExtensionByIdInternal(const std::string& id,
bool include_enabled,
bool include_disabled) {