Index: content/browser/mojo_shell_context.cc |
diff --git a/content/browser/mojo_shell_context.cc b/content/browser/mojo_shell_context.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6911fbedb5b698a0028fbb662ec02e9ec7201429 |
--- /dev/null |
+++ b/content/browser/mojo_shell_context.cc |
@@ -0,0 +1,181 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/mojo_shell_context.h" |
+ |
+#include "base/lazy_instance.h" |
+#include "base/macros.h" |
+#include "base/memory/weak_ptr.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "base/synchronization/lock.h" |
+#include "base/thread_task_runner_handle.h" |
+#include "content/common/process_control.mojom.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/content_browser_client.h" |
+#include "content/public/browser/mojo_app_connection.h" |
+#include "content/public/browser/utility_process_host.h" |
+#include "content/public/browser/utility_process_host_client.h" |
jam
2015/05/29 01:48:54
i don't think this is needed
there are a lot of i
Ken Rockot(use gerrit already)
2015/05/29 03:20:40
Cleaned up some headers left behind, but this one
|
+#include "content/public/common/content_client.h" |
+#include "content/public/common/service_registry.h" |
+#include "mojo/application/public/cpp/application_delegate.h" |
+#include "mojo/common/url_type_converters.h" |
+#include "mojo/services/network/public/interfaces/url_loader.mojom.h" |
+#include "mojo/shell/application_loader.h" |
+#include "mojo/shell/static_application_loader.h" |
+#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" |
+#include "third_party/mojo/src/mojo/public/cpp/bindings/string.h" |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+// Virtual app URL to use as the requestor identity when connecting from browser |
+// code to a Mojo app via the shell proxy. |
+const char kBrowserAppUrl[] = "system:content_browser"; |
+ |
+// An ApplicationRegistry instance used for testing to override builtin loaders. |
+base::LazyInstance<base::Callback<void(ApplicationRegistry*)>> |
+ g_application_registry_initializer_for_testing; |
+ |
+void StartProcessOnIOThread(mojo::InterfaceRequest<ProcessControl> request) { |
+ UtilityProcessHost* process_host = |
+ UtilityProcessHost::Create(nullptr, nullptr); |
+ // TODO(rockot): Make it possible for the embedder to associate app URLs with |
+ // app names so we can have more meaningful process names here. |
+ process_host->SetName(base::UTF8ToUTF16("Mojo Application")); |
+ process_host->StartMojoMode(); |
+ ServiceRegistry* services = process_host->GetServiceRegistry(); |
+ services->ConnectToRemoteService(request.Pass()); |
+} |
+ |
+void OnApplicationLoaded(const GURL& url, LoadApplicationResult result) { |
+ if (result != LOAD_APPLICATION_RESULT_OK) { |
+ LOG(ERROR) << "Failed to launch Mojo application for " << url.spec(); |
+ } |
+} |
+ |
+// The default loader to use for all applications. This launches a utility |
+// process and forwards the Load request the ProcessControl service there. |
+class UtilityProcessLoader : public mojo::shell::ApplicationLoader { |
+ public: |
+ UtilityProcessLoader() {} |
+ ~UtilityProcessLoader() override {} |
+ |
+ private: |
+ // mojo::shell::ApplicationLoader: |
+ void Load( |
+ const GURL& url, |
+ mojo::InterfaceRequest<mojo::Application> application_request) override { |
+ ProcessControlPtr process_control; |
+ auto process_request = mojo::GetProxy(&process_control); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&StartProcessOnIOThread, base::Passed(&process_request))); |
+ process_control->LoadApplication(url.spec(), application_request.Pass(), |
+ base::Bind(&OnApplicationLoaded, url)); |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(UtilityProcessLoader); |
+}; |
+ |
+} // namespace |
+ |
+// Thread-safe proxy providing access to the shell context from any thread. |
+class MojoShellContext::Proxy { |
+ public: |
+ Proxy(MojoShellContext* shell_context) |
+ : shell_context_(shell_context), |
+ task_runner_(base::ThreadTaskRunnerHandle::Get()) { |
+ } |
+ |
+ ~Proxy() {} |
+ |
+ void ConnectToApplication( |
+ const GURL& url, |
+ mojo::InterfaceRequest<mojo::ServiceProvider> request) { |
+ if (task_runner_ == base::ThreadTaskRunnerHandle::Get()) { |
+ if (shell_context_) |
+ shell_context_->ConnectToApplicationOnOwnThread(url, request.Pass()); |
+ } else { |
+ // |shell_context_| outlives the main MessageLoop, so it's safe for it to |
+ // be unretained here. |
+ task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&MojoShellContext::ConnectToApplicationOnOwnThread, |
+ base::Unretained(shell_context_), url, |
+ base::Passed(&request))); |
+ } |
+ } |
+ |
+ private: |
+ MojoShellContext* shell_context_; |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Proxy); |
+}; |
+ |
+// static |
+base::LazyInstance<scoped_ptr<MojoShellContext::Proxy>> |
+MojoShellContext::proxy_ = LAZY_INSTANCE_INITIALIZER; |
+ |
+void MojoShellContext::SetApplicationRegistryInitializerForTesting( |
+ const base::Callback<void(ApplicationRegistry*)>& registry) { |
+ g_application_registry_initializer_for_testing.Get() = registry; |
+} |
+ |
+MojoShellContext::MojoShellContext() |
+ : application_manager_(new mojo::shell::ApplicationManager(this)) { |
+ proxy_.Get().reset(new Proxy(this)); |
+ application_manager_->set_default_loader( |
+ scoped_ptr<mojo::shell::ApplicationLoader>(new UtilityProcessLoader)); |
+ GetContentClient()->browser()->RegisterMojoApplications(this); |
+ if (!g_application_registry_initializer_for_testing.Get().is_null()) |
+ g_application_registry_initializer_for_testing.Get().Run(this); |
+} |
+ |
+MojoShellContext::~MojoShellContext() { |
+} |
+ |
+// static |
+void MojoShellContext::ConnectToApplication( |
+ const GURL& url, |
+ mojo::InterfaceRequest<mojo::ServiceProvider> request) { |
+ proxy_.Get()->ConnectToApplication(url, request.Pass()); |
+} |
+ |
+void MojoShellContext::ConnectToApplicationOnOwnThread( |
+ const GURL& url, |
+ mojo::InterfaceRequest<mojo::ServiceProvider> request) { |
+ mojo::URLRequestPtr url_request = mojo::URLRequest::New(); |
+ url_request->url = mojo::String::From(url); |
+ application_manager_->ConnectToApplication( |
+ url_request.Pass(), GURL(kBrowserAppUrl), request.Pass(), |
+ mojo::ServiceProviderPtr(), base::Bind(&base::DoNothing)); |
+} |
+ |
+void MojoShellContext::RegisterStaticAppForURL( |
+ const GURL& url, |
+ const StaticAppFactory& factory) { |
+ application_manager_->SetLoaderForURL( |
+ scoped_ptr<mojo::shell::ApplicationLoader>( |
+ new mojo::shell::StaticApplicationLoader(factory)), |
+ url); |
+} |
+ |
+GURL MojoShellContext::ResolveMappings(const GURL& url) { |
+ return url; |
+} |
+ |
+GURL MojoShellContext::ResolveMojoURL(const GURL& url) { |
+ return url; |
+} |
+ |
+bool MojoShellContext::CreateFetcher( |
+ const GURL& url, |
+ const mojo::shell::Fetcher::FetchCallback& loader_callback) { |
+ return false; |
+} |
+ |
+} // namespace content |