diff options
author | rockot <rockot@chromium.org> | 2015-06-04 17:30:52 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-05 00:32:18 +0000 |
commit | b814a5850da5aa473ad526eef4b41a82b05037a0 (patch) | |
tree | d1730ed4fccfc7fda63bd51f30891a95e61ba915 /content | |
parent | 87c39e56c03c089751e4ae22dcea9ca7cf17c741 (diff) | |
download | chromium_src-b814a5850da5aa473ad526eef4b41a82b05037a0.zip chromium_src-b814a5850da5aa473ad526eef4b41a82b05037a0.tar.gz chromium_src-b814a5850da5aa473ad526eef4b41a82b05037a0.tar.bz2 |
Embed a mojo ApplicationManager in content/browser
This embeds mojo/shell's ApplicationManager in content/browser
and provides a way for arbitrary browser code to connect to
Mojo apps as if the browser itself were a Mojo app.
This is a basic implementation of Mojo app support which only
loads static apps either in the browser process or a (per-app)
utility process.
Future CLs will address connection to apps from arbitrary render
frames (i.e. connection requests which include the requestor's
origin) as well as refactoring the utility process code further
so that it serves strictly as a Mojo app runner.
BUG=492422
Review URL: https://codereview.chromium.org/1149833007
Cr-Commit-Position: refs/heads/master@{#332974}
Diffstat (limited to 'content')
38 files changed, 830 insertions, 6 deletions
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 71083b9..a8bcd7a 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -29,14 +29,20 @@ source_set("browser") { "//content/browser/service_worker:service_worker_proto", "//content/browser/speech/proto", "//content/public/common:common_sources", + "//content/public/common:mojo_bindings", "//crypto", "//device/battery", "//device/vibration", "//google_apis", + "//mojo/application/public/cpp:cpp_for_chromium", + "//mojo/application/public/interfaces", + "//mojo/common", + "//mojo/shell", "//net", "//net:extras", "//skia", "//sql", + "//third_party/mojo/src/mojo/public/cpp/bindings", "//third_party/npapi", "//third_party/re2", "//third_party/WebKit/public:blink_headers", diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 04640a8..2a92285 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -39,6 +39,7 @@ #include "content/browser/histogram_synchronizer.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/media/media_internals.h" +#include "content/browser/mojo/mojo_shell_context.h" #include "content/browser/net/browser_online_state_observer.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/speech/speech_recognition_manager_impl.h" @@ -897,6 +898,8 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), true)); + mojo_shell_context_.reset(); + #if !defined(OS_IOS) if (RenderProcessHost::run_renderer_in_process()) RenderProcessHostImpl::ShutDownInProcessRenderer(); @@ -1253,6 +1256,8 @@ int BrowserMainLoop::BrowserThreadsStarted() { #endif // !defined(OS_IOS) + mojo_shell_context_.reset(new MojoShellContext); + return result_code_; } diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 9eba81d..14478ec 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h @@ -45,6 +45,7 @@ class BrowserOnlineStateObserver; class BrowserShutdownImpl; class BrowserThreadImpl; class MediaStreamManager; +class MojoShellContext; class ResourceDispatcherHostImpl; class SpeechRecognitionManagerImpl; class StartupTaskRunner; @@ -231,6 +232,7 @@ class CONTENT_EXPORT BrowserMainLoop { // Members initialized in |BrowserThreadsStarted()| -------------------------- scoped_ptr<base::Thread> indexed_db_thread_; + scoped_ptr<MojoShellContext> mojo_shell_context_; // |user_input_monitor_| has to outlive |audio_manager_|, so declared first. scoped_ptr<media::UserInputMonitor> user_input_monitor_; diff --git a/content/browser/mojo/mojo_app_connection_impl.cc b/content/browser/mojo/mojo_app_connection_impl.cc new file mode 100644 index 0000000..d643bbf --- /dev/null +++ b/content/browser/mojo/mojo_app_connection_impl.cc @@ -0,0 +1,28 @@ +// 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/mojo_app_connection_impl.h" + +#include "content/browser/mojo/mojo_shell_context.h" + +namespace content { + +scoped_ptr<MojoAppConnection> MojoAppConnection::Create(const GURL& url) { + return scoped_ptr<MojoAppConnection>(new MojoAppConnectionImpl(url)); +} + +MojoAppConnectionImpl::MojoAppConnectionImpl(const GURL& url) { + MojoShellContext::ConnectToApplication(url, mojo::GetProxy(&services_)); +} + +MojoAppConnectionImpl::~MojoAppConnectionImpl() { +} + +void MojoAppConnectionImpl::ConnectToService( + const std::string& service_name, + mojo::ScopedMessagePipeHandle handle) { + services_->ConnectToService(service_name, handle.Pass()); +} + +} // namespace content diff --git a/content/browser/mojo/mojo_app_connection_impl.h b/content/browser/mojo/mojo_app_connection_impl.h new file mode 100644 index 0000000..4628acc --- /dev/null +++ b/content/browser/mojo/mojo_app_connection_impl.h @@ -0,0 +1,34 @@ +// 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. + +#ifndef CONTENT_BROWSER_MOJO_MOJO_APP_CONNECTION_IMPL_H_ +#define CONTENT_BROWSER_MOJO_MOJO_APP_CONNECTION_IMPL_H_ + +#include "base/macros.h" +#include "content/public/browser/mojo_app_connection.h" +#include "mojo/application/public/interfaces/service_provider.mojom.h" + +class GURL; + +namespace content { + +// Implementation of the app connection mechanism provided to browser code. +class MojoAppConnectionImpl : public MojoAppConnection { + public: + explicit MojoAppConnectionImpl(const GURL& url); + ~MojoAppConnectionImpl() override; + + private: + // MojoAppConnection: + void ConnectToService(const std::string& service_name, + mojo::ScopedMessagePipeHandle handle) override; + + mojo::ServiceProviderPtr services_; + + DISALLOW_COPY_AND_ASSIGN(MojoAppConnectionImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_MOJO_MOJO_APP_CONNECTION_IMPL_H_ diff --git a/content/browser/mojo/mojo_shell_context.cc b/content/browser/mojo/mojo_shell_context.cc new file mode 100644 index 0000000..49e66a9 --- /dev/null +++ b/content/browser/mojo/mojo_shell_context.cc @@ -0,0 +1,178 @@ +// 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/mojo_shell_context.h" + +#include "base/lazy_instance.h" +#include "base/macros.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/utf_string_conversions.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/utility_process_host.h" +#include "content/public/browser/utility_process_host_client.h" +#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 extra set of apps to register on initialization, if set by a test. +const MojoShellContext::StaticApplicationMap* g_applications_for_test; + +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, bool success) { + if (!success) + 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::SetApplicationsForTest( + const StaticApplicationMap* apps) { + g_applications_for_test = apps; +} + +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)); + + StaticApplicationMap apps; + GetContentClient()->browser()->RegisterMojoApplications(&apps); + if (g_applications_for_test) { + // Add testing apps to the map, potentially overwriting whatever the + // browser client registered. + for (const auto& entry : *g_applications_for_test) + apps[entry.first] = entry.second; + } + for (const auto& entry : apps) { + application_manager_->SetLoaderForURL( + scoped_ptr<mojo::shell::ApplicationLoader>( + new mojo::shell::StaticApplicationLoader(entry.second)), + entry.first); + } +} + +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)); +} + +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 diff --git a/content/browser/mojo/mojo_shell_context.h b/content/browser/mojo/mojo_shell_context.h new file mode 100644 index 0000000..b0ac5b1 --- /dev/null +++ b/content/browser/mojo/mojo_shell_context.h @@ -0,0 +1,70 @@ +// 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. + +#ifndef CONTENT_BROWSER_MOJO_MOJO_SHELL_CONTEXT_H_ +#define CONTENT_BROWSER_MOJO_MOJO_SHELL_CONTEXT_H_ + +#include <map> + +#include "base/callback_forward.h" +#include "base/compiler_specific.h" +#include "base/lazy_instance.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "content/common/content_export.h" +#include "mojo/shell/application_manager.h" + +class GURL; + +namespace mojo { +class ApplicationDelegate; +} + +namespace content { + +// MojoShellContext hosts the browser's ApplicationManager, coordinating +// app registration and interconnection. +class CONTENT_EXPORT MojoShellContext + : public NON_EXPORTED_BASE(mojo::shell::ApplicationManager::Delegate) { + public: + using StaticApplicationMap = + std::map<GURL, base::Callback<scoped_ptr<mojo::ApplicationDelegate>()>>; + + MojoShellContext(); + ~MojoShellContext() override; + + // Connects an application at |url| and gets a handle to its exposed services. + // This is only intended for use in browser code that's not part of some Mojo + // application. May be called from any thread. + static void ConnectToApplication( + const GURL& url, + mojo::InterfaceRequest<mojo::ServiceProvider> request); + + static void SetApplicationsForTest(const StaticApplicationMap* apps); + + private: + class Proxy; + friend class Proxy; + + void ConnectToApplicationOnOwnThread( + const GURL& url, + mojo::InterfaceRequest<mojo::ServiceProvider> request); + + // mojo::shell::ApplicationManager::Delegate: + GURL ResolveMappings(const GURL& url) override; + GURL ResolveMojoURL(const GURL& url) override; + bool CreateFetcher( + const GURL& url, + const mojo::shell::Fetcher::FetchCallback& loader_callback) override; + + static base::LazyInstance<scoped_ptr<Proxy>> proxy_; + + scoped_ptr<mojo::shell::ApplicationManager> application_manager_; + + DISALLOW_COPY_AND_ASSIGN(MojoShellContext); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_MOJO_MOJO_SHELL_CONTEXT_H_ diff --git a/content/browser/mojo_shell_browsertest.cc b/content/browser/mojo_shell_browsertest.cc new file mode 100644 index 0000000..3dcde73 --- /dev/null +++ b/content/browser/mojo_shell_browsertest.cc @@ -0,0 +1,60 @@ +// 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 "base/bind.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/run_loop.h" +#include "content/browser/mojo/mojo_shell_context.h" +#include "content/public/browser/mojo_app_connection.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/test_mojo_app.h" +#include "content/public/test/test_mojo_service.mojom.h" +#include "url/gurl.h" + +namespace content { + +const char kInProcessTestMojoAppUrl[] = "system:content_in_process_test_app"; + +class MojoShellTest : public ContentBrowserTest { + public: + MojoShellTest() { + test_apps_[GURL(kInProcessTestMojoAppUrl)] = base::Bind(&CreateTestApp); + MojoShellContext::SetApplicationsForTest(&test_apps_); + } + + private: + static scoped_ptr<mojo::ApplicationDelegate> CreateTestApp() { + return scoped_ptr<mojo::ApplicationDelegate>(new TestMojoApp); + } + + MojoShellContext::StaticApplicationMap test_apps_; + + DISALLOW_COPY_AND_ASSIGN(MojoShellTest); +}; + +IN_PROC_BROWSER_TEST_F(MojoShellTest, TestBrowserConnection) { + auto test_app = MojoAppConnection::Create(GURL(kInProcessTestMojoAppUrl)); + TestMojoServicePtr test_service; + test_app->ConnectToService(&test_service); + + base::RunLoop run_loop; + test_service->DoSomething(run_loop.QuitClosure()); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(MojoShellTest, TestUtilityConnection) { + // With no loader registered at this URL, the shell should spawn a utility + // process and connect us to it. content_shell's utility process always hosts + // a TestMojoApp at |kTestMojoAppUrl|. + auto test_app = MojoAppConnection::Create(GURL(kTestMojoAppUrl)); + TestMojoServicePtr test_service; + test_app->ConnectToService(&test_service); + + base::RunLoop run_loop; + test_service->DoSomething(run_loop.QuitClosure()); + run_loop.Run(); +} + +} // namespace content diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index ecfe362..09f7a4a 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn @@ -486,9 +486,12 @@ mojom("mojo_bindings") { "geolocation_service.mojom", "permission_service.mojom", "presentation/presentation_service.mojom", + "process_control.mojom", "render_frame_setup.mojom", ] + import_dirs = [ "//mojo/services" ] + deps = [ "//content/public/common:mojo_bindings", "//mojo/application/public/interfaces", diff --git a/content/common/process_control.mojom b/content/common/process_control.mojom new file mode 100644 index 0000000..4b3237a --- /dev/null +++ b/content/common/process_control.mojom @@ -0,0 +1,12 @@ +// 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. + +module content; + +import "mojo/application/public/interfaces/application.mojom"; + +interface ProcessControl { + LoadApplication(string url, mojo.Application& request) => (bool success); +}; + diff --git a/content/content.gyp b/content/content.gyp index de5327e..13a8385 100644 --- a/content/content.gyp +++ b/content/content.gyp @@ -287,6 +287,7 @@ 'dependencies': [ 'content_child', 'content_common', + 'content_common_mojo_bindings.gyp:content_common_mojo_bindings', ], }, ], diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 6b8e555..74260af 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -11,10 +11,15 @@ '../device/vibration/vibration.gyp:device_vibration', '../device/vibration/vibration.gyp:device_vibration_mojo_bindings', '../google_apis/google_apis.gyp:google_apis', + '../mojo/mojo_base.gyp:mojo_application_base', + '../mojo/mojo_base.gyp:mojo_url_type_converters', + '../mojo/mojo_services.gyp:network_service_bindings_lib', + '../mojo/mojo_shell.gyp:mojo_shell_lib', '../net/net.gyp:net', '../net/net.gyp:net_extras', '../skia/skia.gyp:skia', '../sql/sql.gyp:sql', + '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', '../third_party/re2/re2.gyp:re2', '../third_party/zlib/google/zip.gyp:zip', '../third_party/zlib/zlib.gyp:zlib', @@ -165,6 +170,7 @@ 'public/browser/media_device_id.h', 'public/browser/message_port_delegate.h', 'public/browser/message_port_provider.h', + 'public/browser/mojo_app_connection.h', 'public/browser/native_web_keyboard_event.h', 'public/browser/navigation_controller.cc', 'public/browser/navigation_controller.h', @@ -1030,8 +1036,12 @@ 'browser/message_port_service.h', 'browser/mime_registry_message_filter.cc', 'browser/mime_registry_message_filter.h', + 'browser/mojo/mojo_app_connection_impl.cc', + 'browser/mojo/mojo_app_connection_impl.h', 'browser/mojo/mojo_application_host.cc', 'browser/mojo/mojo_application_host.h', + 'browser/mojo/mojo_shell_context.cc', + 'browser/mojo/mojo_shell_context.h', 'browser/mojo/service_registrar_android.cc', 'browser/mojo/service_registrar_android.h', 'browser/mojo/service_registry_android.cc', diff --git a/content/content_common_mojo_bindings.gyp b/content/content_common_mojo_bindings.gyp index dc2df70..4f01043 100644 --- a/content/content_common_mojo_bindings.gyp +++ b/content/content_common_mojo_bindings.gyp @@ -16,6 +16,7 @@ 'common/geolocation_service.mojom', 'common/permission_service.mojom', 'common/presentation/presentation_service.mojom', + 'common/process_control.mojom', 'common/render_frame_setup.mojom', # NOTE: Sources duplicated in diff --git a/content/content_shell.gypi b/content/content_shell.gypi index 75cf4c3..2f30de3 100644 --- a/content/content_shell.gypi +++ b/content/content_shell.gypi @@ -234,6 +234,8 @@ 'shell/renderer/shell_content_renderer_client.h', 'shell/renderer/shell_render_view_observer.cc', 'shell/renderer/shell_render_view_observer.h', + 'shell/utility/shell_content_utility_client.cc', + 'shell/utility/shell_content_utility_client.h', ], 'msvs_settings': { 'VCLinkerTool': { diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 24483e6..0dfc8ca 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -83,6 +83,8 @@ 'public/test/test_file_system_options.h', 'public/test/test_launcher.cc', 'public/test/test_launcher.h', + 'public/test/test_mojo_app.cc', + 'public/test/test_mojo_app.h', 'public/test/test_navigation_observer.cc', 'public/test/test_navigation_observer.h', 'public/test/test_notification_tracker.cc', @@ -222,6 +224,7 @@ 'browser/media/media_canplaytype_browsertest.cc', 'browser/media/media_source_browsertest.cc', 'browser/message_port_provider_browsertest.cc', + 'browser/mojo_shell_browsertest.cc', 'browser/net_info_browsertest.cc', 'browser/plugin_browsertest.cc', 'browser/renderer_host/input/touch_action_browsertest.cc', @@ -788,6 +791,7 @@ 'target_name': 'test_support_content', 'type': 'static_library', 'dependencies': [ + '../mojo/mojo_base.gyp:mojo_application_base', '../mojo/mojo_base.gyp:mojo_environment_chromium', '../net/net.gyp:net_test_support', '../skia/skia.gyp:skia', @@ -795,6 +799,7 @@ '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', '../third_party/mojo/mojo_edk.gyp:mojo_system_impl', + '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', '../ui/accessibility/accessibility.gyp:ax_gen', '../ui/base/ime/ui_base_ime.gyp:ui_base_ime', '../ui/base/ui_base.gyp:ui_base', @@ -862,6 +867,7 @@ }], ], 'dependencies': [ + 'content_test_mojo_bindings', 'content.gyp:content_child', 'content.gyp:content_common', 'content.gyp:content_gpu', @@ -880,6 +886,8 @@ '../media/blink/media_blink.gyp:media_blink', '../media/media.gyp:media', '../media/midi/midi.gyp:midi', + '../mojo/mojo_base.gyp:mojo_application_base', + '../mojo/mojo_base.gyp:mojo_environment_chromium', '../ppapi/ppapi_internal.gyp:ppapi_host', '../ppapi/ppapi_internal.gyp:ppapi_proxy', '../ppapi/ppapi_internal.gyp:ppapi_shared', @@ -887,6 +895,7 @@ '../storage/storage_browser.gyp:storage', '../storage/storage_common.gyp:storage_common', '../third_party/WebKit/public/blink.gyp:blink', + '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', '../ui/compositor/compositor.gyp:compositor_test_support', '../ui/surface/surface.gyp:surface', '../v8/tools/gyp/v8.gyp:v8', @@ -1314,6 +1323,15 @@ ], }, { + # GN version: //content/test:test_mojo_bindings + 'target_name': 'content_test_mojo_bindings', + 'type': 'static_library', + 'sources': [ + 'public/test/test_mojo_service.mojom', + ], + 'includes': [ '../third_party/mojo/mojom_bindings_generator.gypi' ], + }, + { # GN version: //content/test:web_ui_test_mojo_bindings 'target_name': 'web_ui_test_mojo_bindings', 'type': 'static_library', @@ -1352,6 +1370,7 @@ '../ipc/ipc.gyp:test_support_ipc', '../media/media.gyp:media_test_support', '../media/media.gyp:shared_memory_support', + '../mojo/mojo_base.gyp:mojo_application_base', '../mojo/mojo_base.gyp:mojo_environment_chromium', '../net/net.gyp:net_test_support', '../ppapi/ppapi_internal.gyp:ppapi_host', diff --git a/content/content_utility.gypi b/content/content_utility.gypi index bbdfd4f..96d81f8 100644 --- a/content/content_utility.gypi +++ b/content/content_utility.gypi @@ -6,6 +6,12 @@ 'dependencies': [ '../base/base.gyp:base', '../courgette/courgette.gyp:courgette_lib', + '../mojo/mojo_base.gyp:mojo_application_base', + '../mojo/mojo_base.gyp:mojo_application_bindings', + '../mojo/mojo_base.gyp:mojo_common_lib', + '../mojo/mojo_shell.gyp:mojo_shell_lib', + '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', + '../url/url.gyp:url_lib', ], 'variables': { 'utility_sources': [ @@ -14,6 +20,8 @@ 'utility/utility_blink_platform_impl.cc', 'utility/utility_blink_platform_impl.h', 'utility/utility_main.cc', + 'utility/utility_process_control_impl.cc', + 'utility/utility_process_control_impl.h', 'utility/utility_thread_impl.cc', 'utility/utility_thread_impl.h', 'utility/webthread_impl_for_utility_thread.cc', diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index a0c7f91..ebe488e 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn @@ -50,6 +50,7 @@ source_set("browser_sources") { # We expose skia headers in the public API. "//skia", + "//third_party/mojo/src/mojo/public/cpp/bindings", "//third_party/mojo/src/mojo/public/cpp/system", ] deps = [ diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index eff374d..579b9f8 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -53,6 +53,10 @@ namespace gfx { class ImageSkia; } +namespace mojo { +class ApplicationDelegate; +} + namespace net { class CookieOptions; class NetLog; @@ -578,6 +582,13 @@ class CONTENT_EXPORT ContentBrowserClient { ServiceRegistry* registry, RenderFrameHost* render_frame_host) {} + using StaticMojoApplicationMap = + std::map<GURL, base::Callback<scoped_ptr<mojo::ApplicationDelegate>()>>; + + // Registers in-process Mojo application loaders with the browser's global + // Mojo shell. + virtual void RegisterMojoApplications(StaticMojoApplicationMap* apps) {} + // Registers additional navigator.connect service factories available in a // particular NavigatorConnectContext. virtual void GetAdditionalNavigatorConnectServices( diff --git a/content/public/browser/mojo_app_connection.h b/content/public/browser/mojo_app_connection.h new file mode 100644 index 0000000..f7c0272 --- /dev/null +++ b/content/public/browser/mojo_app_connection.h @@ -0,0 +1,43 @@ +// 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. + +#ifndef CONTENT_PUBLIC_BROWSER_MOJO_APP_CONNECTION_H_ +#define CONTENT_PUBLIC_BROWSER_MOJO_APP_CONNECTION_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "content/common/content_export.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_ptr.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" +#include "third_party/mojo/src/mojo/public/cpp/system/message_pipe.h" + +class GURL; + +namespace content { + +// This provides a way for arbitrary browser code to connect to Mojo apps. These +// objects are not thread-safe but may be constructed and used on any single +// thread. +class CONTENT_EXPORT MojoAppConnection { + public: + virtual ~MojoAppConnection() {} + + // Creates a new connection to the application at |url|. This may be called + // from any thread. + static scoped_ptr<MojoAppConnection> Create(const GURL& url); + + // Connects to a service within the application. + template <typename Interface> + void ConnectToService(mojo::InterfacePtr<Interface>* proxy) { + ConnectToService(Interface::Name_, mojo::GetProxy(proxy).PassMessagePipe()); + } + + virtual void ConnectToService(const std::string& service_name, + mojo::ScopedMessagePipeHandle handle) = 0; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_MOJO_APP_CONNECTION_H_ diff --git a/content/public/test/DEPS b/content/public/test/DEPS index fbe84ed..88c3916 100644 --- a/content/public/test/DEPS +++ b/content/public/test/DEPS @@ -1,6 +1,7 @@ include_rules = [ "-content", "+content/public", + "+mojo/application", "+v8/include/v8.h", ] diff --git a/content/public/test/test_mojo_app.cc b/content/public/test/test_mojo_app.cc new file mode 100644 index 0000000..bebb7a7 --- /dev/null +++ b/content/public/test/test_mojo_app.cc @@ -0,0 +1,43 @@ +// 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/public/test/test_mojo_app.h" + +#include "base/logging.h" +#include "mojo/application/public/cpp/application_connection.h" +#include "mojo/application/public/cpp/application_impl.h" + +namespace content { + +const char kTestMojoAppUrl[] = "system:content_mojo_test"; + +TestMojoApp::TestMojoApp() : service_binding_(this), app_(nullptr) { +} + +TestMojoApp::~TestMojoApp() { +} + +void TestMojoApp::Initialize(mojo::ApplicationImpl* app) { + app_ = app; +} + +bool TestMojoApp::ConfigureIncomingConnection( + mojo::ApplicationConnection* connection) { + connection->AddService<TestMojoService>(this); + return true; +} + +void TestMojoApp::Create(mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<TestMojoService> request) { + DCHECK(!service_binding_.is_bound()); + service_binding_.Bind(request.Pass()); +} + +void TestMojoApp::DoSomething(const DoSomethingCallback& callback) { + callback.Run(); + DCHECK(app_); + app_->Terminate(); +} + +} // namespace content diff --git a/content/public/test/test_mojo_app.h b/content/public/test/test_mojo_app.h new file mode 100644 index 0000000..e01e7b5 --- /dev/null +++ b/content/public/test/test_mojo_app.h @@ -0,0 +1,50 @@ +// 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. + +#ifndef CONTENT_PUBLIC_TEST_TEST_MOJO_APP_H_ +#define CONTENT_PUBLIC_TEST_TEST_MOJO_APP_H_ + +#include "base/macros.h" +#include "content/public/test/test_mojo_service.mojom.h" +#include "mojo/application/public/cpp/application_delegate.h" +#include "mojo/application/public/cpp/interface_factory.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" + +namespace content { + +extern const char kTestMojoAppUrl[]; + +// Simple Mojo app which provides a TestMojoService impl. The app terminates +// itself after its TestService fulfills a single DoSomething call. +class TestMojoApp : public mojo::ApplicationDelegate, + public mojo::InterfaceFactory<TestMojoService>, + public TestMojoService { + public: + TestMojoApp(); + ~TestMojoApp() override; + + private: + // mojo::ApplicationDelegate: + void Initialize(mojo::ApplicationImpl* app) override; + bool ConfigureIncomingConnection( + mojo::ApplicationConnection* connection) override; + + // mojo::InterfaceFactory<TestMojoService>: + void Create(mojo::ApplicationConnection* connection, + mojo::InterfaceRequest<TestMojoService> request) override; + + // TestMojoService: + void DoSomething(const DoSomethingCallback& callback) override; + + mojo::Binding<TestMojoService> service_binding_; + + // Not owned. + mojo::ApplicationImpl* app_; + + DISALLOW_COPY_AND_ASSIGN(TestMojoApp); +}; + +} // namespace + +#endif // CONTENT_PUBLIC_TEST_TEST_MOJO_APP_H_ diff --git a/content/public/test/test_mojo_service.mojom b/content/public/test/test_mojo_service.mojom new file mode 100644 index 0000000..e417916 --- /dev/null +++ b/content/public/test/test_mojo_service.mojom @@ -0,0 +1,9 @@ +// 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. + +module content; + +interface TestMojoService { + DoSomething() => (); +}; diff --git a/content/public/utility/BUILD.gn b/content/public/utility/BUILD.gn index 999549a..1f3e987 100644 --- a/content/public/utility/BUILD.gn +++ b/content/public/utility/BUILD.gn @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//content/utility/utility.gni") + # See //content/BUILD.gn for how this works. group("utility") { if (is_component_build) { @@ -18,12 +20,9 @@ group("utility") { source_set("utility_sources") { visibility = [ "//content/*" ] - sources = [ - "content_utility_client.cc", - "content_utility_client.h", - "utility_thread.cc", - "utility_thread.h", - ] + sources = rebase_path(content_utility_gypi_values.public_utility_sources, + ".", + "//content") configs += [ "//content:content_implementation" ] diff --git a/content/public/utility/content_utility_client.h b/content/public/utility/content_utility_client.h index 8a333e7..b326eae 100644 --- a/content/public/utility/content_utility_client.h +++ b/content/public/utility/content_utility_client.h @@ -5,8 +5,18 @@ #ifndef CONTENT_PUBLIC_UTILITY_CONTENT_UTILITY_CLIENT_H_ #define CONTENT_PUBLIC_UTILITY_CONTENT_UTILITY_CLIENT_H_ +#include <map> + +#include "base/callback_forward.h" +#include "base/memory/scoped_ptr.h" #include "content/public/common/content_client.h" +class GURL; + +namespace mojo { +class ApplicationDelegate; +} + namespace content { class ServiceRegistry; @@ -14,6 +24,9 @@ class ServiceRegistry; // Embedder API for participating in renderer logic. class CONTENT_EXPORT ContentUtilityClient { public: + using StaticMojoApplicationMap = + std::map<GURL, base::Callback<scoped_ptr<mojo::ApplicationDelegate>()>>; + virtual ~ContentUtilityClient() {} // Notifies us that the UtilityThread has been created. @@ -24,6 +37,9 @@ class CONTENT_EXPORT ContentUtilityClient { // Registers Mojo services. virtual void RegisterMojoServices(ServiceRegistry* registry) {} + + // Registers Mojo applications. + virtual void RegisterMojoApplications(StaticMojoApplicationMap* apps) {} }; } // namespace content diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 6066718..d505da3 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn @@ -170,6 +170,8 @@ static_library("content_shell_lib") { "renderer/shell_content_renderer_client.h", "renderer/shell_render_view_observer.cc", "renderer/shell_render_view_observer.h", + "utility/shell_content_utility_client.cc", + "utility/shell_content_utility_client.h", ] # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc index 42fb382..5858071 100644 --- a/content/shell/app/shell_main_delegate.cc +++ b/content/shell/app/shell_main_delegate.cc @@ -27,6 +27,7 @@ #include "content/shell/common/shell_switches.h" #include "content/shell/renderer/layout_test/layout_test_content_renderer_client.h" #include "content/shell/renderer/shell_content_renderer_client.h" +#include "content/shell/utility/shell_content_utility_client.h" #include "media/base/media_switches.h" #include "media/base/mime_util.h" #include "net/cookies/cookie_monster.h" @@ -346,4 +347,9 @@ ContentRendererClient* ShellMainDelegate::CreateContentRendererClient() { return renderer_client_.get(); } +ContentUtilityClient* ShellMainDelegate::CreateContentUtilityClient() { + utility_client_.reset(new ShellContentUtilityClient); + return utility_client_.get(); +} + } // namespace content diff --git a/content/shell/app/shell_main_delegate.h b/content/shell/app/shell_main_delegate.h index 930009c..f8439bc 100644 --- a/content/shell/app/shell_main_delegate.h +++ b/content/shell/app/shell_main_delegate.h @@ -13,6 +13,7 @@ namespace content { class ShellContentBrowserClient; class ShellContentRendererClient; +class ShellContentUtilityClient; #if defined(OS_ANDROID) class BrowserMainRunner; @@ -33,12 +34,14 @@ class ShellMainDelegate : public ContentMainDelegate { #endif ContentBrowserClient* CreateContentBrowserClient() override; ContentRendererClient* CreateContentRendererClient() override; + ContentUtilityClient* CreateContentUtilityClient() override; static void InitializeResourceBundle(); private: scoped_ptr<ShellContentBrowserClient> browser_client_; scoped_ptr<ShellContentRendererClient> renderer_client_; + scoped_ptr<ShellContentUtilityClient> utility_client_; ShellContentClient content_client_; #if defined(OS_ANDROID) diff --git a/content/shell/utility/DEPS b/content/shell/utility/DEPS new file mode 100644 index 0000000..72513eb --- /dev/null +++ b/content/shell/utility/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+mojo/shell", +] diff --git a/content/shell/utility/shell_content_utility_client.cc b/content/shell/utility/shell_content_utility_client.cc new file mode 100644 index 0000000..d6c2982 --- /dev/null +++ b/content/shell/utility/shell_content_utility_client.cc @@ -0,0 +1,31 @@ +// 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/shell/utility/shell_content_utility_client.h" + +#include "base/bind.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/test/test_mojo_app.h" +#include "mojo/shell/static_application_loader.h" + +namespace content { + +namespace { + +scoped_ptr<mojo::ApplicationDelegate> CreateTestApp() { + return scoped_ptr<mojo::ApplicationDelegate>(new TestMojoApp); +} + +} // namespace + +ShellContentUtilityClient::~ShellContentUtilityClient() { +} + +void ShellContentUtilityClient::RegisterMojoApplications( + StaticMojoApplicationMap* apps) { + apps->insert( + std::make_pair(GURL(kTestMojoAppUrl), base::Bind(&CreateTestApp))); +} + +} // namespace content diff --git a/content/shell/utility/shell_content_utility_client.h b/content/shell/utility/shell_content_utility_client.h new file mode 100644 index 0000000..2479f58 --- /dev/null +++ b/content/shell/utility/shell_content_utility_client.h @@ -0,0 +1,22 @@ +// 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. + +#ifndef CONTENT_SHELL_UTILITY_SHELL_CONTENT_UTILITY_CLIENT_H_ +#define CONTENT_SHELL_UTILITY_SHELL_CONTENT_UTILITY_CLIENT_H_ + +#include "content/public/utility/content_utility_client.h" + +namespace content { + +class ShellContentUtilityClient : public ContentUtilityClient { + public: + ~ShellContentUtilityClient() override; + + // ContentUtilityClient: + void RegisterMojoApplications(StaticMojoApplicationMap* apps) override; +}; + +} // namespace content + +#endif // CONTENT_SHELL_UTILITY_SHELL_CONTENT_UTILITY_CLIENT_H_ diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 848dea1..c254b4e 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn @@ -55,6 +55,7 @@ source_set("test_support") { public_deps += [ "//third_party/WebKit/public:blink" ] deps += [ + ":content_test_mojo_bindings", "//components/scheduler:scheduler", "//components/scheduler:test_support", "//content/browser/speech/proto", @@ -68,6 +69,8 @@ source_set("test_support") { "//cc:test_support", "//ipc/mojo", "//media", + "//mojo/application/public/cpp:cpp_for_chromium", + "//mojo/environment:chromium", "//ppapi/host", "//ppapi/proxy", "//ppapi/proxy:test_support", @@ -201,6 +204,12 @@ source_set("browsertest_support") { } } +mojom("content_test_mojo_bindings") { + sources = [ + "../public/test/test_mojo_service.mojom", + ] +} + mojom("web_ui_test_mojo_bindings") { sources = [ "data/web_ui_test_mojo_bindings.mojom", @@ -279,6 +288,7 @@ if (!is_mac) { "//media/audio:test_support", "//media/base:test_support", "//media:shared_memory_support", + "//mojo/application/public/cpp:cpp_for_chromium", "//mojo/environment:chromium", "//net:test_support", "//ppapi/host", diff --git a/content/utility/BUILD.gn b/content/utility/BUILD.gn index 5767b98..93dae8f 100644 --- a/content/utility/BUILD.gn +++ b/content/utility/BUILD.gn @@ -19,8 +19,14 @@ source_set("utility") { "//content:export", "//content/public/child:child_sources", "//content/public/common:common_sources", + "//content/public/common:mojo_bindings", "//courgette:courgette_lib", + "//mojo/application/public/cpp:cpp_for_chromium", "//mojo/application/public/interfaces", + "//mojo/common", + "//mojo/shell", "//third_party/WebKit/public:blink_headers", + "//third_party/mojo/src/mojo/public/cpp/bindings", + "//url", ] } diff --git a/content/utility/DEPS b/content/utility/DEPS index 47166e2..8b49f0f 100644 --- a/content/utility/DEPS +++ b/content/utility/DEPS @@ -2,5 +2,7 @@ include_rules = [ "+components/scheduler/child", "+content/child", "+content/public/utility", + "+mojo/application", + "+mojo/shell", "+sandbox/win/src", ] diff --git a/content/utility/utility_process_control_impl.cc b/content/utility/utility_process_control_impl.cc new file mode 100644 index 0000000..5d12a2e --- /dev/null +++ b/content/utility/utility_process_control_impl.cc @@ -0,0 +1,54 @@ +// 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/utility/utility_process_control_impl.h" + +#include "base/bind.h" +#include "base/stl_util.h" +#include "content/public/common/content_client.h" +#include "content/public/utility/content_utility_client.h" +#include "content/public/utility/utility_thread.h" +#include "mojo/shell/static_application_loader.h" +#include "url/gurl.h" + +namespace content { + +namespace { + +// Called when a static application terminates. +void QuitProcess() { + UtilityThread::Get()->ReleaseProcessIfNeeded(); +} + +} // namespace + +UtilityProcessControlImpl::UtilityProcessControlImpl() { + ContentUtilityClient::StaticMojoApplicationMap apps; + GetContentClient()->utility()->RegisterMojoApplications(&apps); + for (const auto& entry : apps) { + url_to_loader_map_[entry.first] = new mojo::shell::StaticApplicationLoader( + entry.second, base::Bind(&QuitProcess)); + } +} + +UtilityProcessControlImpl::~UtilityProcessControlImpl() { + STLDeleteValues(&url_to_loader_map_); +} + +void UtilityProcessControlImpl::LoadApplication( + const mojo::String& url, + mojo::InterfaceRequest<mojo::Application> request, + const LoadApplicationCallback& callback) { + GURL application_url = GURL(url.To<std::string>()); + auto it = url_to_loader_map_.find(application_url); + if (it == url_to_loader_map_.end()) { + callback.Run(false); + return; + } + + callback.Run(true); + it->second->Load(application_url, request.Pass()); +} + +} // namespace content diff --git a/content/utility/utility_process_control_impl.h b/content/utility/utility_process_control_impl.h new file mode 100644 index 0000000..dcc0a4d --- /dev/null +++ b/content/utility/utility_process_control_impl.h @@ -0,0 +1,48 @@ +// 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. + +#ifndef UTILITY_PROCESS_CONTROL_IMPL_H_ +#define UTILITY_PROCESS_CONTROL_IMPL_H_ + +#include <map> + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "content/common/process_control.mojom.h" +#include "mojo/application/public/interfaces/application.mojom.h" +#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" + +class GURL; + +namespace mojo { +namespace shell { +class ApplicationLoader; +} // namespace shell +} // namespace mojo + +namespace content { + +// Implementation of the ProcessControl interface. Exposed to the browser via +// the utility process's ServiceRegistry. +class UtilityProcessControlImpl : public ProcessControl { + public: + UtilityProcessControlImpl(); + ~UtilityProcessControlImpl() override; + + using URLToLoaderMap = std::map<GURL, mojo::shell::ApplicationLoader*>; + + // ProcessControl: + void LoadApplication(const mojo::String& url, + mojo::InterfaceRequest<mojo::Application> request, + const LoadApplicationCallback& callback) override; + + private: + URLToLoaderMap url_to_loader_map_; + + DISALLOW_COPY_AND_ASSIGN(UtilityProcessControlImpl); +}; + +} // namespace content + +#endif // UTILITY_PROCESS_CONTROL_IMPL_H_ diff --git a/content/utility/utility_thread_impl.cc b/content/utility/utility_thread_impl.cc index 1a020ea..00ebc6e 100644 --- a/content/utility/utility_thread_impl.cc +++ b/content/utility/utility_thread_impl.cc @@ -15,6 +15,7 @@ #include "content/public/common/content_switches.h" #include "content/public/utility/content_utility_client.h" #include "content/utility/utility_blink_platform_impl.h" +#include "content/utility/utility_process_control_impl.h" #include "ipc/ipc_sync_channel.h" #include "third_party/WebKit/public/web/WebKit.h" @@ -85,6 +86,11 @@ void UtilityThreadImpl::Init() { blink::initialize(blink_platform_impl_.get()); } GetContentClient()->utility()->UtilityThreadStarted(); + + process_control_.reset(new UtilityProcessControlImpl); + service_registry()->AddService(base::Bind( + &UtilityThreadImpl::BindProcessControlRequest, base::Unretained(this))); + GetContentClient()->utility()->RegisterMojoServices(service_registry()); } @@ -135,4 +141,10 @@ void UtilityThreadImpl::OnLoadPlugins( } #endif +void UtilityThreadImpl::BindProcessControlRequest( + mojo::InterfaceRequest<ProcessControl> request) { + DCHECK(process_control_); + process_control_bindings_.AddBinding(process_control_.get(), request.Pass()); +} + } // namespace content diff --git a/content/utility/utility_thread_impl.h b/content/utility/utility_thread_impl.h index 3b1d66d..74908ca 100644 --- a/content/utility/utility_thread_impl.h +++ b/content/utility/utility_thread_impl.h @@ -10,9 +10,12 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "content/child/child_thread_impl.h" #include "content/common/content_export.h" +#include "content/common/process_control.mojom.h" #include "content/public/utility/utility_thread.h" +#include "mojo/common/weak_binding_set.h" namespace base { class FilePath; @@ -21,6 +24,7 @@ class FilePath; namespace content { class BlinkPlatformImpl; class UtilityBlinkPlatformImpl; +class UtilityProcessControlImpl; #if defined(COMPILER_MSVC) // See explanation for other RenderViewHostImpl which is the same issue. @@ -54,11 +58,20 @@ class UtilityThreadImpl : public UtilityThread, void OnLoadPlugins(const std::vector<base::FilePath>& plugin_paths); #endif + void BindProcessControlRequest( + mojo::InterfaceRequest<content::ProcessControl> request); + // True when we're running in batch mode. bool batch_mode_; scoped_ptr<UtilityBlinkPlatformImpl> blink_platform_impl_; + // Process control for Mojo application hosting. + scoped_ptr<UtilityProcessControlImpl> process_control_; + + // Bindings to the ProcessControl impl. + mojo::WeakBindingSet<ProcessControl> process_control_bindings_; + DISALLOW_COPY_AND_ASSIGN(UtilityThreadImpl); }; |