New notification sent when extension uninstall is not allowed.
In the event that an extension uninstall is skipped (not allowed)
because that extension is not user-manageable, a new notification is
sent. The automation hook UninstallExtensionById is revised to handle
this case, and a new PyAuto test is written to exercise this new
functionality (the test attempts to uninstall the WebStore and verifies that
this extension cannot be uninstalled).
BUG=76598
TEST=None.
Review URL: http://codereview.chromium.org/6794040
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80814 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 361e165..9887b4c 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -258,7 +258,7 @@
}
// This is an external extension that we don't have registered. Uninstall.
- UninstallExtension(id, true);
+ UninstallExtension(id, true, NULL);
}
void ExtensionService::ClearProvidersForTesting() {
@@ -362,6 +362,9 @@
}
// static
+// This function is used to implement the command-line switch
+// --uninstall-extension. The LOG statements within this function are used to
+// inform the user if the uninstall cannot be done.
bool ExtensionService::UninstallExtensionHelper(
ExtensionService* extensions_service,
const std::string& extension_id) {
@@ -371,19 +374,21 @@
if (!extension)
extension = extensions_service->GetTerminatedExtension(extension_id);
- // We can't call UninstallExtension with an invalid extension ID. We should
- // not allow an uninstall of a policy-controlled extension.
+ // We can't call UninstallExtension with an invalid extension ID.
if (!extension) {
LOG(WARNING) << "Attempted uninstallation of non-existent extension with "
<< "id: " << extension_id;
return false;
- } else if (!Extension::UserMayDisable(extension->location())) {
- LOG(WARNING) << "Attempted uninstallation of an extension that is non-"
- << "usermanagable with id: " << extension_id;
- return false;
}
- extensions_service->UninstallExtension(extension_id, false);
+ // The following call to UninstallExtension will not allow an uninstall of a
+ // policy-controlled extension.
+ std::string error;
+ if (!extensions_service->UninstallExtension(extension_id, false, &error)) {
+ LOG(WARNING) << "Cannot uninstall extension with id " << extension_id
+ << ": " << error;
+ return false;
+ }
return true;
}
@@ -607,8 +612,9 @@
}
}
-void ExtensionService::UninstallExtension(const std::string& extension_id,
- bool external_uninstall) {
+bool ExtensionService::UninstallExtension(const std::string& extension_id,
+ bool external_uninstall,
+ std::string* error) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const Extension* extension =
@@ -627,8 +633,16 @@
// Policy change which triggers an uninstall will always set
// |external_uninstall| to true so this is the only way to uninstall
// managed extensions.
- if (!Extension::UserMayDisable(location) && !external_uninstall)
- return;
+ if (!Extension::UserMayDisable(location) && !external_uninstall) {
+ NotificationService::current()->Notify(
+ NotificationType::EXTENSION_UNINSTALL_NOT_ALLOWED,
+ Source<Profile>(profile_),
+ Details<const Extension>(extension));
+ if (error != NULL) {
+ *error = errors::kCannotUninstallManagedExtension;
+ }
+ return false;
+ }
UninstalledExtensionInfo uninstalled_extension_info(*extension);
@@ -667,6 +681,8 @@
NotificationType::EXTENSION_UNINSTALLED,
Source<Profile>(profile_),
Details<UninstalledExtensionInfo>(&uninstalled_extension_info));
+
+ return true;
}
void ExtensionService::ClearExtensionData(const GURL& extension_url) {