| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/mojo/mojo_shell_context.h" | 5 #include "content/browser/mojo/mojo_shell_context.h" |
| 6 | 6 |
| 7 #include <unordered_map> | 7 #include <unordered_map> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/path_service.h" | 15 #include "base/path_service.h" |
| 16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
| 18 #include "content/browser/gpu/gpu_process_host.h" | 18 #include "content/browser/gpu/gpu_process_host.h" |
| 19 #include "content/browser/mojo/browser_shell_connection.h" |
| 19 #include "content/browser/mojo/constants.h" | 20 #include "content/browser/mojo/constants.h" |
| 20 #include "content/common/gpu_process_launch_causes.h" | 21 #include "content/common/gpu_process_launch_causes.h" |
| 21 #include "content/common/mojo/mojo_shell_connection_impl.h" | 22 #include "content/common/mojo/mojo_shell_connection_impl.h" |
| 22 #include "content/common/mojo/static_loader.h" | |
| 23 #include "content/common/process_control.mojom.h" | 23 #include "content/common/process_control.mojom.h" |
| 24 #include "content/grit/content_resources.h" | 24 #include "content/grit/content_resources.h" |
| 25 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 26 #include "content/public/browser/content_browser_client.h" | 26 #include "content/public/browser/content_browser_client.h" |
| 27 #include "content/public/browser/utility_process_host.h" | 27 #include "content/public/browser/utility_process_host.h" |
| 28 #include "content/public/browser/utility_process_host_client.h" | 28 #include "content/public/browser/utility_process_host_client.h" |
| 29 #include "content/public/common/content_client.h" | 29 #include "content/public/common/content_client.h" |
| 30 #include "content/public/common/content_switches.h" | 30 #include "content/public/common/content_switches.h" |
| 31 #include "content/public/common/service_registry.h" | 31 #include "content/public/common/service_registry.h" |
| 32 #include "mojo/public/cpp/bindings/interface_request.h" | 32 #include "mojo/public/cpp/bindings/interface_request.h" |
| 33 #include "mojo/public/cpp/bindings/string.h" | 33 #include "mojo/public/cpp/bindings/string.h" |
| 34 #include "services/catalog/factory.h" | 34 #include "services/catalog/factory.h" |
| 35 #include "services/catalog/manifest_provider.h" | 35 #include "services/catalog/manifest_provider.h" |
| 36 #include "services/catalog/store.h" | 36 #include "services/catalog/store.h" |
| 37 #include "services/shell/connect_params.h" | 37 #include "services/shell/connect_params.h" |
| 38 #include "services/shell/loader.h" | |
| 39 #include "services/shell/native_runner.h" | 38 #include "services/shell/native_runner.h" |
| 40 #include "services/shell/public/cpp/identity.h" | 39 #include "services/shell/public/cpp/identity.h" |
| 41 #include "services/shell/public/cpp/shell_client.h" | 40 #include "services/shell/public/cpp/shell_client.h" |
| 42 #include "services/shell/public/interfaces/connector.mojom.h" | 41 #include "services/shell/public/interfaces/connector.mojom.h" |
| 42 #include "services/shell/public/interfaces/shell_client.mojom.h" |
| 43 #include "services/shell/public/interfaces/shell_client_factory.mojom.h" |
| 43 #include "services/shell/runner/host/in_process_native_runner.h" | 44 #include "services/shell/runner/host/in_process_native_runner.h" |
| 44 #include "services/user/public/cpp/constants.h" | 45 #include "services/user/public/cpp/constants.h" |
| 45 | 46 |
| 46 namespace content { | 47 namespace content { |
| 47 | 48 |
| 48 namespace { | 49 namespace { |
| 49 | 50 |
| 50 // An extra set of apps to register on initialization, if set by a test. | 51 // An extra set of apps to register on initialization, if set by a test. |
| 51 const MojoShellContext::StaticApplicationMap* g_applications_for_test; | 52 const MojoShellContext::StaticApplicationMap* g_applications_for_test; |
| 52 | 53 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 63 | 64 |
| 64 ServiceRegistry* services = process_host->GetServiceRegistry(); | 65 ServiceRegistry* services = process_host->GetServiceRegistry(); |
| 65 services->ConnectToRemoteService(std::move(request)); | 66 services->ConnectToRemoteService(std::move(request)); |
| 66 } | 67 } |
| 67 | 68 |
| 68 void OnApplicationLoaded(const std::string& name, bool success) { | 69 void OnApplicationLoaded(const std::string& name, bool success) { |
| 69 if (!success) | 70 if (!success) |
| 70 LOG(ERROR) << "Failed to launch Mojo application for " << name; | 71 LOG(ERROR) << "Failed to launch Mojo application for " << name; |
| 71 } | 72 } |
| 72 | 73 |
| 73 // This launches a utility process and forwards the Load request the | 74 void LaunchAppInUtilityProcess(const std::string& app_name, |
| 74 // mojom::ProcessControl service there. The utility process is sandboxed iff | 75 const base::string16& process_name, |
| 75 // |use_sandbox| is true. | 76 bool use_sandbox, |
| 76 class UtilityProcessLoader : public shell::Loader { | 77 shell::mojom::ShellClientRequest request) { |
| 77 public: | 78 mojom::ProcessControlPtr process_control; |
| 78 UtilityProcessLoader(const base::string16& process_name, bool use_sandbox) | 79 mojom::ProcessControlRequest process_request = |
| 79 : process_name_(process_name), use_sandbox_(use_sandbox) {} | 80 mojo::GetProxy(&process_control); |
| 80 ~UtilityProcessLoader() override {} | 81 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 81 | 82 base::Bind(&StartUtilityProcessOnIOThread, |
| 82 private: | 83 base::Passed(&process_request), |
| 83 // shell::Loader: | 84 process_name, use_sandbox)); |
| 84 void Load(const std::string& name, | 85 process_control->LoadApplication(app_name, std::move(request), |
| 85 shell::mojom::ShellClientRequest request) override { | 86 base::Bind(&OnApplicationLoaded, app_name)); |
| 86 mojom::ProcessControlPtr process_control; | 87 } |
| 87 auto process_request = mojo::GetProxy(&process_control); | |
| 88 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 89 base::Bind(&StartUtilityProcessOnIOThread, | |
| 90 base::Passed(&process_request), | |
| 91 process_name_, use_sandbox_)); | |
| 92 process_control->LoadApplication(name, std::move(request), | |
| 93 base::Bind(&OnApplicationLoaded, name)); | |
| 94 } | |
| 95 | |
| 96 const base::string16 process_name_; | |
| 97 const bool use_sandbox_; | |
| 98 | |
| 99 DISALLOW_COPY_AND_ASSIGN(UtilityProcessLoader); | |
| 100 }; | |
| 101 | 88 |
| 102 // Request mojom::ProcessControl from GPU process host. Must be called on IO | 89 // Request mojom::ProcessControl from GPU process host. Must be called on IO |
| 103 // thread. | 90 // thread. |
| 104 void RequestGpuProcessControl( | 91 void RequestGpuProcessControl( |
| 105 mojo::InterfaceRequest<mojom::ProcessControl> request) { | 92 mojo::InterfaceRequest<mojom::ProcessControl> request) { |
| 106 BrowserChildProcessHostDelegate* process_host = | 93 BrowserChildProcessHostDelegate* process_host = |
| 107 GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, | 94 GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, |
| 108 CAUSE_FOR_GPU_LAUNCH_MOJO_SETUP); | 95 CAUSE_FOR_GPU_LAUNCH_MOJO_SETUP); |
| 109 if (!process_host) { | 96 if (!process_host) { |
| 110 DLOG(ERROR) << "GPU process host not available."; | 97 DLOG(ERROR) << "GPU process host not available."; |
| 111 return; | 98 return; |
| 112 } | 99 } |
| 113 | 100 |
| 114 // TODO(xhwang): It's possible that |process_host| is non-null, but the actual | 101 // TODO(xhwang): It's possible that |process_host| is non-null, but the actual |
| 115 // process is dead. In that case, |request| will be dropped and application | 102 // process is dead. In that case, |request| will be dropped and application |
| 116 // load requests through mojom::ProcessControl will also fail. Make sure we | 103 // load requests through mojom::ProcessControl will also fail. Make sure we |
| 117 // handle | 104 // handle |
| 118 // these cases correctly. | 105 // these cases correctly. |
| 119 process_host->GetServiceRegistry()->ConnectToRemoteService( | 106 process_host->GetServiceRegistry()->ConnectToRemoteService( |
| 120 std::move(request)); | 107 std::move(request)); |
| 121 } | 108 } |
| 122 | 109 |
| 123 // Forwards the load request to the GPU process. | 110 void LaunchAppInGpuProcess(const std::string& app_name, |
| 124 class GpuProcessLoader : public shell::Loader { | 111 shell::mojom::ShellClientRequest request) { |
| 125 public: | 112 mojom::ProcessControlPtr process_control; |
| 126 GpuProcessLoader() {} | 113 mojom::ProcessControlRequest process_request = |
| 127 ~GpuProcessLoader() override {} | 114 mojo::GetProxy(&process_control); |
| 128 | 115 BrowserThread::PostTask( |
| 129 private: | 116 BrowserThread::IO, FROM_HERE, |
| 130 // shell::Loader: | 117 base::Bind(&RequestGpuProcessControl, base::Passed(&process_request))); |
| 131 void Load(const std::string& name, | 118 process_control->LoadApplication(app_name, std::move(request), |
| 132 shell::mojom::ShellClientRequest request) override { | 119 base::Bind(&OnApplicationLoaded, app_name)); |
| 133 mojom::ProcessControlPtr process_control; | 120 } |
| 134 auto process_request = mojo::GetProxy(&process_control); | |
| 135 BrowserThread::PostTask( | |
| 136 BrowserThread::IO, FROM_HERE, | |
| 137 base::Bind(&RequestGpuProcessControl, base::Passed(&process_request))); | |
| 138 process_control->LoadApplication(name, std::move(request), | |
| 139 base::Bind(&OnApplicationLoaded, name)); | |
| 140 } | |
| 141 | |
| 142 DISALLOW_COPY_AND_ASSIGN(GpuProcessLoader); | |
| 143 }; | |
| 144 | 121 |
| 145 } // namespace | 122 } // namespace |
| 146 | 123 |
| 147 // A ManifestProvider which resolves application names to builtin manifest | 124 // A ManifestProvider which resolves application names to builtin manifest |
| 148 // resources for the catalog service to consume. | 125 // resources for the catalog service to consume. |
| 149 class MojoShellContext::BuiltinManifestProvider | 126 class MojoShellContext::BuiltinManifestProvider |
| 150 : public catalog::ManifestProvider { | 127 : public catalog::ManifestProvider { |
| 151 public: | 128 public: |
| 152 BuiltinManifestProvider() {} | 129 BuiltinManifestProvider() {} |
| 153 ~BuiltinManifestProvider() override {} | 130 ~BuiltinManifestProvider() override {} |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 } | 186 } |
| 210 } | 187 } |
| 211 | 188 |
| 212 private: | 189 private: |
| 213 MojoShellContext* shell_context_; | 190 MojoShellContext* shell_context_; |
| 214 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 191 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 215 | 192 |
| 216 DISALLOW_COPY_AND_ASSIGN(Proxy); | 193 DISALLOW_COPY_AND_ASSIGN(Proxy); |
| 217 }; | 194 }; |
| 218 | 195 |
| 196 // Used to attach an existing ShellClient instance as a listener on the global |
| 197 // MojoShellConnection. |
| 198 // TODO(rockot): Find a way to get rid of this. |
| 199 class ShellConnectionListener : public MojoShellConnection::Listener { |
| 200 public: |
| 201 ShellConnectionListener(std::unique_ptr<shell::ShellClient> client) |
| 202 : client_(std::move(client)) {} |
| 203 ~ShellConnectionListener() override {} |
| 204 |
| 205 private: |
| 206 // MojoShellConnection::Listener: |
| 207 bool AcceptConnection(shell::Connection* connection) override { |
| 208 return client_->AcceptConnection(connection); |
| 209 } |
| 210 |
| 211 std::unique_ptr<shell::ShellClient> client_; |
| 212 |
| 213 DISALLOW_COPY_AND_ASSIGN(ShellConnectionListener); |
| 214 }; |
| 215 |
| 219 // static | 216 // static |
| 220 base::LazyInstance<std::unique_ptr<MojoShellContext::Proxy>> | 217 base::LazyInstance<std::unique_ptr<MojoShellContext::Proxy>> |
| 221 MojoShellContext::proxy_ = LAZY_INSTANCE_INITIALIZER; | 218 MojoShellContext::proxy_ = LAZY_INSTANCE_INITIALIZER; |
| 222 | 219 |
| 223 void MojoShellContext::SetApplicationsForTest( | 220 void MojoShellContext::SetApplicationsForTest( |
| 224 const StaticApplicationMap* apps) { | 221 const StaticApplicationMap* apps) { |
| 225 g_applications_for_test = apps; | 222 g_applications_for_test = apps; |
| 226 } | 223 } |
| 227 | 224 |
| 228 MojoShellContext::MojoShellContext() { | 225 MojoShellContext::MojoShellContext() { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 242 manifest_provider_->AddManifestResource("mojo:catalog", | 239 manifest_provider_->AddManifestResource("mojo:catalog", |
| 243 IDR_MOJO_CATALOG_MANIFEST); | 240 IDR_MOJO_CATALOG_MANIFEST); |
| 244 manifest_provider_->AddManifestResource(user_service::kUserServiceName, | 241 manifest_provider_->AddManifestResource(user_service::kUserServiceName, |
| 245 IDR_MOJO_PROFILE_MANIFEST); | 242 IDR_MOJO_PROFILE_MANIFEST); |
| 246 | 243 |
| 247 catalog_.reset(new catalog::Factory(file_task_runner.get(), nullptr, | 244 catalog_.reset(new catalog::Factory(file_task_runner.get(), nullptr, |
| 248 manifest_provider_.get())); | 245 manifest_provider_.get())); |
| 249 shell_.reset(new shell::Shell(std::move(native_runner_factory), | 246 shell_.reset(new shell::Shell(std::move(native_runner_factory), |
| 250 catalog_->TakeShellClient())); | 247 catalog_->TakeShellClient())); |
| 251 | 248 |
| 249 if (!IsRunningInMojoShell()) { |
| 250 MojoShellConnection::Create( |
| 251 shell_->InitInstanceForEmbedder(kBrowserMojoApplicationName), |
| 252 false /* is_external */); |
| 253 } |
| 254 |
| 255 std::unique_ptr<BrowserShellConnection> browser_shell_connection( |
| 256 new BrowserShellConnection); |
| 257 |
| 252 StaticApplicationMap apps; | 258 StaticApplicationMap apps; |
| 253 GetContentClient()->browser()->RegisterInProcessMojoApplications(&apps); | 259 GetContentClient()->browser()->RegisterInProcessMojoApplications(&apps); |
| 254 if (g_applications_for_test) { | 260 if (g_applications_for_test) { |
| 255 // Add testing apps to the map, potentially overwriting whatever the | 261 // Add testing apps to the map, potentially overwriting whatever the |
| 256 // browser client registered. | 262 // browser client registered. |
| 257 for (const auto& entry : *g_applications_for_test) | 263 for (const auto& entry : *g_applications_for_test) |
| 258 apps[entry.first] = entry.second; | 264 apps[entry.first] = entry.second; |
| 259 } | 265 } |
| 260 for (const auto& entry : apps) { | 266 for (const auto& entry : apps) { |
| 261 shell_->SetLoaderForName(base::WrapUnique(new StaticLoader(entry.second)), | 267 browser_shell_connection->AddEmbeddedApplication( |
| 262 entry.first); | 268 entry.first, entry.second, nullptr); |
| 263 } | 269 } |
| 264 | 270 |
| 265 ContentBrowserClient::OutOfProcessMojoApplicationMap sandboxed_apps; | 271 ContentBrowserClient::OutOfProcessMojoApplicationMap sandboxed_apps; |
| 266 GetContentClient() | 272 GetContentClient() |
| 267 ->browser() | 273 ->browser() |
| 268 ->RegisterOutOfProcessMojoApplications(&sandboxed_apps); | 274 ->RegisterOutOfProcessMojoApplications(&sandboxed_apps); |
| 269 for (const auto& app : sandboxed_apps) { | 275 for (const auto& app : sandboxed_apps) { |
| 270 shell_->SetLoaderForName(base::WrapUnique(new UtilityProcessLoader( | 276 browser_shell_connection->AddShellClientRequestHandler( |
| 271 app.second, true /* use_sandbox */)), | 277 app.first, |
| 272 app.first); | 278 base::Bind(&LaunchAppInUtilityProcess, app.first, app.second, |
| 279 true /* use_sandbox */)); |
| 273 } | 280 } |
| 274 | 281 |
| 275 ContentBrowserClient::OutOfProcessMojoApplicationMap unsandboxed_apps; | 282 ContentBrowserClient::OutOfProcessMojoApplicationMap unsandboxed_apps; |
| 276 GetContentClient() | 283 GetContentClient() |
| 277 ->browser() | 284 ->browser() |
| 278 ->RegisterUnsandboxedOutOfProcessMojoApplications(&unsandboxed_apps); | 285 ->RegisterUnsandboxedOutOfProcessMojoApplications(&unsandboxed_apps); |
| 279 for (const auto& app : unsandboxed_apps) { | 286 for (const auto& app : unsandboxed_apps) { |
| 280 shell_->SetLoaderForName(base::WrapUnique(new UtilityProcessLoader( | 287 browser_shell_connection->AddShellClientRequestHandler( |
| 281 app.second, false /* use_sandbox */)), | 288 app.first, |
| 282 app.first); | 289 base::Bind(&LaunchAppInUtilityProcess, app.first, app.second, |
| 290 false /* use_sandbox */)); |
| 283 } | 291 } |
| 284 | 292 |
| 285 #if (ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 293 #if (ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 286 shell_->SetLoaderForName(base::WrapUnique(new GpuProcessLoader), | 294 browser_shell_connection->AddShellClientRequestHandler( |
| 287 "mojo:media"); | 295 "mojo:media", base::Bind(&LaunchAppInGpuProcess, "mojo:media")); |
| 288 #endif | 296 #endif |
| 289 | 297 |
| 290 if (!IsRunningInMojoShell()) { | 298 // Attach our ShellClientFactory implementation to the global connection. |
| 291 MojoShellConnection::Create( | 299 MojoShellConnection* shell_connection = MojoShellConnection::Get(); |
| 292 shell_->InitInstanceForEmbedder(kBrowserMojoApplicationName), | 300 CHECK(shell_connection); |
| 293 false /* is_external */); | 301 shell_connection->AddListener( |
| 294 } | 302 new ShellConnectionListener(std::move(browser_shell_connection))); |
| 295 } | 303 } |
| 296 | 304 |
| 297 MojoShellContext::~MojoShellContext() { | 305 MojoShellContext::~MojoShellContext() { |
| 298 if (!IsRunningInMojoShell()) | 306 if (!IsRunningInMojoShell()) |
| 299 MojoShellConnectionImpl::Destroy(); | 307 MojoShellConnectionImpl::Destroy(); |
| 300 } | 308 } |
| 301 | 309 |
| 302 // static | 310 // static |
| 303 void MojoShellContext::ConnectToApplication( | 311 void MojoShellContext::ConnectToApplication( |
| 304 const std::string& user_id, | 312 const std::string& user_id, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 323 shell::Identity source_id(requestor_name, user_id); | 331 shell::Identity source_id(requestor_name, user_id); |
| 324 params->set_source(source_id); | 332 params->set_source(source_id); |
| 325 params->set_target(shell::Identity(name, user_id)); | 333 params->set_target(shell::Identity(name, user_id)); |
| 326 params->set_remote_interfaces(std::move(request)); | 334 params->set_remote_interfaces(std::move(request)); |
| 327 params->set_local_interfaces(std::move(exposed_services)); | 335 params->set_local_interfaces(std::move(exposed_services)); |
| 328 params->set_connect_callback(callback); | 336 params->set_connect_callback(callback); |
| 329 shell_->Connect(std::move(params)); | 337 shell_->Connect(std::move(params)); |
| 330 } | 338 } |
| 331 | 339 |
| 332 } // namespace content | 340 } // namespace content |
| OLD | NEW |