xref: /aosp_15_r20/frameworks/native/libs/binder/BpBinder.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2005 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 
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "BpBinder"
18*38e8c45fSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker #include <binder/BpBinder.h>
21*38e8c45fSAndroid Build Coastguard Worker 
22*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <binder/IResultReceiver.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcSession.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <binder/Stability.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <binder/Trace.h>
27*38e8c45fSAndroid Build Coastguard Worker 
28*38e8c45fSAndroid Build Coastguard Worker #include <stdio.h>
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker #include "BuildFlags.h"
31*38e8c45fSAndroid Build Coastguard Worker #include "file.h"
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker //#undef ALOGV
34*38e8c45fSAndroid Build Coastguard Worker //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker namespace android {
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker using android::binder::unique_fd;
39*38e8c45fSAndroid Build Coastguard Worker 
40*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
41*38e8c45fSAndroid Build Coastguard Worker 
42*38e8c45fSAndroid Build Coastguard Worker RpcMutex BpBinder::sTrackingLock;
43*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<int32_t, uint32_t> BpBinder::sTrackingMap;
44*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<int32_t, uint32_t> BpBinder::sLastLimitCallbackMap;
45*38e8c45fSAndroid Build Coastguard Worker int BpBinder::sNumTrackedUids = 0;
46*38e8c45fSAndroid Build Coastguard Worker std::atomic_bool BpBinder::sCountByUidEnabled(false);
47*38e8c45fSAndroid Build Coastguard Worker binder_proxy_limit_callback BpBinder::sLimitCallback;
48*38e8c45fSAndroid Build Coastguard Worker binder_proxy_warning_callback BpBinder::sWarningCallback;
49*38e8c45fSAndroid Build Coastguard Worker bool BpBinder::sBinderProxyThrottleCreate = false;
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker static StaticString16 kDescriptorUninit(u"");
52*38e8c45fSAndroid Build Coastguard Worker 
53*38e8c45fSAndroid Build Coastguard Worker // Arbitrarily high value that probably distinguishes a bad behaving app
54*38e8c45fSAndroid Build Coastguard Worker uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500;
55*38e8c45fSAndroid Build Coastguard Worker // Another arbitrary value a binder count needs to drop below before another callback will be called
56*38e8c45fSAndroid Build Coastguard Worker uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000;
57*38e8c45fSAndroid Build Coastguard Worker // Arbitrary value between low and high watermark on a bad behaving app to
58*38e8c45fSAndroid Build Coastguard Worker // trigger a warning callback.
59*38e8c45fSAndroid Build Coastguard Worker uint32_t BpBinder::sBinderProxyCountWarningWatermark = 2250;
60*38e8c45fSAndroid Build Coastguard Worker 
61*38e8c45fSAndroid Build Coastguard Worker std::atomic<uint32_t> BpBinder::sBinderProxyCount(0);
62*38e8c45fSAndroid Build Coastguard Worker std::atomic<uint32_t> BpBinder::sBinderProxyCountWarned(0);
63*38e8c45fSAndroid Build Coastguard Worker 
64*38e8c45fSAndroid Build Coastguard Worker static constexpr uint32_t kBinderProxyCountWarnInterval = 5000;
65*38e8c45fSAndroid Build Coastguard Worker 
66*38e8c45fSAndroid Build Coastguard Worker // Log any transactions for which the data exceeds this size
67*38e8c45fSAndroid Build Coastguard Worker #define LOG_TRANSACTIONS_OVER_SIZE (300 * 1024)
68*38e8c45fSAndroid Build Coastguard Worker 
69*38e8c45fSAndroid Build Coastguard Worker enum {
70*38e8c45fSAndroid Build Coastguard Worker     LIMIT_REACHED_MASK = 0x80000000,        // A flag denoting that the limit has been reached
71*38e8c45fSAndroid Build Coastguard Worker     WARNING_REACHED_MASK = 0x40000000,      // A flag denoting that the warning has been reached
72*38e8c45fSAndroid Build Coastguard Worker     COUNTING_VALUE_MASK = 0x3FFFFFFF,       // A mask of the remaining bits for the count value
73*38e8c45fSAndroid Build Coastguard Worker };
74*38e8c45fSAndroid Build Coastguard Worker 
ObjectManager()75*38e8c45fSAndroid Build Coastguard Worker BpBinder::ObjectManager::ObjectManager()
76*38e8c45fSAndroid Build Coastguard Worker {
77*38e8c45fSAndroid Build Coastguard Worker }
78*38e8c45fSAndroid Build Coastguard Worker 
~ObjectManager()79*38e8c45fSAndroid Build Coastguard Worker BpBinder::ObjectManager::~ObjectManager()
80*38e8c45fSAndroid Build Coastguard Worker {
81*38e8c45fSAndroid Build Coastguard Worker     kill();
82*38e8c45fSAndroid Build Coastguard Worker }
83*38e8c45fSAndroid Build Coastguard Worker 
attach(const void * objectID,void * object,void * cleanupCookie,IBinder::object_cleanup_func func)84*38e8c45fSAndroid Build Coastguard Worker void* BpBinder::ObjectManager::attach(const void* objectID, void* object, void* cleanupCookie,
85*38e8c45fSAndroid Build Coastguard Worker                                       IBinder::object_cleanup_func func) {
86*38e8c45fSAndroid Build Coastguard Worker     entry_t e;
87*38e8c45fSAndroid Build Coastguard Worker     e.object = object;
88*38e8c45fSAndroid Build Coastguard Worker     e.cleanupCookie = cleanupCookie;
89*38e8c45fSAndroid Build Coastguard Worker     e.func = func;
90*38e8c45fSAndroid Build Coastguard Worker 
91*38e8c45fSAndroid Build Coastguard Worker     if (mObjects.find(objectID) != mObjects.end()) {
92*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object "
93*38e8c45fSAndroid Build Coastguard Worker               "ID already in use",
94*38e8c45fSAndroid Build Coastguard Worker               objectID, this, object);
95*38e8c45fSAndroid Build Coastguard Worker         return mObjects[objectID].object;
96*38e8c45fSAndroid Build Coastguard Worker     }
97*38e8c45fSAndroid Build Coastguard Worker 
98*38e8c45fSAndroid Build Coastguard Worker     mObjects.insert({objectID, e});
99*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
100*38e8c45fSAndroid Build Coastguard Worker }
101*38e8c45fSAndroid Build Coastguard Worker 
find(const void * objectID) const102*38e8c45fSAndroid Build Coastguard Worker void* BpBinder::ObjectManager::find(const void* objectID) const
103*38e8c45fSAndroid Build Coastguard Worker {
104*38e8c45fSAndroid Build Coastguard Worker     auto i = mObjects.find(objectID);
105*38e8c45fSAndroid Build Coastguard Worker     if (i == mObjects.end()) return nullptr;
106*38e8c45fSAndroid Build Coastguard Worker     return i->second.object;
107*38e8c45fSAndroid Build Coastguard Worker }
108*38e8c45fSAndroid Build Coastguard Worker 
detach(const void * objectID)109*38e8c45fSAndroid Build Coastguard Worker void* BpBinder::ObjectManager::detach(const void* objectID) {
110*38e8c45fSAndroid Build Coastguard Worker     auto i = mObjects.find(objectID);
111*38e8c45fSAndroid Build Coastguard Worker     if (i == mObjects.end()) return nullptr;
112*38e8c45fSAndroid Build Coastguard Worker     void* value = i->second.object;
113*38e8c45fSAndroid Build Coastguard Worker     mObjects.erase(i);
114*38e8c45fSAndroid Build Coastguard Worker     return value;
115*38e8c45fSAndroid Build Coastguard Worker }
116*38e8c45fSAndroid Build Coastguard Worker 
117*38e8c45fSAndroid Build Coastguard Worker namespace {
118*38e8c45fSAndroid Build Coastguard Worker struct Tag {
119*38e8c45fSAndroid Build Coastguard Worker     wp<IBinder> binder;
120*38e8c45fSAndroid Build Coastguard Worker };
121*38e8c45fSAndroid Build Coastguard Worker } // namespace
122*38e8c45fSAndroid Build Coastguard Worker 
cleanWeak(const void *,void * obj,void *)123*38e8c45fSAndroid Build Coastguard Worker static void cleanWeak(const void* /* id */, void* obj, void* /* cookie */) {
124*38e8c45fSAndroid Build Coastguard Worker     delete static_cast<Tag*>(obj);
125*38e8c45fSAndroid Build Coastguard Worker }
126*38e8c45fSAndroid Build Coastguard Worker 
lookupOrCreateWeak(const void * objectID,object_make_func make,const void * makeArgs)127*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> BpBinder::ObjectManager::lookupOrCreateWeak(const void* objectID, object_make_func make,
128*38e8c45fSAndroid Build Coastguard Worker                                                         const void* makeArgs) {
129*38e8c45fSAndroid Build Coastguard Worker     entry_t& e = mObjects[objectID];
130*38e8c45fSAndroid Build Coastguard Worker     if (e.object != nullptr) {
131*38e8c45fSAndroid Build Coastguard Worker         if (auto attached = static_cast<Tag*>(e.object)->binder.promote()) {
132*38e8c45fSAndroid Build Coastguard Worker             return attached;
133*38e8c45fSAndroid Build Coastguard Worker         }
134*38e8c45fSAndroid Build Coastguard Worker     } else {
135*38e8c45fSAndroid Build Coastguard Worker         e.object = new Tag;
136*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(!e.object, "no more memory");
137*38e8c45fSAndroid Build Coastguard Worker     }
138*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> newObj = make(makeArgs);
139*38e8c45fSAndroid Build Coastguard Worker 
140*38e8c45fSAndroid Build Coastguard Worker     static_cast<Tag*>(e.object)->binder = newObj;
141*38e8c45fSAndroid Build Coastguard Worker     e.cleanupCookie = nullptr;
142*38e8c45fSAndroid Build Coastguard Worker     e.func = cleanWeak;
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker     return newObj;
145*38e8c45fSAndroid Build Coastguard Worker }
146*38e8c45fSAndroid Build Coastguard Worker 
kill()147*38e8c45fSAndroid Build Coastguard Worker void BpBinder::ObjectManager::kill()
148*38e8c45fSAndroid Build Coastguard Worker {
149*38e8c45fSAndroid Build Coastguard Worker     const size_t N = mObjects.size();
150*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Killing %zu objects in manager %p", N, this);
151*38e8c45fSAndroid Build Coastguard Worker     for (auto i : mObjects) {
152*38e8c45fSAndroid Build Coastguard Worker         const entry_t& e = i.second;
153*38e8c45fSAndroid Build Coastguard Worker         if (e.func != nullptr) {
154*38e8c45fSAndroid Build Coastguard Worker             e.func(i.first, e.object, e.cleanupCookie);
155*38e8c45fSAndroid Build Coastguard Worker         }
156*38e8c45fSAndroid Build Coastguard Worker     }
157*38e8c45fSAndroid Build Coastguard Worker 
158*38e8c45fSAndroid Build Coastguard Worker     mObjects.clear();
159*38e8c45fSAndroid Build Coastguard Worker }
160*38e8c45fSAndroid Build Coastguard Worker 
161*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
162*38e8c45fSAndroid Build Coastguard Worker 
create(int32_t handle,std::function<void ()> * postTask)163*38e8c45fSAndroid Build Coastguard Worker sp<BpBinder> BpBinder::create(int32_t handle, std::function<void()>* postTask) {
164*38e8c45fSAndroid Build Coastguard Worker     if constexpr (!kEnableKernelIpc) {
165*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
166*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
167*38e8c45fSAndroid Build Coastguard Worker     }
168*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(postTask == nullptr, "BAD STATE");
169*38e8c45fSAndroid Build Coastguard Worker 
170*38e8c45fSAndroid Build Coastguard Worker     int32_t trackedUid = -1;
171*38e8c45fSAndroid Build Coastguard Worker     if (sCountByUidEnabled) {
172*38e8c45fSAndroid Build Coastguard Worker         trackedUid = IPCThreadState::self()->getCallingUid();
173*38e8c45fSAndroid Build Coastguard Worker         RpcMutexUniqueLock _l(sTrackingLock);
174*38e8c45fSAndroid Build Coastguard Worker         uint32_t trackedValue = sTrackingMap[trackedUid];
175*38e8c45fSAndroid Build Coastguard Worker         if (trackedValue & LIMIT_REACHED_MASK) [[unlikely]] {
176*38e8c45fSAndroid Build Coastguard Worker             if (sBinderProxyThrottleCreate) {
177*38e8c45fSAndroid Build Coastguard Worker                 return nullptr;
178*38e8c45fSAndroid Build Coastguard Worker             }
179*38e8c45fSAndroid Build Coastguard Worker             trackedValue = trackedValue & COUNTING_VALUE_MASK;
180*38e8c45fSAndroid Build Coastguard Worker             uint32_t lastLimitCallbackAt = sLastLimitCallbackMap[trackedUid];
181*38e8c45fSAndroid Build Coastguard Worker 
182*38e8c45fSAndroid Build Coastguard Worker             if (trackedValue > lastLimitCallbackAt &&
183*38e8c45fSAndroid Build Coastguard Worker                 (trackedValue - lastLimitCallbackAt > sBinderProxyCountHighWatermark)) {
184*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Still too many binder proxy objects sent to uid %d from uid %d (%d proxies "
185*38e8c45fSAndroid Build Coastguard Worker                       "held)",
186*38e8c45fSAndroid Build Coastguard Worker                       getuid(), trackedUid, trackedValue);
187*38e8c45fSAndroid Build Coastguard Worker 
188*38e8c45fSAndroid Build Coastguard Worker                 if (sLimitCallback) {
189*38e8c45fSAndroid Build Coastguard Worker                     *postTask = [=]() { sLimitCallback(trackedUid); };
190*38e8c45fSAndroid Build Coastguard Worker                 }
191*38e8c45fSAndroid Build Coastguard Worker 
192*38e8c45fSAndroid Build Coastguard Worker                 sLastLimitCallbackMap[trackedUid] = trackedValue;
193*38e8c45fSAndroid Build Coastguard Worker             }
194*38e8c45fSAndroid Build Coastguard Worker         } else {
195*38e8c45fSAndroid Build Coastguard Worker             uint32_t currentValue = trackedValue & COUNTING_VALUE_MASK;
196*38e8c45fSAndroid Build Coastguard Worker             if (currentValue >= sBinderProxyCountWarningWatermark
197*38e8c45fSAndroid Build Coastguard Worker                     && currentValue < sBinderProxyCountHighWatermark
198*38e8c45fSAndroid Build Coastguard Worker                     && ((trackedValue & WARNING_REACHED_MASK) == 0)) [[unlikely]] {
199*38e8c45fSAndroid Build Coastguard Worker                 sTrackingMap[trackedUid] |= WARNING_REACHED_MASK;
200*38e8c45fSAndroid Build Coastguard Worker                 if (sWarningCallback) {
201*38e8c45fSAndroid Build Coastguard Worker                     *postTask = [=]() { sWarningCallback(trackedUid); };
202*38e8c45fSAndroid Build Coastguard Worker                 }
203*38e8c45fSAndroid Build Coastguard Worker             } else if (currentValue >= sBinderProxyCountHighWatermark) {
204*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
205*38e8c45fSAndroid Build Coastguard Worker                       getuid(), trackedUid, trackedValue);
206*38e8c45fSAndroid Build Coastguard Worker                 sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
207*38e8c45fSAndroid Build Coastguard Worker 
208*38e8c45fSAndroid Build Coastguard Worker                 if (sLimitCallback) {
209*38e8c45fSAndroid Build Coastguard Worker                     *postTask = [=]() { sLimitCallback(trackedUid); };
210*38e8c45fSAndroid Build Coastguard Worker                 }
211*38e8c45fSAndroid Build Coastguard Worker 
212*38e8c45fSAndroid Build Coastguard Worker                 sLastLimitCallbackMap[trackedUid] = trackedValue & COUNTING_VALUE_MASK;
213*38e8c45fSAndroid Build Coastguard Worker                 if (sBinderProxyThrottleCreate) {
214*38e8c45fSAndroid Build Coastguard Worker                     ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy"
215*38e8c45fSAndroid Build Coastguard Worker                           " count drops below %d",
216*38e8c45fSAndroid Build Coastguard Worker                           trackedUid, getuid(), sBinderProxyCountLowWatermark);
217*38e8c45fSAndroid Build Coastguard Worker                     return nullptr;
218*38e8c45fSAndroid Build Coastguard Worker                 }
219*38e8c45fSAndroid Build Coastguard Worker             }
220*38e8c45fSAndroid Build Coastguard Worker         }
221*38e8c45fSAndroid Build Coastguard Worker         sTrackingMap[trackedUid]++;
222*38e8c45fSAndroid Build Coastguard Worker     }
223*38e8c45fSAndroid Build Coastguard Worker     uint32_t numProxies = sBinderProxyCount.fetch_add(1, std::memory_order_relaxed);
224*38e8c45fSAndroid Build Coastguard Worker     binder::os::trace_int(ATRACE_TAG_AIDL, "binder_proxies", numProxies);
225*38e8c45fSAndroid Build Coastguard Worker     uint32_t numLastWarned = sBinderProxyCountWarned.load(std::memory_order_relaxed);
226*38e8c45fSAndroid Build Coastguard Worker     uint32_t numNextWarn = numLastWarned + kBinderProxyCountWarnInterval;
227*38e8c45fSAndroid Build Coastguard Worker     if (numProxies >= numNextWarn) {
228*38e8c45fSAndroid Build Coastguard Worker         // Multiple threads can get here, make sure only one of them gets to
229*38e8c45fSAndroid Build Coastguard Worker         // update the warn counter.
230*38e8c45fSAndroid Build Coastguard Worker         if (sBinderProxyCountWarned.compare_exchange_strong(numLastWarned,
231*38e8c45fSAndroid Build Coastguard Worker                                                             numNextWarn,
232*38e8c45fSAndroid Build Coastguard Worker                                                             std::memory_order_relaxed)) {
233*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
234*38e8c45fSAndroid Build Coastguard Worker         }
235*38e8c45fSAndroid Build Coastguard Worker     }
236*38e8c45fSAndroid Build Coastguard Worker     return sp<BpBinder>::make(BinderHandle{handle}, trackedUid);
237*38e8c45fSAndroid Build Coastguard Worker }
238*38e8c45fSAndroid Build Coastguard Worker 
create(const sp<RpcSession> & session,uint64_t address)239*38e8c45fSAndroid Build Coastguard Worker sp<BpBinder> BpBinder::create(const sp<RpcSession>& session, uint64_t address) {
240*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(session == nullptr, "BpBinder::create null session");
241*38e8c45fSAndroid Build Coastguard Worker 
242*38e8c45fSAndroid Build Coastguard Worker     // These are not currently tracked, since there is no UID or other
243*38e8c45fSAndroid Build Coastguard Worker     // identifier to track them with. However, if similar functionality is
244*38e8c45fSAndroid Build Coastguard Worker     // needed, session objects keep track of all BpBinder objects on a
245*38e8c45fSAndroid Build Coastguard Worker     // per-session basis.
246*38e8c45fSAndroid Build Coastguard Worker 
247*38e8c45fSAndroid Build Coastguard Worker     return sp<BpBinder>::make(RpcHandle{session, address});
248*38e8c45fSAndroid Build Coastguard Worker }
249*38e8c45fSAndroid Build Coastguard Worker 
BpBinder(Handle && handle)250*38e8c45fSAndroid Build Coastguard Worker BpBinder::BpBinder(Handle&& handle)
251*38e8c45fSAndroid Build Coastguard Worker       : mStability(0),
252*38e8c45fSAndroid Build Coastguard Worker         mHandle(handle),
253*38e8c45fSAndroid Build Coastguard Worker         mAlive(true),
254*38e8c45fSAndroid Build Coastguard Worker         mObitsSent(false),
255*38e8c45fSAndroid Build Coastguard Worker         mObituaries(nullptr),
256*38e8c45fSAndroid Build Coastguard Worker         mDescriptorCache(kDescriptorUninit),
257*38e8c45fSAndroid Build Coastguard Worker         mTrackedUid(-1) {
258*38e8c45fSAndroid Build Coastguard Worker     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
259*38e8c45fSAndroid Build Coastguard Worker }
260*38e8c45fSAndroid Build Coastguard Worker 
BpBinder(BinderHandle && handle,int32_t trackedUid)261*38e8c45fSAndroid Build Coastguard Worker BpBinder::BpBinder(BinderHandle&& handle, int32_t trackedUid) : BpBinder(Handle(handle)) {
262*38e8c45fSAndroid Build Coastguard Worker     if constexpr (!kEnableKernelIpc) {
263*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
264*38e8c45fSAndroid Build Coastguard Worker         return;
265*38e8c45fSAndroid Build Coastguard Worker     }
266*38e8c45fSAndroid Build Coastguard Worker 
267*38e8c45fSAndroid Build Coastguard Worker     mTrackedUid = trackedUid;
268*38e8c45fSAndroid Build Coastguard Worker 
269*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Creating BpBinder %p handle %d\n", this, this->binderHandle());
270*38e8c45fSAndroid Build Coastguard Worker 
271*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState::self()->incWeakHandle(this->binderHandle(), this);
272*38e8c45fSAndroid Build Coastguard Worker }
273*38e8c45fSAndroid Build Coastguard Worker 
BpBinder(RpcHandle && handle)274*38e8c45fSAndroid Build Coastguard Worker BpBinder::BpBinder(RpcHandle&& handle) : BpBinder(Handle(handle)) {
275*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(rpcSession() == nullptr, "BpBinder created w/o session object");
276*38e8c45fSAndroid Build Coastguard Worker }
277*38e8c45fSAndroid Build Coastguard Worker 
isRpcBinder() const278*38e8c45fSAndroid Build Coastguard Worker bool BpBinder::isRpcBinder() const {
279*38e8c45fSAndroid Build Coastguard Worker     return std::holds_alternative<RpcHandle>(mHandle);
280*38e8c45fSAndroid Build Coastguard Worker }
281*38e8c45fSAndroid Build Coastguard Worker 
rpcAddress() const282*38e8c45fSAndroid Build Coastguard Worker uint64_t BpBinder::rpcAddress() const {
283*38e8c45fSAndroid Build Coastguard Worker     return std::get<RpcHandle>(mHandle).address;
284*38e8c45fSAndroid Build Coastguard Worker }
285*38e8c45fSAndroid Build Coastguard Worker 
rpcSession() const286*38e8c45fSAndroid Build Coastguard Worker const sp<RpcSession>& BpBinder::rpcSession() const {
287*38e8c45fSAndroid Build Coastguard Worker     return std::get<RpcHandle>(mHandle).session;
288*38e8c45fSAndroid Build Coastguard Worker }
289*38e8c45fSAndroid Build Coastguard Worker 
binderHandle() const290*38e8c45fSAndroid Build Coastguard Worker int32_t BpBinder::binderHandle() const {
291*38e8c45fSAndroid Build Coastguard Worker     return std::get<BinderHandle>(mHandle).handle;
292*38e8c45fSAndroid Build Coastguard Worker }
293*38e8c45fSAndroid Build Coastguard Worker 
getDebugBinderHandle() const294*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> BpBinder::getDebugBinderHandle() const {
295*38e8c45fSAndroid Build Coastguard Worker     if (!isRpcBinder()) {
296*38e8c45fSAndroid Build Coastguard Worker         return binderHandle();
297*38e8c45fSAndroid Build Coastguard Worker     } else {
298*38e8c45fSAndroid Build Coastguard Worker         return std::nullopt;
299*38e8c45fSAndroid Build Coastguard Worker     }
300*38e8c45fSAndroid Build Coastguard Worker }
301*38e8c45fSAndroid Build Coastguard Worker 
isDescriptorCached() const302*38e8c45fSAndroid Build Coastguard Worker bool BpBinder::isDescriptorCached() const {
303*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
304*38e8c45fSAndroid Build Coastguard Worker     return mDescriptorCache.c_str() != kDescriptorUninit.c_str();
305*38e8c45fSAndroid Build Coastguard Worker }
306*38e8c45fSAndroid Build Coastguard Worker 
getInterfaceDescriptor() const307*38e8c45fSAndroid Build Coastguard Worker const String16& BpBinder::getInterfaceDescriptor() const
308*38e8c45fSAndroid Build Coastguard Worker {
309*38e8c45fSAndroid Build Coastguard Worker     if (!isDescriptorCached()) {
310*38e8c45fSAndroid Build Coastguard Worker         sp<BpBinder> thiz = sp<BpBinder>::fromExisting(const_cast<BpBinder*>(this));
311*38e8c45fSAndroid Build Coastguard Worker 
312*38e8c45fSAndroid Build Coastguard Worker         Parcel data;
313*38e8c45fSAndroid Build Coastguard Worker         data.markForBinder(thiz);
314*38e8c45fSAndroid Build Coastguard Worker         Parcel reply;
315*38e8c45fSAndroid Build Coastguard Worker         // do the IPC without a lock held.
316*38e8c45fSAndroid Build Coastguard Worker         status_t err = thiz->transact(INTERFACE_TRANSACTION, data, &reply);
317*38e8c45fSAndroid Build Coastguard Worker         if (err == NO_ERROR) {
318*38e8c45fSAndroid Build Coastguard Worker             String16 res(reply.readString16());
319*38e8c45fSAndroid Build Coastguard Worker             RpcMutexUniqueLock _l(mLock);
320*38e8c45fSAndroid Build Coastguard Worker             // mDescriptorCache could have been assigned while the lock was
321*38e8c45fSAndroid Build Coastguard Worker             // released.
322*38e8c45fSAndroid Build Coastguard Worker             if (mDescriptorCache.c_str() == kDescriptorUninit.c_str()) mDescriptorCache = res;
323*38e8c45fSAndroid Build Coastguard Worker         }
324*38e8c45fSAndroid Build Coastguard Worker     }
325*38e8c45fSAndroid Build Coastguard Worker 
326*38e8c45fSAndroid Build Coastguard Worker     // we're returning a reference to a non-static object here. Usually this
327*38e8c45fSAndroid Build Coastguard Worker     // is not something smart to do, however, with binder objects it is
328*38e8c45fSAndroid Build Coastguard Worker     // (usually) safe because they are reference-counted.
329*38e8c45fSAndroid Build Coastguard Worker 
330*38e8c45fSAndroid Build Coastguard Worker     return mDescriptorCache;
331*38e8c45fSAndroid Build Coastguard Worker }
332*38e8c45fSAndroid Build Coastguard Worker 
isBinderAlive() const333*38e8c45fSAndroid Build Coastguard Worker bool BpBinder::isBinderAlive() const
334*38e8c45fSAndroid Build Coastguard Worker {
335*38e8c45fSAndroid Build Coastguard Worker     return mAlive != 0;
336*38e8c45fSAndroid Build Coastguard Worker }
337*38e8c45fSAndroid Build Coastguard Worker 
pingBinder()338*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::pingBinder()
339*38e8c45fSAndroid Build Coastguard Worker {
340*38e8c45fSAndroid Build Coastguard Worker     Parcel data;
341*38e8c45fSAndroid Build Coastguard Worker     data.markForBinder(sp<BpBinder>::fromExisting(this));
342*38e8c45fSAndroid Build Coastguard Worker     Parcel reply;
343*38e8c45fSAndroid Build Coastguard Worker     return transact(PING_TRANSACTION, data, &reply);
344*38e8c45fSAndroid Build Coastguard Worker }
345*38e8c45fSAndroid Build Coastguard Worker 
startRecordingBinder(const unique_fd & fd)346*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::startRecordingBinder(const unique_fd& fd) {
347*38e8c45fSAndroid Build Coastguard Worker     Parcel send, reply;
348*38e8c45fSAndroid Build Coastguard Worker     send.writeUniqueFileDescriptor(fd);
349*38e8c45fSAndroid Build Coastguard Worker     return transact(START_RECORDING_TRANSACTION, send, &reply);
350*38e8c45fSAndroid Build Coastguard Worker }
351*38e8c45fSAndroid Build Coastguard Worker 
stopRecordingBinder()352*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::stopRecordingBinder() {
353*38e8c45fSAndroid Build Coastguard Worker     Parcel data, reply;
354*38e8c45fSAndroid Build Coastguard Worker     data.markForBinder(sp<BpBinder>::fromExisting(this));
355*38e8c45fSAndroid Build Coastguard Worker     return transact(STOP_RECORDING_TRANSACTION, data, &reply);
356*38e8c45fSAndroid Build Coastguard Worker }
357*38e8c45fSAndroid Build Coastguard Worker 
dump(int fd,const Vector<String16> & args)358*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::dump(int fd, const Vector<String16>& args)
359*38e8c45fSAndroid Build Coastguard Worker {
360*38e8c45fSAndroid Build Coastguard Worker     Parcel send;
361*38e8c45fSAndroid Build Coastguard Worker     Parcel reply;
362*38e8c45fSAndroid Build Coastguard Worker     send.writeFileDescriptor(fd);
363*38e8c45fSAndroid Build Coastguard Worker     const size_t numArgs = args.size();
364*38e8c45fSAndroid Build Coastguard Worker     send.writeInt32(numArgs);
365*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < numArgs; i++) {
366*38e8c45fSAndroid Build Coastguard Worker         send.writeString16(args[i]);
367*38e8c45fSAndroid Build Coastguard Worker     }
368*38e8c45fSAndroid Build Coastguard Worker     status_t err = transact(DUMP_TRANSACTION, send, &reply);
369*38e8c45fSAndroid Build Coastguard Worker     return err;
370*38e8c45fSAndroid Build Coastguard Worker }
371*38e8c45fSAndroid Build Coastguard Worker 
372*38e8c45fSAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-default-arguments)
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)373*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::transact(
374*38e8c45fSAndroid Build Coastguard Worker     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
375*38e8c45fSAndroid Build Coastguard Worker {
376*38e8c45fSAndroid Build Coastguard Worker     // Once a binder has died, it will never come back to life.
377*38e8c45fSAndroid Build Coastguard Worker     if (mAlive) {
378*38e8c45fSAndroid Build Coastguard Worker         bool privateVendor = flags & FLAG_PRIVATE_VENDOR;
379*38e8c45fSAndroid Build Coastguard Worker         // don't send userspace flags to the kernel
380*38e8c45fSAndroid Build Coastguard Worker         flags = flags & ~static_cast<uint32_t>(FLAG_PRIVATE_VENDOR);
381*38e8c45fSAndroid Build Coastguard Worker 
382*38e8c45fSAndroid Build Coastguard Worker         // user transactions require a given stability level
383*38e8c45fSAndroid Build Coastguard Worker         if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
384*38e8c45fSAndroid Build Coastguard Worker             using android::internal::Stability;
385*38e8c45fSAndroid Build Coastguard Worker 
386*38e8c45fSAndroid Build Coastguard Worker             int16_t stability = Stability::getRepr(this);
387*38e8c45fSAndroid Build Coastguard Worker             Stability::Level required = privateVendor ? Stability::VENDOR
388*38e8c45fSAndroid Build Coastguard Worker                 : Stability::getLocalLevel();
389*38e8c45fSAndroid Build Coastguard Worker 
390*38e8c45fSAndroid Build Coastguard Worker             if (!Stability::check(stability, required)) [[unlikely]] {
391*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Cannot do a user transaction on a %s binder (%s) in a %s context.",
392*38e8c45fSAndroid Build Coastguard Worker                       Stability::levelString(stability).c_str(),
393*38e8c45fSAndroid Build Coastguard Worker                       String8(getInterfaceDescriptor()).c_str(),
394*38e8c45fSAndroid Build Coastguard Worker                       Stability::levelString(required).c_str());
395*38e8c45fSAndroid Build Coastguard Worker                 return BAD_TYPE;
396*38e8c45fSAndroid Build Coastguard Worker             }
397*38e8c45fSAndroid Build Coastguard Worker         }
398*38e8c45fSAndroid Build Coastguard Worker 
399*38e8c45fSAndroid Build Coastguard Worker         status_t status;
400*38e8c45fSAndroid Build Coastguard Worker         if (isRpcBinder()) [[unlikely]] {
401*38e8c45fSAndroid Build Coastguard Worker             status = rpcSession()->transact(sp<IBinder>::fromExisting(this), code, data, reply,
402*38e8c45fSAndroid Build Coastguard Worker                                             flags);
403*38e8c45fSAndroid Build Coastguard Worker         } else {
404*38e8c45fSAndroid Build Coastguard Worker             if constexpr (!kEnableKernelIpc) {
405*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
406*38e8c45fSAndroid Build Coastguard Worker                 return INVALID_OPERATION;
407*38e8c45fSAndroid Build Coastguard Worker             }
408*38e8c45fSAndroid Build Coastguard Worker 
409*38e8c45fSAndroid Build Coastguard Worker             status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
410*38e8c45fSAndroid Build Coastguard Worker         }
411*38e8c45fSAndroid Build Coastguard Worker         if (data.dataSize() > LOG_TRANSACTIONS_OVER_SIZE) {
412*38e8c45fSAndroid Build Coastguard Worker             RpcMutexUniqueLock _l(mLock);
413*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Large outgoing transaction of %zu bytes, interface descriptor %s, code %d",
414*38e8c45fSAndroid Build Coastguard Worker                   data.dataSize(), String8(mDescriptorCache).c_str(), code);
415*38e8c45fSAndroid Build Coastguard Worker         }
416*38e8c45fSAndroid Build Coastguard Worker 
417*38e8c45fSAndroid Build Coastguard Worker         if (status == DEAD_OBJECT) mAlive = 0;
418*38e8c45fSAndroid Build Coastguard Worker 
419*38e8c45fSAndroid Build Coastguard Worker         return status;
420*38e8c45fSAndroid Build Coastguard Worker     }
421*38e8c45fSAndroid Build Coastguard Worker 
422*38e8c45fSAndroid Build Coastguard Worker     return DEAD_OBJECT;
423*38e8c45fSAndroid Build Coastguard Worker }
424*38e8c45fSAndroid Build Coastguard Worker 
425*38e8c45fSAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-default-arguments)
linkToDeath(const sp<DeathRecipient> & recipient,void * cookie,uint32_t flags)426*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::linkToDeath(
427*38e8c45fSAndroid Build Coastguard Worker     const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
428*38e8c45fSAndroid Build Coastguard Worker {
429*38e8c45fSAndroid Build Coastguard Worker     if (isRpcBinder()) {
430*38e8c45fSAndroid Build Coastguard Worker         if (rpcSession()->getMaxIncomingThreads() < 1) {
431*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Cannot register a DeathRecipient without any incoming threads. Need to set max "
432*38e8c45fSAndroid Build Coastguard Worker                   "incoming threads to a value greater than 0 before calling linkToDeath.");
433*38e8c45fSAndroid Build Coastguard Worker             return INVALID_OPERATION;
434*38e8c45fSAndroid Build Coastguard Worker         }
435*38e8c45fSAndroid Build Coastguard Worker     } else if constexpr (!kEnableKernelIpc) {
436*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
437*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
438*38e8c45fSAndroid Build Coastguard Worker     } else {
439*38e8c45fSAndroid Build Coastguard Worker         if (ProcessState::self()->getThreadPoolMaxTotalThreadCount() == 0) {
440*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Linking to death on %s but there are no threads (yet?) listening to incoming "
441*38e8c45fSAndroid Build Coastguard Worker                   "transactions. See ProcessState::startThreadPool and "
442*38e8c45fSAndroid Build Coastguard Worker                   "ProcessState::setThreadPoolMaxThreadCount. Generally you should setup the "
443*38e8c45fSAndroid Build Coastguard Worker                   "binder "
444*38e8c45fSAndroid Build Coastguard Worker                   "threadpool before other initialization steps.",
445*38e8c45fSAndroid Build Coastguard Worker                   String8(getInterfaceDescriptor()).c_str());
446*38e8c45fSAndroid Build Coastguard Worker         }
447*38e8c45fSAndroid Build Coastguard Worker     }
448*38e8c45fSAndroid Build Coastguard Worker 
449*38e8c45fSAndroid Build Coastguard Worker     Obituary ob;
450*38e8c45fSAndroid Build Coastguard Worker     ob.recipient = recipient;
451*38e8c45fSAndroid Build Coastguard Worker     ob.cookie = cookie;
452*38e8c45fSAndroid Build Coastguard Worker     ob.flags = flags;
453*38e8c45fSAndroid Build Coastguard Worker 
454*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(recipient == nullptr,
455*38e8c45fSAndroid Build Coastguard Worker                         "linkToDeath(): recipient must be non-NULL");
456*38e8c45fSAndroid Build Coastguard Worker 
457*38e8c45fSAndroid Build Coastguard Worker     {
458*38e8c45fSAndroid Build Coastguard Worker         RpcMutexUniqueLock _l(mLock);
459*38e8c45fSAndroid Build Coastguard Worker 
460*38e8c45fSAndroid Build Coastguard Worker         if (!mObitsSent) {
461*38e8c45fSAndroid Build Coastguard Worker             if (!mObituaries) {
462*38e8c45fSAndroid Build Coastguard Worker                 mObituaries = new Vector<Obituary>;
463*38e8c45fSAndroid Build Coastguard Worker                 if (!mObituaries) {
464*38e8c45fSAndroid Build Coastguard Worker                     return NO_MEMORY;
465*38e8c45fSAndroid Build Coastguard Worker                 }
466*38e8c45fSAndroid Build Coastguard Worker                 ALOGV("Requesting death notification: %p handle %d\n", this, binderHandle());
467*38e8c45fSAndroid Build Coastguard Worker                 if (!isRpcBinder()) {
468*38e8c45fSAndroid Build Coastguard Worker                     if constexpr (kEnableKernelIpc) {
469*38e8c45fSAndroid Build Coastguard Worker                         getWeakRefs()->incWeak(this);
470*38e8c45fSAndroid Build Coastguard Worker                         IPCThreadState* self = IPCThreadState::self();
471*38e8c45fSAndroid Build Coastguard Worker                         self->requestDeathNotification(binderHandle(), this);
472*38e8c45fSAndroid Build Coastguard Worker                         self->flushCommands();
473*38e8c45fSAndroid Build Coastguard Worker                     }
474*38e8c45fSAndroid Build Coastguard Worker                 }
475*38e8c45fSAndroid Build Coastguard Worker             }
476*38e8c45fSAndroid Build Coastguard Worker             ssize_t res = mObituaries->add(ob);
477*38e8c45fSAndroid Build Coastguard Worker             return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
478*38e8c45fSAndroid Build Coastguard Worker         }
479*38e8c45fSAndroid Build Coastguard Worker     }
480*38e8c45fSAndroid Build Coastguard Worker 
481*38e8c45fSAndroid Build Coastguard Worker     return DEAD_OBJECT;
482*38e8c45fSAndroid Build Coastguard Worker }
483*38e8c45fSAndroid Build Coastguard Worker 
484*38e8c45fSAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-default-arguments)
unlinkToDeath(const wp<DeathRecipient> & recipient,void * cookie,uint32_t flags,wp<DeathRecipient> * outRecipient)485*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::unlinkToDeath(
486*38e8c45fSAndroid Build Coastguard Worker     const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
487*38e8c45fSAndroid Build Coastguard Worker     wp<DeathRecipient>* outRecipient)
488*38e8c45fSAndroid Build Coastguard Worker {
489*38e8c45fSAndroid Build Coastguard Worker     if (!kEnableKernelIpc && !isRpcBinder()) {
490*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
491*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
492*38e8c45fSAndroid Build Coastguard Worker     }
493*38e8c45fSAndroid Build Coastguard Worker 
494*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
495*38e8c45fSAndroid Build Coastguard Worker 
496*38e8c45fSAndroid Build Coastguard Worker     if (mObitsSent) {
497*38e8c45fSAndroid Build Coastguard Worker         return DEAD_OBJECT;
498*38e8c45fSAndroid Build Coastguard Worker     }
499*38e8c45fSAndroid Build Coastguard Worker 
500*38e8c45fSAndroid Build Coastguard Worker     const size_t N = mObituaries ? mObituaries->size() : 0;
501*38e8c45fSAndroid Build Coastguard Worker     for (size_t i=0; i<N; i++) {
502*38e8c45fSAndroid Build Coastguard Worker         const Obituary& obit = mObituaries->itemAt(i);
503*38e8c45fSAndroid Build Coastguard Worker         if ((obit.recipient == recipient
504*38e8c45fSAndroid Build Coastguard Worker                     || (recipient == nullptr && obit.cookie == cookie))
505*38e8c45fSAndroid Build Coastguard Worker                 && obit.flags == flags) {
506*38e8c45fSAndroid Build Coastguard Worker             if (outRecipient != nullptr) {
507*38e8c45fSAndroid Build Coastguard Worker                 *outRecipient = mObituaries->itemAt(i).recipient;
508*38e8c45fSAndroid Build Coastguard Worker             }
509*38e8c45fSAndroid Build Coastguard Worker             mObituaries->removeAt(i);
510*38e8c45fSAndroid Build Coastguard Worker             if (mObituaries->size() == 0) {
511*38e8c45fSAndroid Build Coastguard Worker                 ALOGV("Clearing death notification: %p handle %d\n", this, binderHandle());
512*38e8c45fSAndroid Build Coastguard Worker                 if (!isRpcBinder()) {
513*38e8c45fSAndroid Build Coastguard Worker                     if constexpr (kEnableKernelIpc) {
514*38e8c45fSAndroid Build Coastguard Worker                         IPCThreadState* self = IPCThreadState::self();
515*38e8c45fSAndroid Build Coastguard Worker                         self->clearDeathNotification(binderHandle(), this);
516*38e8c45fSAndroid Build Coastguard Worker                         self->flushCommands();
517*38e8c45fSAndroid Build Coastguard Worker                     }
518*38e8c45fSAndroid Build Coastguard Worker                 }
519*38e8c45fSAndroid Build Coastguard Worker                 delete mObituaries;
520*38e8c45fSAndroid Build Coastguard Worker                 mObituaries = nullptr;
521*38e8c45fSAndroid Build Coastguard Worker             }
522*38e8c45fSAndroid Build Coastguard Worker             return NO_ERROR;
523*38e8c45fSAndroid Build Coastguard Worker         }
524*38e8c45fSAndroid Build Coastguard Worker     }
525*38e8c45fSAndroid Build Coastguard Worker 
526*38e8c45fSAndroid Build Coastguard Worker     return NAME_NOT_FOUND;
527*38e8c45fSAndroid Build Coastguard Worker }
528*38e8c45fSAndroid Build Coastguard Worker 
sendObituary()529*38e8c45fSAndroid Build Coastguard Worker void BpBinder::sendObituary()
530*38e8c45fSAndroid Build Coastguard Worker {
531*38e8c45fSAndroid Build Coastguard Worker     if (!kEnableKernelIpc && !isRpcBinder()) {
532*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
533*38e8c45fSAndroid Build Coastguard Worker         return;
534*38e8c45fSAndroid Build Coastguard Worker     }
535*38e8c45fSAndroid Build Coastguard Worker 
536*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", this, binderHandle(),
537*38e8c45fSAndroid Build Coastguard Worker           mObitsSent ? "true" : "false");
538*38e8c45fSAndroid Build Coastguard Worker 
539*38e8c45fSAndroid Build Coastguard Worker     mAlive = 0;
540*38e8c45fSAndroid Build Coastguard Worker     if (mObitsSent) return;
541*38e8c45fSAndroid Build Coastguard Worker 
542*38e8c45fSAndroid Build Coastguard Worker     mLock.lock();
543*38e8c45fSAndroid Build Coastguard Worker     Vector<Obituary>* obits = mObituaries;
544*38e8c45fSAndroid Build Coastguard Worker     if(obits != nullptr) {
545*38e8c45fSAndroid Build Coastguard Worker         ALOGV("Clearing sent death notification: %p handle %d\n", this, binderHandle());
546*38e8c45fSAndroid Build Coastguard Worker         if (!isRpcBinder()) {
547*38e8c45fSAndroid Build Coastguard Worker             if constexpr (kEnableKernelIpc) {
548*38e8c45fSAndroid Build Coastguard Worker                 IPCThreadState* self = IPCThreadState::self();
549*38e8c45fSAndroid Build Coastguard Worker                 self->clearDeathNotification(binderHandle(), this);
550*38e8c45fSAndroid Build Coastguard Worker                 self->flushCommands();
551*38e8c45fSAndroid Build Coastguard Worker             }
552*38e8c45fSAndroid Build Coastguard Worker         }
553*38e8c45fSAndroid Build Coastguard Worker         mObituaries = nullptr;
554*38e8c45fSAndroid Build Coastguard Worker     }
555*38e8c45fSAndroid Build Coastguard Worker     mObitsSent = 1;
556*38e8c45fSAndroid Build Coastguard Worker     mLock.unlock();
557*38e8c45fSAndroid Build Coastguard Worker 
558*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Reporting death of proxy %p for %zu recipients\n",
559*38e8c45fSAndroid Build Coastguard Worker         this, obits ? obits->size() : 0U);
560*38e8c45fSAndroid Build Coastguard Worker 
561*38e8c45fSAndroid Build Coastguard Worker     if (obits != nullptr) {
562*38e8c45fSAndroid Build Coastguard Worker         const size_t N = obits->size();
563*38e8c45fSAndroid Build Coastguard Worker         for (size_t i=0; i<N; i++) {
564*38e8c45fSAndroid Build Coastguard Worker             reportOneDeath(obits->itemAt(i));
565*38e8c45fSAndroid Build Coastguard Worker         }
566*38e8c45fSAndroid Build Coastguard Worker 
567*38e8c45fSAndroid Build Coastguard Worker         delete obits;
568*38e8c45fSAndroid Build Coastguard Worker     }
569*38e8c45fSAndroid Build Coastguard Worker }
570*38e8c45fSAndroid Build Coastguard Worker 
addFrozenStateChangeCallback(const wp<FrozenStateChangeCallback> & callback)571*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::addFrozenStateChangeCallback(const wp<FrozenStateChangeCallback>& callback) {
572*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(isRpcBinder(),
573*38e8c45fSAndroid Build Coastguard Worker                         "addFrozenStateChangeCallback() is not supported for RPC Binder.");
574*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!kEnableKernelIpc, "Binder kernel driver disabled at build time");
575*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(ProcessState::self()->getThreadPoolMaxTotalThreadCount() == 0,
576*38e8c45fSAndroid Build Coastguard Worker                         "addFrozenStateChangeCallback on %s but there are no threads "
577*38e8c45fSAndroid Build Coastguard Worker                         "(yet?) listening to incoming transactions. See "
578*38e8c45fSAndroid Build Coastguard Worker                         "ProcessState::startThreadPool "
579*38e8c45fSAndroid Build Coastguard Worker                         "and ProcessState::setThreadPoolMaxThreadCount. Generally you should "
580*38e8c45fSAndroid Build Coastguard Worker                         "setup the binder threadpool before other initialization steps.",
581*38e8c45fSAndroid Build Coastguard Worker                         String8(getInterfaceDescriptor()).c_str());
582*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(callback == nullptr,
583*38e8c45fSAndroid Build Coastguard Worker                         "addFrozenStateChangeCallback(): callback must be non-NULL");
584*38e8c45fSAndroid Build Coastguard Worker 
585*38e8c45fSAndroid Build Coastguard Worker     const sp<FrozenStateChangeCallback> strongCallback = callback.promote();
586*38e8c45fSAndroid Build Coastguard Worker     if (strongCallback == nullptr) {
587*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
588*38e8c45fSAndroid Build Coastguard Worker     }
589*38e8c45fSAndroid Build Coastguard Worker 
590*38e8c45fSAndroid Build Coastguard Worker     {
591*38e8c45fSAndroid Build Coastguard Worker         RpcMutexUniqueLock _l(mLock);
592*38e8c45fSAndroid Build Coastguard Worker         if (!mFrozen) {
593*38e8c45fSAndroid Build Coastguard Worker             ALOGV("Requesting freeze notification: %p handle %d\n", this, binderHandle());
594*38e8c45fSAndroid Build Coastguard Worker             IPCThreadState* self = IPCThreadState::self();
595*38e8c45fSAndroid Build Coastguard Worker             status_t status = self->addFrozenStateChangeCallback(binderHandle(), this);
596*38e8c45fSAndroid Build Coastguard Worker             if (status != NO_ERROR) {
597*38e8c45fSAndroid Build Coastguard Worker                 // Avoids logspam if kernel does not support freeze
598*38e8c45fSAndroid Build Coastguard Worker                 // notification.
599*38e8c45fSAndroid Build Coastguard Worker                 if (status != INVALID_OPERATION) {
600*38e8c45fSAndroid Build Coastguard Worker                     ALOGE("IPCThreadState.addFrozenStateChangeCallback "
601*38e8c45fSAndroid Build Coastguard Worker                           "failed with %s. %p handle %d\n",
602*38e8c45fSAndroid Build Coastguard Worker                           statusToString(status).c_str(), this, binderHandle());
603*38e8c45fSAndroid Build Coastguard Worker                 }
604*38e8c45fSAndroid Build Coastguard Worker                 return status;
605*38e8c45fSAndroid Build Coastguard Worker             }
606*38e8c45fSAndroid Build Coastguard Worker             mFrozen = std::make_unique<FrozenStateChange>();
607*38e8c45fSAndroid Build Coastguard Worker             if (!mFrozen) {
608*38e8c45fSAndroid Build Coastguard Worker                 std::ignore =
609*38e8c45fSAndroid Build Coastguard Worker                         IPCThreadState::self()->removeFrozenStateChangeCallback(binderHandle(),
610*38e8c45fSAndroid Build Coastguard Worker                                                                                 this);
611*38e8c45fSAndroid Build Coastguard Worker                 return NO_MEMORY;
612*38e8c45fSAndroid Build Coastguard Worker             }
613*38e8c45fSAndroid Build Coastguard Worker         }
614*38e8c45fSAndroid Build Coastguard Worker         if (mFrozen->initialStateReceived) {
615*38e8c45fSAndroid Build Coastguard Worker             strongCallback->onStateChanged(wp<BpBinder>::fromExisting(this),
616*38e8c45fSAndroid Build Coastguard Worker                                            mFrozen->isFrozen
617*38e8c45fSAndroid Build Coastguard Worker                                                    ? FrozenStateChangeCallback::State::FROZEN
618*38e8c45fSAndroid Build Coastguard Worker                                                    : FrozenStateChangeCallback::State::UNFROZEN);
619*38e8c45fSAndroid Build Coastguard Worker         }
620*38e8c45fSAndroid Build Coastguard Worker         ssize_t res = mFrozen->callbacks.add(callback);
621*38e8c45fSAndroid Build Coastguard Worker         if (res < 0) {
622*38e8c45fSAndroid Build Coastguard Worker             return res;
623*38e8c45fSAndroid Build Coastguard Worker         }
624*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
625*38e8c45fSAndroid Build Coastguard Worker     }
626*38e8c45fSAndroid Build Coastguard Worker }
627*38e8c45fSAndroid Build Coastguard Worker 
removeFrozenStateChangeCallback(const wp<FrozenStateChangeCallback> & callback)628*38e8c45fSAndroid Build Coastguard Worker status_t BpBinder::removeFrozenStateChangeCallback(const wp<FrozenStateChangeCallback>& callback) {
629*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(isRpcBinder(),
630*38e8c45fSAndroid Build Coastguard Worker                         "removeFrozenStateChangeCallback() is not supported for RPC Binder.");
631*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!kEnableKernelIpc, "Binder kernel driver disabled at build time");
632*38e8c45fSAndroid Build Coastguard Worker 
633*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
634*38e8c45fSAndroid Build Coastguard Worker 
635*38e8c45fSAndroid Build Coastguard Worker     const size_t N = mFrozen ? mFrozen->callbacks.size() : 0;
636*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < N; i++) {
637*38e8c45fSAndroid Build Coastguard Worker         if (mFrozen->callbacks.itemAt(i) == callback) {
638*38e8c45fSAndroid Build Coastguard Worker             mFrozen->callbacks.removeAt(i);
639*38e8c45fSAndroid Build Coastguard Worker             if (mFrozen->callbacks.size() == 0) {
640*38e8c45fSAndroid Build Coastguard Worker                 ALOGV("Clearing freeze notification: %p handle %d\n", this, binderHandle());
641*38e8c45fSAndroid Build Coastguard Worker                 status_t status =
642*38e8c45fSAndroid Build Coastguard Worker                         IPCThreadState::self()->removeFrozenStateChangeCallback(binderHandle(),
643*38e8c45fSAndroid Build Coastguard Worker                                                                                 this);
644*38e8c45fSAndroid Build Coastguard Worker                 if (status != NO_ERROR) {
645*38e8c45fSAndroid Build Coastguard Worker                     ALOGE("Unexpected error from "
646*38e8c45fSAndroid Build Coastguard Worker                           "IPCThreadState.removeFrozenStateChangeCallback: %s. "
647*38e8c45fSAndroid Build Coastguard Worker                           "%p handle %d\n",
648*38e8c45fSAndroid Build Coastguard Worker                           statusToString(status).c_str(), this, binderHandle());
649*38e8c45fSAndroid Build Coastguard Worker                 }
650*38e8c45fSAndroid Build Coastguard Worker                 mFrozen.reset();
651*38e8c45fSAndroid Build Coastguard Worker             }
652*38e8c45fSAndroid Build Coastguard Worker             return NO_ERROR;
653*38e8c45fSAndroid Build Coastguard Worker         }
654*38e8c45fSAndroid Build Coastguard Worker     }
655*38e8c45fSAndroid Build Coastguard Worker 
656*38e8c45fSAndroid Build Coastguard Worker     return NAME_NOT_FOUND;
657*38e8c45fSAndroid Build Coastguard Worker }
658*38e8c45fSAndroid Build Coastguard Worker 
onFrozenStateChanged(bool isFrozen)659*38e8c45fSAndroid Build Coastguard Worker void BpBinder::onFrozenStateChanged(bool isFrozen) {
660*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(isRpcBinder(), "onFrozenStateChanged is not supported for RPC Binder.");
661*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!kEnableKernelIpc, "Binder kernel driver disabled at build time");
662*38e8c45fSAndroid Build Coastguard Worker 
663*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Sending frozen state change notification for proxy %p handle %d, isFrozen=%s\n", this,
664*38e8c45fSAndroid Build Coastguard Worker           binderHandle(), isFrozen ? "true" : "false");
665*38e8c45fSAndroid Build Coastguard Worker 
666*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
667*38e8c45fSAndroid Build Coastguard Worker     if (!mFrozen) {
668*38e8c45fSAndroid Build Coastguard Worker         return;
669*38e8c45fSAndroid Build Coastguard Worker     }
670*38e8c45fSAndroid Build Coastguard Worker     bool stateChanged = !mFrozen->initialStateReceived || mFrozen->isFrozen != isFrozen;
671*38e8c45fSAndroid Build Coastguard Worker     if (stateChanged) {
672*38e8c45fSAndroid Build Coastguard Worker         mFrozen->isFrozen = isFrozen;
673*38e8c45fSAndroid Build Coastguard Worker         mFrozen->initialStateReceived = true;
674*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < mFrozen->callbacks.size();) {
675*38e8c45fSAndroid Build Coastguard Worker             sp<FrozenStateChangeCallback> callback = mFrozen->callbacks.itemAt(i).promote();
676*38e8c45fSAndroid Build Coastguard Worker             if (callback != nullptr) {
677*38e8c45fSAndroid Build Coastguard Worker                 callback->onStateChanged(wp<BpBinder>::fromExisting(this),
678*38e8c45fSAndroid Build Coastguard Worker                                          isFrozen ? FrozenStateChangeCallback::State::FROZEN
679*38e8c45fSAndroid Build Coastguard Worker                                                   : FrozenStateChangeCallback::State::UNFROZEN);
680*38e8c45fSAndroid Build Coastguard Worker                 i++;
681*38e8c45fSAndroid Build Coastguard Worker             } else {
682*38e8c45fSAndroid Build Coastguard Worker                 mFrozen->callbacks.removeItemsAt(i);
683*38e8c45fSAndroid Build Coastguard Worker             }
684*38e8c45fSAndroid Build Coastguard Worker         }
685*38e8c45fSAndroid Build Coastguard Worker     }
686*38e8c45fSAndroid Build Coastguard Worker }
687*38e8c45fSAndroid Build Coastguard Worker 
reportOneDeath(const Obituary & obit)688*38e8c45fSAndroid Build Coastguard Worker void BpBinder::reportOneDeath(const Obituary& obit)
689*38e8c45fSAndroid Build Coastguard Worker {
690*38e8c45fSAndroid Build Coastguard Worker     sp<DeathRecipient> recipient = obit.recipient.promote();
691*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Reporting death to recipient: %p\n", recipient.get());
692*38e8c45fSAndroid Build Coastguard Worker     if (recipient == nullptr) return;
693*38e8c45fSAndroid Build Coastguard Worker 
694*38e8c45fSAndroid Build Coastguard Worker     recipient->binderDied(wp<BpBinder>::fromExisting(this));
695*38e8c45fSAndroid Build Coastguard Worker }
696*38e8c45fSAndroid Build Coastguard Worker 
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)697*38e8c45fSAndroid Build Coastguard Worker void* BpBinder::attachObject(const void* objectID, void* object, void* cleanupCookie,
698*38e8c45fSAndroid Build Coastguard Worker                              object_cleanup_func func) {
699*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
700*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
701*38e8c45fSAndroid Build Coastguard Worker     return mObjects.attach(objectID, object, cleanupCookie, func);
702*38e8c45fSAndroid Build Coastguard Worker }
703*38e8c45fSAndroid Build Coastguard Worker 
findObject(const void * objectID) const704*38e8c45fSAndroid Build Coastguard Worker void* BpBinder::findObject(const void* objectID) const
705*38e8c45fSAndroid Build Coastguard Worker {
706*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
707*38e8c45fSAndroid Build Coastguard Worker     return mObjects.find(objectID);
708*38e8c45fSAndroid Build Coastguard Worker }
709*38e8c45fSAndroid Build Coastguard Worker 
detachObject(const void * objectID)710*38e8c45fSAndroid Build Coastguard Worker void* BpBinder::detachObject(const void* objectID) {
711*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
712*38e8c45fSAndroid Build Coastguard Worker     return mObjects.detach(objectID);
713*38e8c45fSAndroid Build Coastguard Worker }
714*38e8c45fSAndroid Build Coastguard Worker 
withLock(const std::function<void ()> & doWithLock)715*38e8c45fSAndroid Build Coastguard Worker void BpBinder::withLock(const std::function<void()>& doWithLock) {
716*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
717*38e8c45fSAndroid Build Coastguard Worker     doWithLock();
718*38e8c45fSAndroid Build Coastguard Worker }
719*38e8c45fSAndroid Build Coastguard Worker 
lookupOrCreateWeak(const void * objectID,object_make_func make,const void * makeArgs)720*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> BpBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
721*38e8c45fSAndroid Build Coastguard Worker                                          const void* makeArgs) {
722*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(mLock);
723*38e8c45fSAndroid Build Coastguard Worker     return mObjects.lookupOrCreateWeak(objectID, make, makeArgs);
724*38e8c45fSAndroid Build Coastguard Worker }
725*38e8c45fSAndroid Build Coastguard Worker 
remoteBinder()726*38e8c45fSAndroid Build Coastguard Worker BpBinder* BpBinder::remoteBinder()
727*38e8c45fSAndroid Build Coastguard Worker {
728*38e8c45fSAndroid Build Coastguard Worker     return this;
729*38e8c45fSAndroid Build Coastguard Worker }
730*38e8c45fSAndroid Build Coastguard Worker 
~BpBinder()731*38e8c45fSAndroid Build Coastguard Worker BpBinder::~BpBinder() {
732*38e8c45fSAndroid Build Coastguard Worker     if (isRpcBinder()) [[unlikely]] {
733*38e8c45fSAndroid Build Coastguard Worker         return;
734*38e8c45fSAndroid Build Coastguard Worker     }
735*38e8c45fSAndroid Build Coastguard Worker 
736*38e8c45fSAndroid Build Coastguard Worker     if constexpr (!kEnableKernelIpc) {
737*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
738*38e8c45fSAndroid Build Coastguard Worker         return;
739*38e8c45fSAndroid Build Coastguard Worker     }
740*38e8c45fSAndroid Build Coastguard Worker 
741*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Destroying BpBinder %p handle %d\n", this, binderHandle());
742*38e8c45fSAndroid Build Coastguard Worker 
743*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
744*38e8c45fSAndroid Build Coastguard Worker 
745*38e8c45fSAndroid Build Coastguard Worker     if (mTrackedUid >= 0) {
746*38e8c45fSAndroid Build Coastguard Worker         RpcMutexUniqueLock _l(sTrackingLock);
747*38e8c45fSAndroid Build Coastguard Worker         uint32_t trackedValue = sTrackingMap[mTrackedUid];
748*38e8c45fSAndroid Build Coastguard Worker         if ((trackedValue & COUNTING_VALUE_MASK) == 0) [[unlikely]] {
749*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this,
750*38e8c45fSAndroid Build Coastguard Worker                   binderHandle());
751*38e8c45fSAndroid Build Coastguard Worker         } else {
752*38e8c45fSAndroid Build Coastguard Worker             auto countingValue = trackedValue & COUNTING_VALUE_MASK;
753*38e8c45fSAndroid Build Coastguard Worker             if ((trackedValue & (LIMIT_REACHED_MASK | WARNING_REACHED_MASK)) &&
754*38e8c45fSAndroid Build Coastguard Worker                 (countingValue <= sBinderProxyCountLowWatermark)) [[unlikely]] {
755*38e8c45fSAndroid Build Coastguard Worker                 ALOGI("Limit reached bit reset for uid %d (fewer than %d proxies from uid %d held)",
756*38e8c45fSAndroid Build Coastguard Worker                       getuid(), sBinderProxyCountLowWatermark, mTrackedUid);
757*38e8c45fSAndroid Build Coastguard Worker                 sTrackingMap[mTrackedUid] &= ~(LIMIT_REACHED_MASK | WARNING_REACHED_MASK);
758*38e8c45fSAndroid Build Coastguard Worker                 sLastLimitCallbackMap.erase(mTrackedUid);
759*38e8c45fSAndroid Build Coastguard Worker             }
760*38e8c45fSAndroid Build Coastguard Worker             if (--sTrackingMap[mTrackedUid] == 0) {
761*38e8c45fSAndroid Build Coastguard Worker                 sTrackingMap.erase(mTrackedUid);
762*38e8c45fSAndroid Build Coastguard Worker             }
763*38e8c45fSAndroid Build Coastguard Worker         }
764*38e8c45fSAndroid Build Coastguard Worker     }
765*38e8c45fSAndroid Build Coastguard Worker     uint32_t numProxies = --sBinderProxyCount;
766*38e8c45fSAndroid Build Coastguard Worker     binder::os::trace_int(ATRACE_TAG_AIDL, "binder_proxies", numProxies);
767*38e8c45fSAndroid Build Coastguard Worker     if (ipc) {
768*38e8c45fSAndroid Build Coastguard Worker         ipc->expungeHandle(binderHandle(), this);
769*38e8c45fSAndroid Build Coastguard Worker         ipc->decWeakHandle(binderHandle());
770*38e8c45fSAndroid Build Coastguard Worker     }
771*38e8c45fSAndroid Build Coastguard Worker }
772*38e8c45fSAndroid Build Coastguard Worker 
onFirstRef()773*38e8c45fSAndroid Build Coastguard Worker void BpBinder::onFirstRef() {
774*38e8c45fSAndroid Build Coastguard Worker     if (isRpcBinder()) [[unlikely]] {
775*38e8c45fSAndroid Build Coastguard Worker         return;
776*38e8c45fSAndroid Build Coastguard Worker     }
777*38e8c45fSAndroid Build Coastguard Worker 
778*38e8c45fSAndroid Build Coastguard Worker     if constexpr (!kEnableKernelIpc) {
779*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
780*38e8c45fSAndroid Build Coastguard Worker         return;
781*38e8c45fSAndroid Build Coastguard Worker     }
782*38e8c45fSAndroid Build Coastguard Worker 
783*38e8c45fSAndroid Build Coastguard Worker     ALOGV("onFirstRef BpBinder %p handle %d\n", this, binderHandle());
784*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
785*38e8c45fSAndroid Build Coastguard Worker     if (ipc) ipc->incStrongHandle(binderHandle(), this);
786*38e8c45fSAndroid Build Coastguard Worker }
787*38e8c45fSAndroid Build Coastguard Worker 
onLastStrongRef(const void *)788*38e8c45fSAndroid Build Coastguard Worker void BpBinder::onLastStrongRef(const void* /*id*/) {
789*38e8c45fSAndroid Build Coastguard Worker     if (isRpcBinder()) [[unlikely]] {
790*38e8c45fSAndroid Build Coastguard Worker         (void)rpcSession()->sendDecStrong(this);
791*38e8c45fSAndroid Build Coastguard Worker         return;
792*38e8c45fSAndroid Build Coastguard Worker     }
793*38e8c45fSAndroid Build Coastguard Worker 
794*38e8c45fSAndroid Build Coastguard Worker     if constexpr (!kEnableKernelIpc) {
795*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
796*38e8c45fSAndroid Build Coastguard Worker         return;
797*38e8c45fSAndroid Build Coastguard Worker     }
798*38e8c45fSAndroid Build Coastguard Worker 
799*38e8c45fSAndroid Build Coastguard Worker     ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, binderHandle());
800*38e8c45fSAndroid Build Coastguard Worker     IF_ALOGV() {
801*38e8c45fSAndroid Build Coastguard Worker         printRefs();
802*38e8c45fSAndroid Build Coastguard Worker     }
803*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
804*38e8c45fSAndroid Build Coastguard Worker     if (ipc) ipc->decStrongHandle(binderHandle());
805*38e8c45fSAndroid Build Coastguard Worker 
806*38e8c45fSAndroid Build Coastguard Worker     mLock.lock();
807*38e8c45fSAndroid Build Coastguard Worker     Vector<Obituary>* obits = mObituaries;
808*38e8c45fSAndroid Build Coastguard Worker     if(obits != nullptr) {
809*38e8c45fSAndroid Build Coastguard Worker         if (!obits->isEmpty()) {
810*38e8c45fSAndroid Build Coastguard Worker             ALOGI("onLastStrongRef automatically unlinking death recipients: %s",
811*38e8c45fSAndroid Build Coastguard Worker                   String8(mDescriptorCache).c_str());
812*38e8c45fSAndroid Build Coastguard Worker         }
813*38e8c45fSAndroid Build Coastguard Worker 
814*38e8c45fSAndroid Build Coastguard Worker         if (ipc) ipc->clearDeathNotification(binderHandle(), this);
815*38e8c45fSAndroid Build Coastguard Worker         mObituaries = nullptr;
816*38e8c45fSAndroid Build Coastguard Worker     }
817*38e8c45fSAndroid Build Coastguard Worker     if (mFrozen != nullptr) {
818*38e8c45fSAndroid Build Coastguard Worker         std::ignore = IPCThreadState::self()->removeFrozenStateChangeCallback(binderHandle(), this);
819*38e8c45fSAndroid Build Coastguard Worker         mFrozen.reset();
820*38e8c45fSAndroid Build Coastguard Worker     }
821*38e8c45fSAndroid Build Coastguard Worker     mLock.unlock();
822*38e8c45fSAndroid Build Coastguard Worker 
823*38e8c45fSAndroid Build Coastguard Worker     if (obits != nullptr) {
824*38e8c45fSAndroid Build Coastguard Worker         // XXX Should we tell any remaining DeathRecipient
825*38e8c45fSAndroid Build Coastguard Worker         // objects that the last strong ref has gone away, so they
826*38e8c45fSAndroid Build Coastguard Worker         // are no longer linked?
827*38e8c45fSAndroid Build Coastguard Worker         delete obits;
828*38e8c45fSAndroid Build Coastguard Worker     }
829*38e8c45fSAndroid Build Coastguard Worker }
830*38e8c45fSAndroid Build Coastguard Worker 
onIncStrongAttempted(uint32_t,const void *)831*38e8c45fSAndroid Build Coastguard Worker bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
832*38e8c45fSAndroid Build Coastguard Worker {
833*38e8c45fSAndroid Build Coastguard Worker     // RPC binder doesn't currently support inc from weak binders
834*38e8c45fSAndroid Build Coastguard Worker     if (isRpcBinder()) [[unlikely]] {
835*38e8c45fSAndroid Build Coastguard Worker         return false;
836*38e8c45fSAndroid Build Coastguard Worker     }
837*38e8c45fSAndroid Build Coastguard Worker 
838*38e8c45fSAndroid Build Coastguard Worker     if constexpr (!kEnableKernelIpc) {
839*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
840*38e8c45fSAndroid Build Coastguard Worker         return false;
841*38e8c45fSAndroid Build Coastguard Worker     }
842*38e8c45fSAndroid Build Coastguard Worker 
843*38e8c45fSAndroid Build Coastguard Worker     ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, binderHandle());
844*38e8c45fSAndroid Build Coastguard Worker     IPCThreadState* ipc = IPCThreadState::self();
845*38e8c45fSAndroid Build Coastguard Worker     return ipc ? ipc->attemptIncStrongHandle(binderHandle()) == NO_ERROR : false;
846*38e8c45fSAndroid Build Coastguard Worker }
847*38e8c45fSAndroid Build Coastguard Worker 
getBinderProxyCount(uint32_t uid)848*38e8c45fSAndroid Build Coastguard Worker uint32_t BpBinder::getBinderProxyCount(uint32_t uid)
849*38e8c45fSAndroid Build Coastguard Worker {
850*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(sTrackingLock);
851*38e8c45fSAndroid Build Coastguard Worker     auto it = sTrackingMap.find(uid);
852*38e8c45fSAndroid Build Coastguard Worker     if (it != sTrackingMap.end()) {
853*38e8c45fSAndroid Build Coastguard Worker         return it->second & COUNTING_VALUE_MASK;
854*38e8c45fSAndroid Build Coastguard Worker     }
855*38e8c45fSAndroid Build Coastguard Worker     return 0;
856*38e8c45fSAndroid Build Coastguard Worker }
857*38e8c45fSAndroid Build Coastguard Worker 
getBinderProxyCount()858*38e8c45fSAndroid Build Coastguard Worker uint32_t BpBinder::getBinderProxyCount()
859*38e8c45fSAndroid Build Coastguard Worker {
860*38e8c45fSAndroid Build Coastguard Worker     return sBinderProxyCount.load();
861*38e8c45fSAndroid Build Coastguard Worker }
862*38e8c45fSAndroid Build Coastguard Worker 
getCountByUid(Vector<uint32_t> & uids,Vector<uint32_t> & counts)863*38e8c45fSAndroid Build Coastguard Worker void BpBinder::getCountByUid(Vector<uint32_t>& uids, Vector<uint32_t>& counts)
864*38e8c45fSAndroid Build Coastguard Worker {
865*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(sTrackingLock);
866*38e8c45fSAndroid Build Coastguard Worker     uids.setCapacity(sTrackingMap.size());
867*38e8c45fSAndroid Build Coastguard Worker     counts.setCapacity(sTrackingMap.size());
868*38e8c45fSAndroid Build Coastguard Worker     for (const auto& it : sTrackingMap) {
869*38e8c45fSAndroid Build Coastguard Worker         uids.push_back(it.first);
870*38e8c45fSAndroid Build Coastguard Worker         counts.push_back(it.second & COUNTING_VALUE_MASK);
871*38e8c45fSAndroid Build Coastguard Worker     }
872*38e8c45fSAndroid Build Coastguard Worker }
873*38e8c45fSAndroid Build Coastguard Worker 
enableCountByUid()874*38e8c45fSAndroid Build Coastguard Worker void BpBinder::enableCountByUid() { sCountByUidEnabled.store(true); }
disableCountByUid()875*38e8c45fSAndroid Build Coastguard Worker void BpBinder::disableCountByUid() { sCountByUidEnabled.store(false); }
setCountByUidEnabled(bool enable)876*38e8c45fSAndroid Build Coastguard Worker void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); }
877*38e8c45fSAndroid Build Coastguard Worker 
setBinderProxyCountEventCallback(binder_proxy_limit_callback cbl,binder_proxy_warning_callback cbw)878*38e8c45fSAndroid Build Coastguard Worker void BpBinder::setBinderProxyCountEventCallback(binder_proxy_limit_callback cbl,
879*38e8c45fSAndroid Build Coastguard Worker                                                 binder_proxy_warning_callback cbw) {
880*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(sTrackingLock);
881*38e8c45fSAndroid Build Coastguard Worker     sLimitCallback = std::move(cbl);
882*38e8c45fSAndroid Build Coastguard Worker     sWarningCallback = std::move(cbw);
883*38e8c45fSAndroid Build Coastguard Worker }
884*38e8c45fSAndroid Build Coastguard Worker 
setBinderProxyCountWatermarks(int high,int low,int warning)885*38e8c45fSAndroid Build Coastguard Worker void BpBinder::setBinderProxyCountWatermarks(int high, int low, int warning) {
886*38e8c45fSAndroid Build Coastguard Worker     RpcMutexUniqueLock _l(sTrackingLock);
887*38e8c45fSAndroid Build Coastguard Worker     sBinderProxyCountHighWatermark = high;
888*38e8c45fSAndroid Build Coastguard Worker     sBinderProxyCountLowWatermark = low;
889*38e8c45fSAndroid Build Coastguard Worker     sBinderProxyCountWarningWatermark = warning;
890*38e8c45fSAndroid Build Coastguard Worker }
891*38e8c45fSAndroid Build Coastguard Worker 
892*38e8c45fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
893*38e8c45fSAndroid Build Coastguard Worker 
894*38e8c45fSAndroid Build Coastguard Worker } // namespace android
895