summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/automation/automation_provider.cc2
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc2
-rw-r--r--chrome/browser/extensions/extension_browsertest.cc2
-rw-r--r--chrome/browser/extensions/extension_context_menu_model.cc3
-rw-r--r--chrome/browser/extensions/extension_disabled_ui.cc2
-rw-r--r--chrome/browser/extensions/extension_disabled_ui_browsertest.cc106
-rw-r--r--chrome/browser/extensions/extension_management_api.cc2
-rw-r--r--chrome/browser/extensions/extension_management_apitest.cc5
-rw-r--r--chrome/browser/extensions/extension_management_browsertest.cc12
-rw-r--r--chrome/browser/extensions/extension_prefs.cc24
-rw-r--r--chrome/browser/extensions/extension_prefs.h6
-rw-r--r--chrome/browser/extensions/extension_service.cc43
-rw-r--r--chrome/browser/extensions/extension_service.h3
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc12
-rw-r--r--chrome/browser/notifications/notification_options_menu_model.cc3
-rw-r--r--chrome/browser/sync/test/integration/sync_extension_helper.cc3
-rw-r--r--chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm3
-rw-r--r--chrome/browser/ui/panels/panel_settings_menu_model.cc2
-rw-r--r--chrome/browser/ui/webui/extensions/extension_settings_handler.cc3
19 files changed, 190 insertions, 48 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 26a5792..fb5863e 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -914,7 +914,7 @@ void AutomationProvider::DisableExtension(int extension_handle,
ExtensionService* service = profile_->GetExtensionService();
if (extension && service) {
ExtensionUnloadNotificationObserver observer;
- service->DisableExtension(extension->id());
+ service->DisableExtension(extension->id(), Extension::DISABLE_USER_ACTION);
// The extension unload notification should have been sent synchronously
// with the disable. Just to be safe, check that it was received.
*success = observer.did_receive_unload_notification();
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index 64625e2..843be92 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -4662,7 +4662,7 @@ void TestingAutomationProvider::SetExtensionStateById(
AutomationJSONReply(this, reply_message).SendSuccess(NULL);
}
} else {
- service->DisableExtension(extension->id());
+ service->DisableExtension(extension->id(), Extension::DISABLE_USER_ACTION);
AutomationJSONReply(this, reply_message).SendSuccess(NULL);
}
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index 42b8d06..f8358fa 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -355,7 +355,7 @@ void ExtensionBrowserTest::UninstallExtension(const std::string& extension_id) {
void ExtensionBrowserTest::DisableExtension(const std::string& extension_id) {
ExtensionService* service = browser()->profile()->GetExtensionService();
- service->DisableExtension(extension_id);
+ service->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
}
void ExtensionBrowserTest::EnableExtension(const std::string& extension_id) {
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc
index 426c40b..05707f2 100644
--- a/chrome/browser/extensions/extension_context_menu_model.cc
+++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -135,7 +135,8 @@ void ExtensionContextMenuModel::ExecuteCommand(int command_id) {
}
case DISABLE: {
ExtensionService* extension_service = profile_->GetExtensionService();
- extension_service->DisableExtension(extension_id_);
+ extension_service->DisableExtension(extension_id_,
+ Extension::DISABLE_USER_ACTION);
break;
}
case UNINSTALL: {
diff --git a/chrome/browser/extensions/extension_disabled_ui.cc b/chrome/browser/extensions/extension_disabled_ui.cc
index ed8c203..1d7d59f 100644
--- a/chrome/browser/extensions/extension_disabled_ui.cc
+++ b/chrome/browser/extensions/extension_disabled_ui.cc
@@ -188,6 +188,7 @@ ExtensionDisabledGlobalError::ExtensionDisabledGlobalError(
}
ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() {
+ ReleaseMenuCommandID(menu_command_id_);
HISTOGRAM_ENUMERATION("Extensions.DisabledUIUserResponse",
user_response_, EXTENSION_DISABLED_UI_BUCKET_BOUNDARY);
}
@@ -283,7 +284,6 @@ void ExtensionDisabledGlobalError::Observe(
if (extension == extension_) {
GlobalErrorServiceFactory::GetForProfile(service_->profile())->
RemoveGlobalError(this);
- ReleaseMenuCommandID(menu_command_id_);
if (type == chrome::NOTIFICATION_EXTENSION_LOADED)
user_response_ = REENABLE;
diff --git a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
index d908fa0..8d30040 100644
--- a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
+++ b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/file_path.h"
+#include "base/scoped_temp_dir.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/global_error.h"
#include "chrome/browser/ui/global_error_service.h"
#include "chrome/browser/ui/global_error_service_factory.h"
#include "chrome/common/extensions/extension.h"
@@ -14,7 +18,25 @@
class ExtensionDisabledGlobalErrorTest : public ExtensionBrowserTest {
protected:
void SetUpOnMainThread() {
+ EXPECT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
service_ = browser()->profile()->GetExtensionService();
+ FilePath pem_path = test_data_dir_.
+ AppendASCII("permissions_increase").AppendASCII("permissions.pem");
+ path_v1_ = PackExtensionWithOptions(
+ test_data_dir_.AppendASCII("permissions_increase").AppendASCII("v1"),
+ scoped_temp_dir_.path().AppendASCII("permissions1.crx"),
+ pem_path,
+ FilePath());
+ path_v2_ = PackExtensionWithOptions(
+ test_data_dir_.AppendASCII("permissions_increase").AppendASCII("v2"),
+ scoped_temp_dir_.path().AppendASCII("permissions2.crx"),
+ pem_path,
+ FilePath());
+ path_v3_ = PackExtensionWithOptions(
+ test_data_dir_.AppendASCII("permissions_increase").AppendASCII("v3"),
+ scoped_temp_dir_.path().AppendASCII("permissions3.crx"),
+ pem_path,
+ FilePath());
}
// Returns the ExtensionDisabledGlobalError, if present.
@@ -24,33 +46,46 @@ class ExtensionDisabledGlobalErrorTest : public ExtensionBrowserTest {
GetGlobalErrorByMenuItemCommandID(IDC_EXTENSION_DISABLED_FIRST);
}
- // Helper function to install an extension and upgrade it to a version
- // requiring additional permissions. Returns the new disabled Extension.
- const Extension* InstallAndUpdateIncreasingPermissionsExtension() {
+ // Install the initial version, which should happen just fine.
+ const Extension* InstallIncreasingPermissionExtensionV1() {
size_t size_before = service_->extensions()->size();
-
- // Install the initial version, which should happen just fine.
- const Extension* extension = InstallExtension(
- test_data_dir_.AppendASCII("permissions-low-v1.crx"), 1);
+ const Extension* extension = InstallExtension(path_v1_, 1);
if (!extension)
return NULL;
if (service_->extensions()->size() != size_before + 1)
return NULL;
+ return extension;
+ }
- // Upgrade to a version that wants more permissions. We should disable the
- // extension and prompt the user to reenable.
- if (UpdateExtension(
- extension->id(),
- test_data_dir_.AppendASCII("permissions-high-v2.crx"), -1))
+ // Upgrade to a version that wants more permissions. We should disable the
+ // extension and prompt the user to reenable.
+ const Extension* UpdateIncreasingPermissionExtension(
+ const Extension* extension,
+ const FilePath& crx_path,
+ int expected_change) {
+ size_t size_before = service_->extensions()->size();
+ if (UpdateExtension(extension->id(), crx_path, expected_change))
return NULL;
- EXPECT_EQ(size_before, service_->extensions()->size());
+ EXPECT_EQ(size_before + expected_change, service_->extensions()->size());
if (service_->disabled_extensions()->size() != 1u)
return NULL;
return *service_->disabled_extensions()->begin();
}
+ // Helper function to install an extension and upgrade it to a version
+ // requiring additional permissions. Returns the new disabled Extension.
+ const Extension* InstallAndUpdateIncreasingPermissionsExtension() {
+ const Extension* extension = InstallIncreasingPermissionExtensionV1();
+ extension = UpdateIncreasingPermissionExtension(extension, path_v2_, -1);
+ return extension;
+ }
+
ExtensionService* service_;
+ ScopedTempDir scoped_temp_dir_;
+ FilePath path_v1_;
+ FilePath path_v2_;
+ FilePath path_v3_;
};
// Tests the process of updating an extension to one that requires higher
@@ -79,3 +114,48 @@ IN_PROC_BROWSER_TEST_F(ExtensionDisabledGlobalErrorTest, Uninstall) {
EXPECT_EQ(0u, service_->disabled_extensions()->size());
ASSERT_FALSE(GetExtensionDisabledGlobalError());
}
+
+// Tests that no error appears if the user disabled the extension.
+IN_PROC_BROWSER_TEST_F(ExtensionDisabledGlobalErrorTest, UserDisabled) {
+ const Extension* extension = InstallIncreasingPermissionExtensionV1();
+ DisableExtension(extension->id());
+ extension = UpdateIncreasingPermissionExtension(extension, path_v2_, 0);
+ ASSERT_FALSE(GetExtensionDisabledGlobalError());
+}
+
+// Test that no error appears if the disable reason is unknown
+// (but probably was by the user).
+IN_PROC_BROWSER_TEST_F(ExtensionDisabledGlobalErrorTest,
+ UnknownReasonSamePermissions) {
+ const Extension* extension = InstallIncreasingPermissionExtensionV1();
+ DisableExtension(extension->id());
+ // Clear disable reason to simulate legacy disables.
+ service_->extension_prefs()->RemoveDisableReason(extension->id());
+ // Upgrade to version 2. Infer from version 1 having the same permissions
+ // granted by the user that it was disabled by the user.
+ extension = UpdateIncreasingPermissionExtension(extension, path_v2_, 0);
+ ASSERT_TRUE(extension);
+ ASSERT_FALSE(GetExtensionDisabledGlobalError());
+}
+
+// Test that an error appears if the disable reason is unknown
+// (but probably was for increased permissions).
+IN_PROC_BROWSER_TEST_F(ExtensionDisabledGlobalErrorTest,
+ UnknownReasonHigherPermissions) {
+ const Extension* extension = InstallAndUpdateIncreasingPermissionsExtension();
+ // Clear disable reason to simulate legacy disables.
+ service_->extension_prefs()->RemoveDisableReason(extension->id());
+ // We now have version 2 but only accepted permissions for version 1.
+ GlobalError* error = GetExtensionDisabledGlobalError();
+ ASSERT_TRUE(error);
+ // Also, remove the upgrade error for version 2.
+ GlobalErrorServiceFactory::GetForProfile(browser()->profile())->
+ RemoveGlobalError(error);
+ delete error;
+ // Upgrade to version 3, with even higher permissions. Infer from
+ // version 2 having higher-than-granted permissions that it was disabled
+ // for permissions increase.
+ extension = UpdateIncreasingPermissionExtension(extension, path_v3_, 0);
+ ASSERT_TRUE(extension);
+ ASSERT_TRUE(GetExtensionDisabledGlobalError());
+}
diff --git a/chrome/browser/extensions/extension_management_api.cc b/chrome/browser/extensions/extension_management_api.cc
index 2a96542..0d635ed 100644
--- a/chrome/browser/extensions/extension_management_api.cc
+++ b/chrome/browser/extensions/extension_management_api.cc
@@ -382,7 +382,7 @@ bool SetEnabledFunction::RunImpl() {
}
service()->EnableExtension(extension_id_);
} else if (currently_enabled && !enable) {
- service()->DisableExtension(extension_id_);
+ service()->DisableExtension(extension_id_, Extension::DISABLE_USER_ACTION);
}
BrowserThread::PostTask(
diff --git a/chrome/browser/extensions/extension_management_apitest.cc b/chrome/browser/extensions/extension_management_apitest.cc
index 812bc53..1bcda9e 100644
--- a/chrome/browser/extensions/extension_management_apitest.cc
+++ b/chrome/browser/extensions/extension_management_apitest.cc
@@ -46,11 +46,10 @@ class ExtensionManagementApiTest : public ExtensionApiTest {
ASSERT_TRUE(LoadExtension(basedir.AppendASCII("permissions")));
// Load 2 disabled items.
- ExtensionService* service = browser()->profile()->GetExtensionService();
ASSERT_TRUE(LoadExtension(basedir.AppendASCII("disabled_extension")));
- service->DisableExtension(last_loaded_extension_id_);
+ DisableExtension(last_loaded_extension_id_);
ASSERT_TRUE(LoadExtension(basedir.AppendASCII("disabled_app")));
- service->DisableExtension(last_loaded_extension_id_);
+ DisableExtension(last_loaded_extension_id_);
}
// Load an app, and wait for a message from app "management/launch_on_install"
diff --git a/chrome/browser/extensions/extension_management_browsertest.cc b/chrome/browser/extensions/extension_management_browsertest.cc
index ec789af..49ec02f 100644
--- a/chrome/browser/extensions/extension_management_browsertest.cc
+++ b/chrome/browser/extensions/extension_management_browsertest.cc
@@ -139,13 +139,13 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) {
EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id));
// After disabling, the background page should go away.
- service->DisableExtension(extension_id);
+ DisableExtension(extension_id);
EXPECT_EQ(size_before, service->extensions()->size());
EXPECT_EQ(1u, service->disabled_extensions()->size());
EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension_id));
// And bring it back.
- service->EnableExtension(extension_id);
+ EnableExtension(extension_id);
EXPECT_EQ(size_before + 1, service->extensions()->size());
EXPECT_EQ(0u, service->disabled_extensions()->size());
EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id));
@@ -322,7 +322,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,
InstallExtension(basedir.AppendASCII("v1.crx"), 1);
ASSERT_TRUE(extension);
listener1.WaitUntilSatisfied();
- service->DisableExtension(extension->id());
+ DisableExtension(extension->id());
ASSERT_EQ(disabled_size_before + 1, service->disabled_extensions()->size());
ASSERT_EQ(enabled_size_before, service->extensions()->size());
ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id());
@@ -348,7 +348,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,
// The extension should have not made the callback because it is disabled.
// When we enabled it, it should then make the callback.
ASSERT_FALSE(listener2.was_satisfied());
- service->EnableExtension(extension->id());
+ EnableExtension(extension->id());
listener2.WaitUntilSatisfied();
ASSERT_TRUE(notification_listener.started());
ASSERT_TRUE(notification_listener.finished());
@@ -484,7 +484,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) {
EXPECT_EQ(Extension::EXTERNAL_POLICY_DOWNLOAD, extension->location());
// Try to disable and uninstall the extension which should fail.
- service->DisableExtension(kExtensionId);
+ DisableExtension(kExtensionId);
EXPECT_EQ(size_before + 1, service->extensions()->size());
EXPECT_EQ(0u, service->disabled_extensions()->size());
UninstallExtension(kExtensionId);
@@ -576,7 +576,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, PolicyOverridesUserInstall) {
EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
EXPECT_TRUE(service->disabled_extensions()->is_empty());
- service->DisableExtension(kExtensionId);
+ DisableExtension(kExtensionId);
EXPECT_EQ(1u, service->disabled_extensions()->size());
extension = service->GetExtensionById(kExtensionId, true);
EXPECT_TRUE(extension);
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index 2c5dc80..91c1a6d 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -57,6 +57,9 @@ const char kPrefOrphanAcknowledged[] = "ack_orphan";
// Indicates whether to show an install warning when the user enables.
const char kExtensionDidEscalatePermissions[] = "install_warning_on_enable";
+// Indicates whether the extension was updated while it was disabled.
+const char kPrefDisableReason[] = "disable_reason";
+
// A preference that tracks browser action toolbar configuration. This is a list
// object stored in the Preferences file. The extensions are stored by ID.
const char kExtensionToolbar[] = "extensions.toolbar";
@@ -673,6 +676,27 @@ void ExtensionPrefs::SetDidExtensionEscalatePermissions(
Value::CreateBooleanValue(did_escalate));
}
+Extension::DisableReason ExtensionPrefs::GetDisableReason(
+ const std::string& extension_id) {
+ int value = -1;
+ if (ReadExtensionPrefInteger(extension_id, kPrefDisableReason, &value) &&
+ value >= 0 && value < Extension::DISABLE_LAST) {
+ return static_cast<Extension::DisableReason>(value);
+ }
+ return Extension::DISABLE_UNKNOWN;
+}
+
+void ExtensionPrefs::SetDisableReason(const std::string& extension_id,
+ Extension::DisableReason disable_reason) {
+ UpdateExtensionPref(
+ extension_id, kPrefDisableReason,
+ Value::CreateIntegerValue(static_cast<int>(disable_reason)));
+}
+
+void ExtensionPrefs::RemoveDisableReason(const std::string& extension_id) {
+ UpdateExtensionPref(extension_id, kPrefDisableReason, NULL);
+}
+
void ExtensionPrefs::UpdateBlacklist(
const std::set<std::string>& blacklist_set) {
std::vector<std::string> remove_pref_ids;
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index 39c0360..d7ead34 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -139,6 +139,12 @@ class ExtensionPrefs : public ExtensionContentSettingsStore::Observer,
void SetDidExtensionEscalatePermissions(const Extension* extension,
bool did_escalate);
+ // Getter and setters for disabled reason.
+ Extension::DisableReason GetDisableReason(const std::string& extension_id);
+ void SetDisableReason(const std::string& extension_id,
+ Extension::DisableReason disable_reason);
+ void RemoveDisableReason(const std::string& extension_id);
+
// Returns the version string for the currently installed extension, or
// the empty string if not found.
std::string GetVersionString(const std::string& extension_id);
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index a57a247..27bc442 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -720,7 +720,7 @@ void ExtensionService::ReloadExtension(const std::string& extension_id) {
}
path = current_extension->path();
- DisableExtension(extension_id);
+ DisableExtension(extension_id, Extension::DISABLE_RELOAD);
disabled_extension_paths_[extension_id] = path;
} else {
path = unloaded_extension_paths_[extension_id];
@@ -898,6 +898,7 @@ void ExtensionService::EnableExtension(const std::string& extension_id) {
return;
extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED);
+ extension_prefs_->RemoveDisableReason(extension_id);
const Extension* extension =
GetExtensionByIdInternal(extension_id, false, true, false);
@@ -918,7 +919,9 @@ void ExtensionService::EnableExtension(const std::string& extension_id) {
SyncExtensionChangeIfNeeded(*extension);
}
-void ExtensionService::DisableExtension(const std::string& extension_id) {
+void ExtensionService::DisableExtension(
+ const std::string& extension_id,
+ Extension::DisableReason disable_reason) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// The extension may have been disabled already.
@@ -932,6 +935,7 @@ void ExtensionService::DisableExtension(const std::string& extension_id) {
return;
extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED);
+ extension_prefs_->SetDisableReason(extension_id, disable_reason);
extension = GetExtensionByIdInternal(extension_id, true, false, true);
if (!extension)
@@ -1507,7 +1511,7 @@ void ExtensionService::ProcessExtensionSyncData(
if (extension_sync_data.enabled()) {
EnableExtension(id);
} else {
- DisableExtension(id);
+ DisableExtension(id, Extension::DISABLE_USER_ACTION);
}
// We need to cache some version information here because setting the
@@ -2035,12 +2039,13 @@ bool ExtensionService::AddExtension(const Extension* extension) {
if (disabled) {
disabled_extensions_.Insert(scoped_extension);
SyncExtensionChangeIfNeeded(*extension);
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
+ content::Source<Profile>(profile_),
+ content::Details<const Extension>(extension));
- if (extension_prefs_->DidExtensionEscalatePermissions(extension->id())) {
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
- content::Source<Profile>(profile_),
- content::Details<const Extension>(extension));
+ if (extension_prefs_->GetDisableReason(extension->id()) ==
+ Extension::DISABLE_PERMISSIONS_INCREASE) {
extensions::AddExtensionDisabledError(this, extension);
}
// Although the extension is disabled, we technically did succeed in adding
@@ -2115,6 +2120,9 @@ void ExtensionService::InitializePermissions(const Extension* extension) {
true, true, false);
bool is_extension_upgrade = old != NULL;
bool is_privilege_increase = false;
+ bool previously_disabled = false;
+ Extension::DisableReason disable_reason =
+ extension_prefs_->GetDisableReason(extension->id());
// We only need to compare the granted permissions to the current permissions
// if the extension is not allowed to silently increase its permissions.
@@ -2147,6 +2155,24 @@ void ExtensionService::InitializePermissions(const Extension* extension) {
SetBeingUpgraded(extension, true);
}
+ // If the extension was already disabled, suppress any alerts for becoming
+ // disabled on permissions increase.
+ previously_disabled = extension_prefs_->IsExtensionDisabled(old->id());
+ if (previously_disabled) {
+ Extension::DisableReason reason = extension_prefs_->GetDisableReason(
+ old->id());
+ if (reason == Extension::DISABLE_UNKNOWN) {
+ // Initialize the reason for legacy disabled extensions from whether the
+ // extension already exceeded granted permissions.
+ if (extension_prefs_->DidExtensionEscalatePermissions(old->id()))
+ disable_reason = Extension::DISABLE_PERMISSIONS_INCREASE;
+ else
+ disable_reason = Extension::DISABLE_USER_ACTION;
+ }
+ } else {
+ disable_reason = Extension::DISABLE_PERMISSIONS_INCREASE;
+ }
+
// To upgrade an extension in place, unload the old one and
// then load the new one.
UnloadExtension(old->id(), extension_misc::UNLOAD_REASON_UPDATE);
@@ -2162,6 +2188,7 @@ void ExtensionService::InitializePermissions(const Extension* extension) {
}
extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED);
extension_prefs_->SetDidExtensionEscalatePermissions(extension, true);
+ extension_prefs_->SetDisableReason(extension->id(), disable_reason);
}
}
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 90a91cee..14e7412 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -342,7 +342,8 @@ class ExtensionService
// Disables the extension. If the extension is already disabled, or
// cannot be disabled, does nothing.
- virtual void DisableExtension(const std::string& extension_id);
+ virtual void DisableExtension(const std::string& extension_id,
+ Extension::DisableReason disable_reason);
// Updates the |extension|'s granted permissions lists to include all
// permissions in the |extension|'s manifest and re-enables the
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 3546a47..55e4867 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -2253,7 +2253,7 @@ TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
// Disable it and allow it to run in incognito. These settings should carry
// over to the updated version.
- service_->DisableExtension(good->id());
+ service_->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
service_->SetIsIncognitoEnabled(good->id(), true);
service_->extension_prefs()->SetDidExtensionEscalatePermissions(good, true);
@@ -2932,7 +2932,7 @@ TEST_F(ExtensionServiceTest, DisableExtension) {
EXPECT_TRUE(service_->disabled_extensions()->is_empty());
// Disable it.
- service_->DisableExtension(good_crx);
+ service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
EXPECT_TRUE(service_->extensions()->is_empty());
EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
@@ -2948,7 +2948,7 @@ TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
EXPECT_TRUE(service_->GetTerminatedExtension(good_crx));
// Disable it.
- service_->DisableExtension(good_crx);
+ service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
EXPECT_FALSE(service_->GetTerminatedExtension(good_crx));
EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
@@ -2997,7 +2997,7 @@ TEST_F(ExtensionServiceTest, ReloadExtensions) {
FilePath path = data_dir_.AppendASCII("good.crx");
InstallCRX(path, INSTALL_NEW);
const char* extension_id = good_crx;
- service_->DisableExtension(extension_id);
+ service_->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
EXPECT_EQ(0u, service_->extensions()->size());
EXPECT_EQ(1u, service_->disabled_extensions()->size());
@@ -4073,7 +4073,7 @@ TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
EXPECT_FALSE(data.incognito_enabled());
}
- service_->DisableExtension(good_crx);
+ service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
{
SyncDataList list = service_->GetAllSyncData(syncable::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
@@ -4194,7 +4194,7 @@ TEST_F(ExtensionServiceTest, GetSyncDataList) {
service_->MergeDataAndStartSyncing(syncable::EXTENSIONS, SyncDataList(),
scoped_ptr<SyncChangeProcessor>(new TestSyncProcessorStub));
- service_->DisableExtension(page_action);
+ service_->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
TerminateExtension(theme2_crx);
EXPECT_EQ(0u, service_->GetAllSyncData(syncable::APPS).size());
diff --git a/chrome/browser/notifications/notification_options_menu_model.cc b/chrome/browser/notifications/notification_options_menu_model.cc
index fc96287..4a39595 100644
--- a/chrome/browser/notifications/notification_options_menu_model.cc
+++ b/chrome/browser/notifications/notification_options_menu_model.cc
@@ -239,7 +239,8 @@ void NotificationOptionsMenuModel::ExecuteCommand(int command_id) {
if (extension) {
const std::string& id = extension->id();
if (extension_service->IsExtensionEnabled(id))
- extension_service->DisableExtension(id);
+ extension_service->DisableExtension(
+ id, Extension::DISABLE_USER_ACTION);
else
extension_service->EnableExtension(id);
}
diff --git a/chrome/browser/sync/test/integration/sync_extension_helper.cc b/chrome/browser/sync/test/integration/sync_extension_helper.cc
index f1d8b77..41db664 100644
--- a/chrome/browser/sync/test/integration/sync_extension_helper.cc
+++ b/chrome/browser/sync/test/integration/sync_extension_helper.cc
@@ -101,7 +101,8 @@ void SyncExtensionHelper::EnableExtension(Profile* profile,
void SyncExtensionHelper::DisableExtension(Profile* profile,
const std::string& name) {
- profile->GetExtensionService()->DisableExtension(NameToId(name));
+ profile->GetExtensionService()->DisableExtension(
+ NameToId(name), Extension::DISABLE_USER_ACTION);
}
bool SyncExtensionHelper::IsExtensionEnabled(
diff --git a/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm b/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm
index 91228f0..26c6474 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_action_context_menu.mm
@@ -262,7 +262,8 @@ int CurrentTabId() {
ExtensionService* extensionService = profile_->GetExtensionService();
if (!extensionService)
return; // Incognito mode.
- extensionService->DisableExtension(extension_->id());
+ extensionService->DisableExtension(extension_->id(),
+ Extension::DISABLE_USER_ACTION);
break;
}
case kExtensionContextUninstall: {
diff --git a/chrome/browser/ui/panels/panel_settings_menu_model.cc b/chrome/browser/ui/panels/panel_settings_menu_model.cc
index df8f1d5..93498cb 100644
--- a/chrome/browser/ui/panels/panel_settings_menu_model.cc
+++ b/chrome/browser/ui/panels/panel_settings_menu_model.cc
@@ -92,7 +92,7 @@ void PanelSettingsMenuModel::ExecuteCommand(int command_id) {
break;
case COMMAND_DISABLE:
browser->GetProfile()->GetExtensionService()->DisableExtension(
- extension->id());
+ extension->id(), Extension::DISABLE_USER_ACTION);
break;
case COMMAND_UNINSTALL:
// When the owning panel is being closed by the extension API, the
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
index 1c73ef9..8f8dc11 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
@@ -583,7 +583,8 @@ void ExtensionSettingsHandler::HandleEnableMessage(const ListValue* args) {
extension_service_->EnableExtension(extension_id);
}
} else {
- extension_service_->DisableExtension(extension_id);
+ extension_service_->DisableExtension(
+ extension_id, Extension::DISABLE_USER_ACTION);
}
}