Added anti-singleton services (new process/thread per connection).

TEST=`./out/Debug/mojo_shell --enable-multiprocess ./out/Debug/spinning_cube.pexe.mojo ./out/Debug/echo_client.pexe.mojo`
BUG=#396
R=viettrungluu@chromium.org

Review URL: https://codereview.chromium.org/1444433002 .
diff --git a/shell/application_manager/application_manager.cc b/shell/application_manager/application_manager.cc
index 6e7b965..2dfdc3e 100644
--- a/shell/application_manager/application_manager.cc
+++ b/shell/application_manager/application_manager.cc
@@ -8,6 +8,7 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/trace_event/trace_event.h"
 #include "mojo/public/cpp/bindings/binding.h"
@@ -48,11 +49,10 @@
 
 class ApplicationManager::ContentHandlerConnection {
  public:
-  ContentHandlerConnection(ApplicationManager* manager,
-                           const GURL& content_handler_url)
-      : manager_(manager), content_handler_url_(content_handler_url) {
+  ContentHandlerConnection(ApplicationManager* manager, Identity identity)
+      : manager_(manager), identity_(identity) {
     ServiceProviderPtr services;
-    manager->ConnectToApplication(content_handler_url, GURL(),
+    manager->ConnectToApplication(identity_.url, GURL(),
                                   mojo::GetProxy(&services), nullptr,
                                   base::Closure());
     mojo::MessagePipe pipe;
@@ -67,11 +67,13 @@
 
   mojo::ContentHandler* content_handler() { return content_handler_.get(); }
 
-  GURL content_handler_url() { return content_handler_url_; }
+  const GURL& content_handler_url() const { return identity_.url; }
+
+  const Identity& identity() const { return identity_; }
 
  private:
   ApplicationManager* manager_;
-  GURL content_handler_url_;
+  const Identity identity_;
   mojo::ContentHandlerPtr content_handler_;
 
   DISALLOW_COPY_AND_ASSIGN(ContentHandlerConnection);
@@ -230,6 +232,9 @@
   if (!shell_impl)
     return false;
 
+  DCHECK(!GetNativeApplicationOptionsForURL(application_url)
+              ->new_process_per_connection);
+
   ConnectToClient(shell_impl, resolved_url, requestor_url, services->Pass(),
                   exposed_services->Pass());
   return true;
@@ -253,6 +258,17 @@
   return true;
 }
 
+Identity ApplicationManager::MakeApplicationIdentity(const GURL& resolved_url) {
+  static uint64_t unique_id_number = 1;
+  bool new_process_per_connection =
+      GetNativeApplicationOptionsForURL(
+          GetBaseURLAndQuery(resolved_url, nullptr))
+          ->new_process_per_connection;
+  return new_process_per_connection
+             ? Identity(resolved_url, base::Uint64ToString(unique_id_number++))
+             : Identity(resolved_url);
+}
+
 InterfaceRequest<Application> ApplicationManager::RegisterShell(
     const GURL& resolved_url,
     const GURL& requestor_url,
@@ -260,7 +276,7 @@
     ServiceProviderPtr exposed_services,
     const base::Closure& on_application_end,
     const std::vector<std::string>& parameters) {
-  Identity app_identity(resolved_url);
+  Identity app_identity = MakeApplicationIdentity(resolved_url);
 
   mojo::ApplicationPtr application;
   InterfaceRequest<Application> application_request =
@@ -274,6 +290,9 @@
   return application_request;
 }
 
+// Note: If a service was created with a unique ID, intending to be unique
+// (such that multiple requests for a service result in unique processes), then
+// 'GetShellImpl' should return nullptr.
 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) {
   const auto& shell_it = identity_to_shell_impl_.find(Identity(url));
   if (shell_it != identity_to_shell_impl_.end())
@@ -410,12 +429,14 @@
     InterfaceRequest<Application> application_request,
     mojo::URLResponsePtr url_response) {
   ContentHandlerConnection* connection = nullptr;
-  auto it = url_to_content_handler_.find(content_handler_url);
-  if (it != url_to_content_handler_.end()) {
+  Identity content_handler_id = MakeApplicationIdentity(content_handler_url);
+  auto it = identity_to_content_handler_.find(content_handler_id);
+  if (it != identity_to_content_handler_.end()) {
     connection = it->second.get();
   } else {
-    connection = new ContentHandlerConnection(this, content_handler_url);
-    url_to_content_handler_[content_handler_url] = make_scoped_ptr(connection);
+    connection = new ContentHandlerConnection(this, content_handler_id);
+    identity_to_content_handler_[content_handler_id] =
+        make_scoped_ptr(connection);
   }
 
   connection->content_handler()->StartApplication(application_request.Pass(),
@@ -485,10 +506,9 @@
 void ApplicationManager::OnContentHandlerError(
     ContentHandlerConnection* content_handler) {
   // Remove the mapping to the content handler.
-  auto it =
-      url_to_content_handler_.find(content_handler->content_handler_url());
-  DCHECK(it != url_to_content_handler_.end());
-  url_to_content_handler_.erase(it);
+  auto it = identity_to_content_handler_.find(content_handler->identity());
+  DCHECK(it != identity_to_content_handler_.end());
+  identity_to_content_handler_.erase(it);
 }
 
 mojo::ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName(
diff --git a/shell/application_manager/application_manager.h b/shell/application_manager/application_manager.h
index 0a5e8b0..3be4992 100644
--- a/shell/application_manager/application_manager.h
+++ b/shell/application_manager/application_manager.h
@@ -146,8 +146,8 @@
   using SchemeToLoaderMap =
       std::map<std::string, scoped_ptr<ApplicationLoader>>;
   using IdentityToShellImplMap = std::map<Identity, scoped_ptr<ShellImpl>>;
-  using URLToContentHandlerMap =
-      std::map<GURL, scoped_ptr<ContentHandlerConnection>>;
+  using IdentityToContentHandlerMap =
+      std::map<Identity, scoped_ptr<ContentHandlerConnection>>;
   using URLToArgsMap = std::map<GURL, std::vector<std::string>>;
   using MimeTypeToURLMap = std::map<std::string, GURL>;
   using URLToNativeOptionsMap = std::map<GURL, NativeApplicationOptions>;
@@ -175,6 +175,12 @@
       const std::vector<std::string>& parameters,
       ApplicationLoader* loader);
 
+  // Creates an Identity for the service identified by |resolved_url|.
+  // If |new_process_per_connection| is true for the URL's options, then the
+  // identity is unique. Otherwise, repeated invocations with the same
+  // |resolved_url| will result in an equivalent Identity.
+  Identity MakeApplicationIdentity(const GURL& resolved_url);
+
   mojo::InterfaceRequest<mojo::Application> RegisterShell(
       // The URL after resolution and redirects, including the querystring.
       const GURL& resolved_url,
@@ -234,7 +240,7 @@
   scoped_ptr<NativeRunnerFactory> native_runner_factory_;
 
   IdentityToShellImplMap identity_to_shell_impl_;
-  URLToContentHandlerMap url_to_content_handler_;
+  IdentityToContentHandlerMap identity_to_content_handler_;
   URLToArgsMap url_to_args_;
   // Note: The keys are URLs after mapping and resolving.
   URLToNativeOptionsMap url_to_native_options_;
diff --git a/shell/application_manager/native_application_options.h b/shell/application_manager/native_application_options.h
index f4c71c4..103ab14 100644
--- a/shell/application_manager/native_application_options.h
+++ b/shell/application_manager/native_application_options.h
@@ -12,6 +12,7 @@
 // TODO(vtl): Maybe these some of these should be tristate (unknown/true/false)
 // instead of of booleans.
 struct NativeApplicationOptions {
+  bool new_process_per_connection = false;
   bool force_in_process = false;
   bool require_32_bit = false;
   bool allow_new_privs = false;