Reenable disabled component extensions with profile resetter.

Sice disabled extensions are synced and component extensions do not
have a UI for reenabling them, once disabled will stay disabled forever.

It happened that for some reason some component extensions were
disabled. The reason is unknown, but at least users will be able to
recover from this situation by using the profile resetter.

Note, that we allow to disable component extensions programatically,
which was used at least for the Hotword component extension.

TEST=Disable a component extension programatically, then reset the
     profile in chrome://settings.
BUG=680429

Review-Url: https://codereview.chromium.org/2647783003
Cr-Commit-Position: refs/heads/master@{#446575}
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index abaae912..2b7ba6f 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -259,6 +259,19 @@
   return bubble_count;
 }
 
+scoped_refptr<Extension> CreateExtension(const base::string16& name,
+                                         const base::FilePath& path,
+                                         Manifest::Location location) {
+  base::DictionaryValue manifest;
+  manifest.SetString(extensions::manifest_keys::kVersion, "1.0.0.0");
+  manifest.SetString(extensions::manifest_keys::kName, name);
+  std::string error;
+  scoped_refptr<Extension> extension =
+      Extension::Create(path, location, manifest, Extension::NO_FLAGS, &error);
+  EXPECT_TRUE(extension.get() != nullptr) << error;
+  return extension;
+}
+
 }  // namespace
 
 class MockExtensionProvider : public extensions::ExternalProviderInterface {
@@ -6409,6 +6422,36 @@
   EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
 }
 
+// As for components, only external component extensions can be disabled.
+TEST_F(ExtensionServiceTest, DisablingComponentExtensions) {
+  InitializeEmptyExtensionService();
+  service_->Init();
+
+  scoped_refptr<Extension> external_component_extension = CreateExtension(
+      base::ASCIIToUTF16("external_component_extension"),
+      base::FilePath(FILE_PATH_LITERAL("//external_component_extension")),
+      Manifest::EXTERNAL_COMPONENT);
+  service_->AddExtension(external_component_extension.get());
+  EXPECT_TRUE(registry()->enabled_extensions().Contains(
+      external_component_extension->id()));
+  service_->DisableExtension(external_component_extension->id(),
+                             extensions::Extension::DISABLE_USER_ACTION);
+  EXPECT_TRUE(registry()->disabled_extensions().Contains(
+      external_component_extension->id()));
+
+  scoped_refptr<Extension> component_extension = CreateExtension(
+      base::ASCIIToUTF16("component_extension"),
+      base::FilePath(FILE_PATH_LITERAL("//component_extension")),
+      Manifest::COMPONENT);
+  service_->AddExtension(component_extension.get());
+  EXPECT_TRUE(
+      registry()->enabled_extensions().Contains(component_extension->id()));
+  service_->DisableExtension(component_extension->id(),
+                             extensions::Extension::DISABLE_USER_ACTION);
+  EXPECT_FALSE(
+      registry()->disabled_extensions().Contains(component_extension->id()));
+}
+
 // Test that installing multiple external extensions works.
 // Flaky on windows; http://crbug.com/295757 .
 // Causes race conditions with an in-process utility thread, so disable under