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