Extension loading improvements.
Add a method that allows loading a single specific extension.
Load extensions upon successful install.

Review is for which ever one of you gets in first, or both if you care. ;-)

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9082 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 3038cabb..60f9880 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -130,7 +130,12 @@
       NotificationService::AllSources(),
       Details<FilePath>(&path));
 
-  // TODO(erikkay): now what?
+  // Immediately try to load the extension.
+  g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
+      NewRunnableMethod(backend_.get(),
+          &ExtensionsServiceBackend::LoadSingleExtension,
+          path,
+          scoped_refptr<ExtensionsServiceFrontendInterface>(this)));
 }
 
 
@@ -160,43 +165,67 @@
       // from local directories that developers are just hacking in place.
       // TODO(erikkay): perhaps we should use a different code path for this.
     }
-    FilePath manifest_path =
-        child_path.AppendASCII(Extension::kManifestFilename);
-    if (!file_util::PathExists(manifest_path)) {
-      ReportExtensionLoadError(frontend.get(), child_path,
-                               Extension::kInvalidManifestError);
-      continue;
-    }
 
-    JSONFileValueSerializer serializer(manifest_path.ToWStringHack());
-    std::string error;
-    scoped_ptr<Value> root(serializer.Deserialize(&error));
-    if (!root.get()) {
-      ReportExtensionLoadError(frontend.get(), child_path,
-                               error);
-      continue;
-    }
-
-    if (!root->IsType(Value::TYPE_DICTIONARY)) {
-      ReportExtensionLoadError(frontend.get(), child_path,
-                               Extension::kInvalidManifestError);
-      continue;
-    }
-
-    scoped_ptr<Extension> extension(new Extension(child_path));
-    if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()),
-                                  &error)) {
-      ReportExtensionLoadError(frontend.get(), child_path, error);
-      continue;
-    }
-
-    extensions->push_back(extension.release());
+    Extension* extension = LoadExtension(child_path, frontend);
+    if (extension)
+      extensions->push_back(extension);
   }
 
   ReportExtensionsLoaded(frontend.get(), extensions.release());
   return true;
 }
 
+bool ExtensionsServiceBackend::LoadSingleExtension(
+    const FilePath& path_in,
+    scoped_refptr<ExtensionsServiceFrontendInterface> frontend) {
+  FilePath path = path_in;
+  if (!file_util::AbsolutePath(&path))
+    NOTREACHED();
+  Extension* extension = LoadExtension(path, frontend);
+  if (extension) {
+    ExtensionList* extensions = new ExtensionList;
+    extensions->push_back(extension);
+    ReportExtensionsLoaded(frontend.get(), extensions);
+    return true;
+  }
+  return false;
+}
+
+Extension* ExtensionsServiceBackend::LoadExtension(
+    const FilePath& path,
+    scoped_refptr<ExtensionsServiceFrontendInterface> frontend) {
+  FilePath manifest_path =
+      path.AppendASCII(Extension::kManifestFilename);
+  if (!file_util::PathExists(manifest_path)) {
+    ReportExtensionLoadError(frontend.get(), path,
+                             Extension::kInvalidManifestError);
+    return NULL;
+  }
+
+  JSONFileValueSerializer serializer(manifest_path.ToWStringHack());
+  std::string error;
+  scoped_ptr<Value> root(serializer.Deserialize(&error));
+  if (!root.get()) {
+    ReportExtensionLoadError(frontend.get(), path,
+                             error);
+    return NULL;
+  }
+
+  if (!root->IsType(Value::TYPE_DICTIONARY)) {
+    ReportExtensionLoadError(frontend.get(), path,
+                             Extension::kInvalidManifestError);
+    return NULL;
+  }
+
+  scoped_ptr<Extension> extension(new Extension(path));
+  if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()),
+                                &error)) {
+    ReportExtensionLoadError(frontend.get(), path, error);
+    return NULL;
+  }
+  return extension.release();
+}
+
 void ExtensionsServiceBackend::ReportExtensionLoadError(
     ExtensionsServiceFrontendInterface *frontend, const FilePath& path,
     const std::string &error) {