| 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 <memory> |
| 8 #include <string> |
| 8 #include <utility> | 9 #include <utility> |
| 9 | 10 |
| 10 #include "base/bind.h" | 11 #include "base/bind.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" | |
| 16 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 17 #include "base/threading/thread_task_runner_handle.h" | |
| 18 #include "content/browser/gpu/gpu_process_host.h" | 16 #include "content/browser/gpu/gpu_process_host.h" |
| 19 #include "content/common/mojo/constants.h" | 17 #include "content/common/mojo/constants.h" |
| 20 #include "content/common/mojo/mojo_shell_connection_impl.h" | |
| 21 #include "content/common/process_control.mojom.h" | 18 #include "content/common/process_control.mojom.h" |
| 22 #include "content/grit/content_resources.h" | 19 #include "content/grit/content_resources.h" |
| 23 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 24 #include "content/public/browser/content_browser_client.h" | 21 #include "content/public/browser/content_browser_client.h" |
| 25 #include "content/public/browser/utility_process_host.h" | 22 #include "content/public/browser/utility_process_host.h" |
| 26 #include "content/public/browser/utility_process_host_client.h" | 23 #include "content/public/browser/utility_process_host_client.h" |
| 27 #include "content/public/common/content_client.h" | 24 #include "content/public/common/content_client.h" |
| 28 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/mojo_shell_connection.h" |
| 29 #include "mojo/edk/embedder/embedder.h" | 26 #include "mojo/edk/embedder/embedder.h" |
| 30 #include "mojo/public/cpp/bindings/interface_request.h" | |
| 31 #include "mojo/public/cpp/bindings/string.h" | |
| 32 #include "services/catalog/catalog.h" | 27 #include "services/catalog/catalog.h" |
| 33 #include "services/catalog/manifest_provider.h" | 28 #include "services/catalog/manifest_provider.h" |
| 34 #include "services/catalog/store.h" | 29 #include "services/catalog/store.h" |
| 35 #include "services/shell/connect_params.h" | 30 #include "services/shell/connect_params.h" |
| 36 #include "services/shell/native_runner.h" | 31 #include "services/shell/native_runner.h" |
| 37 #include "services/shell/public/cpp/connector.h" | 32 #include "services/shell/public/cpp/connector.h" |
| 38 #include "services/shell/public/cpp/identity.h" | |
| 39 #include "services/shell/public/cpp/service.h" | 33 #include "services/shell/public/cpp/service.h" |
| 40 #include "services/shell/public/interfaces/connector.mojom.h" | |
| 41 #include "services/shell/public/interfaces/service.mojom.h" | 34 #include "services/shell/public/interfaces/service.mojom.h" |
| 42 #include "services/shell/public/interfaces/service_factory.mojom.h" | |
| 43 #include "services/shell/runner/common/client_util.h" | 35 #include "services/shell/runner/common/client_util.h" |
| 44 #include "services/shell/runner/host/in_process_native_runner.h" | 36 #include "services/shell/runner/host/in_process_native_runner.h" |
| 37 #include "services/shell/service_manager.h" |
| 45 #include "services/user/public/cpp/constants.h" | 38 #include "services/user/public/cpp/constants.h" |
| 46 | 39 |
| 47 namespace content { | 40 namespace content { |
| 48 | 41 |
| 49 namespace { | 42 namespace { |
| 50 | 43 |
| 51 base::LazyInstance<std::unique_ptr<shell::Connector>>::Leaky | 44 base::LazyInstance<std::unique_ptr<shell::Connector>>::Leaky |
| 52 g_io_thread_connector = LAZY_INSTANCE_INITIALIZER; | 45 g_io_thread_connector = LAZY_INSTANCE_INITIALIZER; |
| 53 | 46 |
| 54 void DestroyConnectorOnIOThread() { g_io_thread_connector.Get().reset(); } | 47 void DestroyConnectorOnIOThread() { g_io_thread_connector.Get().reset(); } |
| 55 | 48 |
| 56 void StartUtilityProcessOnIOThread( | 49 void StartUtilityProcessOnIOThread(mojom::ProcessControlRequest request, |
| 57 mojo::InterfaceRequest<mojom::ProcessControl> request, | 50 const base::string16& process_name, |
| 58 const base::string16& process_name, | 51 bool use_sandbox) { |
| 59 bool use_sandbox) { | |
| 60 UtilityProcessHost* process_host = | 52 UtilityProcessHost* process_host = |
| 61 UtilityProcessHost::Create(nullptr, nullptr); | 53 UtilityProcessHost::Create(nullptr, nullptr); |
| 62 process_host->SetName(process_name); | 54 process_host->SetName(process_name); |
| 63 if (!use_sandbox) | 55 if (!use_sandbox) |
| 64 process_host->DisableSandbox(); | 56 process_host->DisableSandbox(); |
| 65 process_host->Start(); | 57 process_host->Start(); |
| 66 | 58 |
| 67 process_host->GetRemoteInterfaces()->GetInterface(std::move(request)); | 59 process_host->GetRemoteInterfaces()->GetInterface(std::move(request)); |
| 68 } | 60 } |
| 69 | 61 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 mojo::GetProxy(&process_control); | 107 mojo::GetProxy(&process_control); |
| 116 BrowserThread::PostTask( | 108 BrowserThread::PostTask( |
| 117 BrowserThread::IO, FROM_HERE, | 109 BrowserThread::IO, FROM_HERE, |
| 118 base::Bind(&RequestGpuProcessControl, base::Passed(&process_request))); | 110 base::Bind(&RequestGpuProcessControl, base::Passed(&process_request))); |
| 119 process_control->LoadApplication(app_name, std::move(request), | 111 process_control->LoadApplication(app_name, std::move(request), |
| 120 base::Bind(&OnApplicationLoaded, app_name)); | 112 base::Bind(&OnApplicationLoaded, app_name)); |
| 121 } | 113 } |
| 122 | 114 |
| 123 #endif // ENABLE_MOJO_MEDIA_IN_GPU_PROCESS | 115 #endif // ENABLE_MOJO_MEDIA_IN_GPU_PROCESS |
| 124 | 116 |
| 125 } // namespace | |
| 126 | |
| 127 // A ManifestProvider which resolves application names to builtin manifest | 117 // A ManifestProvider which resolves application names to builtin manifest |
| 128 // resources for the catalog service to consume. | 118 // resources for the catalog service to consume. |
| 129 class MojoShellContext::BuiltinManifestProvider | 119 class BuiltinManifestProvider : public catalog::ManifestProvider { |
| 130 : public catalog::ManifestProvider { | |
| 131 public: | 120 public: |
| 132 BuiltinManifestProvider() {} | 121 BuiltinManifestProvider() {} |
| 133 ~BuiltinManifestProvider() override {} | 122 ~BuiltinManifestProvider() override {} |
| 134 | 123 |
| 135 void AddManifestResource(const std::string& name, int resource_id) { | 124 void AddManifests(std::unique_ptr< |
| 136 auto result = manifest_resources_.insert( | 125 ContentBrowserClient::MojoApplicationManifestMap> manifests) { |
| 137 std::make_pair(name, resource_id)); | 126 DCHECK(!manifests_); |
| 138 DCHECK(result.second); | 127 manifests_ = std::move(manifests); |
| 139 } | 128 } |
| 140 | 129 |
| 141 void AddManifests(std::unique_ptr< | 130 void AddManifestResource(const std::string& name, int resource_id) { |
| 142 ContentBrowserClient::MojoApplicationManifestMap> manifests) { | 131 std::string contents = GetContentClient()->GetDataResource( |
| 143 manifests_ = std::move(manifests); | 132 resource_id, ui::ScaleFactor::SCALE_FACTOR_NONE).as_string(); |
| 133 DCHECK(!contents.empty()); |
| 134 |
| 135 DCHECK(manifests_); |
| 136 auto result = manifests_->insert(std::make_pair(name, contents)); |
| 137 DCHECK(result.second) << "Duplicate manifest entry: " << name; |
| 144 } | 138 } |
| 145 | 139 |
| 146 private: | 140 private: |
| 147 // catalog::ManifestProvider: | 141 // catalog::ManifestProvider: |
| 148 bool GetApplicationManifest(const base::StringPiece& name, | 142 bool GetApplicationManifest(const base::StringPiece& name, |
| 149 std::string* manifest_contents) override { | 143 std::string* manifest_contents) override { |
| 150 auto it = manifest_resources_.find(name.as_string()); | |
| 151 if (it != manifest_resources_.end()) { | |
| 152 *manifest_contents = | |
| 153 GetContentClient() | |
| 154 ->GetDataResource(it->second, ui::ScaleFactor::SCALE_FACTOR_NONE) | |
| 155 .as_string(); | |
| 156 DCHECK(!manifest_contents->empty()); | |
| 157 return true; | |
| 158 } | |
| 159 auto manifest_it = manifests_->find(name.as_string()); | 144 auto manifest_it = manifests_->find(name.as_string()); |
| 160 if (manifest_it != manifests_->end()) { | 145 if (manifest_it != manifests_->end()) { |
| 161 *manifest_contents = manifest_it->second; | 146 *manifest_contents = manifest_it->second; |
| 162 DCHECK(!manifest_contents->empty()); | 147 DCHECK(!manifest_contents->empty()); |
| 163 return true; | 148 return true; |
| 164 } | 149 } |
| 165 return false; | 150 return false; |
| 166 } | 151 } |
| 167 | 152 |
| 168 std::unordered_map<std::string, int> manifest_resources_; | |
| 169 std::unique_ptr<ContentBrowserClient::MojoApplicationManifestMap> manifests_; | 153 std::unique_ptr<ContentBrowserClient::MojoApplicationManifestMap> manifests_; |
| 170 | 154 |
| 171 DISALLOW_COPY_AND_ASSIGN(BuiltinManifestProvider); | 155 DISALLOW_COPY_AND_ASSIGN(BuiltinManifestProvider); |
| 172 }; | 156 }; |
| 173 | 157 |
| 158 } // namespace |
| 159 |
| 160 // State which lives on the IO thread and drives the ServiceManager. |
| 161 class MojoShellContext::InProcessServiceManagerContext |
| 162 : public base::RefCountedThreadSafe<InProcessServiceManagerContext> { |
| 163 public: |
| 164 InProcessServiceManagerContext() {} |
| 165 |
| 166 shell::mojom::ServiceRequest Start( |
| 167 std::unique_ptr<BuiltinManifestProvider> manifest_provider) { |
| 168 shell::mojom::ServicePtr embedder_service_proxy; |
| 169 shell::mojom::ServiceRequest embedder_service_request = |
| 170 mojo::GetProxy(&embedder_service_proxy); |
| 171 shell::mojom::ServicePtrInfo embedder_service_proxy_info = |
| 172 embedder_service_proxy.PassInterface(); |
| 173 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)->PostTask( |
| 174 FROM_HERE, |
| 175 base::Bind(&InProcessServiceManagerContext::StartOnIOThread, this, |
| 176 base::Passed(&manifest_provider), |
| 177 base::Passed(&embedder_service_proxy_info))); |
| 178 return embedder_service_request; |
| 179 } |
| 180 |
| 181 void ShutDown() { |
| 182 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)->PostTask( |
| 183 FROM_HERE, |
| 184 base::Bind(&InProcessServiceManagerContext::ShutDownOnIOThread, this)); |
| 185 } |
| 186 |
| 187 private: |
| 188 friend class base::RefCountedThreadSafe<InProcessServiceManagerContext>; |
| 189 |
| 190 ~InProcessServiceManagerContext() {} |
| 191 |
| 192 void StartOnIOThread( |
| 193 std::unique_ptr<BuiltinManifestProvider> manifest_provider, |
| 194 shell::mojom::ServicePtrInfo embedder_service_proxy_info) { |
| 195 manifest_provider_ = std::move(manifest_provider); |
| 196 |
| 197 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner = |
| 198 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE); |
| 199 std::unique_ptr<shell::NativeRunnerFactory> native_runner_factory( |
| 200 new shell::InProcessNativeRunnerFactory( |
| 201 BrowserThread::GetBlockingPool())); |
| 202 catalog_.reset(new catalog::Catalog( |
| 203 file_task_runner.get(), nullptr, manifest_provider_.get())); |
| 204 service_manager_.reset(new shell::ServiceManager( |
| 205 std::move(native_runner_factory), catalog_->TakeService())); |
| 206 |
| 207 shell::mojom::ServiceRequest request = |
| 208 service_manager_->StartEmbedderService(kBrowserMojoApplicationName); |
| 209 mojo::FuseInterface( |
| 210 std::move(request), std::move(embedder_service_proxy_info)); |
| 211 } |
| 212 |
| 213 void ShutDownOnIOThread() { |
| 214 service_manager_.reset(); |
| 215 catalog_.reset(); |
| 216 manifest_provider_.reset(); |
| 217 } |
| 218 |
| 219 std::unique_ptr<BuiltinManifestProvider> manifest_provider_; |
| 220 std::unique_ptr<catalog::Catalog> catalog_; |
| 221 std::unique_ptr<shell::ServiceManager> service_manager_; |
| 222 |
| 223 DISALLOW_COPY_AND_ASSIGN(InProcessServiceManagerContext); |
| 224 }; |
| 225 |
| 226 |
| 174 MojoShellContext::MojoShellContext() { | 227 MojoShellContext::MojoShellContext() { |
| 175 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner = | |
| 176 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE); | |
| 177 std::unique_ptr<shell::NativeRunnerFactory> native_runner_factory( | |
| 178 new shell::InProcessNativeRunnerFactory( | |
| 179 BrowserThread::GetBlockingPool())); | |
| 180 | |
| 181 // Allow the embedder to register additional Mojo application manifests | |
| 182 // beyond the default ones below. | |
| 183 std::unique_ptr<ContentBrowserClient::MojoApplicationManifestMap> manifests( | |
| 184 new ContentBrowserClient::MojoApplicationManifestMap); | |
| 185 GetContentClient()->browser()->RegisterMojoApplicationManifests( | |
| 186 manifests.get()); | |
| 187 | |
| 188 manifest_provider_.reset(new BuiltinManifestProvider); | |
| 189 manifest_provider_->AddManifests(std::move(manifests)); | |
| 190 manifest_provider_->AddManifestResource(kBrowserMojoApplicationName, | |
| 191 IDR_MOJO_CONTENT_BROWSER_MANIFEST); | |
| 192 manifest_provider_->AddManifestResource(kGpuMojoApplicationName, | |
| 193 IDR_MOJO_CONTENT_GPU_MANIFEST); | |
| 194 manifest_provider_->AddManifestResource(kRendererMojoApplicationName, | |
| 195 IDR_MOJO_CONTENT_RENDERER_MANIFEST); | |
| 196 manifest_provider_->AddManifestResource(kUtilityMojoApplicationName, | |
| 197 IDR_MOJO_CONTENT_UTILITY_MANIFEST); | |
| 198 manifest_provider_->AddManifestResource("mojo:catalog", | |
| 199 IDR_MOJO_CATALOG_MANIFEST); | |
| 200 manifest_provider_->AddManifestResource(user_service::kUserServiceName, | |
| 201 IDR_MOJO_PROFILE_MANIFEST); | |
| 202 | |
| 203 catalog_.reset(new catalog::Catalog(file_task_runner.get(), nullptr, | |
| 204 manifest_provider_.get())); | |
| 205 | |
| 206 shell::mojom::ServiceRequest request; | 228 shell::mojom::ServiceRequest request; |
| 207 if (shell::ShellIsRemote()) { | 229 if (shell::ShellIsRemote()) { |
| 208 mojo::edk::SetParentPipeHandleFromCommandLine(); | 230 mojo::edk::SetParentPipeHandleFromCommandLine(); |
| 209 request = shell::GetServiceRequestFromCommandLine(); | 231 request = shell::GetServiceRequestFromCommandLine(); |
| 210 } else { | 232 } else { |
| 211 service_manager_.reset(new shell::ServiceManager( | 233 // Allow the embedder to register additional Mojo application manifests |
| 212 std::move(native_runner_factory), catalog_->TakeService())); | 234 // beyond the default ones below. |
| 213 request = | 235 std::unique_ptr<ContentBrowserClient::MojoApplicationManifestMap> manifests( |
| 214 service_manager_->StartEmbedderService(kBrowserMojoApplicationName); | 236 new ContentBrowserClient::MojoApplicationManifestMap); |
| 237 GetContentClient()->browser()->RegisterMojoApplicationManifests( |
| 238 manifests.get()); |
| 239 std::unique_ptr<BuiltinManifestProvider> manifest_provider = |
| 240 base::MakeUnique<BuiltinManifestProvider>(); |
| 241 manifest_provider->AddManifests(std::move(manifests)); |
| 242 manifest_provider->AddManifestResource(kBrowserMojoApplicationName, |
| 243 IDR_MOJO_CONTENT_BROWSER_MANIFEST); |
| 244 manifest_provider->AddManifestResource(kGpuMojoApplicationName, |
| 245 IDR_MOJO_CONTENT_GPU_MANIFEST); |
| 246 manifest_provider->AddManifestResource(kRendererMojoApplicationName, |
| 247 IDR_MOJO_CONTENT_RENDERER_MANIFEST); |
| 248 manifest_provider->AddManifestResource(kUtilityMojoApplicationName, |
| 249 IDR_MOJO_CONTENT_UTILITY_MANIFEST); |
| 250 manifest_provider->AddManifestResource("mojo:catalog", |
| 251 IDR_MOJO_CATALOG_MANIFEST); |
| 252 manifest_provider->AddManifestResource(user_service::kUserServiceName, |
| 253 IDR_MOJO_PROFILE_MANIFEST); |
| 254 |
| 255 in_process_context_ = new InProcessServiceManagerContext; |
| 256 request = in_process_context_->Start(std::move(manifest_provider)); |
| 215 } | 257 } |
| 216 MojoShellConnection::SetForProcess(MojoShellConnection::Create( | 258 MojoShellConnection::SetForProcess(MojoShellConnection::Create( |
| 217 std::move(request), | 259 std::move(request), |
| 218 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))); | 260 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))); |
| 219 | 261 |
| 220 ContentBrowserClient::StaticMojoApplicationMap apps; | 262 ContentBrowserClient::StaticMojoApplicationMap apps; |
| 221 GetContentClient()->browser()->RegisterInProcessMojoApplications(&apps); | 263 GetContentClient()->browser()->RegisterInProcessMojoApplications(&apps); |
| 222 for (const auto& entry : apps) { | 264 for (const auto& entry : apps) { |
| 223 MojoShellConnection::GetForProcess()->AddEmbeddedService(entry.first, | 265 MojoShellConnection::GetForProcess()->AddEmbeddedService(entry.first, |
| 224 entry.second); | 266 entry.second); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 MojoShellConnection::GetForProcess()->AddServiceRequestHandler( | 299 MojoShellConnection::GetForProcess()->AddServiceRequestHandler( |
| 258 "mojo:media", base::Bind(&LaunchAppInGpuProcess, "mojo:media")); | 300 "mojo:media", base::Bind(&LaunchAppInGpuProcess, "mojo:media")); |
| 259 #endif | 301 #endif |
| 260 } | 302 } |
| 261 | 303 |
| 262 MojoShellContext::~MojoShellContext() { | 304 MojoShellContext::~MojoShellContext() { |
| 263 if (MojoShellConnection::GetForProcess()) | 305 if (MojoShellConnection::GetForProcess()) |
| 264 MojoShellConnection::DestroyForProcess(); | 306 MojoShellConnection::DestroyForProcess(); |
| 265 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 307 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 266 base::Bind(&DestroyConnectorOnIOThread)); | 308 base::Bind(&DestroyConnectorOnIOThread)); |
| 267 catalog_.reset(); | 309 if (in_process_context_) |
| 310 in_process_context_->ShutDown(); |
| 268 } | 311 } |
| 269 | 312 |
| 270 // static | 313 // static |
| 271 shell::Connector* MojoShellContext::GetConnectorForIOThread() { | 314 shell::Connector* MojoShellContext::GetConnectorForIOThread() { |
| 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 273 return g_io_thread_connector.Get().get(); | 316 return g_io_thread_connector.Get().get(); |
| 274 } | 317 } |
| 275 | 318 |
| 276 } // namespace content | 319 } // namespace content |
| OLD | NEW |