1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file exposes services in the browser to child processes.
6 
7 #include "content/browser/browser_child_process_host_impl.h"
8 
9 #include "base/bind.h"
10 #include "base/no_destructor.h"
11 #include "base/task/thread_pool.h"
12 #include "build/build_config.h"
13 #include "components/discardable_memory/public/mojom/discardable_shared_memory_manager.mojom.h"
14 #include "components/discardable_memory/service/discardable_shared_memory_manager.h"
15 #include "content/browser/field_trial_recorder.h"
16 #include "content/common/field_trial_recorder.mojom.h"
17 #include "content/public/browser/browser_child_process_host_delegate.h"
18 #include "content/public/browser/browser_task_traits.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/device_service.h"
21 #include "services/device/public/mojom/power_monitor.mojom.h"
22 #include "services/metrics/public/cpp/ukm_recorder.h"
23 #include "services/metrics/public/mojom/ukm_interface.mojom.h"
24 #include "services/metrics/ukm_recorder_interface.h"
25 
26 #if defined(OS_MAC)
27 #include "content/browser/sandbox_support_mac_impl.h"
28 #include "content/common/sandbox_support_mac.mojom.h"
29 #endif
30 
31 #if defined(OS_WIN)
32 #include "content/browser/renderer_host/dwrite_font_proxy_impl_win.h"
33 #include "content/public/common/font_cache_dispatcher_win.h"
34 #include "content/public/common/font_cache_win.mojom.h"
35 #endif
36 
37 namespace content {
38 namespace {
39 
40 BrowserChildProcessHost::BindHostReceiverInterceptor&
GetBindHostReceiverInterceptor()41 GetBindHostReceiverInterceptor() {
42   static base::NoDestructor<
43       BrowserChildProcessHost::BindHostReceiverInterceptor>
44       interceptor;
45   return *interceptor;
46 }
47 
48 }  // namespace
49 
BindHostReceiver(mojo::GenericPendingReceiver receiver)50 void BrowserChildProcessHostImpl::BindHostReceiver(
51     mojo::GenericPendingReceiver receiver) {
52   const auto& interceptor = GetBindHostReceiverInterceptor();
53   if (interceptor) {
54     interceptor.Run(this, &receiver);
55     if (!receiver)
56       return;
57   }
58 
59   if (auto r =
60           receiver.As<memory_instrumentation::mojom::CoordinatorConnector>()) {
61     // Well-behaved child processes do not bind this interface more than once.
62     if (!coordinator_connector_receiver_.is_bound())
63       coordinator_connector_receiver_.Bind(std::move(r));
64     return;
65   }
66 
67 #if defined(OS_MAC)
68   if (auto r = receiver.As<mojom::SandboxSupportMac>()) {
69     static base::NoDestructor<SandboxSupportMacImpl> sandbox_support;
70     sandbox_support->BindReceiver(std::move(r));
71     return;
72   }
73 #endif
74 
75 #if defined(OS_WIN)
76   if (auto r = receiver.As<mojom::FontCacheWin>()) {
77     FontCacheDispatcher::Create(std::move(r));
78     return;
79   }
80 
81   if (auto r = receiver.As<blink::mojom::DWriteFontProxy>()) {
82     base::ThreadPool::CreateSequencedTaskRunner(
83         {base::TaskPriority::USER_BLOCKING, base::MayBlock()})
84         ->PostTask(FROM_HERE,
85                    base::BindOnce(&DWriteFontProxyImpl::Create, std::move(r)));
86     return;
87   }
88 #endif
89 
90   if (auto r = receiver.As<mojom::FieldTrialRecorder>()) {
91     GetUIThreadTaskRunner({})->PostTask(
92         FROM_HERE, base::BindOnce(&FieldTrialRecorder::Create, std::move(r)));
93     return;
94   }
95 
96   if (auto r = receiver.As<
97                discardable_memory::mojom::DiscardableSharedMemoryManager>()) {
98     discardable_memory::DiscardableSharedMemoryManager::Get()->Bind(
99         std::move(r));
100     return;
101   }
102 
103   if (auto r = receiver.As<device::mojom::PowerMonitor>()) {
104     GetUIThreadTaskRunner({})->PostTask(
105         FROM_HERE,
106         base::BindOnce(
107             [](mojo::PendingReceiver<device::mojom::PowerMonitor> r) {
108               GetDeviceService().BindPowerMonitor(std::move(r));
109             },
110             std::move(r)));
111     return;
112   }
113 
114   if (auto r = receiver.As<ukm::mojom::UkmRecorderInterface>()) {
115     metrics::UkmRecorderInterface::Create(ukm::UkmRecorder::Get(),
116                                           std::move(r));
117     return;
118   }
119 
120   delegate_->BindHostReceiver(std::move(receiver));
121 }
122 
123 // static
InterceptBindHostReceiverForTesting(BindHostReceiverInterceptor callback)124 void BrowserChildProcessHost::InterceptBindHostReceiverForTesting(
125     BindHostReceiverInterceptor callback) {
126   GetBindHostReceiverInterceptor() = std::move(callback);
127 }
128 
129 }  // namespace content
130