Change the NaCl loader and broker processes to use the ServiceManager.

This is the first child process outside of content to be connected to
the ServiceManager so this CL adds a way for content embedders to
provide additional service manifests via ContentBrowserClient. This
would introduce an unnecessary string copy when obtaining service
manifest overlays, so this changes that API to take a StringPiece.

BUG=666605
[email protected]

Review-Url: https://codereview.chromium.org/2501913002
Cr-Commit-Position: refs/heads/master@{#440299}
diff --git a/content/BUILD.gn b/content/BUILD.gn
index 85f4a51..33c2d22 100644
--- a/content/BUILD.gn
+++ b/content/BUILD.gn
@@ -92,6 +92,7 @@
       "public/common/content_switches.cc",
       "public/common/content_switches.h",
       "public/common/mojo_channel_switches.cc",
+      "public/common/mojo_channel_switches.h",
     ]
     set_sources_assignment_filter(sources_assignment_filter)
 
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index d311660a..3bca51b7 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -297,6 +297,10 @@
   data_.handle = handle;
 }
 
+std::string BrowserChildProcessHostImpl::GetServiceRequestChannelToken() {
+  return child_connection_->service_token();
+}
+
 void BrowserChildProcessHostImpl::ForceShutdown() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   g_child_process_list.Get().remove(this);
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h
index 9ac631e..08521db 100644
--- a/content/browser/browser_child_process_host_impl.h
+++ b/content/browser/browser_child_process_host_impl.h
@@ -80,6 +80,7 @@
       override;
   void SetName(const base::string16& name) override;
   void SetHandle(base::ProcessHandle handle) override;
+  std::string GetServiceRequestChannelToken() override;
 
   // ChildProcessHostDelegate implementation:
   bool CanShutdown() override;
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc
index 7eab342..c6076ce6 100644
--- a/content/browser/service_manager/service_manager_context.cc
+++ b/content/browser/service_manager/service_manager_context.cc
@@ -114,10 +114,31 @@
   BuiltinManifestProvider() {}
   ~BuiltinManifestProvider() override {}
 
-  void AddManifestValue(const std::string& name,
-                        std::unique_ptr<base::Value> manifest_contents) {
+  void AddServiceManifest(base::StringPiece name, int resource_id) {
+    std::string contents =
+        GetContentClient()
+            ->GetDataResource(resource_id, ui::ScaleFactor::SCALE_FACTOR_NONE)
+            .as_string();
+    DCHECK(!contents.empty());
+
+    std::unique_ptr<base::Value> manifest_value =
+        base::JSONReader::Read(contents);
+    DCHECK(manifest_value);
+
+    std::unique_ptr<base::Value> overlay_value =
+        GetContentClient()->browser()->GetServiceManifestOverlay(name);
+    if (overlay_value) {
+      base::DictionaryValue* manifest_dictionary = nullptr;
+      bool result = manifest_value->GetAsDictionary(&manifest_dictionary);
+      DCHECK(result);
+      base::DictionaryValue* overlay_dictionary = nullptr;
+      result = overlay_value->GetAsDictionary(&overlay_dictionary);
+      DCHECK(result);
+      MergeDictionary(manifest_dictionary, overlay_dictionary);
+    }
+
     auto result = manifests_.insert(
-        std::make_pair(name, std::move(manifest_contents)));
+        std::make_pair(name.as_string(), std::move(manifest_value)));
     DCHECK(result.second) << "Duplicate manifest entry: " << name;
   }
 
@@ -238,30 +259,13 @@
     };
 
     for (size_t i = 0; i < arraysize(kManifests); ++i) {
-      std::string contents = GetContentClient()->GetDataResource(
-          kManifests[i].resource_id,
-          ui::ScaleFactor::SCALE_FACTOR_NONE).as_string();
-      base::debug::Alias(&i);
-      CHECK(!contents.empty());
-
-      std::unique_ptr<base::Value> manifest_value =
-          base::JSONReader::Read(contents);
-      base::debug::Alias(&contents);
-      CHECK(manifest_value);
-
-      std::unique_ptr<base::Value> overlay_value =
-          GetContentClient()->browser()->GetServiceManifestOverlay(
-              kManifests[i].name);
-      if (overlay_value) {
-        base::DictionaryValue* manifest_dictionary = nullptr;
-        CHECK(manifest_value->GetAsDictionary(&manifest_dictionary));
-        base::DictionaryValue* overlay_dictionary = nullptr;
-        CHECK(overlay_value->GetAsDictionary(&overlay_dictionary));
-        MergeDictionary(manifest_dictionary, overlay_dictionary);
-      }
-
-      manifest_provider->AddManifestValue(kManifests[i].name,
-                                          std::move(manifest_value));
+      manifest_provider->AddServiceManifest(kManifests[i].name,
+                                            kManifests[i].resource_id);
+    }
+    for (const auto& manifest :
+         GetContentClient()->browser()->GetExtraServiceManifests()) {
+      manifest_provider->AddServiceManifest(manifest.name,
+                                            manifest.resource_id);
     }
     in_process_context_ = new InProcessServiceManagerContext;
     request = in_process_context_->Start(std::move(manifest_provider));
diff --git a/content/public/browser/browser_child_process_host.h b/content/public/browser/browser_child_process_host.h
index 7b5b9025..7f8bb93 100644
--- a/content/public/browser/browser_child_process_host.h
+++ b/content/public/browser/browser_child_process_host.h
@@ -92,6 +92,9 @@
   // this object.
   virtual void SetHandle(base::ProcessHandle handle) = 0;
 
+  // Returns the child message pipe token for the service request.
+  virtual std::string GetServiceRequestChannelToken() = 0;
+
 #if defined(OS_MACOSX)
   // Returns a PortProvider used to get the task port for child processes.
   static base::PortProvider* GetPortProvider();
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 279bede..6db33e99e 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -420,10 +420,15 @@
 #endif  // defined(OS_WIN)
 
 std::unique_ptr<base::Value> ContentBrowserClient::GetServiceManifestOverlay(
-    const std::string& name) {
+    base::StringPiece name) {
   return nullptr;
 }
 
+std::vector<ContentBrowserClient::ServiceManifestInfo>
+ContentBrowserClient::GetExtraServiceManifests() {
+  return std::vector<ContentBrowserClient::ServiceManifestInfo>();
+}
+
 std::unique_ptr<MemoryCoordinatorDelegate>
 ContentBrowserClient::GetMemoryCoordinatorDelegate() {
   return std::unique_ptr<MemoryCoordinatorDelegate>();
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 4c4c1cf6..9c78311 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -709,7 +709,19 @@
   // with content's own for |name|. Additional entries will be appended to their
   // respective sections.
   virtual std::unique_ptr<base::Value> GetServiceManifestOverlay(
-      const std::string& name);
+      base::StringPiece name);
+
+  struct ServiceManifestInfo {
+    // The name of the service.
+    std::string name;
+
+    // The resource ID of the manifest.
+    int resource_id;
+  };
+
+  // Allows the embedder to provide extra service manifests to be registered
+  // with the service manager context.
+  virtual std::vector<ServiceManifestInfo> GetExtraServiceManifests();
 
   // Allows to override the visibility state of a RenderFrameHost.
   // |visibility_state| should not be null. It will only be set if needed.
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 2b44625..402b298 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -219,8 +219,7 @@
 }
 
 std::unique_ptr<base::Value>
-ShellContentBrowserClient::GetServiceManifestOverlay(
-    const std::string& name) {
+ShellContentBrowserClient::GetServiceManifestOverlay(base::StringPiece name) {
   int id = -1;
   if (name == content::mojom::kBrowserServiceName)
     id = IDR_CONTENT_SHELL_BROWSER_MANIFEST_OVERLAY;
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h
index d1937bfb..7b9d9d8 100644
--- a/content/shell/browser/shell_content_browser_client.h
+++ b/content/shell/browser/shell_content_browser_client.h
@@ -39,7 +39,7 @@
   void RegisterInProcessServices(StaticServiceMap* services) override;
   void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
   std::unique_ptr<base::Value> GetServiceManifestOverlay(
-      const std::string& name) override;
+      base::StringPiece name) override;
   void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
                                       int child_process_id) override;
   void ResourceDispatcherHostCreated() override;
diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc
index c196a7fc..900463e4 100644
--- a/content/zygote/zygote_linux.cc
+++ b/content/zygote/zygote_linux.cc
@@ -562,8 +562,9 @@
   base::GlobalDescriptors::Mapping mapping;
   std::string process_type;
   std::string channel_id;
-  const std::string channel_id_prefix = std::string("--")
-      + switches::kMojoChannelToken + std::string("=");
+  const std::string channel_id_prefix = std::string("--") +
+                                        switches::kServiceRequestChannelToken +
+                                        std::string("=");
 
   if (!iter.ReadString(&process_type))
     return -1;