Asynchronously create the ppapi broker.

BUG=none
TEST=none

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81525 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/plugin_service.cc b/content/browser/plugin_service.cc
index 409bd67e..1a12a36 100644
--- a/content/browser/plugin_service.cc
+++ b/content/browser/plugin_service.cc
@@ -223,6 +223,22 @@
   return NULL;
 }
 
+PpapiBrokerProcessHost* PluginService::FindPpapiBrokerProcess(
+    const FilePath& broker_path) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  for (BrowserChildProcessHost::Iterator iter(
+           ChildProcessInfo::PPAPI_BROKER_PROCESS);
+       !iter.Done(); ++iter) {
+    PpapiBrokerProcessHost* broker =
+        static_cast<PpapiBrokerProcessHost*>(*iter);
+    if (broker->broker_path() == broker_path)
+      return broker;
+  }
+
+  return NULL;
+}
+
 PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess(
     const FilePath& plugin_path) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -254,15 +270,8 @@
   if (plugin_host)
     return plugin_host;
 
-  // Validate that the plugin is actually registered. There should generally
-  // be very few plugins so a brute-force search is fine.
-  PepperPluginInfo* info = NULL;
-  for (size_t i = 0; i < ppapi_plugins_.size(); i++) {
-    if (ppapi_plugins_[i].path == plugin_path) {
-      info = &ppapi_plugins_[i];
-      break;
-    }
-  }
+  // Validate that the plugin is actually registered.
+  PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
   if (!info)
     return NULL;
 
@@ -275,6 +284,32 @@
   return new_host.release();
 }
 
+PpapiBrokerProcessHost* PluginService::FindOrStartPpapiBrokerProcess(
+    const FilePath& plugin_path) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  PpapiBrokerProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path);
+  if (plugin_host)
+    return plugin_host;
+
+  // Validate that the plugin is actually registered.
+  PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path);
+  if (!info)
+    return NULL;
+
+  // TODO(ddorwin): Uncomment once out of process is supported.
+  // DCHECK(info->is_out_of_process);
+
+  // This broker isn't loaded by any broker process, so create a new process.
+  scoped_ptr<PpapiBrokerProcessHost> new_host(
+      new PpapiBrokerProcessHost);
+  if (!new_host->Init(*info)) {
+    NOTREACHED();  // Init is not expected to fail.
+    return NULL;
+  }
+  return new_host.release();
+}
+
 void PluginService::OpenChannelToNpapiPlugin(
     int render_process_id,
     int render_view_id,
@@ -300,6 +335,16 @@
     client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
 }
 
+void PluginService::OpenChannelToPpapiBroker(
+    const FilePath& path,
+    PpapiBrokerProcessHost::Client* client) {
+  PpapiBrokerProcessHost* plugin_host = FindOrStartPpapiBrokerProcess(path);
+  if (plugin_host)
+    plugin_host->OpenChannelToPpapiBroker(client);
+  else  // Send error.
+    client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
+}
+
 void PluginService::GetAllowedPluginForOpenChannelToPlugin(
     int render_process_id,
     int render_view_id,
@@ -503,6 +548,19 @@
   }
 }
 
+// There should generally be very few plugins so a brute-force search is fine.
+PepperPluginInfo* PluginService::GetRegisteredPpapiPluginInfo(
+    const FilePath& plugin_path) {
+  PepperPluginInfo* info = NULL;
+  for (size_t i = 0; i < ppapi_plugins_.size(); i++) {
+   if (ppapi_plugins_[i].path == plugin_path) {
+     info = &ppapi_plugins_[i];
+     break;
+   }
+  }
+  return info;
+}
+
 #if defined(OS_LINUX)
 // static
 void PluginService::RegisterFilePathWatcher(