Implement sideload wipeout for Extensions.

BUG=154624
TEST=None
Review URL: https://codereview.chromium.org/11189094

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163350 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 00f0234..38e5a80 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -139,6 +139,7 @@
 using extensions::Extension;
 using extensions::ExtensionIdSet;
 using extensions::ExtensionInfo;
+using extensions::FeatureSwitch;
 using extensions::UnloadedExtensionInfo;
 using extensions::PermissionMessage;
 using extensions::PermissionMessages;
@@ -442,6 +443,17 @@
   return installed_extensions;
 }
 
+const ExtensionSet* ExtensionService::GetWipedOutExtensions() const {
+  ExtensionSet* extension_set = new ExtensionSet();
+  for (ExtensionSet::const_iterator iter = disabled_extensions_.begin();
+       iter != disabled_extensions_.end(); ++iter) {
+    int disabled_reason = extension_prefs_->GetDisableReasons((*iter)->id());
+    if ((disabled_reason & Extension::DISABLE_SIDELOAD_WIPEOUT) != 0)
+      extension_set->Insert(*iter);
+  }
+  return extension_set;
+}
+
 extensions::PendingExtensionManager*
     ExtensionService::pending_extension_manager() {
   return &pending_extension_manager_;
@@ -562,6 +574,11 @@
   component_loader_->LoadAll();
   extensions::InstalledLoader(this).LoadAllExtensions();
 
+  // The Sideload Wipeout effort takes place during load (see above), so once
+  // that is done the flag can be set so that we don't have to check again.
+  if (FeatureSwitch::sideload_wipeout()->IsEnabled())
+    extension_prefs_->SetSideloadWipeoutDone();
+
   // If we are running in the import process, don't bother initializing the
   // extension service since this can interfere with the main browser process
   // that is already running an extension service for this profile.
@@ -1997,6 +2014,10 @@
   // extension if necessary.
   InitializePermissions(extension);
 
+  // If this extension is a sideloaded extension and we've not performed a
+  // wipeout before, we might disable this extension here.
+  MaybeWipeout(extension);
+
   if (extension_prefs_->IsExtensionDisabled(extension->id())) {
     disabled_extensions_.Insert(scoped_extension);
     SyncExtensionChangeIfNeeded(*extension);
@@ -2161,6 +2182,29 @@
   }
 }
 
+void ExtensionService::MaybeWipeout(
+    const extensions::Extension* extension) {
+  if (!FeatureSwitch::sideload_wipeout()->IsEnabled())
+    return;
+
+  bool done = extension_prefs_->GetSideloadWipeoutDone();
+  if (done)
+    return;
+
+  int disable_reasons = extension_prefs_->GetDisableReasons(extension->id());
+  if (disable_reasons == Extension::DISABLE_NONE) {
+    Extension::Location location = extension->location();
+    if (location == Extension::EXTERNAL_REGISTRY ||
+        (location == Extension::INTERNAL && !extension->from_webstore())) {
+      extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED);
+      extension_prefs_->AddDisableReason(
+          extension->id(),
+          static_cast<Extension::DisableReason>(
+          Extension::DISABLE_SIDELOAD_WIPEOUT));
+    }
+  }
+}
+
 void ExtensionService::UpdateActiveExtensionsInCrashReporter() {
   std::set<std::string> extension_ids;
   for (ExtensionSet::const_iterator iter = extensions_.begin();