Fix to make 'Enable accessibility features.' option change take effect immediately

Add loading and unloading code to SystemOptionsHandler
Add unregister_component_extension to ExtensionService

BUG=chromium-os:11887
TEST=manually confirmed that enabling/disabling a11y features works immediately

Review URL: http://codereview.chromium.org/7129015

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89302 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index a835f6a..63fc24b 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -191,6 +191,11 @@
 
 }  // namespace
 
+bool ExtensionService::ComponentExtensionInfo::Equals(
+    const ComponentExtensionInfo& other) const {
+  return other.manifest == manifest && other.root_directory == root_directory;
+}
+
 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData()
     : background_page_ready(false),
       being_upgraded(false) {
@@ -575,6 +580,18 @@
   return &pending_extension_manager_;
 }
 
+void ExtensionService::UnregisterComponentExtension(
+    const ComponentExtensionInfo& info) {
+  RegisteredComponentExtensions new_component_extension_manifests;
+  for (RegisteredComponentExtensions::iterator it =
+           component_extension_manifests_.begin();
+       it != component_extension_manifests_.end(); ++it) {
+    if (!it->Equals(info))
+      new_component_extension_manifests.push_back(*it);
+  }
+  component_extension_manifests_.swap(new_component_extension_manifests);
+}
+
 ExtensionService::~ExtensionService() {
   // No need to unload extensions here because they are profile-scoped, and the
   // profile is in the process of being deleted.
@@ -967,6 +984,27 @@
   return extension;
 }
 
+void ExtensionService::UnloadComponentExtension(
+    const ComponentExtensionInfo& info) {
+  JSONStringValueSerializer serializer(info.manifest);
+  scoped_ptr<Value> manifest(serializer.Deserialize(NULL, NULL));
+  if (!manifest.get()) {
+    DLOG(ERROR) << "Failed to parse manifest for extension";
+    return;
+  }
+  std::string public_key;
+  std::string public_key_bytes;
+  std::string id;
+  if (!static_cast<DictionaryValue*>(manifest.get())->
+      GetString(extension_manifest_keys::kPublicKey, &public_key) ||
+      !Extension::ParsePEMKeyBytes(public_key, &public_key_bytes) ||
+      !Extension::GenerateId(public_key_bytes, &id)) {
+    DLOG(ERROR) << "Failed to get extension id";
+    return;
+  }
+  UnloadExtension(id, UnloadedExtensionInfo::DISABLE);
+}
+
 void ExtensionService::LoadAllExtensions() {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));