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