blob: b46bf194a1c1fd798b093cb4709a3ed1dea5cba3 [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#pragma once
17
Parth Sane56a04712024-04-22 14:21:07 +000018#include <android/os/BnServiceManager.h>
19#include <android/os/IServiceManager.h>
20#include <binder/IPCThreadState.h>
Parth Sanea6676ba2024-10-04 14:14:07 +000021#include <binder/Trace.h>
Parth Saneb6ed0eb2024-06-25 14:38:42 +000022#include <map>
23#include <memory>
Parth Sane56a04712024-04-22 14:21:07 +000024
25namespace android {
26
Parth Saneb6ed0eb2024-06-25 14:38:42 +000027class BinderCacheWithInvalidation
28 : public std::enable_shared_from_this<BinderCacheWithInvalidation> {
29 class BinderInvalidation : public IBinder::DeathRecipient {
30 public:
31 BinderInvalidation(std::weak_ptr<BinderCacheWithInvalidation> cache, const std::string& key)
32 : mCache(cache), mKey(key) {}
33
34 void binderDied(const wp<IBinder>& who) override {
35 sp<IBinder> binder = who.promote();
36 if (std::shared_ptr<BinderCacheWithInvalidation> cache = mCache.lock()) {
37 cache->removeItem(mKey, binder);
38 } else {
39 ALOGI("Binder Cache pointer expired: %s", mKey.c_str());
40 }
41 }
42
43 private:
44 std::weak_ptr<BinderCacheWithInvalidation> mCache;
45 std::string mKey;
46 };
47 struct Entry {
48 sp<IBinder> service;
49 sp<BinderInvalidation> deathRecipient;
50 };
51
52public:
53 sp<IBinder> getItem(const std::string& key) const {
54 std::lock_guard<std::mutex> lock(mCacheMutex);
55
56 if (auto it = mCache.find(key); it != mCache.end()) {
57 return it->second.service;
58 }
59 return nullptr;
60 }
61
62 bool removeItem(const std::string& key, const sp<IBinder>& who) {
Parth Sanea6676ba2024-10-04 14:14:07 +000063 std::string traceStr;
64 uint64_t tag = ATRACE_TAG_AIDL;
65 if (atrace_is_tag_enabled(tag)) {
66 traceStr = "BinderCacheWithInvalidation::removeItem " + key;
67 }
68 binder::ScopedTrace aidlTrace(tag, traceStr.c_str());
Parth Saneb6ed0eb2024-06-25 14:38:42 +000069 std::lock_guard<std::mutex> lock(mCacheMutex);
70 if (auto it = mCache.find(key); it != mCache.end()) {
71 if (it->second.service == who) {
72 status_t result = who->unlinkToDeath(it->second.deathRecipient);
73 if (result != DEAD_OBJECT) {
74 ALOGW("Unlinking to dead binder resulted in: %d", result);
75 }
76 mCache.erase(key);
77 return true;
78 }
79 }
80 return false;
81 }
82
83 binder::Status setItem(const std::string& key, const sp<IBinder>& item) {
84 sp<BinderInvalidation> deathRecipient =
85 sp<BinderInvalidation>::make(shared_from_this(), key);
86
87 // linkToDeath if binder is a remote binder.
88 if (item->localBinder() == nullptr) {
89 status_t status = item->linkToDeath(deathRecipient);
90 if (status != android::OK) {
Parth Sanea6676ba2024-10-04 14:14:07 +000091 std::string traceStr;
92 uint64_t tag = ATRACE_TAG_AIDL;
93 if (atrace_is_tag_enabled(tag)) {
94 traceStr =
95 "BinderCacheWithInvalidation::setItem Failed LinkToDeath for service " +
96 key + " : " + std::to_string(status);
97 }
98 binder::ScopedTrace aidlTrace(tag, traceStr.c_str());
99
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000100 ALOGE("Failed to linkToDeath binder for service %s. Error: %d", key.c_str(),
101 status);
102 return binder::Status::fromStatusT(status);
103 }
104 }
Parth Sanea6676ba2024-10-04 14:14:07 +0000105 binder::ScopedTrace aidlTrace(ATRACE_TAG_AIDL,
106 "BinderCacheWithInvalidation::setItem Successfully Cached");
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000107 std::lock_guard<std::mutex> lock(mCacheMutex);
Parth Sanedc207542024-11-14 11:49:08 +0000108 mCache[key] = {.service = item, .deathRecipient = deathRecipient};
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000109 return binder::Status::ok();
110 }
111
112 bool isClientSideCachingEnabled(const std::string& serviceName);
113
114private:
115 std::map<std::string, Entry> mCache;
116 mutable std::mutex mCacheMutex;
117};
118
Parth Sane56a04712024-04-22 14:21:07 +0000119class BackendUnifiedServiceManager : public android::os::BnServiceManager {
120public:
121 explicit BackendUnifiedServiceManager(const sp<os::IServiceManager>& impl);
122
Alice Wang11da1502024-07-25 12:03:22 +0000123 binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
124 binder::Status getService2(const ::std::string& name, os::Service* out) override;
Alice Wang8578f132024-05-03 09:01:56 +0000125 binder::Status checkService(const ::std::string& name, os::Service* out) override;
Parth Sane56a04712024-04-22 14:21:07 +0000126 binder::Status addService(const ::std::string& name, const sp<IBinder>& service,
127 bool allowIsolated, int32_t dumpPriority) override;
128 binder::Status listServices(int32_t dumpPriority,
129 ::std::vector<::std::string>* _aidl_return) override;
130 binder::Status registerForNotifications(const ::std::string& name,
131 const sp<os::IServiceCallback>& callback) override;
132 binder::Status unregisterForNotifications(const ::std::string& name,
133 const sp<os::IServiceCallback>& callback) override;
134 binder::Status isDeclared(const ::std::string& name, bool* _aidl_return) override;
135 binder::Status getDeclaredInstances(const ::std::string& iface,
136 ::std::vector<::std::string>* _aidl_return) override;
137 binder::Status updatableViaApex(const ::std::string& name,
138 ::std::optional<::std::string>* _aidl_return) override;
139 binder::Status getUpdatableNames(const ::std::string& apexName,
140 ::std::vector<::std::string>* _aidl_return) override;
141 binder::Status getConnectionInfo(const ::std::string& name,
142 ::std::optional<os::ConnectionInfo>* _aidl_return) override;
143 binder::Status registerClientCallback(const ::std::string& name, const sp<IBinder>& service,
144 const sp<os::IClientCallback>& callback) override;
145 binder::Status tryUnregisterService(const ::std::string& name,
146 const sp<IBinder>& service) override;
147 binder::Status getServiceDebugInfo(::std::vector<os::ServiceDebugInfo>* _aidl_return) override;
148
Parth Sanedc207542024-11-14 11:49:08 +0000149 void enableAddServiceCache(bool value) { mEnableAddServiceCache = value; }
Parth Sane56a04712024-04-22 14:21:07 +0000150 // for legacy ABI
151 const String16& getInterfaceDescriptor() const override {
152 return mTheRealServiceManager->getInterfaceDescriptor();
153 }
154
Parth Sane56a04712024-04-22 14:21:07 +0000155private:
Parth Sanedc207542024-11-14 11:49:08 +0000156 bool mEnableAddServiceCache = true;
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000157 std::shared_ptr<BinderCacheWithInvalidation> mCacheForGetService;
Parth Sane56a04712024-04-22 14:21:07 +0000158 sp<os::IServiceManager> mTheRealServiceManager;
Devin Moore18f63752024-08-08 21:01:24 +0000159 binder::Status toBinderService(const ::std::string& name, const os::Service& in,
160 os::Service* _out);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000161 binder::Status updateCache(const std::string& serviceName, const os::Service& service);
Parth Sanedc207542024-11-14 11:49:08 +0000162 binder::Status updateCache(const std::string& serviceName, const sp<IBinder>& binder);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000163 bool returnIfCached(const std::string& serviceName, os::Service* _out);
Parth Sane56a04712024-04-22 14:21:07 +0000164};
165
166sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager();
167
Devin Moore18f63752024-08-08 21:01:24 +0000168android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service);
169
170} // namespace android