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 #include "content/utility/services.h"
6 
7 #include <utility>
8 
9 #include "base/no_destructor.h"
10 #include "base/threading/thread_task_runner_handle.h"
11 #include "build/build_config.h"
12 #include "components/services/storage/public/mojom/storage_service.mojom.h"
13 #include "components/services/storage/storage_service_impl.h"
14 #include "content/child/child_process.h"
15 #include "content/public/utility/content_utility_client.h"
16 #include "content/public/utility/utility_thread.h"
17 #include "device/vr/buildflags/buildflags.h"
18 #include "media/media_buildflags.h"
19 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
20 #include "mojo/public/cpp/bindings/service_factory.h"
21 #include "services/audio/service_factory.h"
22 #include "services/data_decoder/data_decoder_service.h"
23 #include "services/network/network_service.h"
24 #include "services/service_manager/public/cpp/binder_registry.h"
25 #include "services/tracing/public/mojom/tracing_service.mojom.h"
26 #include "services/tracing/tracing_service.h"
27 #include "services/video_capture/public/mojom/video_capture_service.mojom.h"
28 #include "services/video_capture/video_capture_service_impl.h"
29 
30 #if defined(OS_MACOSX)
31 #include "base/mac/mach_logging.h"
32 #include "sandbox/mac/system_services.h"
33 #include "services/service_manager/sandbox/features.h"
34 #include "services/service_manager/sandbox/sandbox_type.h"
35 #endif
36 
37 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
38 #include "media/cdm/cdm_adapter_factory.h"          // nogncheck
39 #include "media/mojo/services/cdm_service.h"        // nogncheck
40 #include "media/mojo/services/mojo_cdm_helper.h"    // nogncheck
41 #include "media/mojo/services/mojo_media_client.h"  // nogncheck
42 #if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
43 #include "media/cdm/cdm_host_file.h"
44 #endif  // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
45 
46 #if BUILDFLAG(ENABLE_VR) && !defined(OS_ANDROID)
47 #include "content/services/isolated_xr_device/xr_device_service.h"  // nogncheck
48 #include "device/vr/public/mojom/isolated_xr_service.mojom.h"       // nogncheck
49 #endif
50 
51 #if defined(OS_WIN)
52 #include "sandbox/win/src/sandbox.h"
53 
54 extern sandbox::TargetServices* g_utility_target_services;
55 #endif  // defined(OS_WIN)
56 #endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
57 
58 namespace content {
59 
60 namespace {
61 
62 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
63 
CreateCdmHelper(service_manager::mojom::InterfaceProvider * interface_provider)64 std::unique_ptr<media::CdmAuxiliaryHelper> CreateCdmHelper(
65     service_manager::mojom::InterfaceProvider* interface_provider) {
66   return std::make_unique<media::MojoCdmHelper>(interface_provider);
67 }
68 
69 class ContentCdmServiceClient final : public media::CdmService::Client {
70  public:
71   ContentCdmServiceClient() = default;
72   ~ContentCdmServiceClient() override = default;
73 
EnsureSandboxed()74   void EnsureSandboxed() override {
75 #if defined(OS_WIN)
76     // |g_utility_target_services| can be null if --no-sandbox is specified.
77     if (g_utility_target_services)
78       g_utility_target_services->LowerToken();
79 #endif
80   }
81 
CreateCdmFactory(service_manager::mojom::InterfaceProvider * host_interfaces)82   std::unique_ptr<media::CdmFactory> CreateCdmFactory(
83       service_manager::mojom::InterfaceProvider* host_interfaces) override {
84     return std::make_unique<media::CdmAdapterFactory>(
85         base::BindRepeating(&CreateCdmHelper, host_interfaces));
86   }
87 
88 #if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
AddCdmHostFilePaths(std::vector<media::CdmHostFilePath> * cdm_host_file_paths)89   void AddCdmHostFilePaths(
90       std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override {
91     GetContentClient()->AddContentDecryptionModules(nullptr,
92                                                     cdm_host_file_paths);
93   }
94 #endif  // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
95 };
96 #endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
97 
RunNetworkService(mojo::PendingReceiver<network::mojom::NetworkService> receiver)98 auto RunNetworkService(
99     mojo::PendingReceiver<network::mojom::NetworkService> receiver) {
100   auto binders = std::make_unique<service_manager::BinderRegistry>();
101   GetContentClient()->utility()->RegisterNetworkBinders(binders.get());
102   return std::make_unique<network::NetworkService>(
103       std::move(binders), std::move(receiver),
104       /*delay_initialization_until_set_client=*/true);
105 }
106 
RunAudio(mojo::PendingReceiver<audio::mojom::AudioService> receiver)107 auto RunAudio(mojo::PendingReceiver<audio::mojom::AudioService> receiver) {
108 #if defined(OS_MACOSX)
109   // Don't connect to launch services when running sandboxed
110   // (https://crbug.com/874785).
111   if (service_manager::IsAudioSandboxEnabled()) {
112     sandbox::DisableLaunchServices();
113   }
114 
115   // Set the audio process to run with similar scheduling parameters as the
116   // browser process.
117   task_category_policy category;
118   category.role = TASK_FOREGROUND_APPLICATION;
119   kern_return_t result = task_policy_set(
120       mach_task_self(), TASK_CATEGORY_POLICY,
121       reinterpret_cast<task_policy_t>(&category), TASK_CATEGORY_POLICY_COUNT);
122 
123   MACH_LOG_IF(ERROR, result != KERN_SUCCESS, result)
124       << "task_policy_set TASK_CATEGORY_POLICY";
125 
126   task_qos_policy qos;
127   qos.task_latency_qos_tier = LATENCY_QOS_TIER_0;
128   qos.task_throughput_qos_tier = THROUGHPUT_QOS_TIER_0;
129   result = task_policy_set(mach_task_self(), TASK_BASE_QOS_POLICY,
130                            reinterpret_cast<task_policy_t>(&qos),
131                            TASK_QOS_POLICY_COUNT);
132 
133   MACH_LOG_IF(ERROR, result != KERN_SUCCESS, result)
134       << "task_policy_set TASK_QOS_POLICY";
135 #endif
136 
137   return audio::CreateStandaloneService(std::move(receiver));
138 }
139 
140 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
RunCdmService(mojo::PendingReceiver<media::mojom::CdmService> receiver)141 auto RunCdmService(mojo::PendingReceiver<media::mojom::CdmService> receiver) {
142   return std::make_unique<media::CdmService>(
143       std::make_unique<ContentCdmServiceClient>(), std::move(receiver));
144 }
145 #endif
146 
RunDataDecoder(mojo::PendingReceiver<data_decoder::mojom::DataDecoderService> receiver)147 auto RunDataDecoder(
148     mojo::PendingReceiver<data_decoder::mojom::DataDecoderService> receiver) {
149   UtilityThread::Get()->EnsureBlinkInitialized();
150   return std::make_unique<data_decoder::DataDecoderService>(
151       std::move(receiver));
152 }
153 
RunStorageService(mojo::PendingReceiver<storage::mojom::StorageService> receiver)154 auto RunStorageService(
155     mojo::PendingReceiver<storage::mojom::StorageService> receiver) {
156   return std::make_unique<storage::StorageServiceImpl>(
157       std::move(receiver), ChildProcess::current()->io_task_runner());
158 }
159 
RunTracing(mojo::PendingReceiver<tracing::mojom::TracingService> receiver)160 auto RunTracing(
161     mojo::PendingReceiver<tracing::mojom::TracingService> receiver) {
162   return std::make_unique<tracing::TracingService>(std::move(receiver));
163 }
164 
RunVideoCapture(mojo::PendingReceiver<video_capture::mojom::VideoCaptureService> receiver)165 auto RunVideoCapture(
166     mojo::PendingReceiver<video_capture::mojom::VideoCaptureService> receiver) {
167   return std::make_unique<video_capture::VideoCaptureServiceImpl>(
168       std::move(receiver), base::ThreadTaskRunnerHandle::Get());
169 }
170 
171 #if BUILDFLAG(ENABLE_VR) && !defined(OS_ANDROID)
RunXrDeviceService(mojo::PendingReceiver<device::mojom::XRDeviceService> receiver)172 auto RunXrDeviceService(
173     mojo::PendingReceiver<device::mojom::XRDeviceService> receiver) {
174   return std::make_unique<device::XrDeviceService>(std::move(receiver));
175 }
176 #endif
177 
GetIOThreadServiceFactory()178 mojo::ServiceFactory& GetIOThreadServiceFactory() {
179   static base::NoDestructor<mojo::ServiceFactory> factory{
180       RunNetworkService,
181   };
182   return *factory;
183 }
184 
GetMainThreadServiceFactory()185 mojo::ServiceFactory& GetMainThreadServiceFactory() {
186   // clang-format off
187   static base::NoDestructor<mojo::ServiceFactory> factory{
188     RunAudio,
189 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
190     RunCdmService,
191 #endif
192     RunDataDecoder,
193     RunStorageService,
194     RunTracing,
195     RunVideoCapture,
196 #if BUILDFLAG(ENABLE_VR) && !defined(OS_ANDROID)
197     RunXrDeviceService,
198 #endif
199   };
200   // clang-format on
201   return *factory;
202 }
203 
204 }  // namespace
205 
HandleServiceRequestOnIOThread(mojo::GenericPendingReceiver receiver,base::SequencedTaskRunner * main_thread_task_runner)206 void HandleServiceRequestOnIOThread(
207     mojo::GenericPendingReceiver receiver,
208     base::SequencedTaskRunner* main_thread_task_runner) {
209   if (GetIOThreadServiceFactory().MaybeRunService(&receiver))
210     return;
211 
212   // If the request was handled already, we should not reach this point.
213   DCHECK(receiver.is_valid());
214   auto* embedder_factory =
215       GetContentClient()->utility()->GetIOThreadServiceFactory();
216   if (embedder_factory && embedder_factory->MaybeRunService(&receiver))
217     return;
218 
219   DCHECK(receiver.is_valid());
220   main_thread_task_runner->PostTask(
221       FROM_HERE,
222       base::BindOnce(&HandleServiceRequestOnMainThread, std::move(receiver)));
223 }
224 
HandleServiceRequestOnMainThread(mojo::GenericPendingReceiver receiver)225 void HandleServiceRequestOnMainThread(mojo::GenericPendingReceiver receiver) {
226   if (GetMainThreadServiceFactory().MaybeRunService(&receiver))
227     return;
228 
229   // If the request was handled already, we should not reach this point.
230   DCHECK(receiver.is_valid());
231   auto* embedder_factory =
232       GetContentClient()->utility()->GetMainThreadServiceFactory();
233   if (embedder_factory && embedder_factory->MaybeRunService(&receiver))
234     return;
235 
236   DCHECK(receiver.is_valid());
237   DLOG(ERROR) << "Unhandled out-of-process service request for "
238               << receiver.interface_name().value();
239 }
240 
241 }  // namespace content
242