summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-29 19:27:31 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-29 19:27:31 +0000
commit06f9256f22242c46365458eadab409c79509d8d8 (patch)
treea46c7b7470f3315d35b1da105888240d242c9cc5 /chrome/browser
parent3b5648911bcde7d6dddc0fbef236257ea14b58af (diff)
downloadchromium_src-06f9256f22242c46365458eadab409c79509d8d8.zip
chromium_src-06f9256f22242c46365458eadab409c79509d8d8.tar.gz
chromium_src-06f9256f22242c46365458eadab409c79509d8d8.tar.bz2
[Sync] Add support for enabling/disabling an extension before it's installed
Make Enable/DisableExtension handle non-installed extensions gracefully. Make DisableExtension handle terminated extensions. Make ProcessSyncData enable/disable an extension regardless of whether it's already installed. BUG=72659 TEST= Review URL: http://codereview.chromium.org/6903127 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83571 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/extensions/extension_pref_value_map.cc5
-rw-r--r--chrome/browser/extensions/extension_service.cc81
-rw-r--r--chrome/browser/extensions/extension_service.h7
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc4
4 files changed, 59 insertions, 38 deletions
diff --git a/chrome/browser/extensions/extension_pref_value_map.cc b/chrome/browser/extensions/extension_pref_value_map.cc
index 02ebcdf..7032be9 100644
--- a/chrome/browser/extensions/extension_pref_value_map.cc
+++ b/chrome/browser/extensions/extension_pref_value_map.cc
@@ -101,7 +101,10 @@ void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
bool is_enabled) {
ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
- CHECK(i != entries_.end());
+ // This may happen when sync sets the extension state for an
+ // extension that is not installed.
+ if (i == entries_.end())
+ return;
if (i->second->enabled == is_enabled)
return;
std::set<std::string> keys; // keys set by this extension
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 0e43ded..45e796e 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -749,13 +749,18 @@ bool ExtensionService::IsExternalExtensionUninstalled(
void ExtensionService::EnableExtension(const std::string& extension_id) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (IsExtensionEnabled(extension_id))
+ return;
+
+ extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED);
+
const Extension* extension =
GetExtensionByIdInternal(extension_id, false, true, false);
+ // This can happen if sync enables an extension that is not
+ // installed yet.
if (!extension)
return;
- extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED);
-
// Move it over to the enabled list.
extensions_.push_back(make_scoped_refptr(extension));
ExtensionList::iterator iter = std::find(disabled_extensions_.begin(),
@@ -772,23 +777,35 @@ void ExtensionService::EnableExtension(const std::string& extension_id) {
void ExtensionService::DisableExtension(const std::string& extension_id) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- const Extension* extension =
- GetExtensionByIdInternal(extension_id, true, false, false);
// The extension may have been disabled already.
- if (!extension)
+ if (!IsExtensionEnabled(extension_id))
return;
- if (!Extension::UserMayDisable(extension->location()))
+ const Extension* extension = GetInstalledExtension(extension_id);
+ // |extension| can be NULL if sync disables an extension that is not
+ // installed yet.
+ if (extension && !Extension::UserMayDisable(extension->location()))
return;
extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED);
+ extension = GetExtensionByIdInternal(extension_id, true, false, true);
+ if (!extension)
+ return;
+
// Move it over to the disabled list.
disabled_extensions_.push_back(make_scoped_refptr(extension));
ExtensionList::iterator iter = std::find(extensions_.begin(),
extensions_.end(),
extension);
- extensions_.erase(iter);
+ if (iter != extensions_.end()) {
+ extensions_.erase(iter);
+ } else {
+ iter = std::find(terminated_extensions_.begin(),
+ terminated_extensions_.end(),
+ extension);
+ terminated_extensions_.erase(iter);
+ }
NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE);
}
@@ -1352,21 +1369,17 @@ void ExtensionService::ProcessSyncData(
return;
}
+ // Set user settings.
+ if (extension_sync_data.enabled) {
+ EnableExtension(id);
+ } else {
+ DisableExtension(id);
+ }
SetIsIncognitoEnabled(id, extension_sync_data.incognito_enabled);
- const Extension* extension =
- GetExtensionByIdInternal(id, true, true, false);
- // TODO(akalin): Figure out what to do with terminated extensions.
-
- // Handle already-installed extensions.
+ const Extension* extension = GetInstalledExtension(id);
if (extension) {
- // TODO(akalin): Make it so we can enable/disable an extension
- // even if it's not installed yet.
- if (extension_sync_data.enabled) {
- EnableExtension(id);
- } else {
- DisableExtension(id);
- }
+ // If the extension is already installed, check if it's outdated.
int result = extension->version()->CompareTo(extension_sync_data.version);
if (result < 0) {
// Extension is outdated.
@@ -1378,22 +1391,22 @@ void ExtensionService::ProcessSyncData(
// TODO(akalin): Move that code here.
}
return;
+ } else {
+ // TODO(akalin): Remove need to pass the enabled flag.
+ //
+ // TODO(akalin): Replace silent update with a list of enabled
+ // permissions.
+ if (!pending_extension_manager()->AddFromSync(
+ id,
+ extension_sync_data.update_url,
+ filter,
+ true, // install_silently
+ extension_sync_data.enabled)) {
+ LOG(WARNING) << "Could not add pending extension for " << id;
+ return;
+ }
+ CheckForUpdatesSoon();
}
-
- // Handle not-yet-installed extensions.
- //
- // TODO(akalin): Replace silent update with a list of enabled
- // permissions.
- if (!pending_extension_manager()->AddFromSync(
- id,
- extension_sync_data.update_url,
- filter,
- true, // install_silently
- extension_sync_data.enabled)) {
- LOG(WARNING) << "Could not add pending extension for " << id;
- return;
- }
- CheckForUpdatesSoon();
}
bool ExtensionService::IsIncognitoEnabled(
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 94f15a9..a18aab5 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -276,9 +276,12 @@ class ExtensionService
virtual bool IsExternalExtensionUninstalled(
const std::string& extension_id) const OVERRIDE;
- // Enable or disable an extension. No action if the extension is already
- // enabled/disabled.
+ // Enables the extension. If the extension is already enabled, does
+ // nothing.
virtual void EnableExtension(const std::string& extension_id);
+
+ // Disables the extension. If the extension is already disabled, or
+ // cannot be disabled, does nothing.
virtual void DisableExtension(const std::string& extension_id);
// Updates the |extension|'s granted permissions lists to include all
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 1e67410..55f1f47 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -3598,16 +3598,18 @@ TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
ExtensionSyncData extension_sync_data;
extension_sync_data.id = good_crx;
extension_sync_data.update_url = GURL("http://www.google.com");
- extension_sync_data.enabled = true;
+ extension_sync_data.enabled = false;
extension_sync_data.incognito_enabled = true;
{
scoped_ptr<Version> version(Version::GetVersionFromString("1.2.3.4"));
extension_sync_data.version = *version;
}
+ EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
service_->ProcessSyncData(extension_sync_data, &AllExtensions);
EXPECT_TRUE(service_->updater()->WillCheckSoon());
+ EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
PendingExtensionInfo info;