xref: /aosp_15_r20/frameworks/native/libs/binder/BackendUnifiedServiceManager.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2024 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker #pragma once
17*38e8c45fSAndroid Build Coastguard Worker 
18*38e8c45fSAndroid Build Coastguard Worker #include <android/os/BnServiceManager.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <android/os/IServiceManager.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <binder/Trace.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <map>
23*38e8c45fSAndroid Build Coastguard Worker #include <memory>
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker namespace android {
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker class BinderCacheWithInvalidation
28*38e8c45fSAndroid Build Coastguard Worker       : public std::enable_shared_from_this<BinderCacheWithInvalidation> {
29*38e8c45fSAndroid Build Coastguard Worker     class BinderInvalidation : public IBinder::DeathRecipient {
30*38e8c45fSAndroid Build Coastguard Worker     public:
BinderInvalidation(std::weak_ptr<BinderCacheWithInvalidation> cache,const std::string & key)31*38e8c45fSAndroid Build Coastguard Worker         BinderInvalidation(std::weak_ptr<BinderCacheWithInvalidation> cache, const std::string& key)
32*38e8c45fSAndroid Build Coastguard Worker               : mCache(cache), mKey(key) {}
33*38e8c45fSAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> & who)34*38e8c45fSAndroid Build Coastguard Worker         void binderDied(const wp<IBinder>& who) override {
35*38e8c45fSAndroid Build Coastguard Worker             sp<IBinder> binder = who.promote();
36*38e8c45fSAndroid Build Coastguard Worker             if (std::shared_ptr<BinderCacheWithInvalidation> cache = mCache.lock()) {
37*38e8c45fSAndroid Build Coastguard Worker                 cache->removeItem(mKey, binder);
38*38e8c45fSAndroid Build Coastguard Worker             } else {
39*38e8c45fSAndroid Build Coastguard Worker                 ALOGI("Binder Cache pointer expired: %s", mKey.c_str());
40*38e8c45fSAndroid Build Coastguard Worker             }
41*38e8c45fSAndroid Build Coastguard Worker         }
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker     private:
44*38e8c45fSAndroid Build Coastguard Worker         std::weak_ptr<BinderCacheWithInvalidation> mCache;
45*38e8c45fSAndroid Build Coastguard Worker         std::string mKey;
46*38e8c45fSAndroid Build Coastguard Worker     };
47*38e8c45fSAndroid Build Coastguard Worker     struct Entry {
48*38e8c45fSAndroid Build Coastguard Worker         sp<IBinder> service;
49*38e8c45fSAndroid Build Coastguard Worker         sp<BinderInvalidation> deathRecipient;
50*38e8c45fSAndroid Build Coastguard Worker     };
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker public:
getItem(const std::string & key)53*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> getItem(const std::string& key) const {
54*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mCacheMutex);
55*38e8c45fSAndroid Build Coastguard Worker 
56*38e8c45fSAndroid Build Coastguard Worker         if (auto it = mCache.find(key); it != mCache.end()) {
57*38e8c45fSAndroid Build Coastguard Worker             return it->second.service;
58*38e8c45fSAndroid Build Coastguard Worker         }
59*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
60*38e8c45fSAndroid Build Coastguard Worker     }
61*38e8c45fSAndroid Build Coastguard Worker 
removeItem(const std::string & key,const sp<IBinder> & who)62*38e8c45fSAndroid Build Coastguard Worker     bool removeItem(const std::string& key, const sp<IBinder>& who) {
63*38e8c45fSAndroid Build Coastguard Worker         std::string traceStr;
64*38e8c45fSAndroid Build Coastguard Worker         uint64_t tag = ATRACE_TAG_AIDL;
65*38e8c45fSAndroid Build Coastguard Worker         if (atrace_is_tag_enabled(tag)) {
66*38e8c45fSAndroid Build Coastguard Worker             traceStr = "BinderCacheWithInvalidation::removeItem " + key;
67*38e8c45fSAndroid Build Coastguard Worker         }
68*38e8c45fSAndroid Build Coastguard Worker         binder::ScopedTrace aidlTrace(tag, traceStr.c_str());
69*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mCacheMutex);
70*38e8c45fSAndroid Build Coastguard Worker         if (auto it = mCache.find(key); it != mCache.end()) {
71*38e8c45fSAndroid Build Coastguard Worker             if (it->second.service == who) {
72*38e8c45fSAndroid Build Coastguard Worker                 status_t result = who->unlinkToDeath(it->second.deathRecipient);
73*38e8c45fSAndroid Build Coastguard Worker                 if (result != DEAD_OBJECT) {
74*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Unlinking to dead binder resulted in: %d", result);
75*38e8c45fSAndroid Build Coastguard Worker                 }
76*38e8c45fSAndroid Build Coastguard Worker                 mCache.erase(key);
77*38e8c45fSAndroid Build Coastguard Worker                 return true;
78*38e8c45fSAndroid Build Coastguard Worker             }
79*38e8c45fSAndroid Build Coastguard Worker         }
80*38e8c45fSAndroid Build Coastguard Worker         return false;
81*38e8c45fSAndroid Build Coastguard Worker     }
82*38e8c45fSAndroid Build Coastguard Worker 
setItem(const std::string & key,const sp<IBinder> & item)83*38e8c45fSAndroid Build Coastguard Worker     binder::Status setItem(const std::string& key, const sp<IBinder>& item) {
84*38e8c45fSAndroid Build Coastguard Worker         sp<BinderInvalidation> deathRecipient =
85*38e8c45fSAndroid Build Coastguard Worker                 sp<BinderInvalidation>::make(shared_from_this(), key);
86*38e8c45fSAndroid Build Coastguard Worker 
87*38e8c45fSAndroid Build Coastguard Worker         // linkToDeath if binder is a remote binder.
88*38e8c45fSAndroid Build Coastguard Worker         if (item->localBinder() == nullptr) {
89*38e8c45fSAndroid Build Coastguard Worker             status_t status = item->linkToDeath(deathRecipient);
90*38e8c45fSAndroid Build Coastguard Worker             if (status != android::OK) {
91*38e8c45fSAndroid Build Coastguard Worker                 std::string traceStr;
92*38e8c45fSAndroid Build Coastguard Worker                 uint64_t tag = ATRACE_TAG_AIDL;
93*38e8c45fSAndroid Build Coastguard Worker                 if (atrace_is_tag_enabled(tag)) {
94*38e8c45fSAndroid Build Coastguard Worker                     traceStr =
95*38e8c45fSAndroid Build Coastguard Worker                             "BinderCacheWithInvalidation::setItem Failed LinkToDeath for service " +
96*38e8c45fSAndroid Build Coastguard Worker                             key + " : " + std::to_string(status);
97*38e8c45fSAndroid Build Coastguard Worker                 }
98*38e8c45fSAndroid Build Coastguard Worker                 binder::ScopedTrace aidlTrace(tag, traceStr.c_str());
99*38e8c45fSAndroid Build Coastguard Worker 
100*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Failed to linkToDeath binder for service %s. Error: %d", key.c_str(),
101*38e8c45fSAndroid Build Coastguard Worker                       status);
102*38e8c45fSAndroid Build Coastguard Worker                 return binder::Status::fromStatusT(status);
103*38e8c45fSAndroid Build Coastguard Worker             }
104*38e8c45fSAndroid Build Coastguard Worker         }
105*38e8c45fSAndroid Build Coastguard Worker         binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
106*38e8c45fSAndroid Build Coastguard Worker                                       "BinderCacheWithInvalidation::setItem Successfully Cached");
107*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mCacheMutex);
108*38e8c45fSAndroid Build Coastguard Worker         mCache[key] = {.service = item, .deathRecipient = deathRecipient};
109*38e8c45fSAndroid Build Coastguard Worker         return binder::Status::ok();
110*38e8c45fSAndroid Build Coastguard Worker     }
111*38e8c45fSAndroid Build Coastguard Worker 
112*38e8c45fSAndroid Build Coastguard Worker     bool isClientSideCachingEnabled(const std::string& serviceName);
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker private:
115*38e8c45fSAndroid Build Coastguard Worker     std::map<std::string, Entry> mCache;
116*38e8c45fSAndroid Build Coastguard Worker     mutable std::mutex mCacheMutex;
117*38e8c45fSAndroid Build Coastguard Worker };
118*38e8c45fSAndroid Build Coastguard Worker 
119*38e8c45fSAndroid Build Coastguard Worker class BackendUnifiedServiceManager : public android::os::BnServiceManager {
120*38e8c45fSAndroid Build Coastguard Worker public:
121*38e8c45fSAndroid Build Coastguard Worker     explicit BackendUnifiedServiceManager(const sp<os::IServiceManager>& impl);
122*38e8c45fSAndroid Build Coastguard Worker 
123*38e8c45fSAndroid Build Coastguard Worker     binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
124*38e8c45fSAndroid Build Coastguard Worker     binder::Status getService2(const ::std::string& name, os::Service* out) override;
125*38e8c45fSAndroid Build Coastguard Worker     binder::Status checkService(const ::std::string& name, os::Service* out) override;
126*38e8c45fSAndroid Build Coastguard Worker     binder::Status addService(const ::std::string& name, const sp<IBinder>& service,
127*38e8c45fSAndroid Build Coastguard Worker                               bool allowIsolated, int32_t dumpPriority) override;
128*38e8c45fSAndroid Build Coastguard Worker     binder::Status listServices(int32_t dumpPriority,
129*38e8c45fSAndroid Build Coastguard Worker                                 ::std::vector<::std::string>* _aidl_return) override;
130*38e8c45fSAndroid Build Coastguard Worker     binder::Status registerForNotifications(const ::std::string& name,
131*38e8c45fSAndroid Build Coastguard Worker                                             const sp<os::IServiceCallback>& callback) override;
132*38e8c45fSAndroid Build Coastguard Worker     binder::Status unregisterForNotifications(const ::std::string& name,
133*38e8c45fSAndroid Build Coastguard Worker                                               const sp<os::IServiceCallback>& callback) override;
134*38e8c45fSAndroid Build Coastguard Worker     binder::Status isDeclared(const ::std::string& name, bool* _aidl_return) override;
135*38e8c45fSAndroid Build Coastguard Worker     binder::Status getDeclaredInstances(const ::std::string& iface,
136*38e8c45fSAndroid Build Coastguard Worker                                         ::std::vector<::std::string>* _aidl_return) override;
137*38e8c45fSAndroid Build Coastguard Worker     binder::Status updatableViaApex(const ::std::string& name,
138*38e8c45fSAndroid Build Coastguard Worker                                     ::std::optional<::std::string>* _aidl_return) override;
139*38e8c45fSAndroid Build Coastguard Worker     binder::Status getUpdatableNames(const ::std::string& apexName,
140*38e8c45fSAndroid Build Coastguard Worker                                      ::std::vector<::std::string>* _aidl_return) override;
141*38e8c45fSAndroid Build Coastguard Worker     binder::Status getConnectionInfo(const ::std::string& name,
142*38e8c45fSAndroid Build Coastguard Worker                                      ::std::optional<os::ConnectionInfo>* _aidl_return) override;
143*38e8c45fSAndroid Build Coastguard Worker     binder::Status registerClientCallback(const ::std::string& name, const sp<IBinder>& service,
144*38e8c45fSAndroid Build Coastguard Worker                                           const sp<os::IClientCallback>& callback) override;
145*38e8c45fSAndroid Build Coastguard Worker     binder::Status tryUnregisterService(const ::std::string& name,
146*38e8c45fSAndroid Build Coastguard Worker                                         const sp<IBinder>& service) override;
147*38e8c45fSAndroid Build Coastguard Worker     binder::Status getServiceDebugInfo(::std::vector<os::ServiceDebugInfo>* _aidl_return) override;
148*38e8c45fSAndroid Build Coastguard Worker 
enableAddServiceCache(bool value)149*38e8c45fSAndroid Build Coastguard Worker     void enableAddServiceCache(bool value) { mEnableAddServiceCache = value; }
150*38e8c45fSAndroid Build Coastguard Worker     // for legacy ABI
getInterfaceDescriptor()151*38e8c45fSAndroid Build Coastguard Worker     const String16& getInterfaceDescriptor() const override {
152*38e8c45fSAndroid Build Coastguard Worker         return mTheRealServiceManager->getInterfaceDescriptor();
153*38e8c45fSAndroid Build Coastguard Worker     }
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker private:
156*38e8c45fSAndroid Build Coastguard Worker     bool mEnableAddServiceCache = true;
157*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<BinderCacheWithInvalidation> mCacheForGetService;
158*38e8c45fSAndroid Build Coastguard Worker     sp<os::IServiceManager> mTheRealServiceManager;
159*38e8c45fSAndroid Build Coastguard Worker     binder::Status toBinderService(const ::std::string& name, const os::Service& in,
160*38e8c45fSAndroid Build Coastguard Worker                                    os::Service* _out);
161*38e8c45fSAndroid Build Coastguard Worker     binder::Status updateCache(const std::string& serviceName, const os::Service& service);
162*38e8c45fSAndroid Build Coastguard Worker     binder::Status updateCache(const std::string& serviceName, const sp<IBinder>& binder,
163*38e8c45fSAndroid Build Coastguard Worker                                bool isLazyService);
164*38e8c45fSAndroid Build Coastguard Worker     bool returnIfCached(const std::string& serviceName, os::Service* _out);
165*38e8c45fSAndroid Build Coastguard Worker };
166*38e8c45fSAndroid Build Coastguard Worker 
167*38e8c45fSAndroid Build Coastguard Worker sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager();
168*38e8c45fSAndroid Build Coastguard Worker 
169*38e8c45fSAndroid Build Coastguard Worker android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service);
170*38e8c45fSAndroid Build Coastguard Worker 
171*38e8c45fSAndroid Build Coastguard Worker } // namespace android
172