xref: /aosp_15_r20/frameworks/native/libs/binder/BackendUnifiedServiceManager.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
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 
18 #include <android/os/IAccessor.h>
19 #include <android/os/IServiceManager.h>
20 #include <binder/RpcSession.h>
21 
22 #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
23 #include <android-base/properties.h>
24 #endif
25 
26 namespace android {
27 
28 #ifdef LIBBINDER_CLIENT_CACHE
29 constexpr bool kUseCache = true;
30 #else
31 constexpr bool kUseCache = false;
32 #endif
33 
34 #ifdef LIBBINDER_ADDSERVICE_CACHE
35 constexpr bool kUseCacheInAddService = true;
36 #else
37 constexpr bool kUseCacheInAddService = false;
38 #endif
39 
40 #ifdef LIBBINDER_REMOVE_CACHE_STATIC_LIST
41 constexpr bool kRemoveStaticList = true;
42 #else
43 constexpr bool kRemoveStaticList = false;
44 #endif
45 
46 using AidlServiceManager = android::os::IServiceManager;
47 using android::os::IAccessor;
48 using binder::Status;
49 
50 static const char* kStaticCachableList[] = {
51         // go/keep-sorted start
52         "accessibility",
53         "account",
54         "activity",
55         "alarm",
56         "android.frameworks.stats.IStats/default",
57         "android.system.keystore2.IKeystoreService/default",
58         "appops",
59         "audio",
60         "autofill",
61         "batteryproperties",
62         "batterystats",
63         "biometic",
64         "carrier_config",
65         "connectivity",
66         "content",
67         "content_capture",
68         "device_policy",
69         "display",
70         "dropbox",
71         "econtroller",
72         "graphicsstats",
73         "input",
74         "input_method",
75         "isub",
76         "jobscheduler",
77         "legacy_permission",
78         "location",
79         "lock_settings",
80         "media.extractor",
81         "media.metrics",
82         "media.player",
83         "media.resource_manager",
84         "media_resource_monitor",
85         "mount",
86         "netd_listener",
87         "netstats",
88         "network_management",
89         "nfc",
90         "notification",
91         "package",
92         "package_native",
93         "performance_hint",
94         "permission",
95         "permission_checker",
96         "permissionmgr",
97         "phone",
98         "platform_compat",
99         "power",
100         "processinfo",
101         "role",
102         "sensitive_content_protection_service",
103         "sensorservice",
104         "statscompanion",
105         "telephony.registry",
106         "thermalservice",
107         "time_detector",
108         "tracing.proxy",
109         "trust",
110         "uimode",
111         "user",
112         "vibrator",
113         "virtualdevice",
114         "virtualdevice_native",
115         "webviewupdate",
116         "window",
117         // go/keep-sorted end
118 };
119 
createServiceWithMetadata(const sp<IBinder> & service,bool isLazyService)120 os::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 
isClientSideCachingEnabled(const std::string & serviceName)127 bool BinderCacheWithInvalidation::isClientSideCachingEnabled(const std::string& serviceName) {
128     sp<ProcessState> self = ProcessState::selfOrNull();
129     if (!self || self->getThreadPoolMaxTotalThreadCount() <= 0) {
130         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     if (kRemoveStaticList) return true;
136     for (const char* name : kStaticCachableList) {
137         if (name == serviceName) {
138             return true;
139         }
140     }
141     return false;
142 }
143 
updateCache(const std::string & serviceName,const os::Service & service)144 Status BackendUnifiedServiceManager::updateCache(const std::string& serviceName,
145                                                  const os::Service& service) {
146     if (!kUseCache) {
147         return Status::ok();
148     }
149 
150     if (service.getTag() == os::Service::Tag::serviceWithMetadata) {
151         auto serviceWithMetadata = service.get<os::Service::Tag::serviceWithMetadata>();
152         return updateCache(serviceName, serviceWithMetadata.service,
153                            serviceWithMetadata.isLazyService);
154     }
155     return Status::ok();
156 }
157 
updateCache(const std::string & serviceName,const sp<IBinder> & binder,bool isServiceLazy)158 Status BackendUnifiedServiceManager::updateCache(const std::string& serviceName,
159                                                  const sp<IBinder>& binder, bool isServiceLazy) {
160     std::string traceStr;
161     // Don't cache if service is lazy
162     if (kRemoveStaticList && isServiceLazy) {
163         return Status::ok();
164     }
165     if (atrace_is_tag_enabled(ATRACE_TAG_AIDL)) {
166         traceStr = "BinderCacheWithInvalidation::updateCache : " + serviceName;
167     }
168     binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL, traceStr.c_str());
169     if (!binder) {
170         binder::ScopedTrace
171                 aidlTrace(ATRACE_TAG_AIDL,
172                           "BinderCacheWithInvalidation::updateCache failed: binder_null");
173     } else if (!binder->isBinderAlive()) {
174         binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
175                                       "BinderCacheWithInvalidation::updateCache failed: "
176                                       "isBinderAlive_false");
177     }
178     // If we reach here with kRemoveStaticList=true then we know service isn't lazy
179     else if (mCacheForGetService->isClientSideCachingEnabled(serviceName)) {
180         binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
181                                       "BinderCacheWithInvalidation::updateCache successful");
182         return mCacheForGetService->setItem(serviceName, binder);
183     } else {
184         binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
185                                       "BinderCacheWithInvalidation::updateCache failed: "
186                                       "caching_not_enabled");
187     }
188     return Status::ok();
189 }
190 
returnIfCached(const std::string & serviceName,os::Service * _out)191 bool BackendUnifiedServiceManager::returnIfCached(const std::string& serviceName,
192                                                   os::Service* _out) {
193     if (!kUseCache) {
194         return false;
195     }
196     sp<IBinder> item = mCacheForGetService->getItem(serviceName);
197     // TODO(b/363177618): Enable caching for binders which are always null.
198     if (item != nullptr && item->isBinderAlive()) {
199         *_out = createServiceWithMetadata(item, false);
200         return true;
201     }
202     return false;
203 }
204 
BackendUnifiedServiceManager(const sp<AidlServiceManager> & impl)205 BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl)
206       : mTheRealServiceManager(impl) {
207     mCacheForGetService = std::make_shared<BinderCacheWithInvalidation>();
208 }
209 
getService(const::std::string & name,sp<IBinder> * _aidl_return)210 Status BackendUnifiedServiceManager::getService(const ::std::string& name,
211                                                 sp<IBinder>* _aidl_return) {
212     os::Service service;
213     Status status = getService2(name, &service);
214     *_aidl_return = service.get<os::Service::Tag::serviceWithMetadata>().service;
215     return status;
216 }
217 
getService2(const::std::string & name,os::Service * _out)218 Status BackendUnifiedServiceManager::getService2(const ::std::string& name, os::Service* _out) {
219     if (returnIfCached(name, _out)) {
220         return Status::ok();
221     }
222     os::Service service;
223     Status status = mTheRealServiceManager->getService2(name, &service);
224 
225     if (status.isOk()) {
226         status = toBinderService(name, service, _out);
227         if (status.isOk()) {
228             return updateCache(name, service);
229         }
230     }
231     return status;
232 }
233 
checkService(const::std::string & name,os::Service * _out)234 Status BackendUnifiedServiceManager::checkService(const ::std::string& name, os::Service* _out) {
235     os::Service service;
236     if (returnIfCached(name, _out)) {
237         return Status::ok();
238     }
239 
240     Status status = mTheRealServiceManager->checkService(name, &service);
241     if (status.isOk()) {
242         status = toBinderService(name, service, _out);
243         if (status.isOk()) {
244             return updateCache(name, service);
245         }
246     }
247     return status;
248 }
249 
toBinderService(const::std::string & name,const os::Service & in,os::Service * _out)250 Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name,
251                                                      const os::Service& in, os::Service* _out) {
252     switch (in.getTag()) {
253         case os::Service::Tag::serviceWithMetadata: {
254             auto serviceWithMetadata = in.get<os::Service::Tag::serviceWithMetadata>();
255             if (serviceWithMetadata.service == nullptr) {
256                 // failed to find a service. Check to see if we have any local
257                 // injected Accessors for this service.
258                 os::Service accessor;
259                 Status status = getInjectedAccessor(name, &accessor);
260                 if (!status.isOk()) {
261                     *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
262                             createServiceWithMetadata(nullptr, false));
263                     return status;
264                 }
265                 if (accessor.getTag() == os::Service::Tag::accessor &&
266                     accessor.get<os::Service::Tag::accessor>() != nullptr) {
267                     ALOGI("Found local injected service for %s, will attempt to create connection",
268                           name.c_str());
269                     // Call this again using the accessor Service to get the real
270                     // service's binder into _out
271                     return toBinderService(name, accessor, _out);
272                 }
273             }
274 
275             *_out = in;
276             return Status::ok();
277         }
278         case os::Service::Tag::accessor: {
279             sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>();
280             sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder);
281             if (accessor == nullptr) {
282                 ALOGE("Service#accessor doesn't have accessor. VM is maybe starting...");
283                 *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
284                         createServiceWithMetadata(nullptr, false));
285                 return Status::ok();
286             }
287             auto request = [=] {
288                 os::ParcelFileDescriptor fd;
289                 Status ret = accessor->addConnection(&fd);
290                 if (ret.isOk()) {
291                     return base::unique_fd(fd.release());
292                 } else {
293                     ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str());
294                     return base::unique_fd(-1);
295                 }
296             };
297             auto session = RpcSession::make();
298             status_t status = session->setupPreconnectedClient(base::unique_fd{}, request);
299             if (status != OK) {
300                 ALOGE("Failed to set up preconnected binder RPC client: %s",
301                       statusToString(status).c_str());
302                 return Status::fromStatusT(status);
303             }
304             session->setSessionSpecificRoot(accessorBinder);
305             *_out = os::Service::make<os::Service::Tag::serviceWithMetadata>(
306                     createServiceWithMetadata(session->getRootObject(), false));
307             return Status::ok();
308         }
309         default: {
310             LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag());
311         }
312     }
313 }
314 
addService(const::std::string & name,const sp<IBinder> & service,bool allowIsolated,int32_t dumpPriority)315 Status BackendUnifiedServiceManager::addService(const ::std::string& name,
316                                                 const sp<IBinder>& service, bool allowIsolated,
317                                                 int32_t dumpPriority) {
318     Status status = mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
319     // mEnableAddServiceCache is true by default.
320     if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) {
321         return updateCache(name, service,
322                            dumpPriority & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE);
323     }
324     return status;
325 }
listServices(int32_t dumpPriority,::std::vector<::std::string> * _aidl_return)326 Status BackendUnifiedServiceManager::listServices(int32_t dumpPriority,
327                                                   ::std::vector<::std::string>* _aidl_return) {
328     return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
329 }
registerForNotifications(const::std::string & name,const sp<os::IServiceCallback> & callback)330 Status BackendUnifiedServiceManager::registerForNotifications(
331         const ::std::string& name, const sp<os::IServiceCallback>& callback) {
332     return mTheRealServiceManager->registerForNotifications(name, callback);
333 }
unregisterForNotifications(const::std::string & name,const sp<os::IServiceCallback> & callback)334 Status BackendUnifiedServiceManager::unregisterForNotifications(
335         const ::std::string& name, const sp<os::IServiceCallback>& callback) {
336     return mTheRealServiceManager->unregisterForNotifications(name, callback);
337 }
isDeclared(const::std::string & name,bool * _aidl_return)338 Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name, bool* _aidl_return) {
339     return mTheRealServiceManager->isDeclared(name, _aidl_return);
340 }
getDeclaredInstances(const::std::string & iface,::std::vector<::std::string> * _aidl_return)341 Status BackendUnifiedServiceManager::getDeclaredInstances(
342         const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) {
343     return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
344 }
updatableViaApex(const::std::string & name,::std::optional<::std::string> * _aidl_return)345 Status BackendUnifiedServiceManager::updatableViaApex(
346         const ::std::string& name, ::std::optional<::std::string>* _aidl_return) {
347     return mTheRealServiceManager->updatableViaApex(name, _aidl_return);
348 }
getUpdatableNames(const::std::string & apexName,::std::vector<::std::string> * _aidl_return)349 Status BackendUnifiedServiceManager::getUpdatableNames(const ::std::string& apexName,
350                                                        ::std::vector<::std::string>* _aidl_return) {
351     return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return);
352 }
getConnectionInfo(const::std::string & name,::std::optional<os::ConnectionInfo> * _aidl_return)353 Status BackendUnifiedServiceManager::getConnectionInfo(
354         const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) {
355     return mTheRealServiceManager->getConnectionInfo(name, _aidl_return);
356 }
registerClientCallback(const::std::string & name,const sp<IBinder> & service,const sp<os::IClientCallback> & callback)357 Status BackendUnifiedServiceManager::registerClientCallback(
358         const ::std::string& name, const sp<IBinder>& service,
359         const sp<os::IClientCallback>& callback) {
360     return mTheRealServiceManager->registerClientCallback(name, service, callback);
361 }
tryUnregisterService(const::std::string & name,const sp<IBinder> & service)362 Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name,
363                                                           const sp<IBinder>& service) {
364     return mTheRealServiceManager->tryUnregisterService(name, service);
365 }
getServiceDebugInfo(::std::vector<os::ServiceDebugInfo> * _aidl_return)366 Status BackendUnifiedServiceManager::getServiceDebugInfo(
367         ::std::vector<os::ServiceDebugInfo>* _aidl_return) {
368     return mTheRealServiceManager->getServiceDebugInfo(_aidl_return);
369 }
370 
371 [[clang::no_destroy]] static std::once_flag gUSmOnce;
372 [[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager;
373 
getBackendUnifiedServiceManager()374 sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
375     std::call_once(gUSmOnce, []() {
376 #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
377         /* wait for service manager */ {
378             using std::literals::chrono_literals::operator""s;
379             using android::base::WaitForProperty;
380             while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
381                 ALOGE("Waited for servicemanager.ready for a second, waiting another...");
382             }
383         }
384 #endif
385 
386         sp<AidlServiceManager> sm = nullptr;
387         while (sm == nullptr) {
388             sm = interface_cast<AidlServiceManager>(
389                     ProcessState::self()->getContextObject(nullptr));
390             if (sm == nullptr) {
391                 ALOGE("Waiting 1s on context object on %s.",
392                       ProcessState::self()->getDriverName().c_str());
393                 sleep(1);
394             }
395         }
396 
397         gUnifiedServiceManager = sp<BackendUnifiedServiceManager>::make(sm);
398     });
399 
400     return gUnifiedServiceManager;
401 }
402 
403 } // namespace android
404