xref: /aosp_15_r20/frameworks/native/libs/binder/ndk/ibinder.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2018 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 #include <android/binder_ibinder.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_ibinder_platform.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_stability.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_status.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <binder/Functional.h>
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/Trace.h>
25*38e8c45fSAndroid Build Coastguard Worker #if __has_include(<private/android_filesystem_config.h>)
26*38e8c45fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
27*38e8c45fSAndroid Build Coastguard Worker #endif
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker #include "../BuildFlags.h"
30*38e8c45fSAndroid Build Coastguard Worker #include "ibinder_internal.h"
31*38e8c45fSAndroid Build Coastguard Worker #include "parcel_internal.h"
32*38e8c45fSAndroid Build Coastguard Worker #include "status_internal.h"
33*38e8c45fSAndroid Build Coastguard Worker 
34*38e8c45fSAndroid Build Coastguard Worker using DeathRecipient = ::android::IBinder::DeathRecipient;
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker using ::android::IBinder;
37*38e8c45fSAndroid Build Coastguard Worker using ::android::IResultReceiver;
38*38e8c45fSAndroid Build Coastguard Worker using ::android::Parcel;
39*38e8c45fSAndroid Build Coastguard Worker using ::android::sp;
40*38e8c45fSAndroid Build Coastguard Worker using ::android::status_t;
41*38e8c45fSAndroid Build Coastguard Worker using ::android::statusToString;
42*38e8c45fSAndroid Build Coastguard Worker using ::android::String16;
43*38e8c45fSAndroid Build Coastguard Worker using ::android::String8;
44*38e8c45fSAndroid Build Coastguard Worker using ::android::wp;
45*38e8c45fSAndroid Build Coastguard Worker using ::android::binder::impl::make_scope_guard;
46*38e8c45fSAndroid Build Coastguard Worker using ::android::binder::impl::scope_guard;
47*38e8c45fSAndroid Build Coastguard Worker using ::android::binder::os::get_trace_enabled_tags;
48*38e8c45fSAndroid Build Coastguard Worker using ::android::binder::os::trace_begin;
49*38e8c45fSAndroid Build Coastguard Worker using ::android::binder::os::trace_end;
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker // transaction codes for getInterfaceHash and getInterfaceVersion are defined
52*38e8c45fSAndroid Build Coastguard Worker // in file : system/tools/aidl/aidl.cpp
53*38e8c45fSAndroid Build Coastguard Worker static constexpr int kGetInterfaceVersionId = 0x00fffffe;
54*38e8c45fSAndroid Build Coastguard Worker static const char* kInterfaceVersion = "getInterfaceVersion";
55*38e8c45fSAndroid Build Coastguard Worker static constexpr int kGetInterfaceHashId = 0x00fffffd;
56*38e8c45fSAndroid Build Coastguard Worker static const char* kInterfaceHash = "getInterfaceHash";
57*38e8c45fSAndroid Build Coastguard Worker static const char* kNdkTrace = "AIDL::ndk::";
58*38e8c45fSAndroid Build Coastguard Worker static const char* kServerTrace = "::server";
59*38e8c45fSAndroid Build Coastguard Worker static const char* kClientTrace = "::client";
60*38e8c45fSAndroid Build Coastguard Worker static const char* kSeparator = "::";
61*38e8c45fSAndroid Build Coastguard Worker static const char* kUnknownCode = "Unknown_Transaction_Code:";
62*38e8c45fSAndroid Build Coastguard Worker 
63*38e8c45fSAndroid Build Coastguard Worker namespace ABBinderTag {
64*38e8c45fSAndroid Build Coastguard Worker 
65*38e8c45fSAndroid Build Coastguard Worker static const void* kId = "ABBinder";
66*38e8c45fSAndroid Build Coastguard Worker static void* kValue = static_cast<void*>(new bool{true});
clean(const void *,void *,void *)67*38e8c45fSAndroid Build Coastguard Worker void clean(const void* /*id*/, void* /*obj*/, void* /*cookie*/) {
68*38e8c45fSAndroid Build Coastguard Worker     /* do nothing */
69*38e8c45fSAndroid Build Coastguard Worker }
70*38e8c45fSAndroid Build Coastguard Worker 
attach(const sp<IBinder> & binder)71*38e8c45fSAndroid Build Coastguard Worker static void attach(const sp<IBinder>& binder) {
72*38e8c45fSAndroid Build Coastguard Worker     auto alreadyAttached = binder->attachObject(kId, kValue, nullptr /*cookie*/, clean);
73*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(alreadyAttached != nullptr, "can only attach once");
74*38e8c45fSAndroid Build Coastguard Worker }
has(const sp<IBinder> & binder)75*38e8c45fSAndroid Build Coastguard Worker static bool has(const sp<IBinder>& binder) {
76*38e8c45fSAndroid Build Coastguard Worker     return binder != nullptr && binder->findObject(kId) == kValue;
77*38e8c45fSAndroid Build Coastguard Worker }
78*38e8c45fSAndroid Build Coastguard Worker 
79*38e8c45fSAndroid Build Coastguard Worker }  // namespace ABBinderTag
80*38e8c45fSAndroid Build Coastguard Worker 
81*38e8c45fSAndroid Build Coastguard Worker namespace ABpBinderTag {
82*38e8c45fSAndroid Build Coastguard Worker 
83*38e8c45fSAndroid Build Coastguard Worker static const void* kId = "ABpBinder";
84*38e8c45fSAndroid Build Coastguard Worker struct Value {
85*38e8c45fSAndroid Build Coastguard Worker     wp<ABpBinder> binder;
86*38e8c45fSAndroid Build Coastguard Worker };
clean(const void * id,void * obj,void * cookie)87*38e8c45fSAndroid Build Coastguard Worker void clean(const void* id, void* obj, void* cookie) {
88*38e8c45fSAndroid Build Coastguard Worker     // be weary of leaks!
89*38e8c45fSAndroid Build Coastguard Worker     // ALOGI("Deleting an ABpBinder");
90*38e8c45fSAndroid Build Coastguard Worker 
91*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(id != kId, "%p %p %p", id, obj, cookie);
92*38e8c45fSAndroid Build Coastguard Worker 
93*38e8c45fSAndroid Build Coastguard Worker     delete static_cast<Value*>(obj);
94*38e8c45fSAndroid Build Coastguard Worker }
95*38e8c45fSAndroid Build Coastguard Worker 
96*38e8c45fSAndroid Build Coastguard Worker }  // namespace ABpBinderTag
97*38e8c45fSAndroid Build Coastguard Worker 
AIBinder(const AIBinder_Class * clazz)98*38e8c45fSAndroid Build Coastguard Worker AIBinder::AIBinder(const AIBinder_Class* clazz) : mClazz(clazz) {}
~AIBinder()99*38e8c45fSAndroid Build Coastguard Worker AIBinder::~AIBinder() {}
100*38e8c45fSAndroid Build Coastguard Worker 
101*38e8c45fSAndroid Build Coastguard Worker // b/175635923 libcxx causes "implicit-conversion" with a string with invalid char
SanitizeString(const String16 & str)102*38e8c45fSAndroid Build Coastguard Worker static std::string SanitizeString(const String16& str) {
103*38e8c45fSAndroid Build Coastguard Worker     std::string sanitized{String8(str)};
104*38e8c45fSAndroid Build Coastguard Worker     for (auto& c : sanitized) {
105*38e8c45fSAndroid Build Coastguard Worker         if (!isprint(c)) {
106*38e8c45fSAndroid Build Coastguard Worker             c = '?';
107*38e8c45fSAndroid Build Coastguard Worker         }
108*38e8c45fSAndroid Build Coastguard Worker     }
109*38e8c45fSAndroid Build Coastguard Worker     return sanitized;
110*38e8c45fSAndroid Build Coastguard Worker }
111*38e8c45fSAndroid Build Coastguard Worker 
getMethodName(const AIBinder_Class * clazz,transaction_code_t code)112*38e8c45fSAndroid Build Coastguard Worker const std::string getMethodName(const AIBinder_Class* clazz, transaction_code_t code) {
113*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/150155678) - Move getInterfaceHash and getInterfaceVersion to libbinder and remove
114*38e8c45fSAndroid Build Coastguard Worker     // hardcoded cases.
115*38e8c45fSAndroid Build Coastguard Worker     if (code <= clazz->getTransactionCodeToFunctionLength() && code >= FIRST_CALL_TRANSACTION) {
116*38e8c45fSAndroid Build Coastguard Worker         // Codes have FIRST_CALL_TRANSACTION as added offset. Subtract to access function name
117*38e8c45fSAndroid Build Coastguard Worker         return clazz->getFunctionName(code);
118*38e8c45fSAndroid Build Coastguard Worker     } else if (code == kGetInterfaceVersionId) {
119*38e8c45fSAndroid Build Coastguard Worker         return kInterfaceVersion;
120*38e8c45fSAndroid Build Coastguard Worker     } else if (code == kGetInterfaceHashId) {
121*38e8c45fSAndroid Build Coastguard Worker         return kInterfaceHash;
122*38e8c45fSAndroid Build Coastguard Worker     }
123*38e8c45fSAndroid Build Coastguard Worker     return kUnknownCode + std::to_string(code);
124*38e8c45fSAndroid Build Coastguard Worker }
125*38e8c45fSAndroid Build Coastguard Worker 
getTraceSectionName(const AIBinder_Class * clazz,transaction_code_t code,bool isServer)126*38e8c45fSAndroid Build Coastguard Worker const std::string getTraceSectionName(const AIBinder_Class* clazz, transaction_code_t code,
127*38e8c45fSAndroid Build Coastguard Worker                                       bool isServer) {
128*38e8c45fSAndroid Build Coastguard Worker     if (clazz == nullptr) {
129*38e8c45fSAndroid Build Coastguard Worker         ALOGE("class associated with binder is null. Class is needed to add trace with interface "
130*38e8c45fSAndroid Build Coastguard Worker               "name and function name");
131*38e8c45fSAndroid Build Coastguard Worker         return kNdkTrace;
132*38e8c45fSAndroid Build Coastguard Worker     }
133*38e8c45fSAndroid Build Coastguard Worker 
134*38e8c45fSAndroid Build Coastguard Worker     const std::string descriptor = clazz->getInterfaceDescriptorUtf8();
135*38e8c45fSAndroid Build Coastguard Worker     const std::string methodName = getMethodName(clazz, code);
136*38e8c45fSAndroid Build Coastguard Worker 
137*38e8c45fSAndroid Build Coastguard Worker     size_t traceSize =
138*38e8c45fSAndroid Build Coastguard Worker             strlen(kNdkTrace) + descriptor.size() + strlen(kSeparator) + methodName.size();
139*38e8c45fSAndroid Build Coastguard Worker     traceSize += isServer ? strlen(kServerTrace) : strlen(kClientTrace);
140*38e8c45fSAndroid Build Coastguard Worker 
141*38e8c45fSAndroid Build Coastguard Worker     std::string trace;
142*38e8c45fSAndroid Build Coastguard Worker     // reserve to avoid repeated allocations
143*38e8c45fSAndroid Build Coastguard Worker     trace.reserve(traceSize);
144*38e8c45fSAndroid Build Coastguard Worker 
145*38e8c45fSAndroid Build Coastguard Worker     trace += kNdkTrace;
146*38e8c45fSAndroid Build Coastguard Worker     trace += clazz->getInterfaceDescriptorUtf8();
147*38e8c45fSAndroid Build Coastguard Worker     trace += kSeparator;
148*38e8c45fSAndroid Build Coastguard Worker     trace += methodName;
149*38e8c45fSAndroid Build Coastguard Worker     trace += isServer ? kServerTrace : kClientTrace;
150*38e8c45fSAndroid Build Coastguard Worker 
151*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(trace.size() != traceSize, "Trace size mismatch. Expected %zu, got %zu",
152*38e8c45fSAndroid Build Coastguard Worker                         traceSize, trace.size());
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker     return trace;
155*38e8c45fSAndroid Build Coastguard Worker }
156*38e8c45fSAndroid Build Coastguard Worker 
associateClass(const AIBinder_Class * clazz)157*38e8c45fSAndroid Build Coastguard Worker bool AIBinder::associateClass(const AIBinder_Class* clazz) {
158*38e8c45fSAndroid Build Coastguard Worker     if (clazz == nullptr) return false;
159*38e8c45fSAndroid Build Coastguard Worker 
160*38e8c45fSAndroid Build Coastguard Worker     // If mClazz is non-null, this must have been called and cached
161*38e8c45fSAndroid Build Coastguard Worker     // already. So, we can safely call this first. Due to the implementation
162*38e8c45fSAndroid Build Coastguard Worker     // of getInterfaceDescriptor (at time of writing), two simultaneous calls
163*38e8c45fSAndroid Build Coastguard Worker     // may lead to extra binder transactions, but this is expected to be
164*38e8c45fSAndroid Build Coastguard Worker     // exceedingly rare. Once we have a binder, when we get it again later,
165*38e8c45fSAndroid Build Coastguard Worker     // we won't make another binder transaction here.
166*38e8c45fSAndroid Build Coastguard Worker     const String16& descriptor = getBinder()->getInterfaceDescriptor();
167*38e8c45fSAndroid Build Coastguard Worker     const String16& newDescriptor = clazz->getInterfaceDescriptor();
168*38e8c45fSAndroid Build Coastguard Worker 
169*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mClazzMutex);
170*38e8c45fSAndroid Build Coastguard Worker     if (mClazz == clazz) return true;
171*38e8c45fSAndroid Build Coastguard Worker 
172*38e8c45fSAndroid Build Coastguard Worker     // If this is an ABpBinder, the first class object becomes the canonical one. The implication
173*38e8c45fSAndroid Build Coastguard Worker     // of this is that no API can require a proxy information to get information on how to behave.
174*38e8c45fSAndroid Build Coastguard Worker     // from the class itself - which should only store the interface descriptor. The functionality
175*38e8c45fSAndroid Build Coastguard Worker     // should be implemented by adding AIBinder_* APIs to set values on binders themselves, by
176*38e8c45fSAndroid Build Coastguard Worker     // setting things on AIBinder_Class which get transferred along with the binder, so that they
177*38e8c45fSAndroid Build Coastguard Worker     // can be read along with the BpBinder, or by modifying APIs directly (e.g. an option in
178*38e8c45fSAndroid Build Coastguard Worker     // onTransact).
179*38e8c45fSAndroid Build Coastguard Worker     //
180*38e8c45fSAndroid Build Coastguard Worker     // While this check is required to support linkernamespaces, one downside of it is that
181*38e8c45fSAndroid Build Coastguard Worker     // you may parcel code to communicate between things in the same process. However, comms
182*38e8c45fSAndroid Build Coastguard Worker     // between linkernamespaces like this already happen for cross-language calls like Java<->C++
183*38e8c45fSAndroid Build Coastguard Worker     // or Rust<->Java, and there are good stability guarantees here. This interacts with
184*38e8c45fSAndroid Build Coastguard Worker     // binder Stability checks exactly like any other in-process call. The stability is known
185*38e8c45fSAndroid Build Coastguard Worker     // to the IBinder object, so that it doesn't matter if a class object comes from
186*38e8c45fSAndroid Build Coastguard Worker     // a different stability level.
187*38e8c45fSAndroid Build Coastguard Worker     if (mClazz != nullptr && !asABpBinder()) {
188*38e8c45fSAndroid Build Coastguard Worker         const String16& currentDescriptor = mClazz->getInterfaceDescriptor();
189*38e8c45fSAndroid Build Coastguard Worker         if (newDescriptor == currentDescriptor) {
190*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Class descriptors '%s' match during associateClass, but they are different class"
191*38e8c45fSAndroid Build Coastguard Worker                   " objects (%p vs %p). Class descriptor collision?",
192*38e8c45fSAndroid Build Coastguard Worker                   String8(currentDescriptor).c_str(), clazz, mClazz);
193*38e8c45fSAndroid Build Coastguard Worker         } else {
194*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Class cannot be associated on object which already has a class. "
195*38e8c45fSAndroid Build Coastguard Worker                   "Trying to associate to '%s' but already set to '%s'.",
196*38e8c45fSAndroid Build Coastguard Worker                   __func__, String8(newDescriptor).c_str(), String8(currentDescriptor).c_str());
197*38e8c45fSAndroid Build Coastguard Worker         }
198*38e8c45fSAndroid Build Coastguard Worker 
199*38e8c45fSAndroid Build Coastguard Worker         // always a failure because we know mClazz != clazz
200*38e8c45fSAndroid Build Coastguard Worker         return false;
201*38e8c45fSAndroid Build Coastguard Worker     }
202*38e8c45fSAndroid Build Coastguard Worker 
203*38e8c45fSAndroid Build Coastguard Worker     // This will always be an O(n) comparison, but it's expected to be extremely rare.
204*38e8c45fSAndroid Build Coastguard Worker     // since it's an error condition. Do the comparison after we take the lock and
205*38e8c45fSAndroid Build Coastguard Worker     // check the pointer equality fast path. By always taking the lock, it's also
206*38e8c45fSAndroid Build Coastguard Worker     // more flake-proof. However, the check is not dependent on the lock.
207*38e8c45fSAndroid Build Coastguard Worker     if (descriptor != newDescriptor && !(asABpBinder() && asABpBinder()->isServiceFuzzing())) {
208*38e8c45fSAndroid Build Coastguard Worker         if (getBinder()->isBinderAlive()) {
209*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Expecting binder to have class '%s' but descriptor is actually '%s'.",
210*38e8c45fSAndroid Build Coastguard Worker                   __func__, String8(newDescriptor).c_str(), SanitizeString(descriptor).c_str());
211*38e8c45fSAndroid Build Coastguard Worker         } else {
212*38e8c45fSAndroid Build Coastguard Worker             // b/155793159
213*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s: Cannot associate class '%s' to dead binder with cached descriptor '%s'.",
214*38e8c45fSAndroid Build Coastguard Worker                   __func__, String8(newDescriptor).c_str(), SanitizeString(descriptor).c_str());
215*38e8c45fSAndroid Build Coastguard Worker         }
216*38e8c45fSAndroid Build Coastguard Worker         return false;
217*38e8c45fSAndroid Build Coastguard Worker     }
218*38e8c45fSAndroid Build Coastguard Worker 
219*38e8c45fSAndroid Build Coastguard Worker     // A local binder being set for the first time OR
220*38e8c45fSAndroid Build Coastguard Worker     // ignoring a proxy binder which is set multiple time, by considering the first
221*38e8c45fSAndroid Build Coastguard Worker     // associated class as the canonical one.
222*38e8c45fSAndroid Build Coastguard Worker     if (mClazz == nullptr) {
223*38e8c45fSAndroid Build Coastguard Worker         mClazz = clazz;
224*38e8c45fSAndroid Build Coastguard Worker     }
225*38e8c45fSAndroid Build Coastguard Worker 
226*38e8c45fSAndroid Build Coastguard Worker     return true;
227*38e8c45fSAndroid Build Coastguard Worker }
228*38e8c45fSAndroid Build Coastguard Worker 
ABBinder(const AIBinder_Class * clazz,void * userData)229*38e8c45fSAndroid Build Coastguard Worker ABBinder::ABBinder(const AIBinder_Class* clazz, void* userData)
230*38e8c45fSAndroid Build Coastguard Worker     : AIBinder(clazz), BBinder(), mUserData(userData) {
231*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(clazz == nullptr, "clazz == nullptr");
232*38e8c45fSAndroid Build Coastguard Worker }
~ABBinder()233*38e8c45fSAndroid Build Coastguard Worker ABBinder::~ABBinder() {
234*38e8c45fSAndroid Build Coastguard Worker     getClass()->onDestroy(mUserData);
235*38e8c45fSAndroid Build Coastguard Worker }
236*38e8c45fSAndroid Build Coastguard Worker 
getInterfaceDescriptor() const237*38e8c45fSAndroid Build Coastguard Worker const String16& ABBinder::getInterfaceDescriptor() const {
238*38e8c45fSAndroid Build Coastguard Worker     return getClass()->getInterfaceDescriptor();
239*38e8c45fSAndroid Build Coastguard Worker }
240*38e8c45fSAndroid Build Coastguard Worker 
dump(int fd,const::android::Vector<String16> & args)241*38e8c45fSAndroid Build Coastguard Worker status_t ABBinder::dump(int fd, const ::android::Vector<String16>& args) {
242*38e8c45fSAndroid Build Coastguard Worker     AIBinder_onDump onDump = getClass()->onDump;
243*38e8c45fSAndroid Build Coastguard Worker 
244*38e8c45fSAndroid Build Coastguard Worker     if (onDump == nullptr) {
245*38e8c45fSAndroid Build Coastguard Worker         return STATUS_OK;
246*38e8c45fSAndroid Build Coastguard Worker     }
247*38e8c45fSAndroid Build Coastguard Worker 
248*38e8c45fSAndroid Build Coastguard Worker     // technically UINT32_MAX would be okay here, but INT32_MAX is expected since this may be
249*38e8c45fSAndroid Build Coastguard Worker     // null in Java
250*38e8c45fSAndroid Build Coastguard Worker     if (args.size() > INT32_MAX) {
251*38e8c45fSAndroid Build Coastguard Worker         ALOGE("ABBinder::dump received too many arguments: %zu", args.size());
252*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
253*38e8c45fSAndroid Build Coastguard Worker     }
254*38e8c45fSAndroid Build Coastguard Worker 
255*38e8c45fSAndroid Build Coastguard Worker     std::vector<String8> utf8Args;  // owns memory of utf8s
256*38e8c45fSAndroid Build Coastguard Worker     utf8Args.reserve(args.size());
257*38e8c45fSAndroid Build Coastguard Worker     std::vector<const char*> utf8Pointers;  // what can be passed over NDK API
258*38e8c45fSAndroid Build Coastguard Worker     utf8Pointers.reserve(args.size());
259*38e8c45fSAndroid Build Coastguard Worker 
260*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < args.size(); i++) {
261*38e8c45fSAndroid Build Coastguard Worker         utf8Args.push_back(String8(args[i]));
262*38e8c45fSAndroid Build Coastguard Worker         utf8Pointers.push_back(utf8Args[i].c_str());
263*38e8c45fSAndroid Build Coastguard Worker     }
264*38e8c45fSAndroid Build Coastguard Worker 
265*38e8c45fSAndroid Build Coastguard Worker     return onDump(this, fd, utf8Pointers.data(), utf8Pointers.size());
266*38e8c45fSAndroid Build Coastguard Worker }
267*38e8c45fSAndroid Build Coastguard Worker 
onTransact(transaction_code_t code,const Parcel & data,Parcel * reply,binder_flags_t flags)268*38e8c45fSAndroid Build Coastguard Worker status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply,
269*38e8c45fSAndroid Build Coastguard Worker                               binder_flags_t flags) {
270*38e8c45fSAndroid Build Coastguard Worker     std::string sectionName;
271*38e8c45fSAndroid Build Coastguard Worker     bool tracingEnabled = get_trace_enabled_tags() & ATRACE_TAG_AIDL;
272*38e8c45fSAndroid Build Coastguard Worker     if (tracingEnabled) {
273*38e8c45fSAndroid Build Coastguard Worker         sectionName = getTraceSectionName(getClass(), code, true /*isServer*/);
274*38e8c45fSAndroid Build Coastguard Worker         trace_begin(ATRACE_TAG_AIDL, sectionName.c_str());
275*38e8c45fSAndroid Build Coastguard Worker     }
276*38e8c45fSAndroid Build Coastguard Worker 
277*38e8c45fSAndroid Build Coastguard Worker     scope_guard guard = make_scope_guard([&]() {
278*38e8c45fSAndroid Build Coastguard Worker         if (tracingEnabled) trace_end(ATRACE_TAG_AIDL);
279*38e8c45fSAndroid Build Coastguard Worker     });
280*38e8c45fSAndroid Build Coastguard Worker 
281*38e8c45fSAndroid Build Coastguard Worker     if (isUserCommand(code)) {
282*38e8c45fSAndroid Build Coastguard Worker         if (getClass()->writeHeader && !data.checkInterface(this)) {
283*38e8c45fSAndroid Build Coastguard Worker             return STATUS_BAD_TYPE;
284*38e8c45fSAndroid Build Coastguard Worker         }
285*38e8c45fSAndroid Build Coastguard Worker 
286*38e8c45fSAndroid Build Coastguard Worker         const AParcel in = AParcel::readOnly(this, &data);
287*38e8c45fSAndroid Build Coastguard Worker         AParcel out = AParcel(this, reply, false /*owns*/);
288*38e8c45fSAndroid Build Coastguard Worker 
289*38e8c45fSAndroid Build Coastguard Worker         binder_status_t status = getClass()->onTransact(this, code, &in, &out);
290*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(status);
291*38e8c45fSAndroid Build Coastguard Worker     } else if (code == SHELL_COMMAND_TRANSACTION && getClass()->handleShellCommand != nullptr) {
292*38e8c45fSAndroid Build Coastguard Worker         if constexpr (!android::kEnableKernelIpc) {
293*38e8c45fSAndroid Build Coastguard Worker             // Non-IPC builds do not have getCallingUid(),
294*38e8c45fSAndroid Build Coastguard Worker             // so we have no way of authenticating the caller
295*38e8c45fSAndroid Build Coastguard Worker             return STATUS_PERMISSION_DENIED;
296*38e8c45fSAndroid Build Coastguard Worker         }
297*38e8c45fSAndroid Build Coastguard Worker 
298*38e8c45fSAndroid Build Coastguard Worker         int in = data.readFileDescriptor();
299*38e8c45fSAndroid Build Coastguard Worker         int out = data.readFileDescriptor();
300*38e8c45fSAndroid Build Coastguard Worker         int err = data.readFileDescriptor();
301*38e8c45fSAndroid Build Coastguard Worker 
302*38e8c45fSAndroid Build Coastguard Worker         int argc = data.readInt32();
303*38e8c45fSAndroid Build Coastguard Worker         std::vector<String8> utf8Args;          // owns memory of utf8s
304*38e8c45fSAndroid Build Coastguard Worker         std::vector<const char*> utf8Pointers;  // what can be passed over NDK API
305*38e8c45fSAndroid Build Coastguard Worker         for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
306*38e8c45fSAndroid Build Coastguard Worker             utf8Args.push_back(String8(data.readString16()));
307*38e8c45fSAndroid Build Coastguard Worker             utf8Pointers.push_back(utf8Args[i].c_str());
308*38e8c45fSAndroid Build Coastguard Worker         }
309*38e8c45fSAndroid Build Coastguard Worker 
310*38e8c45fSAndroid Build Coastguard Worker         data.readStrongBinder();  // skip over the IShellCallback
311*38e8c45fSAndroid Build Coastguard Worker         sp<IResultReceiver> resultReceiver = IResultReceiver::asInterface(data.readStrongBinder());
312*38e8c45fSAndroid Build Coastguard Worker 
313*38e8c45fSAndroid Build Coastguard Worker         // Shell commands should only be callable by ADB.
314*38e8c45fSAndroid Build Coastguard Worker         uid_t uid = AIBinder_getCallingUid();
315*38e8c45fSAndroid Build Coastguard Worker         if (uid != 0 /* root */
316*38e8c45fSAndroid Build Coastguard Worker #ifdef AID_SHELL
317*38e8c45fSAndroid Build Coastguard Worker             && uid != AID_SHELL
318*38e8c45fSAndroid Build Coastguard Worker #endif
319*38e8c45fSAndroid Build Coastguard Worker         ) {
320*38e8c45fSAndroid Build Coastguard Worker             if (resultReceiver != nullptr) {
321*38e8c45fSAndroid Build Coastguard Worker                 resultReceiver->send(-1);
322*38e8c45fSAndroid Build Coastguard Worker             }
323*38e8c45fSAndroid Build Coastguard Worker             return STATUS_PERMISSION_DENIED;
324*38e8c45fSAndroid Build Coastguard Worker         }
325*38e8c45fSAndroid Build Coastguard Worker 
326*38e8c45fSAndroid Build Coastguard Worker         // Check that the file descriptors are valid.
327*38e8c45fSAndroid Build Coastguard Worker         if (in == STATUS_BAD_TYPE || out == STATUS_BAD_TYPE || err == STATUS_BAD_TYPE) {
328*38e8c45fSAndroid Build Coastguard Worker             if (resultReceiver != nullptr) {
329*38e8c45fSAndroid Build Coastguard Worker                 resultReceiver->send(-1);
330*38e8c45fSAndroid Build Coastguard Worker             }
331*38e8c45fSAndroid Build Coastguard Worker             return STATUS_BAD_VALUE;
332*38e8c45fSAndroid Build Coastguard Worker         }
333*38e8c45fSAndroid Build Coastguard Worker 
334*38e8c45fSAndroid Build Coastguard Worker         binder_status_t status = getClass()->handleShellCommand(
335*38e8c45fSAndroid Build Coastguard Worker                 this, in, out, err, utf8Pointers.data(), utf8Pointers.size());
336*38e8c45fSAndroid Build Coastguard Worker         if (resultReceiver != nullptr) {
337*38e8c45fSAndroid Build Coastguard Worker             resultReceiver->send(status);
338*38e8c45fSAndroid Build Coastguard Worker         }
339*38e8c45fSAndroid Build Coastguard Worker         return status;
340*38e8c45fSAndroid Build Coastguard Worker     } else {
341*38e8c45fSAndroid Build Coastguard Worker         return BBinder::onTransact(code, data, reply, flags);
342*38e8c45fSAndroid Build Coastguard Worker     }
343*38e8c45fSAndroid Build Coastguard Worker }
344*38e8c45fSAndroid Build Coastguard Worker 
addDeathRecipient(const::android::sp<AIBinder_DeathRecipient> &,void *)345*38e8c45fSAndroid Build Coastguard Worker void ABBinder::addDeathRecipient(const ::android::sp<AIBinder_DeathRecipient>& /* recipient */,
346*38e8c45fSAndroid Build Coastguard Worker                                  void* /* cookie */) {
347*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL("Should not reach this. Can't linkToDeath local binders.");
348*38e8c45fSAndroid Build Coastguard Worker }
349*38e8c45fSAndroid Build Coastguard Worker 
ABpBinder(const::android::sp<::android::IBinder> & binder)350*38e8c45fSAndroid Build Coastguard Worker ABpBinder::ABpBinder(const ::android::sp<::android::IBinder>& binder)
351*38e8c45fSAndroid Build Coastguard Worker     : AIBinder(nullptr /*clazz*/), mRemote(binder) {
352*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(binder == nullptr, "binder == nullptr");
353*38e8c45fSAndroid Build Coastguard Worker }
354*38e8c45fSAndroid Build Coastguard Worker 
~ABpBinder()355*38e8c45fSAndroid Build Coastguard Worker ABpBinder::~ABpBinder() {
356*38e8c45fSAndroid Build Coastguard Worker     for (auto& recip : mDeathRecipients) {
357*38e8c45fSAndroid Build Coastguard Worker         sp<AIBinder_DeathRecipient> strongRecip = recip.recipient.promote();
358*38e8c45fSAndroid Build Coastguard Worker         if (strongRecip) {
359*38e8c45fSAndroid Build Coastguard Worker             strongRecip->pruneThisTransferEntry(getBinder(), recip.cookie);
360*38e8c45fSAndroid Build Coastguard Worker         }
361*38e8c45fSAndroid Build Coastguard Worker     }
362*38e8c45fSAndroid Build Coastguard Worker }
363*38e8c45fSAndroid Build Coastguard Worker 
lookupOrCreateFromBinder(const::android::sp<::android::IBinder> & binder)364*38e8c45fSAndroid Build Coastguard Worker sp<AIBinder> ABpBinder::lookupOrCreateFromBinder(const ::android::sp<::android::IBinder>& binder) {
365*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
366*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
367*38e8c45fSAndroid Build Coastguard Worker     }
368*38e8c45fSAndroid Build Coastguard Worker     if (ABBinderTag::has(binder)) {
369*38e8c45fSAndroid Build Coastguard Worker         return static_cast<ABBinder*>(binder.get());
370*38e8c45fSAndroid Build Coastguard Worker     }
371*38e8c45fSAndroid Build Coastguard Worker 
372*38e8c45fSAndroid Build Coastguard Worker     // The following code ensures that for a given binder object (remote or local), if it is not an
373*38e8c45fSAndroid Build Coastguard Worker     // ABBinder then at most one ABpBinder object exists in a given process representing it.
374*38e8c45fSAndroid Build Coastguard Worker 
375*38e8c45fSAndroid Build Coastguard Worker     auto* value = static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId));
376*38e8c45fSAndroid Build Coastguard Worker     if (value == nullptr) {
377*38e8c45fSAndroid Build Coastguard Worker         value = new ABpBinderTag::Value;
378*38e8c45fSAndroid Build Coastguard Worker         auto oldValue = static_cast<ABpBinderTag::Value*>(
379*38e8c45fSAndroid Build Coastguard Worker                 binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value),
380*38e8c45fSAndroid Build Coastguard Worker                                      nullptr /*cookie*/, ABpBinderTag::clean));
381*38e8c45fSAndroid Build Coastguard Worker 
382*38e8c45fSAndroid Build Coastguard Worker         // allocated by another thread
383*38e8c45fSAndroid Build Coastguard Worker         if (oldValue) {
384*38e8c45fSAndroid Build Coastguard Worker             delete value;
385*38e8c45fSAndroid Build Coastguard Worker             value = oldValue;
386*38e8c45fSAndroid Build Coastguard Worker         }
387*38e8c45fSAndroid Build Coastguard Worker     }
388*38e8c45fSAndroid Build Coastguard Worker 
389*38e8c45fSAndroid Build Coastguard Worker     sp<ABpBinder> ret;
390*38e8c45fSAndroid Build Coastguard Worker     binder->withLock([&]() {
391*38e8c45fSAndroid Build Coastguard Worker         ret = value->binder.promote();
392*38e8c45fSAndroid Build Coastguard Worker         if (ret == nullptr) {
393*38e8c45fSAndroid Build Coastguard Worker             ret = sp<ABpBinder>::make(binder);
394*38e8c45fSAndroid Build Coastguard Worker             value->binder = ret;
395*38e8c45fSAndroid Build Coastguard Worker         }
396*38e8c45fSAndroid Build Coastguard Worker     });
397*38e8c45fSAndroid Build Coastguard Worker 
398*38e8c45fSAndroid Build Coastguard Worker     return ret;
399*38e8c45fSAndroid Build Coastguard Worker }
400*38e8c45fSAndroid Build Coastguard Worker 
addDeathRecipient(const::android::sp<AIBinder_DeathRecipient> & recipient,void * cookie)401*38e8c45fSAndroid Build Coastguard Worker void ABpBinder::addDeathRecipient(const ::android::sp<AIBinder_DeathRecipient>& recipient,
402*38e8c45fSAndroid Build Coastguard Worker                                   void* cookie) {
403*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
404*38e8c45fSAndroid Build Coastguard Worker     mDeathRecipients.emplace_back(recipient, cookie);
405*38e8c45fSAndroid Build Coastguard Worker }
406*38e8c45fSAndroid Build Coastguard Worker 
407*38e8c45fSAndroid Build Coastguard Worker struct AIBinder_Weak {
408*38e8c45fSAndroid Build Coastguard Worker     wp<AIBinder> binder;
409*38e8c45fSAndroid Build Coastguard Worker };
AIBinder_Weak_new(AIBinder * binder)410*38e8c45fSAndroid Build Coastguard Worker AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder) {
411*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
412*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
413*38e8c45fSAndroid Build Coastguard Worker     }
414*38e8c45fSAndroid Build Coastguard Worker 
415*38e8c45fSAndroid Build Coastguard Worker     return new AIBinder_Weak{wp<AIBinder>(binder)};
416*38e8c45fSAndroid Build Coastguard Worker }
AIBinder_Weak_delete(AIBinder_Weak * weakBinder)417*38e8c45fSAndroid Build Coastguard Worker void AIBinder_Weak_delete(AIBinder_Weak* weakBinder) {
418*38e8c45fSAndroid Build Coastguard Worker     delete weakBinder;
419*38e8c45fSAndroid Build Coastguard Worker }
AIBinder_Weak_promote(AIBinder_Weak * weakBinder)420*38e8c45fSAndroid Build Coastguard Worker AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder) {
421*38e8c45fSAndroid Build Coastguard Worker     if (weakBinder == nullptr) {
422*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
423*38e8c45fSAndroid Build Coastguard Worker     }
424*38e8c45fSAndroid Build Coastguard Worker 
425*38e8c45fSAndroid Build Coastguard Worker     sp<AIBinder> binder = weakBinder->binder.promote();
426*38e8c45fSAndroid Build Coastguard Worker     AIBinder_incStrong(binder.get());
427*38e8c45fSAndroid Build Coastguard Worker     return binder.get();
428*38e8c45fSAndroid Build Coastguard Worker }
429*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Weak_clone(const AIBinder_Weak * weak)430*38e8c45fSAndroid Build Coastguard Worker AIBinder_Weak* AIBinder_Weak_clone(const AIBinder_Weak* weak) {
431*38e8c45fSAndroid Build Coastguard Worker     if (weak == nullptr) {
432*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
433*38e8c45fSAndroid Build Coastguard Worker     }
434*38e8c45fSAndroid Build Coastguard Worker 
435*38e8c45fSAndroid Build Coastguard Worker     return new AIBinder_Weak{weak->binder};
436*38e8c45fSAndroid Build Coastguard Worker }
437*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_lt(const AIBinder * lhs,const AIBinder * rhs)438*38e8c45fSAndroid Build Coastguard Worker bool AIBinder_lt(const AIBinder* lhs, const AIBinder* rhs) {
439*38e8c45fSAndroid Build Coastguard Worker     if (lhs == nullptr || rhs == nullptr) return lhs < rhs;
440*38e8c45fSAndroid Build Coastguard Worker 
441*38e8c45fSAndroid Build Coastguard Worker     return const_cast<AIBinder*>(lhs)->getBinder() < const_cast<AIBinder*>(rhs)->getBinder();
442*38e8c45fSAndroid Build Coastguard Worker }
443*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Weak_lt(const AIBinder_Weak * lhs,const AIBinder_Weak * rhs)444*38e8c45fSAndroid Build Coastguard Worker bool AIBinder_Weak_lt(const AIBinder_Weak* lhs, const AIBinder_Weak* rhs) {
445*38e8c45fSAndroid Build Coastguard Worker     if (lhs == nullptr || rhs == nullptr) return lhs < rhs;
446*38e8c45fSAndroid Build Coastguard Worker 
447*38e8c45fSAndroid Build Coastguard Worker     return lhs->binder < rhs->binder;
448*38e8c45fSAndroid Build Coastguard Worker }
449*38e8c45fSAndroid Build Coastguard Worker 
450*38e8c45fSAndroid Build Coastguard Worker // WARNING: When multiple classes exist with the same interface descriptor in different
451*38e8c45fSAndroid Build Coastguard Worker // linkernamespaces, the first one to be associated with mClazz becomes the canonical one
452*38e8c45fSAndroid Build Coastguard Worker // and the only requirement on this is that the interface descriptors match. If this
453*38e8c45fSAndroid Build Coastguard Worker // is an ABpBinder, no other state can be referenced from mClazz.
AIBinder_Class(const char * interfaceDescriptor,AIBinder_Class_onCreate onCreate,AIBinder_Class_onDestroy onDestroy,AIBinder_Class_onTransact onTransact)454*38e8c45fSAndroid Build Coastguard Worker AIBinder_Class::AIBinder_Class(const char* interfaceDescriptor, AIBinder_Class_onCreate onCreate,
455*38e8c45fSAndroid Build Coastguard Worker                                AIBinder_Class_onDestroy onDestroy,
456*38e8c45fSAndroid Build Coastguard Worker                                AIBinder_Class_onTransact onTransact)
457*38e8c45fSAndroid Build Coastguard Worker     : onCreate(onCreate),
458*38e8c45fSAndroid Build Coastguard Worker       onDestroy(onDestroy),
459*38e8c45fSAndroid Build Coastguard Worker       onTransact(onTransact),
460*38e8c45fSAndroid Build Coastguard Worker       mInterfaceDescriptor(interfaceDescriptor),
461*38e8c45fSAndroid Build Coastguard Worker       mWideInterfaceDescriptor(interfaceDescriptor) {}
462*38e8c45fSAndroid Build Coastguard Worker 
setTransactionCodeMap(const char ** transactionCodeMap,size_t length)463*38e8c45fSAndroid Build Coastguard Worker bool AIBinder_Class::setTransactionCodeMap(const char** transactionCodeMap, size_t length) {
464*38e8c45fSAndroid Build Coastguard Worker     if (mTransactionCodeToFunction != nullptr) {
465*38e8c45fSAndroid Build Coastguard Worker         ALOGE("mTransactionCodeToFunction is already set!");
466*38e8c45fSAndroid Build Coastguard Worker         return false;
467*38e8c45fSAndroid Build Coastguard Worker     }
468*38e8c45fSAndroid Build Coastguard Worker     mTransactionCodeToFunction = transactionCodeMap;
469*38e8c45fSAndroid Build Coastguard Worker     mTransactionCodeToFunctionLength = length;
470*38e8c45fSAndroid Build Coastguard Worker     return true;
471*38e8c45fSAndroid Build Coastguard Worker }
472*38e8c45fSAndroid Build Coastguard Worker 
getFunctionName(transaction_code_t code) const473*38e8c45fSAndroid Build Coastguard Worker const char* AIBinder_Class::getFunctionName(transaction_code_t code) const {
474*38e8c45fSAndroid Build Coastguard Worker     if (mTransactionCodeToFunction == nullptr) {
475*38e8c45fSAndroid Build Coastguard Worker         ALOGE("mTransactionCodeToFunction is not set!");
476*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
477*38e8c45fSAndroid Build Coastguard Worker     }
478*38e8c45fSAndroid Build Coastguard Worker 
479*38e8c45fSAndroid Build Coastguard Worker     if (code < FIRST_CALL_TRANSACTION ||
480*38e8c45fSAndroid Build Coastguard Worker         code - FIRST_CALL_TRANSACTION >= mTransactionCodeToFunctionLength) {
481*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Function name for requested code not found!");
482*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
483*38e8c45fSAndroid Build Coastguard Worker     }
484*38e8c45fSAndroid Build Coastguard Worker 
485*38e8c45fSAndroid Build Coastguard Worker     return mTransactionCodeToFunction[code - FIRST_CALL_TRANSACTION];
486*38e8c45fSAndroid Build Coastguard Worker }
487*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Class_define(const char * interfaceDescriptor,AIBinder_Class_onCreate onCreate,AIBinder_Class_onDestroy onDestroy,AIBinder_Class_onTransact onTransact)488*38e8c45fSAndroid Build Coastguard Worker AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor,
489*38e8c45fSAndroid Build Coastguard Worker                                       AIBinder_Class_onCreate onCreate,
490*38e8c45fSAndroid Build Coastguard Worker                                       AIBinder_Class_onDestroy onDestroy,
491*38e8c45fSAndroid Build Coastguard Worker                                       AIBinder_Class_onTransact onTransact) {
492*38e8c45fSAndroid Build Coastguard Worker     if (interfaceDescriptor == nullptr || onCreate == nullptr || onDestroy == nullptr ||
493*38e8c45fSAndroid Build Coastguard Worker         onTransact == nullptr) {
494*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
495*38e8c45fSAndroid Build Coastguard Worker     }
496*38e8c45fSAndroid Build Coastguard Worker 
497*38e8c45fSAndroid Build Coastguard Worker     return new AIBinder_Class(interfaceDescriptor, onCreate, onDestroy, onTransact);
498*38e8c45fSAndroid Build Coastguard Worker }
499*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Class_setOnDump(AIBinder_Class * clazz,AIBinder_onDump onDump)500*38e8c45fSAndroid Build Coastguard Worker void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) {
501*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(clazz == nullptr, "setOnDump requires non-null clazz");
502*38e8c45fSAndroid Build Coastguard Worker 
503*38e8c45fSAndroid Build Coastguard Worker     // this is required to be called before instances are instantiated
504*38e8c45fSAndroid Build Coastguard Worker     clazz->onDump = onDump;
505*38e8c45fSAndroid Build Coastguard Worker }
506*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Class_setTransactionCodeToFunctionNameMap(AIBinder_Class * clazz,const char ** transactionCodeToFunction,size_t length)507*38e8c45fSAndroid Build Coastguard Worker void AIBinder_Class_setTransactionCodeToFunctionNameMap(AIBinder_Class* clazz,
508*38e8c45fSAndroid Build Coastguard Worker                                                         const char** transactionCodeToFunction,
509*38e8c45fSAndroid Build Coastguard Worker                                                         size_t length) {
510*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(clazz == nullptr || transactionCodeToFunction == nullptr,
511*38e8c45fSAndroid Build Coastguard Worker                         "Valid clazz and transactionCodeToFunction are needed to set code to "
512*38e8c45fSAndroid Build Coastguard Worker                         "function mapping.");
513*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!clazz->setTransactionCodeMap(transactionCodeToFunction, length),
514*38e8c45fSAndroid Build Coastguard Worker                         "Failed to set transactionCodeToFunction to clazz! Is "
515*38e8c45fSAndroid Build Coastguard Worker                         "transactionCodeToFunction already set?");
516*38e8c45fSAndroid Build Coastguard Worker }
517*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Class_getFunctionName(AIBinder_Class * clazz,transaction_code_t code)518*38e8c45fSAndroid Build Coastguard Worker const char* AIBinder_Class_getFunctionName(AIBinder_Class* clazz, transaction_code_t code) {
519*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(
520*38e8c45fSAndroid Build Coastguard Worker             clazz == nullptr,
521*38e8c45fSAndroid Build Coastguard Worker             "Valid clazz is needed to get function name for requested transaction code");
522*38e8c45fSAndroid Build Coastguard Worker     return clazz->getFunctionName(code);
523*38e8c45fSAndroid Build Coastguard Worker }
524*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class * clazz)525*38e8c45fSAndroid Build Coastguard Worker void AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class* clazz) {
526*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(clazz == nullptr, "disableInterfaceTokenHeader requires non-null clazz");
527*38e8c45fSAndroid Build Coastguard Worker 
528*38e8c45fSAndroid Build Coastguard Worker     clazz->writeHeader = false;
529*38e8c45fSAndroid Build Coastguard Worker }
530*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Class_setHandleShellCommand(AIBinder_Class * clazz,AIBinder_handleShellCommand handleShellCommand)531*38e8c45fSAndroid Build Coastguard Worker void AIBinder_Class_setHandleShellCommand(AIBinder_Class* clazz,
532*38e8c45fSAndroid Build Coastguard Worker                                           AIBinder_handleShellCommand handleShellCommand) {
533*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(clazz == nullptr, "setHandleShellCommand requires non-null clazz");
534*38e8c45fSAndroid Build Coastguard Worker 
535*38e8c45fSAndroid Build Coastguard Worker     clazz->handleShellCommand = handleShellCommand;
536*38e8c45fSAndroid Build Coastguard Worker }
537*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_Class_getDescriptor(const AIBinder_Class * clazz)538*38e8c45fSAndroid Build Coastguard Worker const char* AIBinder_Class_getDescriptor(const AIBinder_Class* clazz) {
539*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(clazz == nullptr, "getDescriptor requires non-null clazz");
540*38e8c45fSAndroid Build Coastguard Worker 
541*38e8c45fSAndroid Build Coastguard Worker     return clazz->getInterfaceDescriptorUtf8();
542*38e8c45fSAndroid Build Coastguard Worker }
543*38e8c45fSAndroid Build Coastguard Worker 
~TransferDeathRecipient()544*38e8c45fSAndroid Build Coastguard Worker AIBinder_DeathRecipient::TransferDeathRecipient::~TransferDeathRecipient() {
545*38e8c45fSAndroid Build Coastguard Worker     if (mOnUnlinked != nullptr) {
546*38e8c45fSAndroid Build Coastguard Worker         mOnUnlinked(mCookie);
547*38e8c45fSAndroid Build Coastguard Worker     }
548*38e8c45fSAndroid Build Coastguard Worker }
549*38e8c45fSAndroid Build Coastguard Worker 
binderDied(const wp<IBinder> & who)550*38e8c45fSAndroid Build Coastguard Worker void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) {
551*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(who != mWho, "%p (%p) vs %p (%p)", who.unsafe_get(), who.get_refs(),
552*38e8c45fSAndroid Build Coastguard Worker                         mWho.unsafe_get(), mWho.get_refs());
553*38e8c45fSAndroid Build Coastguard Worker 
554*38e8c45fSAndroid Build Coastguard Worker     mOnDied(mCookie);
555*38e8c45fSAndroid Build Coastguard Worker 
556*38e8c45fSAndroid Build Coastguard Worker     sp<AIBinder_DeathRecipient> recipient = mParentRecipient.promote();
557*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> strongWho = who.promote();
558*38e8c45fSAndroid Build Coastguard Worker 
559*38e8c45fSAndroid Build Coastguard Worker     // otherwise this will be cleaned up later with pruneDeadTransferEntriesLocked
560*38e8c45fSAndroid Build Coastguard Worker     if (recipient != nullptr && strongWho != nullptr) {
561*38e8c45fSAndroid Build Coastguard Worker         status_t result = recipient->unlinkToDeath(strongWho, mCookie);
562*38e8c45fSAndroid Build Coastguard Worker         if (result != ::android::DEAD_OBJECT) {
563*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Unlinking to dead binder resulted in: %d", result);
564*38e8c45fSAndroid Build Coastguard Worker         }
565*38e8c45fSAndroid Build Coastguard Worker     }
566*38e8c45fSAndroid Build Coastguard Worker 
567*38e8c45fSAndroid Build Coastguard Worker     mWho = nullptr;
568*38e8c45fSAndroid Build Coastguard Worker }
569*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied)570*38e8c45fSAndroid Build Coastguard Worker AIBinder_DeathRecipient::AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied)
571*38e8c45fSAndroid Build Coastguard Worker     : mOnDied(onDied), mOnUnlinked(nullptr) {
572*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(onDied == nullptr, "onDied == nullptr");
573*38e8c45fSAndroid Build Coastguard Worker }
574*38e8c45fSAndroid Build Coastguard Worker 
pruneThisTransferEntry(const sp<IBinder> & who,void * cookie)575*38e8c45fSAndroid Build Coastguard Worker void AIBinder_DeathRecipient::pruneThisTransferEntry(const sp<IBinder>& who, void* cookie) {
576*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
577*38e8c45fSAndroid Build Coastguard Worker     mDeathRecipients.erase(std::remove_if(mDeathRecipients.begin(), mDeathRecipients.end(),
578*38e8c45fSAndroid Build Coastguard Worker                                           [&](const sp<TransferDeathRecipient>& tdr) {
579*38e8c45fSAndroid Build Coastguard Worker                                               auto tdrWho = tdr->getWho();
580*38e8c45fSAndroid Build Coastguard Worker                                               return tdrWho != nullptr && tdrWho.promote() == who &&
581*38e8c45fSAndroid Build Coastguard Worker                                                      cookie == tdr->getCookie();
582*38e8c45fSAndroid Build Coastguard Worker                                           }),
583*38e8c45fSAndroid Build Coastguard Worker                            mDeathRecipients.end());
584*38e8c45fSAndroid Build Coastguard Worker }
585*38e8c45fSAndroid Build Coastguard Worker 
pruneDeadTransferEntriesLocked()586*38e8c45fSAndroid Build Coastguard Worker void AIBinder_DeathRecipient::pruneDeadTransferEntriesLocked() {
587*38e8c45fSAndroid Build Coastguard Worker     mDeathRecipients.erase(std::remove_if(mDeathRecipients.begin(), mDeathRecipients.end(),
588*38e8c45fSAndroid Build Coastguard Worker                                           [](const sp<TransferDeathRecipient>& tdr) {
589*38e8c45fSAndroid Build Coastguard Worker                                               return tdr->getWho() == nullptr;
590*38e8c45fSAndroid Build Coastguard Worker                                           }),
591*38e8c45fSAndroid Build Coastguard Worker                            mDeathRecipients.end());
592*38e8c45fSAndroid Build Coastguard Worker }
593*38e8c45fSAndroid Build Coastguard Worker 
linkToDeath(const sp<IBinder> & binder,void * cookie)594*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_DeathRecipient::linkToDeath(const sp<IBinder>& binder, void* cookie) {
595*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(binder == nullptr, "binder == nullptr");
596*38e8c45fSAndroid Build Coastguard Worker 
597*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
598*38e8c45fSAndroid Build Coastguard Worker 
599*38e8c45fSAndroid Build Coastguard Worker     if (mOnUnlinked && cookie &&
600*38e8c45fSAndroid Build Coastguard Worker         std::find_if(mDeathRecipients.begin(), mDeathRecipients.end(),
601*38e8c45fSAndroid Build Coastguard Worker                      [&cookie](android::sp<TransferDeathRecipient> recipient) {
602*38e8c45fSAndroid Build Coastguard Worker                          return recipient->getCookie() == cookie;
603*38e8c45fSAndroid Build Coastguard Worker                      }) != mDeathRecipients.end()) {
604*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Attempting to AIBinder_linkToDeath with the same cookie with an onUnlink callback. "
605*38e8c45fSAndroid Build Coastguard Worker               "This will cause the onUnlinked callback to be called multiple times with the same "
606*38e8c45fSAndroid Build Coastguard Worker               "cookie, which is usually not intended.");
607*38e8c45fSAndroid Build Coastguard Worker     }
608*38e8c45fSAndroid Build Coastguard Worker     if (!mOnUnlinked && cookie) {
609*38e8c45fSAndroid Build Coastguard Worker         ALOGW("AIBinder_linkToDeath is being called with a non-null cookie and no onUnlink "
610*38e8c45fSAndroid Build Coastguard Worker               "callback set. This might not be intended. AIBinder_DeathRecipient_setOnUnlinked "
611*38e8c45fSAndroid Build Coastguard Worker               "should be called first.");
612*38e8c45fSAndroid Build Coastguard Worker     }
613*38e8c45fSAndroid Build Coastguard Worker 
614*38e8c45fSAndroid Build Coastguard Worker     sp<TransferDeathRecipient> recipient =
615*38e8c45fSAndroid Build Coastguard Worker             new TransferDeathRecipient(binder, cookie, this, mOnDied, mOnUnlinked);
616*38e8c45fSAndroid Build Coastguard Worker 
617*38e8c45fSAndroid Build Coastguard Worker     status_t status = binder->linkToDeath(recipient, cookie, 0 /*flags*/);
618*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) {
619*38e8c45fSAndroid Build Coastguard Worker         // When we failed to link, the destructor of TransferDeathRecipient runs here, which
620*38e8c45fSAndroid Build Coastguard Worker         // ensures that mOnUnlinked is called before we return with an error from this method.
621*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(status);
622*38e8c45fSAndroid Build Coastguard Worker     }
623*38e8c45fSAndroid Build Coastguard Worker 
624*38e8c45fSAndroid Build Coastguard Worker     mDeathRecipients.push_back(recipient);
625*38e8c45fSAndroid Build Coastguard Worker 
626*38e8c45fSAndroid Build Coastguard Worker     pruneDeadTransferEntriesLocked();
627*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
628*38e8c45fSAndroid Build Coastguard Worker }
629*38e8c45fSAndroid Build Coastguard Worker 
unlinkToDeath(const sp<IBinder> & binder,void * cookie)630*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_DeathRecipient::unlinkToDeath(const sp<IBinder>& binder, void* cookie) {
631*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(binder == nullptr, "binder == nullptr");
632*38e8c45fSAndroid Build Coastguard Worker 
633*38e8c45fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
634*38e8c45fSAndroid Build Coastguard Worker 
635*38e8c45fSAndroid Build Coastguard Worker     for (auto it = mDeathRecipients.rbegin(); it != mDeathRecipients.rend(); ++it) {
636*38e8c45fSAndroid Build Coastguard Worker         sp<TransferDeathRecipient> recipient = *it;
637*38e8c45fSAndroid Build Coastguard Worker 
638*38e8c45fSAndroid Build Coastguard Worker         if (recipient->getCookie() == cookie && recipient->getWho() == binder) {
639*38e8c45fSAndroid Build Coastguard Worker             mDeathRecipients.erase(it.base() - 1);
640*38e8c45fSAndroid Build Coastguard Worker 
641*38e8c45fSAndroid Build Coastguard Worker             status_t status = binder->unlinkToDeath(recipient, cookie, 0 /*flags*/);
642*38e8c45fSAndroid Build Coastguard Worker             if (status != ::android::OK) {
643*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("%s: removed reference to death recipient but unlink failed: %s", __func__,
644*38e8c45fSAndroid Build Coastguard Worker                       statusToString(status).c_str());
645*38e8c45fSAndroid Build Coastguard Worker             }
646*38e8c45fSAndroid Build Coastguard Worker             return PruneStatusT(status);
647*38e8c45fSAndroid Build Coastguard Worker         }
648*38e8c45fSAndroid Build Coastguard Worker     }
649*38e8c45fSAndroid Build Coastguard Worker 
650*38e8c45fSAndroid Build Coastguard Worker     return STATUS_NAME_NOT_FOUND;
651*38e8c45fSAndroid Build Coastguard Worker }
652*38e8c45fSAndroid Build Coastguard Worker 
setOnUnlinked(AIBinder_DeathRecipient_onBinderUnlinked onUnlinked)653*38e8c45fSAndroid Build Coastguard Worker void AIBinder_DeathRecipient::setOnUnlinked(AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) {
654*38e8c45fSAndroid Build Coastguard Worker     mOnUnlinked = onUnlinked;
655*38e8c45fSAndroid Build Coastguard Worker }
656*38e8c45fSAndroid Build Coastguard Worker 
657*38e8c45fSAndroid Build Coastguard Worker // start of C-API methods
658*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_new(const AIBinder_Class * clazz,void * args)659*38e8c45fSAndroid Build Coastguard Worker AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args) {
660*38e8c45fSAndroid Build Coastguard Worker     if (clazz == nullptr) {
661*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Must provide class to construct local binder.", __func__);
662*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
663*38e8c45fSAndroid Build Coastguard Worker     }
664*38e8c45fSAndroid Build Coastguard Worker 
665*38e8c45fSAndroid Build Coastguard Worker     void* userData = clazz->onCreate(args);
666*38e8c45fSAndroid Build Coastguard Worker 
667*38e8c45fSAndroid Build Coastguard Worker     sp<AIBinder> ret = new ABBinder(clazz, userData);
668*38e8c45fSAndroid Build Coastguard Worker     ABBinderTag::attach(ret->getBinder());
669*38e8c45fSAndroid Build Coastguard Worker 
670*38e8c45fSAndroid Build Coastguard Worker     AIBinder_incStrong(ret.get());
671*38e8c45fSAndroid Build Coastguard Worker     return ret.get();
672*38e8c45fSAndroid Build Coastguard Worker }
673*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_isRemote(const AIBinder * binder)674*38e8c45fSAndroid Build Coastguard Worker bool AIBinder_isRemote(const AIBinder* binder) {
675*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
676*38e8c45fSAndroid Build Coastguard Worker         return false;
677*38e8c45fSAndroid Build Coastguard Worker     }
678*38e8c45fSAndroid Build Coastguard Worker 
679*38e8c45fSAndroid Build Coastguard Worker     return binder->isRemote();
680*38e8c45fSAndroid Build Coastguard Worker }
681*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_isAlive(const AIBinder * binder)682*38e8c45fSAndroid Build Coastguard Worker bool AIBinder_isAlive(const AIBinder* binder) {
683*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
684*38e8c45fSAndroid Build Coastguard Worker         return false;
685*38e8c45fSAndroid Build Coastguard Worker     }
686*38e8c45fSAndroid Build Coastguard Worker 
687*38e8c45fSAndroid Build Coastguard Worker     return const_cast<AIBinder*>(binder)->getBinder()->isBinderAlive();
688*38e8c45fSAndroid Build Coastguard Worker }
689*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_ping(AIBinder * binder)690*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_ping(AIBinder* binder) {
691*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
692*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
693*38e8c45fSAndroid Build Coastguard Worker     }
694*38e8c45fSAndroid Build Coastguard Worker 
695*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(binder->getBinder()->pingBinder());
696*38e8c45fSAndroid Build Coastguard Worker }
697*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_dump(AIBinder * binder,int fd,const char ** args,uint32_t numArgs)698*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_dump(AIBinder* binder, int fd, const char** args, uint32_t numArgs) {
699*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
700*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
701*38e8c45fSAndroid Build Coastguard Worker     }
702*38e8c45fSAndroid Build Coastguard Worker 
703*38e8c45fSAndroid Build Coastguard Worker     ABBinder* bBinder = binder->asABBinder();
704*38e8c45fSAndroid Build Coastguard Worker     if (bBinder != nullptr) {
705*38e8c45fSAndroid Build Coastguard Worker         AIBinder_onDump onDump = binder->getClass()->onDump;
706*38e8c45fSAndroid Build Coastguard Worker         if (onDump == nullptr) {
707*38e8c45fSAndroid Build Coastguard Worker             return STATUS_OK;
708*38e8c45fSAndroid Build Coastguard Worker         }
709*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(onDump(bBinder, fd, args, numArgs));
710*38e8c45fSAndroid Build Coastguard Worker     }
711*38e8c45fSAndroid Build Coastguard Worker 
712*38e8c45fSAndroid Build Coastguard Worker     ::android::Vector<String16> utf16Args;
713*38e8c45fSAndroid Build Coastguard Worker     utf16Args.setCapacity(numArgs);
714*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < numArgs; i++) {
715*38e8c45fSAndroid Build Coastguard Worker         utf16Args.push(String16(String8(args[i])));
716*38e8c45fSAndroid Build Coastguard Worker     }
717*38e8c45fSAndroid Build Coastguard Worker 
718*38e8c45fSAndroid Build Coastguard Worker     status_t status = binder->getBinder()->dump(fd, utf16Args);
719*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
720*38e8c45fSAndroid Build Coastguard Worker }
721*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_linkToDeath(AIBinder * binder,AIBinder_DeathRecipient * recipient,void * cookie)722*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
723*38e8c45fSAndroid Build Coastguard Worker                                      void* cookie) {
724*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr || recipient == nullptr) {
725*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Must provide binder (%p) and recipient (%p)", __func__, binder, recipient);
726*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
727*38e8c45fSAndroid Build Coastguard Worker     }
728*38e8c45fSAndroid Build Coastguard Worker 
729*38e8c45fSAndroid Build Coastguard Worker     binder_status_t ret = recipient->linkToDeath(binder->getBinder(), cookie);
730*38e8c45fSAndroid Build Coastguard Worker     if (ret == STATUS_OK) {
731*38e8c45fSAndroid Build Coastguard Worker         binder->addDeathRecipient(recipient, cookie);
732*38e8c45fSAndroid Build Coastguard Worker     }
733*38e8c45fSAndroid Build Coastguard Worker     return ret;
734*38e8c45fSAndroid Build Coastguard Worker }
735*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_unlinkToDeath(AIBinder * binder,AIBinder_DeathRecipient * recipient,void * cookie)736*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
737*38e8c45fSAndroid Build Coastguard Worker                                        void* cookie) {
738*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr || recipient == nullptr) {
739*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Must provide binder (%p) and recipient (%p)", __func__, binder, recipient);
740*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
741*38e8c45fSAndroid Build Coastguard Worker     }
742*38e8c45fSAndroid Build Coastguard Worker 
743*38e8c45fSAndroid Build Coastguard Worker     // returns binder_status_t
744*38e8c45fSAndroid Build Coastguard Worker     return recipient->unlinkToDeath(binder->getBinder(), cookie);
745*38e8c45fSAndroid Build Coastguard Worker }
746*38e8c45fSAndroid Build Coastguard Worker 
747*38e8c45fSAndroid Build Coastguard Worker #ifdef BINDER_WITH_KERNEL_IPC
AIBinder_getCallingUid()748*38e8c45fSAndroid Build Coastguard Worker uid_t AIBinder_getCallingUid() {
749*38e8c45fSAndroid Build Coastguard Worker     return ::android::IPCThreadState::self()->getCallingUid();
750*38e8c45fSAndroid Build Coastguard Worker }
751*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_getCallingPid()752*38e8c45fSAndroid Build Coastguard Worker pid_t AIBinder_getCallingPid() {
753*38e8c45fSAndroid Build Coastguard Worker     return ::android::IPCThreadState::self()->getCallingPid();
754*38e8c45fSAndroid Build Coastguard Worker }
755*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_isHandlingTransaction()756*38e8c45fSAndroid Build Coastguard Worker bool AIBinder_isHandlingTransaction() {
757*38e8c45fSAndroid Build Coastguard Worker     return ::android::IPCThreadState::self()->getServingStackPointer() != nullptr;
758*38e8c45fSAndroid Build Coastguard Worker }
759*38e8c45fSAndroid Build Coastguard Worker #endif
760*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_incStrong(AIBinder * binder)761*38e8c45fSAndroid Build Coastguard Worker void AIBinder_incStrong(AIBinder* binder) {
762*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
763*38e8c45fSAndroid Build Coastguard Worker         return;
764*38e8c45fSAndroid Build Coastguard Worker     }
765*38e8c45fSAndroid Build Coastguard Worker 
766*38e8c45fSAndroid Build Coastguard Worker     binder->incStrong(nullptr);
767*38e8c45fSAndroid Build Coastguard Worker }
AIBinder_decStrong(AIBinder * binder)768*38e8c45fSAndroid Build Coastguard Worker void AIBinder_decStrong(AIBinder* binder) {
769*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
770*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: on null binder", __func__);
771*38e8c45fSAndroid Build Coastguard Worker         return;
772*38e8c45fSAndroid Build Coastguard Worker     }
773*38e8c45fSAndroid Build Coastguard Worker 
774*38e8c45fSAndroid Build Coastguard Worker     binder->decStrong(nullptr);
775*38e8c45fSAndroid Build Coastguard Worker }
AIBinder_debugGetRefCount(AIBinder * binder)776*38e8c45fSAndroid Build Coastguard Worker int32_t AIBinder_debugGetRefCount(AIBinder* binder) {
777*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
778*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: on null binder", __func__);
779*38e8c45fSAndroid Build Coastguard Worker         return -1;
780*38e8c45fSAndroid Build Coastguard Worker     }
781*38e8c45fSAndroid Build Coastguard Worker 
782*38e8c45fSAndroid Build Coastguard Worker     return binder->getStrongCount();
783*38e8c45fSAndroid Build Coastguard Worker }
784*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_associateClass(AIBinder * binder,const AIBinder_Class * clazz)785*38e8c45fSAndroid Build Coastguard Worker bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz) {
786*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
787*38e8c45fSAndroid Build Coastguard Worker         return false;
788*38e8c45fSAndroid Build Coastguard Worker     }
789*38e8c45fSAndroid Build Coastguard Worker 
790*38e8c45fSAndroid Build Coastguard Worker     return binder->associateClass(clazz);
791*38e8c45fSAndroid Build Coastguard Worker }
792*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_getClass(AIBinder * binder)793*38e8c45fSAndroid Build Coastguard Worker const AIBinder_Class* AIBinder_getClass(AIBinder* binder) {
794*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
795*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
796*38e8c45fSAndroid Build Coastguard Worker     }
797*38e8c45fSAndroid Build Coastguard Worker 
798*38e8c45fSAndroid Build Coastguard Worker     return binder->getClass();
799*38e8c45fSAndroid Build Coastguard Worker }
800*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_getUserData(AIBinder * binder)801*38e8c45fSAndroid Build Coastguard Worker void* AIBinder_getUserData(AIBinder* binder) {
802*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
803*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
804*38e8c45fSAndroid Build Coastguard Worker     }
805*38e8c45fSAndroid Build Coastguard Worker 
806*38e8c45fSAndroid Build Coastguard Worker     ABBinder* bBinder = binder->asABBinder();
807*38e8c45fSAndroid Build Coastguard Worker     if (bBinder == nullptr) {
808*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
809*38e8c45fSAndroid Build Coastguard Worker     }
810*38e8c45fSAndroid Build Coastguard Worker 
811*38e8c45fSAndroid Build Coastguard Worker     return bBinder->getUserData();
812*38e8c45fSAndroid Build Coastguard Worker }
813*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_prepareTransaction(AIBinder * binder,AParcel ** in)814*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) {
815*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr || in == nullptr) {
816*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: requires non-null parameters binder (%p) and in (%p).", __func__, binder, in);
817*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
818*38e8c45fSAndroid Build Coastguard Worker     }
819*38e8c45fSAndroid Build Coastguard Worker     const AIBinder_Class* clazz = binder->getClass();
820*38e8c45fSAndroid Build Coastguard Worker     if (clazz == nullptr) {
821*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Class must be defined for a remote binder transaction. See "
822*38e8c45fSAndroid Build Coastguard Worker               "AIBinder_associateClass.",
823*38e8c45fSAndroid Build Coastguard Worker               __func__);
824*38e8c45fSAndroid Build Coastguard Worker         return STATUS_INVALID_OPERATION;
825*38e8c45fSAndroid Build Coastguard Worker     }
826*38e8c45fSAndroid Build Coastguard Worker 
827*38e8c45fSAndroid Build Coastguard Worker     *in = new AParcel(binder);
828*38e8c45fSAndroid Build Coastguard Worker     (*in)->get()->markForBinder(binder->getBinder());
829*38e8c45fSAndroid Build Coastguard Worker 
830*38e8c45fSAndroid Build Coastguard Worker     status_t status = android::OK;
831*38e8c45fSAndroid Build Coastguard Worker 
832*38e8c45fSAndroid Build Coastguard Worker     // note - this is the only read of a value in clazz, and it comes with a warning
833*38e8c45fSAndroid Build Coastguard Worker     // on the API itself. Do not copy this design. Instead, attach data in a new
834*38e8c45fSAndroid Build Coastguard Worker     // version of the prepareTransaction function.
835*38e8c45fSAndroid Build Coastguard Worker     if (clazz->writeHeader) {
836*38e8c45fSAndroid Build Coastguard Worker         status = (*in)->get()->writeInterfaceToken(clazz->getInterfaceDescriptor());
837*38e8c45fSAndroid Build Coastguard Worker     }
838*38e8c45fSAndroid Build Coastguard Worker     binder_status_t ret = PruneStatusT(status);
839*38e8c45fSAndroid Build Coastguard Worker 
840*38e8c45fSAndroid Build Coastguard Worker     if (ret != STATUS_OK) {
841*38e8c45fSAndroid Build Coastguard Worker         delete *in;
842*38e8c45fSAndroid Build Coastguard Worker         *in = nullptr;
843*38e8c45fSAndroid Build Coastguard Worker     }
844*38e8c45fSAndroid Build Coastguard Worker 
845*38e8c45fSAndroid Build Coastguard Worker     return ret;
846*38e8c45fSAndroid Build Coastguard Worker }
847*38e8c45fSAndroid Build Coastguard Worker 
DestroyParcel(AParcel ** parcel)848*38e8c45fSAndroid Build Coastguard Worker static void DestroyParcel(AParcel** parcel) {
849*38e8c45fSAndroid Build Coastguard Worker     delete *parcel;
850*38e8c45fSAndroid Build Coastguard Worker     *parcel = nullptr;
851*38e8c45fSAndroid Build Coastguard Worker }
852*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_transact(AIBinder * binder,transaction_code_t code,AParcel ** in,AParcel ** out,binder_flags_t flags)853*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in,
854*38e8c45fSAndroid Build Coastguard Worker                                   AParcel** out, binder_flags_t flags) {
855*38e8c45fSAndroid Build Coastguard Worker     const AIBinder_Class* clazz = binder ? binder->getClass() : nullptr;
856*38e8c45fSAndroid Build Coastguard Worker 
857*38e8c45fSAndroid Build Coastguard Worker     std::string sectionName;
858*38e8c45fSAndroid Build Coastguard Worker     bool tracingEnabled = get_trace_enabled_tags() & ATRACE_TAG_AIDL;
859*38e8c45fSAndroid Build Coastguard Worker     if (tracingEnabled) {
860*38e8c45fSAndroid Build Coastguard Worker         sectionName = getTraceSectionName(clazz, code, false /*isServer*/);
861*38e8c45fSAndroid Build Coastguard Worker         trace_begin(ATRACE_TAG_AIDL, sectionName.c_str());
862*38e8c45fSAndroid Build Coastguard Worker     }
863*38e8c45fSAndroid Build Coastguard Worker 
864*38e8c45fSAndroid Build Coastguard Worker     scope_guard guard = make_scope_guard([&]() {
865*38e8c45fSAndroid Build Coastguard Worker         if (tracingEnabled) trace_end(ATRACE_TAG_AIDL);
866*38e8c45fSAndroid Build Coastguard Worker     });
867*38e8c45fSAndroid Build Coastguard Worker 
868*38e8c45fSAndroid Build Coastguard Worker     if (in == nullptr) {
869*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: requires non-null in parameter", __func__);
870*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
871*38e8c45fSAndroid Build Coastguard Worker     }
872*38e8c45fSAndroid Build Coastguard Worker 
873*38e8c45fSAndroid Build Coastguard Worker     using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>;
874*38e8c45fSAndroid Build Coastguard Worker     // This object is the input to the transaction. This function takes ownership of it and deletes
875*38e8c45fSAndroid Build Coastguard Worker     // it.
876*38e8c45fSAndroid Build Coastguard Worker     AutoParcelDestroyer forIn(in, DestroyParcel);
877*38e8c45fSAndroid Build Coastguard Worker 
878*38e8c45fSAndroid Build Coastguard Worker     if (!isUserCommand(code)) {
879*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Only user-defined transactions can be made from the NDK, but requested: %d",
880*38e8c45fSAndroid Build Coastguard Worker               __func__, code);
881*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNKNOWN_TRANSACTION;
882*38e8c45fSAndroid Build Coastguard Worker     }
883*38e8c45fSAndroid Build Coastguard Worker 
884*38e8c45fSAndroid Build Coastguard Worker     constexpr binder_flags_t kAllFlags = FLAG_PRIVATE_VENDOR | FLAG_ONEWAY | FLAG_CLEAR_BUF;
885*38e8c45fSAndroid Build Coastguard Worker     if ((flags & ~kAllFlags) != 0) {
886*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: Unrecognized flags sent: %d", __func__, flags);
887*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
888*38e8c45fSAndroid Build Coastguard Worker     }
889*38e8c45fSAndroid Build Coastguard Worker 
890*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr || *in == nullptr || out == nullptr) {
891*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: requires non-null parameters binder (%p), in (%p), and out (%p).", __func__,
892*38e8c45fSAndroid Build Coastguard Worker               binder, in, out);
893*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
894*38e8c45fSAndroid Build Coastguard Worker     }
895*38e8c45fSAndroid Build Coastguard Worker 
896*38e8c45fSAndroid Build Coastguard Worker     if ((*in)->getBinder() != binder) {
897*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: parcel is associated with binder object %p but called with %p", __func__, binder,
898*38e8c45fSAndroid Build Coastguard Worker               (*in)->getBinder());
899*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
900*38e8c45fSAndroid Build Coastguard Worker     }
901*38e8c45fSAndroid Build Coastguard Worker 
902*38e8c45fSAndroid Build Coastguard Worker     *out = new AParcel(binder);
903*38e8c45fSAndroid Build Coastguard Worker 
904*38e8c45fSAndroid Build Coastguard Worker     status_t status = binder->getBinder()->transact(code, *(*in)->get(), (*out)->get(), flags);
905*38e8c45fSAndroid Build Coastguard Worker     binder_status_t ret = PruneStatusT(status);
906*38e8c45fSAndroid Build Coastguard Worker 
907*38e8c45fSAndroid Build Coastguard Worker     if (ret != STATUS_OK) {
908*38e8c45fSAndroid Build Coastguard Worker         delete *out;
909*38e8c45fSAndroid Build Coastguard Worker         *out = nullptr;
910*38e8c45fSAndroid Build Coastguard Worker     }
911*38e8c45fSAndroid Build Coastguard Worker 
912*38e8c45fSAndroid Build Coastguard Worker     return ret;
913*38e8c45fSAndroid Build Coastguard Worker }
914*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_DeathRecipient_new(AIBinder_DeathRecipient_onBinderDied onBinderDied)915*38e8c45fSAndroid Build Coastguard Worker AIBinder_DeathRecipient* AIBinder_DeathRecipient_new(
916*38e8c45fSAndroid Build Coastguard Worker         AIBinder_DeathRecipient_onBinderDied onBinderDied) {
917*38e8c45fSAndroid Build Coastguard Worker     if (onBinderDied == nullptr) {
918*38e8c45fSAndroid Build Coastguard Worker         ALOGE("%s: requires non-null onBinderDied parameter.", __func__);
919*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
920*38e8c45fSAndroid Build Coastguard Worker     }
921*38e8c45fSAndroid Build Coastguard Worker     auto ret = new AIBinder_DeathRecipient(onBinderDied);
922*38e8c45fSAndroid Build Coastguard Worker     ret->incStrong(nullptr);
923*38e8c45fSAndroid Build Coastguard Worker     return ret;
924*38e8c45fSAndroid Build Coastguard Worker }
925*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_DeathRecipient_setOnUnlinked(AIBinder_DeathRecipient * recipient,AIBinder_DeathRecipient_onBinderUnlinked onUnlinked)926*38e8c45fSAndroid Build Coastguard Worker void AIBinder_DeathRecipient_setOnUnlinked(AIBinder_DeathRecipient* recipient,
927*38e8c45fSAndroid Build Coastguard Worker                                            AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) {
928*38e8c45fSAndroid Build Coastguard Worker     if (recipient == nullptr) {
929*38e8c45fSAndroid Build Coastguard Worker         return;
930*38e8c45fSAndroid Build Coastguard Worker     }
931*38e8c45fSAndroid Build Coastguard Worker 
932*38e8c45fSAndroid Build Coastguard Worker     recipient->setOnUnlinked(onUnlinked);
933*38e8c45fSAndroid Build Coastguard Worker }
934*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient * recipient)935*38e8c45fSAndroid Build Coastguard Worker void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) {
936*38e8c45fSAndroid Build Coastguard Worker     if (recipient == nullptr) {
937*38e8c45fSAndroid Build Coastguard Worker         return;
938*38e8c45fSAndroid Build Coastguard Worker     }
939*38e8c45fSAndroid Build Coastguard Worker 
940*38e8c45fSAndroid Build Coastguard Worker     recipient->decStrong(nullptr);
941*38e8c45fSAndroid Build Coastguard Worker }
942*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_getExtension(AIBinder * binder,AIBinder ** outExt)943*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_getExtension(AIBinder* binder, AIBinder** outExt) {
944*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr || outExt == nullptr) {
945*38e8c45fSAndroid Build Coastguard Worker         if (outExt != nullptr) {
946*38e8c45fSAndroid Build Coastguard Worker             *outExt = nullptr;
947*38e8c45fSAndroid Build Coastguard Worker         }
948*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
949*38e8c45fSAndroid Build Coastguard Worker     }
950*38e8c45fSAndroid Build Coastguard Worker 
951*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> ext;
952*38e8c45fSAndroid Build Coastguard Worker     status_t res = binder->getBinder()->getExtension(&ext);
953*38e8c45fSAndroid Build Coastguard Worker 
954*38e8c45fSAndroid Build Coastguard Worker     if (res != android::OK) {
955*38e8c45fSAndroid Build Coastguard Worker         *outExt = nullptr;
956*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(res);
957*38e8c45fSAndroid Build Coastguard Worker     }
958*38e8c45fSAndroid Build Coastguard Worker 
959*38e8c45fSAndroid Build Coastguard Worker     sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(ext);
960*38e8c45fSAndroid Build Coastguard Worker     if (ret != nullptr) ret->incStrong(binder);
961*38e8c45fSAndroid Build Coastguard Worker 
962*38e8c45fSAndroid Build Coastguard Worker     *outExt = ret.get();
963*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
964*38e8c45fSAndroid Build Coastguard Worker }
965*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_setExtension(AIBinder * binder,AIBinder * ext)966*38e8c45fSAndroid Build Coastguard Worker binder_status_t AIBinder_setExtension(AIBinder* binder, AIBinder* ext) {
967*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr || ext == nullptr) {
968*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
969*38e8c45fSAndroid Build Coastguard Worker     }
970*38e8c45fSAndroid Build Coastguard Worker 
971*38e8c45fSAndroid Build Coastguard Worker     ABBinder* rawBinder = binder->asABBinder();
972*38e8c45fSAndroid Build Coastguard Worker     if (rawBinder == nullptr) {
973*38e8c45fSAndroid Build Coastguard Worker         return STATUS_INVALID_OPERATION;
974*38e8c45fSAndroid Build Coastguard Worker     }
975*38e8c45fSAndroid Build Coastguard Worker 
976*38e8c45fSAndroid Build Coastguard Worker     rawBinder->setExtension(ext->getBinder());
977*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
978*38e8c45fSAndroid Build Coastguard Worker }
979*38e8c45fSAndroid Build Coastguard Worker 
980*38e8c45fSAndroid Build Coastguard Worker // platform methods follow
981*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_setRequestingSid(AIBinder * binder,bool requestingSid)982*38e8c45fSAndroid Build Coastguard Worker void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) {
983*38e8c45fSAndroid Build Coastguard Worker     ABBinder* localBinder = binder->asABBinder();
984*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(localBinder == nullptr,
985*38e8c45fSAndroid Build Coastguard Worker                         "AIBinder_setRequestingSid must be called on a local binder");
986*38e8c45fSAndroid Build Coastguard Worker 
987*38e8c45fSAndroid Build Coastguard Worker     localBinder->setRequestingSid(requestingSid);
988*38e8c45fSAndroid Build Coastguard Worker }
989*38e8c45fSAndroid Build Coastguard Worker 
990*38e8c45fSAndroid Build Coastguard Worker #ifdef BINDER_WITH_KERNEL_IPC
AIBinder_getCallingSid()991*38e8c45fSAndroid Build Coastguard Worker const char* AIBinder_getCallingSid() {
992*38e8c45fSAndroid Build Coastguard Worker     return ::android::IPCThreadState::self()->getCallingSid();
993*38e8c45fSAndroid Build Coastguard Worker }
994*38e8c45fSAndroid Build Coastguard Worker #endif
995*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_setMinSchedulerPolicy(AIBinder * binder,int policy,int priority)996*38e8c45fSAndroid Build Coastguard Worker void AIBinder_setMinSchedulerPolicy(AIBinder* binder, int policy, int priority) {
997*38e8c45fSAndroid Build Coastguard Worker     binder->asABBinder()->setMinSchedulerPolicy(policy, priority);
998*38e8c45fSAndroid Build Coastguard Worker }
999*38e8c45fSAndroid Build Coastguard Worker 
AIBinder_setInheritRt(AIBinder * binder,bool inheritRt)1000*38e8c45fSAndroid Build Coastguard Worker void AIBinder_setInheritRt(AIBinder* binder, bool inheritRt) {
1001*38e8c45fSAndroid Build Coastguard Worker     ABBinder* localBinder = binder->asABBinder();
1002*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(localBinder == nullptr,
1003*38e8c45fSAndroid Build Coastguard Worker                         "AIBinder_setInheritRt must be called on a local binder");
1004*38e8c45fSAndroid Build Coastguard Worker 
1005*38e8c45fSAndroid Build Coastguard Worker     localBinder->setInheritRt(inheritRt);
1006*38e8c45fSAndroid Build Coastguard Worker }