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 }