Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: content/browser/service_manager/service_manager_context.cc

Issue 2695803004: Make browser process a singleton service (Closed)
Patch Set: . Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/service_manager/service_manager_context.h" 5 #include "content/browser/service_manager/service_manager_context.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/json/json_reader.h" 12 #include "base/json/json_reader.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/process/process_handle.h"
16 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
17 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
18 #include "content/browser/gpu/gpu_process_host.h" 19 #include "content/browser/gpu/gpu_process_host.h"
19 #include "content/browser/service_manager/merge_dictionary.h" 20 #include "content/browser/service_manager/merge_dictionary.h"
20 #include "content/common/service_manager/service_manager_connection_impl.h" 21 #include "content/common/service_manager/service_manager_connection_impl.h"
21 #include "content/grit/content_resources.h" 22 #include "content/grit/content_resources.h"
22 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/content_browser_client.h" 24 #include "content/public/browser/content_browser_client.h"
24 #include "content/public/browser/utility_process_host.h" 25 #include "content/public/browser/utility_process_host.h"
25 #include "content/public/browser/utility_process_host_client.h" 26 #include "content/public/browser/utility_process_host_client.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 }; 176 };
176 177
177 } // namespace 178 } // namespace
178 179
179 // State which lives on the IO thread and drives the ServiceManager. 180 // State which lives on the IO thread and drives the ServiceManager.
180 class ServiceManagerContext::InProcessServiceManagerContext 181 class ServiceManagerContext::InProcessServiceManagerContext
181 : public base::RefCountedThreadSafe<InProcessServiceManagerContext> { 182 : public base::RefCountedThreadSafe<InProcessServiceManagerContext> {
182 public: 183 public:
183 InProcessServiceManagerContext() {} 184 InProcessServiceManagerContext() {}
184 185
185 service_manager::mojom::ServiceRequest Start( 186 void Start(
187 service_manager::mojom::ServicePtrInfo packaged_services_service_info,
186 std::unique_ptr<BuiltinManifestProvider> manifest_provider) { 188 std::unique_ptr<BuiltinManifestProvider> manifest_provider) {
187 service_manager::mojom::ServicePtr embedder_service_proxy; 189 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
188 service_manager::mojom::ServiceRequest embedder_service_request( 190 ->PostTask(FROM_HERE,
189 &embedder_service_proxy); 191 base::Bind(&InProcessServiceManagerContext::StartOnIOThread,
190 service_manager::mojom::ServicePtrInfo embedder_service_proxy_info = 192 this, base::Passed(&manifest_provider),
191 embedder_service_proxy.PassInterface(); 193 base::Passed(&packaged_services_service_info)));
192 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)->PostTask(
193 FROM_HERE,
194 base::Bind(&InProcessServiceManagerContext::StartOnIOThread, this,
195 base::Passed(&manifest_provider),
196 base::Passed(&embedder_service_proxy_info)));
197 return embedder_service_request;
198 } 194 }
199 195
200 void ShutDown() { 196 void ShutDown() {
201 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)->PostTask( 197 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)->PostTask(
202 FROM_HERE, 198 FROM_HERE,
203 base::Bind(&InProcessServiceManagerContext::ShutDownOnIOThread, this)); 199 base::Bind(&InProcessServiceManagerContext::ShutDownOnIOThread, this));
204 } 200 }
205 201
206 private: 202 private:
207 friend class base::RefCountedThreadSafe<InProcessServiceManagerContext>; 203 friend class base::RefCountedThreadSafe<InProcessServiceManagerContext>;
208 204
209 ~InProcessServiceManagerContext() {} 205 ~InProcessServiceManagerContext() {}
210 206
211 void StartOnIOThread( 207 void StartOnIOThread(
212 std::unique_ptr<BuiltinManifestProvider> manifest_provider, 208 std::unique_ptr<BuiltinManifestProvider> manifest_provider,
213 service_manager::mojom::ServicePtrInfo embedder_service_proxy_info) { 209 service_manager::mojom::ServicePtrInfo packaged_services_service_info) {
214 manifest_provider_ = std::move(manifest_provider); 210 manifest_provider_ = std::move(manifest_provider);
215 catalog_ = 211 catalog_ =
216 base::MakeUnique<catalog::Catalog>(nullptr, manifest_provider_.get()); 212 base::MakeUnique<catalog::Catalog>(nullptr, manifest_provider_.get());
217 service_manager_ = base::MakeUnique<service_manager::ServiceManager>( 213 service_manager_ = base::MakeUnique<service_manager::ServiceManager>(
218 base::MakeUnique<NullServiceProcessLauncherFactory>(), 214 base::MakeUnique<NullServiceProcessLauncherFactory>(),
219 catalog_->TakeService()); 215 catalog_->TakeService());
220 216
221 service_manager::mojom::ServicePtr service; 217 service_manager::mojom::ServicePtr packaged_services_service;
222 service.Bind(std::move(embedder_service_proxy_info)); 218 packaged_services_service.Bind(std::move(packaged_services_service_info));
223 service_manager_->RegisterService( 219 service_manager_->RegisterService(
224 service_manager::Identity( 220 service_manager::Identity(mojom::kPackagedServicesServiceName,
225 mojom::kBrowserServiceName, service_manager::mojom::kRootUserID), 221 service_manager::mojom::kRootUserID),
226 std::move(service), nullptr); 222 std::move(packaged_services_service), nullptr);
227 } 223 }
228 224
229 void ShutDownOnIOThread() { 225 void ShutDownOnIOThread() {
230 service_manager_.reset(); 226 service_manager_.reset();
231 catalog_.reset(); 227 catalog_.reset();
232 manifest_provider_.reset(); 228 manifest_provider_.reset();
233 } 229 }
234 230
235 std::unique_ptr<BuiltinManifestProvider> manifest_provider_; 231 std::unique_ptr<BuiltinManifestProvider> manifest_provider_;
236 std::unique_ptr<catalog::Catalog> catalog_; 232 std::unique_ptr<catalog::Catalog> catalog_;
237 std::unique_ptr<service_manager::ServiceManager> service_manager_; 233 std::unique_ptr<service_manager::ServiceManager> service_manager_;
238 234
239 DISALLOW_COPY_AND_ASSIGN(InProcessServiceManagerContext); 235 DISALLOW_COPY_AND_ASSIGN(InProcessServiceManagerContext);
240 }; 236 };
241 237
242 ServiceManagerContext::ServiceManagerContext() { 238 ServiceManagerContext::ServiceManagerContext() {
243 service_manager::mojom::ServiceRequest request; 239 service_manager::mojom::ServiceRequest packaged_services_request;
244 if (service_manager::ServiceManagerIsRemote()) { 240 if (service_manager::ServiceManagerIsRemote()) {
245 mojo::edk::SetParentPipeHandleFromCommandLine(); 241 mojo::edk::SetParentPipeHandleFromCommandLine();
246 request = service_manager::GetServiceRequestFromCommandLine(); 242 packaged_services_request =
243 service_manager::GetServiceRequestFromCommandLine();
247 } else { 244 } else {
248 std::unique_ptr<BuiltinManifestProvider> manifest_provider = 245 std::unique_ptr<BuiltinManifestProvider> manifest_provider =
249 base::MakeUnique<BuiltinManifestProvider>(); 246 base::MakeUnique<BuiltinManifestProvider>();
250 247
251 static const struct ManifestInfo { 248 static const struct ManifestInfo {
252 const char* name; 249 const char* name;
253 int resource_id; 250 int resource_id;
254 } kManifests[] = { 251 } kManifests[] = {
255 { mojom::kBrowserServiceName, IDR_MOJO_CONTENT_BROWSER_MANIFEST }, 252 {mojom::kBrowserServiceName, IDR_MOJO_CONTENT_BROWSER_MANIFEST},
256 { mojom::kGpuServiceName, IDR_MOJO_CONTENT_GPU_MANIFEST }, 253 {mojom::kGpuServiceName, IDR_MOJO_CONTENT_GPU_MANIFEST},
257 { mojom::kPluginServiceName, IDR_MOJO_CONTENT_PLUGIN_MANIFEST }, 254 {mojom::kPackagedServicesServiceName,
258 { mojom::kRendererServiceName, IDR_MOJO_CONTENT_RENDERER_MANIFEST }, 255 IDR_MOJO_CONTENT_PACKAGED_SERVICES_MANIFEST},
259 { mojom::kUtilityServiceName, IDR_MOJO_CONTENT_UTILITY_MANIFEST }, 256 {mojom::kPluginServiceName, IDR_MOJO_CONTENT_PLUGIN_MANIFEST},
260 { catalog::mojom::kServiceName, IDR_MOJO_CATALOG_MANIFEST }, 257 {mojom::kRendererServiceName, IDR_MOJO_CONTENT_RENDERER_MANIFEST},
258 {mojom::kUtilityServiceName, IDR_MOJO_CONTENT_UTILITY_MANIFEST},
259 {catalog::mojom::kServiceName, IDR_MOJO_CATALOG_MANIFEST},
261 }; 260 };
262 261
263 for (size_t i = 0; i < arraysize(kManifests); ++i) { 262 for (size_t i = 0; i < arraysize(kManifests); ++i) {
264 manifest_provider->AddServiceManifest(kManifests[i].name, 263 manifest_provider->AddServiceManifest(kManifests[i].name,
265 kManifests[i].resource_id); 264 kManifests[i].resource_id);
266 } 265 }
267 for (const auto& manifest : 266 for (const auto& manifest :
268 GetContentClient()->browser()->GetExtraServiceManifests()) { 267 GetContentClient()->browser()->GetExtraServiceManifests()) {
269 manifest_provider->AddServiceManifest(manifest.name, 268 manifest_provider->AddServiceManifest(manifest.name,
270 manifest.resource_id); 269 manifest.resource_id);
271 } 270 }
272 in_process_context_ = new InProcessServiceManagerContext; 271 in_process_context_ = new InProcessServiceManagerContext;
273 request = in_process_context_->Start(std::move(manifest_provider)); 272
273 service_manager::mojom::ServicePtr packaged_services_service;
274 packaged_services_request = mojo::MakeRequest(&packaged_services_service);
275 in_process_context_->Start(packaged_services_service.PassInterface(),
276 std::move(manifest_provider));
274 } 277 }
278
279 packaged_services_connection_ = ServiceManagerConnection::Create(
280 std::move(packaged_services_request),
281 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
282
283 service_manager::mojom::ServicePtr root_browser_service;
275 ServiceManagerConnection::SetForProcess(ServiceManagerConnection::Create( 284 ServiceManagerConnection::SetForProcess(ServiceManagerConnection::Create(
276 std::move(request), 285 mojo::MakeRequest(&root_browser_service),
277 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))); 286 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
278 287
288 service_manager::mojom::PIDReceiverPtr pid_receiver;
289 packaged_services_connection_->GetConnector()->StartService(
290 service_manager::Identity(mojom::kBrowserServiceName,
291 service_manager::mojom::kRootUserID),
292 std::move(root_browser_service), mojo::MakeRequest(&pid_receiver));
293 pid_receiver->SetPID(base::GetCurrentProcId());
294
295 packaged_services_connection_->Start();
296 ServiceManagerConnection::GetForProcess()->Start();
297
279 ServiceInfo device_info; 298 ServiceInfo device_info;
280 device_info.factory = 299 device_info.factory =
281 base::Bind(&device::CreateDeviceService, 300 base::Bind(&device::CreateDeviceService,
282 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)); 301 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE));
283 ServiceManagerConnection::GetForProcess()->AddEmbeddedService( 302 packaged_services_connection_->AddEmbeddedService(device::mojom::kServiceName,
284 device::mojom::kServiceName, device_info); 303 device_info);
285 304
286 ContentBrowserClient::StaticServiceMap services; 305 ContentBrowserClient::StaticServiceMap services;
287 GetContentClient()->browser()->RegisterInProcessServices(&services); 306 GetContentClient()->browser()->RegisterInProcessServices(&services);
288 for (const auto& entry : services) { 307 for (const auto& entry : services) {
289 ServiceManagerConnection::GetForProcess()->AddEmbeddedService(entry.first, 308 packaged_services_connection_->AddEmbeddedService(entry.first,
290 entry.second); 309 entry.second);
291 } 310 }
292 311
293 // This is safe to assign directly from any thread, because 312 // This is safe to assign directly from any thread, because
294 // ServiceManagerContext must be constructed before anyone can call 313 // ServiceManagerContext must be constructed before anyone can call
295 // GetConnectorForIOThread(). 314 // GetConnectorForIOThread().
296 g_io_thread_connector.Get() = 315 g_io_thread_connector.Get() =
297 ServiceManagerConnection::GetForProcess()->GetConnector()->Clone(); 316 ServiceManagerConnection::GetForProcess()->GetConnector()->Clone();
298 317
299 ServiceManagerConnection::GetForProcess()->Start();
300
301 ContentBrowserClient::OutOfProcessServiceMap sandboxed_services; 318 ContentBrowserClient::OutOfProcessServiceMap sandboxed_services;
302 GetContentClient() 319 GetContentClient()
303 ->browser() 320 ->browser()
304 ->RegisterOutOfProcessServices(&sandboxed_services); 321 ->RegisterOutOfProcessServices(&sandboxed_services);
305 for (const auto& service : sandboxed_services) { 322 for (const auto& service : sandboxed_services) {
306 ServiceManagerConnection::GetForProcess()->AddServiceRequestHandler( 323 packaged_services_connection_->AddServiceRequestHandler(
307 service.first, 324 service.first, base::Bind(&StartServiceInUtilityProcess, service.first,
308 base::Bind(&StartServiceInUtilityProcess, service.first, service.second, 325 service.second, true /* use_sandbox */));
309 true /* use_sandbox */));
310 } 326 }
311 327
312 ContentBrowserClient::OutOfProcessServiceMap unsandboxed_services; 328 ContentBrowserClient::OutOfProcessServiceMap unsandboxed_services;
313 GetContentClient() 329 GetContentClient()
314 ->browser() 330 ->browser()
315 ->RegisterUnsandboxedOutOfProcessServices(&unsandboxed_services); 331 ->RegisterUnsandboxedOutOfProcessServices(&unsandboxed_services);
316 unsandboxed_services.insert( 332 unsandboxed_services.insert(
317 std::make_pair(shape_detection::mojom::kServiceName, 333 std::make_pair(shape_detection::mojom::kServiceName,
318 base::ASCIIToUTF16("Shape Detection Service"))); 334 base::ASCIIToUTF16("Shape Detection Service")));
319 for (const auto& service : unsandboxed_services) { 335 for (const auto& service : unsandboxed_services) {
320 ServiceManagerConnection::GetForProcess()->AddServiceRequestHandler( 336 packaged_services_connection_->AddServiceRequestHandler(
321 service.first, 337 service.first, base::Bind(&StartServiceInUtilityProcess, service.first,
322 base::Bind(&StartServiceInUtilityProcess, service.first, service.second, 338 service.second, false /* use_sandbox */));
323 false /* use_sandbox */));
324 } 339 }
325 340
326 #if (ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 341 #if (ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
327 ServiceManagerConnection::GetForProcess()->AddServiceRequestHandler( 342 packaged_services_connection_->AddServiceRequestHandler(
328 "media", base::Bind(&StartServiceInGpuProcess, "media")); 343 "media", base::Bind(&StartServiceInGpuProcess, "media"));
329 #endif 344 #endif
330
331 // Initiates the first connection to device service to create the singleton
332 // instance, later the same instance will serve all the clients wanting to
333 // connect to device service.
334 // TODO(rockot): http://crbug.com/679407 Eliminate this connection once
335 // content_browser is itself a singleton service.
336 std::unique_ptr<service_manager::Connection> device_connection =
337 ServiceManagerConnection::GetForProcess()->GetConnector()->Connect(
338 device::mojom::kServiceName);
339 } 345 }
340 346
341 ServiceManagerContext::~ServiceManagerContext() { 347 ServiceManagerContext::~ServiceManagerContext() {
342 // NOTE: The in-process ServiceManager MUST be destroyed before the browser 348 // NOTE: The in-process ServiceManager MUST be destroyed before the browser
343 // process-wide ServiceManagerConnection. Otherwise it's possible for the 349 // process-wide ServiceManagerConnection. Otherwise it's possible for the
344 // ServiceManager to receive connection requests for service:content_browser 350 // ServiceManager to receive connection requests for service:content_browser
345 // which it may attempt to service by launching a new instance of the browser. 351 // which it may attempt to service by launching a new instance of the browser.
346 if (in_process_context_) 352 if (in_process_context_)
347 in_process_context_->ShutDown(); 353 in_process_context_->ShutDown();
348 if (ServiceManagerConnection::GetForProcess()) 354 if (ServiceManagerConnection::GetForProcess())
349 ServiceManagerConnection::DestroyForProcess(); 355 ServiceManagerConnection::DestroyForProcess();
350 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 356 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
351 base::Bind(&DestroyConnectorOnIOThread)); 357 base::Bind(&DestroyConnectorOnIOThread));
352 } 358 }
353 359
354 // static 360 // static
355 service_manager::Connector* ServiceManagerContext::GetConnectorForIOThread() { 361 service_manager::Connector* ServiceManagerContext::GetConnectorForIOThread() {
356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
357 return g_io_thread_connector.Get().get(); 363 return g_io_thread_connector.Get().get();
358 } 364 }
359 365
360 } // namespace content 366 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698