Add a launchApp method to extension management API.

This makes it possible for new tab replacement extensions to recreate the same
app launch experience as the built-in NTP (pinned tabs, launch containers,
etc.)

Also add the extension version to data we report about extensions via
the management API.

BUG=56325,55474
TEST=An extension using chrome.experimental.management.launchApp(<id>) should
work to launch an app the same way that app gets launched from the built-in
new tab page.



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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60334 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 6751671..c1867ca 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -273,13 +273,14 @@
 
   // Management.
   RegisterFunction<GetAllExtensionsFunction>();
+  RegisterFunction<LaunchAppFunction>();
   RegisterFunction<SetEnabledFunction>();
-  RegisterFunction<InstallFunction>();
   RegisterFunction<UninstallFunction>();
 
   // WebstorePrivate.
   RegisterFunction<GetSyncLoginFunction>();
   RegisterFunction<GetStoreLoginFunction>();
+  RegisterFunction<InstallFunction>();
   RegisterFunction<SetStoreLoginFunction>();
 }
 
diff --git a/chrome/browser/extensions/extension_management_api.cc b/chrome/browser/extensions/extension_management_api.cc
index 95447a6..43f13f0 100644
--- a/chrome/browser/extensions/extension_management_api.cc
+++ b/chrome/browser/extensions/extension_management_api.cc
@@ -38,9 +38,10 @@
 const char kOptionsUrlKey[] = "optionsUrl";
 const char kSizeKey[] = "size";
 const char kUrlKey[] = "url";
+const char kVersionKey[] = "version";
 
 const char kNoExtensionError[] = "No extension with id *";
-
+const char kNotAnAppError[] = "Extension * is not an App";
 }
 
 ExtensionsService* ExtensionManagementFunction::service() {
@@ -54,6 +55,7 @@
   info->SetBoolean(kIsAppKey, extension.is_app());
   info->SetString(kNameKey, extension.name());
   info->SetBoolean(kEnabledKey, enabled);
+  info->SetString(kVersionKey, extension.VersionString());
   if (!extension.options_url().is_empty())
     info->SetString(kOptionsUrlKey,
                     extension.options_url().possibly_invalid_spec());
@@ -102,6 +104,27 @@
   return true;
 }
 
+bool LaunchAppFunction::RunImpl() {
+  std::string extension_id;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id));
+  Extension* extension = service()->GetExtensionById(extension_id, true);
+  if (!extension) {
+    error_ = ExtensionErrorUtils::FormatErrorMessage(kNoExtensionError,
+                                                     extension_id);
+    return false;
+  }
+  if (!extension->is_app()) {
+    error_ = ExtensionErrorUtils::FormatErrorMessage(kNotAnAppError,
+                                                     extension_id);
+    return false;
+  }
+
+  extension_misc::LaunchContainer container = extension->launch_container();
+  Browser::OpenApplication(profile(), extension, container);
+
+  return true;
+}
+
 bool SetEnabledFunction::RunImpl() {
   std::string extension_id;
   bool enable;
diff --git a/chrome/browser/extensions/extension_management_api.h b/chrome/browser/extensions/extension_management_api.h
index 841baea..4109886 100644
--- a/chrome/browser/extensions/extension_management_api.h
+++ b/chrome/browser/extensions/extension_management_api.h
@@ -24,6 +24,12 @@
   DECLARE_EXTENSION_FUNCTION_NAME("experimental.management.getAll");
 };
 
+class LaunchAppFunction : public ExtensionManagementFunction {
+  ~LaunchAppFunction() {}
+  virtual bool RunImpl();
+  DECLARE_EXTENSION_FUNCTION_NAME("experimental.management.launchApp");
+};
+
 class SetEnabledFunction : public ExtensionManagementFunction {
   ~SetEnabledFunction() {}
   virtual bool RunImpl();
diff --git a/chrome/browser/extensions/extension_management_api_browsertest.cc b/chrome/browser/extensions/extension_management_api_browsertest.cc
index 63fdfcf..643072d1 100644
--- a/chrome/browser/extensions/extension_management_api_browsertest.cc
+++ b/chrome/browser/extensions/extension_management_api_browsertest.cc
@@ -28,3 +28,16 @@
       test_data_dir_.AppendASCII("api_test/management/enabled_extension")));
   ASSERT_TRUE(listener2.WaitUntilSatisfied());
 }
+
+IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, LaunchApp) {
+  ExtensionTestMessageListener listener1("app_launched");
+  ExtensionTestMessageListener listener2("got_expected_error");
+  ASSERT_TRUE(LoadExtension(
+      test_data_dir_.AppendASCII("management/simple_extension")));
+  ASSERT_TRUE(LoadExtension(
+      test_data_dir_.AppendASCII("management/packaged_app")));
+  ASSERT_TRUE(LoadExtension(
+      test_data_dir_.AppendASCII("management/launch_app")));
+  ASSERT_TRUE(listener1.WaitUntilSatisfied());
+  ASSERT_TRUE(listener2.WaitUntilSatisfied());
+}