Chromium Code Reviews| 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 |