blob: 03d687a9cce411f5e55c1e7f4630a48aab152031 [file] [log] [blame]
Parth Sane56a04712024-04-22 14:21:07 +00001/*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "BackendUnifiedServiceManager.h"
17
Alice Wang8578f132024-05-03 09:01:56 +000018#include <android/os/IAccessor.h>
Parth Sane5e1b7e12024-11-29 10:40:41 +000019#include <android/os/IServiceManager.h>
Alice Wang8578f132024-05-03 09:01:56 +000020#include <binder/RpcSession.h>
21
Tomasz Wasilczykfe25f122024-06-26 12:45:57 -070022#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
23#include <android-base/properties.h>
24#endif
25
Parth Sane56a04712024-04-22 14:21:07 +000026namespace android {
27
Parth Saneb6ed0eb2024-06-25 14:38:42 +000028#ifdef LIBBINDER_CLIENT_CACHE
29constexpr bool kUseCache = true;
30#else
31constexpr bool kUseCache = false;
32#endif
33
Parth Sanedc207542024-11-14 11:49:08 +000034#ifdef LIBBINDER_ADDSERVICE_CACHE
35constexpr bool kUseCacheInAddService = true;
36#else
37constexpr bool kUseCacheInAddService = false;
38#endif
39
Parth Sane5e1b7e12024-11-29 10:40:41 +000040#ifdef LIBBINDER_REMOVE_CACHE_STATIC_LIST
41constexpr bool kRemoveStaticList = true;
42#else
43constexpr bool kRemoveStaticList = false;
44#endif
45
Parth Sane56a04712024-04-22 14:21:07 +000046using AidlServiceManager = android::os::IServiceManager;
Devin Moore678984f2024-10-18 22:43:22 +000047using android::os::IAccessor;
48using binder::Status;
Parth Sane56a04712024-04-22 14:21:07 +000049
Parth Saneb6ed0eb2024-06-25 14:38:42 +000050static const char* kStaticCachableList[] = {
Parth Saneac492702024-09-18 15:54:16 +000051 // go/keep-sorted start
52 "accessibility",
53 "account",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000054 "activity",
Parth Saneac492702024-09-18 15:54:16 +000055 "alarm",
Parth Sane0105ea52024-10-11 11:41:16 +000056 "android.frameworks.stats.IStats/default",
Parth Saneac492702024-09-18 15:54:16 +000057 "android.system.keystore2.IKeystoreService/default",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000058 "appops",
59 "audio",
Parth Sane0105ea52024-10-11 11:41:16 +000060 "autofill",
61 "batteryproperties",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000062 "batterystats",
Parth Sane0105ea52024-10-11 11:41:16 +000063 "biometic",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000064 "carrier_config",
65 "connectivity",
Parth Saneac492702024-09-18 15:54:16 +000066 "content",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000067 "content_capture",
68 "device_policy",
69 "display",
70 "dropbox",
71 "econtroller",
Parth Saneac492702024-09-18 15:54:16 +000072 "graphicsstats",
73 "input",
74 "input_method",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000075 "isub",
Parth Saneac492702024-09-18 15:54:16 +000076 "jobscheduler",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000077 "legacy_permission",
78 "location",
Parth Sane0105ea52024-10-11 11:41:16 +000079 "lock_settings",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000080 "media.extractor",
81 "media.metrics",
82 "media.player",
83 "media.resource_manager",
Parth Saneac492702024-09-18 15:54:16 +000084 "media_resource_monitor",
85 "mount",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000086 "netd_listener",
87 "netstats",
88 "network_management",
89 "nfc",
Parth Saneac492702024-09-18 15:54:16 +000090 "notification",
91 "package",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000092 "package_native",
93 "performance_hint",
94 "permission",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000095 "permission_checker",
Parth Saneac492702024-09-18 15:54:16 +000096 "permissionmgr",
Parth Saneb6ed0eb2024-06-25 14:38:42 +000097 "phone",
98 "platform_compat",
99 "power",
Parth Sane0105ea52024-10-11 11:41:16 +0000100 "processinfo",
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000101 "role",
Parth Sane0105ea52024-10-11 11:41:16 +0000102 "sensitive_content_protection_service",
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000103 "sensorservice",
104 "statscompanion",
105 "telephony.registry",
106 "thermalservice",
107 "time_detector",
Parth Sane0105ea52024-10-11 11:41:16 +0000108 "tracing.proxy",
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000109 "trust",
110 "uimode",
Parth Saneac492702024-09-18 15:54:16 +0000111 "user",
Parth Sane0105ea52024-10-11 11:41:16 +0000112 "vibrator",
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000113 "virtualdevice",
114 "virtualdevice_native",
115 "webviewupdate",
Parth Saneac492702024-09-18 15:54:16 +0000116 "window",
117 // go/keep-sorted end
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000118};
119
Parth Sane5e1b7e12024-11-29 10:40:41 +0000120os::ServiceWithMetadata createServiceWithMetadata(const sp<IBinder>& service, bool isLazyService) {
121 os::ServiceWithMetadata out = os::ServiceWithMetadata();
122 out.service = service;
123 out.isLazyService = isLazyService;
124 return out;
125}
126
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000127bool BinderCacheWithInvalidation::isClientSideCachingEnabled(const std::string& serviceName) {
Devin Moore74bc5892024-10-23 17:12:19 +0000128 sp<ProcessState> self = ProcessState::selfOrNull();
129 if (!self || self->getThreadPoolMaxTotalThreadCount() <= 0) {
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000130 ALOGW("Thread Pool max thread count is 0. Cannot cache binder as linkToDeath cannot be "
131 "implemented. serviceName: %s",
132 serviceName.c_str());
133 return false;
134 }
135 for (const char* name : kStaticCachableList) {
136 if (name == serviceName) {
137 return true;
138 }
139 }
140 return false;
141}
142
Devin Moore678984f2024-10-18 22:43:22 +0000143Status BackendUnifiedServiceManager::updateCache(const std::string& serviceName,
144 const os::Service& service) {
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000145 if (!kUseCache) {
Devin Moore678984f2024-10-18 22:43:22 +0000146 return Status::ok();
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000147 }
Parth Sanedc207542024-11-14 11:49:08 +0000148
Parth Sane5e1b7e12024-11-29 10:40:41 +0000149 if (service.getTag() == os::Service::Tag::serviceWithMetadata) {
150 auto serviceWithMetadata = service.get<os::Service::Tag::serviceWithMetadata>();
151 return updateCache(serviceName, serviceWithMetadata.service,
152 serviceWithMetadata.isLazyService);
Parth Sanedc207542024-11-14 11:49:08 +0000153 }
154 return Status::ok();
155}
156
157Status BackendUnifiedServiceManager::updateCache(const std::string& serviceName,
Parth Sane5e1b7e12024-11-29 10:40:41 +0000158 const sp<IBinder>& binder, bool isServiceLazy) {
Parth Sanea6676ba2024-10-04 14:14:07 +0000159 std::string traceStr;
Parth Sane5e1b7e12024-11-29 10:40:41 +0000160 // Don't cache if service is lazy
161 if (kRemoveStaticList && isServiceLazy) {
162 return Status::ok();
163 }
Parth Sanea6676ba2024-10-04 14:14:07 +0000164 if (atrace_is_tag_enabled(ATRACE_TAG_AIDL)) {
165 traceStr = "BinderCacheWithInvalidation::updateCache : " + serviceName;
166 }
167 binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL, traceStr.c_str());
Parth Sanedc207542024-11-14 11:49:08 +0000168 if (!binder) {
169 binder::ScopedTrace
170 aidlTrace(ATRACE_TAG_AIDL,
171 "BinderCacheWithInvalidation::updateCache failed: binder_null");
172 } else if (!binder->isBinderAlive()) {
173 binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
174 "BinderCacheWithInvalidation::updateCache failed: "
175 "isBinderAlive_false");
Parth Sane5e1b7e12024-11-29 10:40:41 +0000176 }
177 // If we reach here with kRemoveStaticList=true then we know service isn't lazy
178 else if (kRemoveStaticList || mCacheForGetService->isClientSideCachingEnabled(serviceName)) {
Parth Sanedc207542024-11-14 11:49:08 +0000179 binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
180 "BinderCacheWithInvalidation::updateCache successful");
181 return mCacheForGetService->setItem(serviceName, binder);
182 } else {
183 binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
184 "BinderCacheWithInvalidation::updateCache failed: "
185 "caching_not_enabled");
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000186 }
Devin Moore678984f2024-10-18 22:43:22 +0000187 return Status::ok();
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000188}
189
190bool BackendUnifiedServiceManager::returnIfCached(const std::string& serviceName,
191 os::Service* _out) {
192 if (!kUseCache) {
193 return false;
194 }
195 sp<IBinder> item = mCacheForGetService->getItem(serviceName);
196 // TODO(b/363177618): Enable caching for binders which are always null.
197 if (item != nullptr && item->isBinderAlive()) {
Parth Sane5e1b7e12024-11-29 10:40:41 +0000198 *_out = createServiceWithMetadata(item, false);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000199 return true;
200 }
201 return false;
202}
203
Parth Sane56a04712024-04-22 14:21:07 +0000204BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl)
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000205 : mTheRealServiceManager(impl) {
206 mCacheForGetService = std::make_shared<BinderCacheWithInvalidation>();
207}
Parth Sane56a04712024-04-22 14:21:07 +0000208
Devin Moore678984f2024-10-18 22:43:22 +0000209Status BackendUnifiedServiceManager::getService(const ::std::string& name,
210 sp<IBinder>* _aidl_return) {
Alice Wang8578f132024-05-03 09:01:56 +0000211 os::Service service;
Devin Moore678984f2024-10-18 22:43:22 +0000212 Status status = getService2(name, &service);
Parth Sane5e1b7e12024-11-29 10:40:41 +0000213 *_aidl_return = service.get<os::Service::Tag::serviceWithMetadata>().service;
Alice Wang11da1502024-07-25 12:03:22 +0000214 return status;
215}
216
Devin Moore678984f2024-10-18 22:43:22 +0000217Status BackendUnifiedServiceManager::getService2(const ::std::string& name, os::Service* _out) {
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000218 if (returnIfCached(name, _out)) {
Devin Moore678984f2024-10-18 22:43:22 +0000219 return Status::ok();
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000220 }
Alice Wang11da1502024-07-25 12:03:22 +0000221 os::Service service;
Devin Moore678984f2024-10-18 22:43:22 +0000222 Status status = mTheRealServiceManager->getService2(name, &service);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000223
Devin Moore18f63752024-08-08 21:01:24 +0000224 if (status.isOk()) {
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000225 status = toBinderService(name, service, _out);
226 if (status.isOk()) {
227 return updateCache(name, service);
228 }
Devin Moore18f63752024-08-08 21:01:24 +0000229 }
Alice Wang8578f132024-05-03 09:01:56 +0000230 return status;
Parth Sane56a04712024-04-22 14:21:07 +0000231}
Alice Wang8578f132024-05-03 09:01:56 +0000232
Devin Moore678984f2024-10-18 22:43:22 +0000233Status BackendUnifiedServiceManager::checkService(const ::std::string& name, os::Service* _out) {
Alice Wang8578f132024-05-03 09:01:56 +0000234 os::Service service;
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000235 if (returnIfCached(name, _out)) {
Devin Moore678984f2024-10-18 22:43:22 +0000236 return Status::ok();
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000237 }
238
Devin Moore678984f2024-10-18 22:43:22 +0000239 Status status = mTheRealServiceManager->checkService(name, &service);
Devin Moore18f63752024-08-08 21:01:24 +0000240 if (status.isOk()) {
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000241 status = toBinderService(name, service, _out);
242 if (status.isOk()) {
243 return updateCache(name, service);
244 }
Devin Moore18f63752024-08-08 21:01:24 +0000245 }
Alice Wang8578f132024-05-03 09:01:56 +0000246 return status;
Parth Sane56a04712024-04-22 14:21:07 +0000247}
Alice Wang8578f132024-05-03 09:01:56 +0000248
Devin Moore678984f2024-10-18 22:43:22 +0000249Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name,
250 const os::Service& in, os::Service* _out) {
Alice Wang8578f132024-05-03 09:01:56 +0000251 switch (in.getTag()) {
Parth Sane5e1b7e12024-11-29 10:40:41 +0000252 case os::Service::Tag::serviceWithMetadata: {
253 auto serviceWithMetadata = in.get<os::Service::Tag::serviceWithMetadata>();
254 if (serviceWithMetadata.service == nullptr) {
Devin Moore18f63752024-08-08 21:01:24 +0000255 // failed to find a service. Check to see if we have any local
256 // injected Accessors for this service.
257 os::Service accessor;
Devin Moore678984f2024-10-18 22:43:22 +0000258 Status status = getInjectedAccessor(name, &accessor);
Devin Moore18f63752024-08-08 21:01:24 +0000259 if (!status.isOk()) {
Parth Sane5e1b7e12024-11-29 10:40:41 +0000260 *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
261 createServiceWithMetadata(nullptr, false));
Devin Moore18f63752024-08-08 21:01:24 +0000262 return status;
263 }
264 if (accessor.getTag() == os::Service::Tag::accessor &&
265 accessor.get<os::Service::Tag::accessor>() != nullptr) {
266 ALOGI("Found local injected service for %s, will attempt to create connection",
267 name.c_str());
268 // Call this again using the accessor Service to get the real
269 // service's binder into _out
270 return toBinderService(name, accessor, _out);
271 }
272 }
273
Alice Wang8578f132024-05-03 09:01:56 +0000274 *_out = in;
Devin Moore678984f2024-10-18 22:43:22 +0000275 return Status::ok();
Alice Wang8578f132024-05-03 09:01:56 +0000276 }
277 case os::Service::Tag::accessor: {
278 sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>();
279 sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder);
280 if (accessor == nullptr) {
281 ALOGE("Service#accessor doesn't have accessor. VM is maybe starting...");
Parth Sane5e1b7e12024-11-29 10:40:41 +0000282 *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
283 createServiceWithMetadata(nullptr, false));
Devin Moore678984f2024-10-18 22:43:22 +0000284 return Status::ok();
Alice Wang8578f132024-05-03 09:01:56 +0000285 }
286 auto request = [=] {
287 os::ParcelFileDescriptor fd;
Devin Moore678984f2024-10-18 22:43:22 +0000288 Status ret = accessor->addConnection(&fd);
Alice Wang8578f132024-05-03 09:01:56 +0000289 if (ret.isOk()) {
290 return base::unique_fd(fd.release());
291 } else {
292 ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str());
293 return base::unique_fd(-1);
294 }
295 };
296 auto session = RpcSession::make();
Devin Moore18f63752024-08-08 21:01:24 +0000297 status_t status = session->setupPreconnectedClient(base::unique_fd{}, request);
298 if (status != OK) {
299 ALOGE("Failed to set up preconnected binder RPC client: %s",
300 statusToString(status).c_str());
Devin Moore678984f2024-10-18 22:43:22 +0000301 return Status::fromStatusT(status);
Devin Moore18f63752024-08-08 21:01:24 +0000302 }
Alice Wang8578f132024-05-03 09:01:56 +0000303 session->setSessionSpecificRoot(accessorBinder);
Parth Sane5e1b7e12024-11-29 10:40:41 +0000304 *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
305 createServiceWithMetadata(session->getRootObject(), false));
Devin Moore678984f2024-10-18 22:43:22 +0000306 return Status::ok();
Alice Wang8578f132024-05-03 09:01:56 +0000307 }
308 default: {
309 LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag());
310 }
311 }
312}
313
Devin Moore678984f2024-10-18 22:43:22 +0000314Status BackendUnifiedServiceManager::addService(const ::std::string& name,
315 const sp<IBinder>& service, bool allowIsolated,
316 int32_t dumpPriority) {
Parth Sanedc207542024-11-14 11:49:08 +0000317 Status status = mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
318 // mEnableAddServiceCache is true by default.
319 if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) {
Parth Sane5e1b7e12024-11-29 10:40:41 +0000320 return updateCache(name, service,
321 dumpPriority & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE);
Parth Sanedc207542024-11-14 11:49:08 +0000322 }
323 return status;
Parth Sane56a04712024-04-22 14:21:07 +0000324}
Devin Moore678984f2024-10-18 22:43:22 +0000325Status BackendUnifiedServiceManager::listServices(int32_t dumpPriority,
326 ::std::vector<::std::string>* _aidl_return) {
Parth Sane56a04712024-04-22 14:21:07 +0000327 return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
328}
Devin Moore678984f2024-10-18 22:43:22 +0000329Status BackendUnifiedServiceManager::registerForNotifications(
Parth Sane56a04712024-04-22 14:21:07 +0000330 const ::std::string& name, const sp<os::IServiceCallback>& callback) {
331 return mTheRealServiceManager->registerForNotifications(name, callback);
332}
Devin Moore678984f2024-10-18 22:43:22 +0000333Status BackendUnifiedServiceManager::unregisterForNotifications(
Parth Sane56a04712024-04-22 14:21:07 +0000334 const ::std::string& name, const sp<os::IServiceCallback>& callback) {
335 return mTheRealServiceManager->unregisterForNotifications(name, callback);
336}
Devin Moore678984f2024-10-18 22:43:22 +0000337Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name, bool* _aidl_return) {
Parth Sane56a04712024-04-22 14:21:07 +0000338 return mTheRealServiceManager->isDeclared(name, _aidl_return);
339}
Devin Moore678984f2024-10-18 22:43:22 +0000340Status BackendUnifiedServiceManager::getDeclaredInstances(
Parth Sane56a04712024-04-22 14:21:07 +0000341 const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) {
342 return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
343}
Devin Moore678984f2024-10-18 22:43:22 +0000344Status BackendUnifiedServiceManager::updatableViaApex(
Parth Sane56a04712024-04-22 14:21:07 +0000345 const ::std::string& name, ::std::optional<::std::string>* _aidl_return) {
346 return mTheRealServiceManager->updatableViaApex(name, _aidl_return);
347}
Devin Moore678984f2024-10-18 22:43:22 +0000348Status BackendUnifiedServiceManager::getUpdatableNames(const ::std::string& apexName,
349 ::std::vector<::std::string>* _aidl_return) {
Parth Sane56a04712024-04-22 14:21:07 +0000350 return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return);
351}
Devin Moore678984f2024-10-18 22:43:22 +0000352Status BackendUnifiedServiceManager::getConnectionInfo(
Parth Sane56a04712024-04-22 14:21:07 +0000353 const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) {
354 return mTheRealServiceManager->getConnectionInfo(name, _aidl_return);
355}
Devin Moore678984f2024-10-18 22:43:22 +0000356Status BackendUnifiedServiceManager::registerClientCallback(
Parth Sane56a04712024-04-22 14:21:07 +0000357 const ::std::string& name, const sp<IBinder>& service,
358 const sp<os::IClientCallback>& callback) {
359 return mTheRealServiceManager->registerClientCallback(name, service, callback);
360}
Devin Moore678984f2024-10-18 22:43:22 +0000361Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name,
362 const sp<IBinder>& service) {
Parth Sane56a04712024-04-22 14:21:07 +0000363 return mTheRealServiceManager->tryUnregisterService(name, service);
364}
Devin Moore678984f2024-10-18 22:43:22 +0000365Status BackendUnifiedServiceManager::getServiceDebugInfo(
Parth Sane56a04712024-04-22 14:21:07 +0000366 ::std::vector<os::ServiceDebugInfo>* _aidl_return) {
367 return mTheRealServiceManager->getServiceDebugInfo(_aidl_return);
368}
369
370[[clang::no_destroy]] static std::once_flag gUSmOnce;
371[[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager;
372
373sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
374 std::call_once(gUSmOnce, []() {
375#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
376 /* wait for service manager */ {
377 using std::literals::chrono_literals::operator""s;
378 using android::base::WaitForProperty;
379 while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
380 ALOGE("Waited for servicemanager.ready for a second, waiting another...");
381 }
382 }
383#endif
384
385 sp<AidlServiceManager> sm = nullptr;
386 while (sm == nullptr) {
387 sm = interface_cast<AidlServiceManager>(
388 ProcessState::self()->getContextObject(nullptr));
389 if (sm == nullptr) {
390 ALOGE("Waiting 1s on context object on %s.",
391 ProcessState::self()->getDriverName().c_str());
392 sleep(1);
393 }
394 }
395
396 gUnifiedServiceManager = sp<BackendUnifiedServiceManager>::make(sm);
397 });
398
399 return gUnifiedServiceManager;
400}
401
Devin Moore18f63752024-08-08 21:01:24 +0000402} // namespace android