blob: 47b2ec9f2ceb7029b78875b3f612b37de611150d [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 Saneb6ed0eb2024-06-25 14:38:42 +000021#include <map>
22#include <memory>
Parth Sane56a04712024-04-22 14:21:07 +000023
24namespace android {
25
Parth Saneb6ed0eb2024-06-25 14:38:42 +000026class BinderCacheWithInvalidation
27 : public std::enable_shared_from_this<BinderCacheWithInvalidation> {
28 class BinderInvalidation : public IBinder::DeathRecipient {
29 public:
30 BinderInvalidation(std::weak_ptr<BinderCacheWithInvalidation> cache, const std::string& key)
31 : mCache(cache), mKey(key) {}
32
33 void binderDied(const wp<IBinder>& who) override {
34 sp<IBinder> binder = who.promote();
35 if (std::shared_ptr<BinderCacheWithInvalidation> cache = mCache.lock()) {
36 cache->removeItem(mKey, binder);
37 } else {
38 ALOGI("Binder Cache pointer expired: %s", mKey.c_str());
39 }
40 }
41
42 private:
43 std::weak_ptr<BinderCacheWithInvalidation> mCache;
44 std::string mKey;
45 };
46 struct Entry {
47 sp<IBinder> service;
48 sp<BinderInvalidation> deathRecipient;
49 };
50
51public:
52 sp<IBinder> getItem(const std::string& key) const {
53 std::lock_guard<std::mutex> lock(mCacheMutex);
54
55 if (auto it = mCache.find(key); it != mCache.end()) {
56 return it->second.service;
57 }
58 return nullptr;
59 }
60
61 bool removeItem(const std::string& key, const sp<IBinder>& who) {
62 std::lock_guard<std::mutex> lock(mCacheMutex);
63 if (auto it = mCache.find(key); it != mCache.end()) {
64 if (it->second.service == who) {
65 status_t result = who->unlinkToDeath(it->second.deathRecipient);
66 if (result != DEAD_OBJECT) {
67 ALOGW("Unlinking to dead binder resulted in: %d", result);
68 }
69 mCache.erase(key);
70 return true;
71 }
72 }
73 return false;
74 }
75
76 binder::Status setItem(const std::string& key, const sp<IBinder>& item) {
77 sp<BinderInvalidation> deathRecipient =
78 sp<BinderInvalidation>::make(shared_from_this(), key);
79
80 // linkToDeath if binder is a remote binder.
81 if (item->localBinder() == nullptr) {
82 status_t status = item->linkToDeath(deathRecipient);
83 if (status != android::OK) {
84 ALOGE("Failed to linkToDeath binder for service %s. Error: %d", key.c_str(),
85 status);
86 return binder::Status::fromStatusT(status);
87 }
88 }
89 std::lock_guard<std::mutex> lock(mCacheMutex);
90 Entry entry = {.service = item, .deathRecipient = deathRecipient};
91 mCache[key] = entry;
92 return binder::Status::ok();
93 }
94
95 bool isClientSideCachingEnabled(const std::string& serviceName);
96
97private:
98 std::map<std::string, Entry> mCache;
99 mutable std::mutex mCacheMutex;
100};
101
Parth Sane56a04712024-04-22 14:21:07 +0000102class BackendUnifiedServiceManager : public android::os::BnServiceManager {
103public:
104 explicit BackendUnifiedServiceManager(const sp<os::IServiceManager>& impl);
105
106 sp<os::IServiceManager> getImpl();
Alice Wang11da1502024-07-25 12:03:22 +0000107 binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
108 binder::Status getService2(const ::std::string& name, os::Service* out) override;
Alice Wang8578f132024-05-03 09:01:56 +0000109 binder::Status checkService(const ::std::string& name, os::Service* out) override;
Parth Sane56a04712024-04-22 14:21:07 +0000110 binder::Status addService(const ::std::string& name, const sp<IBinder>& service,
111 bool allowIsolated, int32_t dumpPriority) override;
112 binder::Status listServices(int32_t dumpPriority,
113 ::std::vector<::std::string>* _aidl_return) override;
114 binder::Status registerForNotifications(const ::std::string& name,
115 const sp<os::IServiceCallback>& callback) override;
116 binder::Status unregisterForNotifications(const ::std::string& name,
117 const sp<os::IServiceCallback>& callback) override;
118 binder::Status isDeclared(const ::std::string& name, bool* _aidl_return) override;
119 binder::Status getDeclaredInstances(const ::std::string& iface,
120 ::std::vector<::std::string>* _aidl_return) override;
121 binder::Status updatableViaApex(const ::std::string& name,
122 ::std::optional<::std::string>* _aidl_return) override;
123 binder::Status getUpdatableNames(const ::std::string& apexName,
124 ::std::vector<::std::string>* _aidl_return) override;
125 binder::Status getConnectionInfo(const ::std::string& name,
126 ::std::optional<os::ConnectionInfo>* _aidl_return) override;
127 binder::Status registerClientCallback(const ::std::string& name, const sp<IBinder>& service,
128 const sp<os::IClientCallback>& callback) override;
129 binder::Status tryUnregisterService(const ::std::string& name,
130 const sp<IBinder>& service) override;
131 binder::Status getServiceDebugInfo(::std::vector<os::ServiceDebugInfo>* _aidl_return) override;
132
133 // for legacy ABI
134 const String16& getInterfaceDescriptor() const override {
135 return mTheRealServiceManager->getInterfaceDescriptor();
136 }
137
Parth Sane56a04712024-04-22 14:21:07 +0000138private:
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000139 std::shared_ptr<BinderCacheWithInvalidation> mCacheForGetService;
Parth Sane56a04712024-04-22 14:21:07 +0000140 sp<os::IServiceManager> mTheRealServiceManager;
Devin Moore18f63752024-08-08 21:01:24 +0000141 binder::Status toBinderService(const ::std::string& name, const os::Service& in,
142 os::Service* _out);
Parth Saneb6ed0eb2024-06-25 14:38:42 +0000143 binder::Status updateCache(const std::string& serviceName, const os::Service& service);
144 bool returnIfCached(const std::string& serviceName, os::Service* _out);
Parth Sane56a04712024-04-22 14:21:07 +0000145};
146
147sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager();
148
Devin Moore18f63752024-08-08 21:01:24 +0000149android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service);
150
151} // namespace android