| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2018 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 |  | 
 | 17 | #include <android/binder_ibinder.h> | 
 | 18 | #include "AIBinder_internal.h" | 
 | 19 |  | 
 | 20 | #include <android/binder_status.h> | 
 | 21 | #include "AParcel_internal.h" | 
 | 22 |  | 
 | 23 | #include <android-base/logging.h> | 
 | 24 |  | 
| Steven Moreland | 901c745 | 2018-09-04 16:17:28 -0700 | [diff] [blame] | 25 | using DeathRecipient = ::android::IBinder::DeathRecipient; | 
 | 26 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 27 | using ::android::IBinder; | 
 | 28 | using ::android::Parcel; | 
 | 29 | using ::android::sp; | 
 | 30 | using ::android::String16; | 
 | 31 | using ::android::wp; | 
 | 32 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 33 | namespace ABBinderTag { | 
 | 34 |  | 
 | 35 | static const void* kId = "ABBinder"; | 
 | 36 | static void* kValue = static_cast<void*>(new bool{true}); | 
| Steven Moreland | 9496895 | 2018-09-05 14:42:59 -0700 | [diff] [blame] | 37 | void clean(const void* /*id*/, void* /*obj*/, void* /*cookie*/){/* do nothing */}; | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 38 |  | 
 | 39 | static void attach(const sp<IBinder>& binder) { | 
| Steven Moreland | 9496895 | 2018-09-05 14:42:59 -0700 | [diff] [blame] | 40 |     binder->attachObject(kId, kValue, nullptr /*cookie*/, clean); | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 41 | } | 
 | 42 | static bool has(const sp<IBinder>& binder) { | 
 | 43 |     return binder != nullptr && binder->findObject(kId) == kValue; | 
 | 44 | } | 
 | 45 |  | 
 | 46 | } // namespace ABBinderTag | 
 | 47 |  | 
| Steven Moreland | 9496895 | 2018-09-05 14:42:59 -0700 | [diff] [blame] | 48 | namespace ABpBinderTag { | 
 | 49 |  | 
 | 50 | static std::mutex gLock; | 
 | 51 | static const void* kId = "ABpBinder"; | 
 | 52 | struct Value { | 
 | 53 |     wp<ABpBinder> binder; | 
 | 54 | }; | 
 | 55 | void clean(const void* id, void* obj, void* cookie) { | 
 | 56 |     CHECK(id == kId) << id << " " << obj << " " << cookie; | 
 | 57 |  | 
 | 58 |     delete static_cast<Value*>(obj); | 
 | 59 | }; | 
 | 60 |  | 
 | 61 | } // namespace ABpBinderTag | 
 | 62 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 63 | AIBinder::AIBinder(const AIBinder_Class* clazz) : mClazz(clazz) {} | 
 | 64 | AIBinder::~AIBinder() {} | 
 | 65 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 66 | bool AIBinder::associateClass(const AIBinder_Class* clazz) { | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 67 |     using ::android::String8; | 
 | 68 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 69 |     if (clazz == nullptr) return false; | 
 | 70 |     if (mClazz == clazz) return true; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 71 |  | 
 | 72 |     String8 newDescriptor(clazz->getInterfaceDescriptor()); | 
 | 73 |  | 
 | 74 |     if (mClazz != nullptr) { | 
 | 75 |         String8 currentDescriptor(mClazz->getInterfaceDescriptor()); | 
 | 76 |         if (newDescriptor == currentDescriptor) { | 
 | 77 |             LOG(ERROR) << __func__ << ": Class descriptors '" << currentDescriptor | 
 | 78 |                        << "' match during associateClass, but they are different class objects. " | 
 | 79 |                           "Class descriptor collision?"; | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 80 |         } else { | 
 | 81 |             LOG(ERROR) << __func__ | 
 | 82 |                        << ": Class cannot be associated on object which already has a class. " | 
 | 83 |                           "Trying to associate to '" | 
 | 84 |                        << newDescriptor.c_str() << "' but already set to '" | 
 | 85 |                        << currentDescriptor.c_str() << "'."; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 86 |         } | 
 | 87 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 88 |         // always a failure because we know mClazz != clazz | 
 | 89 |         return false; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 90 |     } | 
 | 91 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 92 |     CHECK(asABpBinder() != nullptr); // ABBinder always has a descriptor | 
 | 93 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 94 |     String8 descriptor(getBinder()->getInterfaceDescriptor()); | 
 | 95 |     if (descriptor != newDescriptor) { | 
 | 96 |         LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str() | 
 | 97 |                    << "' but descriptor is actually '" << descriptor.c_str() << "'."; | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 98 |         return false; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 99 |     } | 
 | 100 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 101 |     // if this is a local object, it's not one known to libbinder_ndk | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 102 |     mClazz = clazz; | 
 | 103 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 104 |     return true; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 105 | } | 
 | 106 |  | 
 | 107 | ABBinder::ABBinder(const AIBinder_Class* clazz, void* userData) | 
 | 108 |       : AIBinder(clazz), BBinder(), mUserData(userData) { | 
 | 109 |     CHECK(clazz != nullptr); | 
 | 110 | } | 
 | 111 | ABBinder::~ABBinder() { | 
 | 112 |     getClass()->onDestroy(mUserData); | 
 | 113 | } | 
 | 114 |  | 
 | 115 | const String16& ABBinder::getInterfaceDescriptor() const { | 
 | 116 |     return getClass()->getInterfaceDescriptor(); | 
 | 117 | } | 
 | 118 |  | 
 | 119 | binder_status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply, | 
 | 120 |                                      binder_flags_t flags) { | 
 | 121 |     if (isUserCommand(code)) { | 
 | 122 |         if (!data.checkInterface(this)) { | 
 | 123 |             return EX_ILLEGAL_STATE; | 
 | 124 |         } | 
 | 125 |  | 
 | 126 |         const AParcel in = AParcel::readOnly(this, &data); | 
 | 127 |         AParcel out = AParcel(this, reply, false /*owns*/); | 
 | 128 |  | 
 | 129 |         return getClass()->onTransact(this, code, &in, &out); | 
 | 130 |     } else { | 
 | 131 |         return BBinder::onTransact(code, data, reply, flags); | 
 | 132 |     } | 
 | 133 | } | 
 | 134 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 135 | ABpBinder::ABpBinder(const ::android::sp<::android::IBinder>& binder) | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 136 |       : AIBinder(nullptr /*clazz*/), BpRefBase(binder) { | 
 | 137 |     CHECK(binder != nullptr); | 
 | 138 | } | 
 | 139 | ABpBinder::~ABpBinder() {} | 
 | 140 |  | 
| Steven Moreland | 9496895 | 2018-09-05 14:42:59 -0700 | [diff] [blame] | 141 | void ABpBinder::onLastStrongRef(const void* id) { | 
 | 142 |     { | 
 | 143 |         std::lock_guard<std::mutex> lock(ABpBinderTag::gLock); | 
 | 144 |         // Since ABpBinder is OBJECT_LIFETIME_WEAK, we must remove this weak reference in order for | 
 | 145 |         // the ABpBinder to be deleted. Since a strong reference to this ABpBinder object should no | 
 | 146 |         // longer be able to exist at the time of this method call, there is no longer a need to | 
 | 147 |         // recover it. | 
 | 148 |  | 
 | 149 |         ABpBinderTag::Value* value = | 
 | 150 |                 static_cast<ABpBinderTag::Value*>(remote()->findObject(ABpBinderTag::kId)); | 
 | 151 |         if (value != nullptr) { | 
 | 152 |             value->binder = nullptr; | 
 | 153 |         } | 
 | 154 |     } | 
 | 155 |  | 
 | 156 |     BpRefBase::onLastStrongRef(id); | 
 | 157 | } | 
 | 158 |  | 
 | 159 | sp<AIBinder> ABpBinder::lookupOrCreateFromBinder(const ::android::sp<::android::IBinder>& binder) { | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 160 |     if (binder == nullptr) { | 
 | 161 |         return nullptr; | 
 | 162 |     } | 
 | 163 |     if (ABBinderTag::has(binder)) { | 
 | 164 |         return static_cast<ABBinder*>(binder.get()); | 
 | 165 |     } | 
| Steven Moreland | 9496895 | 2018-09-05 14:42:59 -0700 | [diff] [blame] | 166 |  | 
 | 167 |     // The following code ensures that for a given binder object (remote or local), if it is not an | 
 | 168 |     // ABBinder then at most one ABpBinder object exists in a given process representing it. | 
 | 169 |     std::lock_guard<std::mutex> lock(ABpBinderTag::gLock); | 
 | 170 |  | 
 | 171 |     ABpBinderTag::Value* value = | 
 | 172 |             static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId)); | 
 | 173 |     if (value == nullptr) { | 
 | 174 |         value = new ABpBinderTag::Value; | 
 | 175 |         binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value), nullptr /*cookie*/, | 
 | 176 |                              ABpBinderTag::clean); | 
 | 177 |     } | 
 | 178 |  | 
 | 179 |     sp<ABpBinder> ret = value->binder.promote(); | 
 | 180 |     if (ret == nullptr) { | 
 | 181 |         ret = new ABpBinder(binder); | 
 | 182 |         value->binder = ret; | 
 | 183 |     } | 
 | 184 |  | 
 | 185 |     return ret; | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 186 | } | 
 | 187 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 188 | struct AIBinder_Weak { | 
 | 189 |     wp<AIBinder> binder; | 
 | 190 | }; | 
 | 191 | AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder) { | 
| Steven Moreland | 5ccb70f | 2018-09-04 16:30:21 -0700 | [diff] [blame] | 192 |     if (binder == nullptr) { | 
 | 193 |         return nullptr; | 
 | 194 |     } | 
 | 195 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 196 |     return new AIBinder_Weak{wp<AIBinder>(binder)}; | 
 | 197 | } | 
| Steven Moreland | 5ccb70f | 2018-09-04 16:30:21 -0700 | [diff] [blame] | 198 | void AIBinder_Weak_delete(AIBinder_Weak** weakBinder) { | 
 | 199 |     if (weakBinder == nullptr) { | 
 | 200 |         return; | 
 | 201 |     } | 
 | 202 |  | 
 | 203 |     delete *weakBinder; | 
 | 204 |     *weakBinder = nullptr; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 205 | } | 
 | 206 | AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder) { | 
| Steven Moreland | 5ccb70f | 2018-09-04 16:30:21 -0700 | [diff] [blame] | 207 |     if (weakBinder == nullptr) { | 
 | 208 |         return nullptr; | 
 | 209 |     } | 
 | 210 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 211 |     sp<AIBinder> binder = weakBinder->binder.promote(); | 
 | 212 |     AIBinder_incStrong(binder.get()); | 
 | 213 |     return binder.get(); | 
 | 214 | } | 
 | 215 |  | 
 | 216 | AIBinder_Class::AIBinder_Class(const char* interfaceDescriptor, AIBinder_Class_onCreate onCreate, | 
 | 217 |                                AIBinder_Class_onDestroy onDestroy, | 
 | 218 |                                AIBinder_Class_onTransact onTransact) | 
 | 219 |       : onCreate(onCreate), | 
 | 220 |         onDestroy(onDestroy), | 
 | 221 |         onTransact(onTransact), | 
 | 222 |         mInterfaceDescriptor(interfaceDescriptor) {} | 
 | 223 |  | 
 | 224 | AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor, | 
 | 225 |                                       AIBinder_Class_onCreate onCreate, | 
 | 226 |                                       AIBinder_Class_onDestroy onDestroy, | 
 | 227 |                                       AIBinder_Class_onTransact onTransact) { | 
 | 228 |     if (interfaceDescriptor == nullptr || onCreate == nullptr || onDestroy == nullptr || | 
 | 229 |         onTransact == nullptr) { | 
 | 230 |         return nullptr; | 
 | 231 |     } | 
 | 232 |  | 
 | 233 |     return new AIBinder_Class(interfaceDescriptor, onCreate, onDestroy, onTransact); | 
 | 234 | } | 
 | 235 |  | 
| Steven Moreland | 901c745 | 2018-09-04 16:17:28 -0700 | [diff] [blame] | 236 | void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) { | 
 | 237 |     CHECK(who == mWho); | 
 | 238 |  | 
 | 239 |     mOnDied(mCookie); | 
 | 240 |     mWho = nullptr; | 
 | 241 | } | 
 | 242 |  | 
 | 243 | AIBinder_DeathRecipient::AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied) | 
 | 244 |       : mOnDied(onDied) { | 
 | 245 |     CHECK(onDied != nullptr); | 
 | 246 | } | 
 | 247 |  | 
 | 248 | binder_status_t AIBinder_DeathRecipient::linkToDeath(AIBinder* binder, void* cookie) { | 
 | 249 |     CHECK(binder != nullptr); | 
 | 250 |  | 
 | 251 |     std::lock_guard<std::mutex> l(mDeathRecipientsMutex); | 
 | 252 |  | 
 | 253 |     sp<TransferDeathRecipient> recipient = | 
 | 254 |             new TransferDeathRecipient(binder->getBinder(), cookie, mOnDied); | 
 | 255 |  | 
 | 256 |     binder_status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/); | 
 | 257 |     if (status != EX_NONE) { | 
 | 258 |         return status; | 
 | 259 |     } | 
 | 260 |  | 
 | 261 |     mDeathRecipients.push_back(recipient); | 
 | 262 |     return EX_NONE; | 
 | 263 | } | 
 | 264 |  | 
 | 265 | binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* cookie) { | 
 | 266 |     CHECK(binder != nullptr); | 
 | 267 |  | 
 | 268 |     std::lock_guard<std::mutex> l(mDeathRecipientsMutex); | 
 | 269 |  | 
 | 270 |     for (auto it = mDeathRecipients.rbegin(); it != mDeathRecipients.rend(); ++it) { | 
 | 271 |         sp<TransferDeathRecipient> recipient = *it; | 
 | 272 |  | 
 | 273 |         if (recipient->getCookie() == cookie && | 
 | 274 |  | 
 | 275 |             recipient->getWho() == binder->getBinder()) { | 
 | 276 |             mDeathRecipients.erase(it.base() - 1); | 
 | 277 |  | 
 | 278 |             binder_status_t status = | 
 | 279 |                     binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/); | 
 | 280 |             if (status != EX_NONE) { | 
 | 281 |                 LOG(ERROR) << __func__ | 
 | 282 |                            << ": removed reference to death recipient but unlink failed."; | 
 | 283 |             } | 
 | 284 |             return status; | 
 | 285 |         } | 
 | 286 |     } | 
 | 287 |  | 
 | 288 |     return -ENOENT; | 
 | 289 | } | 
 | 290 |  | 
 | 291 | // start of C-API methods | 
 | 292 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 293 | AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args) { | 
 | 294 |     if (clazz == nullptr) { | 
 | 295 |         LOG(ERROR) << __func__ << ": Must provide class to construct local binder."; | 
 | 296 |         return nullptr; | 
 | 297 |     } | 
 | 298 |  | 
 | 299 |     void* userData = clazz->onCreate(args); | 
 | 300 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 301 |     sp<AIBinder> ret = new ABBinder(clazz, userData); | 
 | 302 |     ABBinderTag::attach(ret->getBinder()); | 
 | 303 |  | 
 | 304 |     AIBinder_incStrong(ret.get()); | 
 | 305 |     return ret.get(); | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 306 | } | 
 | 307 |  | 
| Steven Moreland | 5ea54da | 2018-09-04 13:29:55 -0700 | [diff] [blame] | 308 | bool AIBinder_isRemote(const AIBinder* binder) { | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 309 |     if (binder == nullptr) { | 
 | 310 |         return true; | 
 | 311 |     } | 
 | 312 |  | 
 | 313 |     return binder->isRemote(); | 
 | 314 | } | 
 | 315 |  | 
| Steven Moreland | 65867d7 | 2018-09-04 14:22:26 -0700 | [diff] [blame] | 316 | bool AIBinder_isAlive(const AIBinder* binder) { | 
 | 317 |     if (binder == nullptr) { | 
 | 318 |         return false; | 
 | 319 |     } | 
 | 320 |  | 
 | 321 |     return const_cast<AIBinder*>(binder)->getBinder()->isBinderAlive(); | 
 | 322 | } | 
 | 323 |  | 
 | 324 | binder_status_t AIBinder_ping(AIBinder* binder) { | 
 | 325 |     if (binder == nullptr) { | 
 | 326 |         return EX_NULL_POINTER; | 
 | 327 |     } | 
 | 328 |  | 
 | 329 |     return binder->getBinder()->pingBinder(); | 
 | 330 | } | 
 | 331 |  | 
| Steven Moreland | 901c745 | 2018-09-04 16:17:28 -0700 | [diff] [blame] | 332 | binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, | 
 | 333 |                                      void* cookie) { | 
 | 334 |     if (binder == nullptr || recipient == nullptr) { | 
 | 335 |         LOG(ERROR) << __func__ << ": Must provide binder and recipient."; | 
 | 336 |         return EX_NULL_POINTER; | 
 | 337 |     } | 
 | 338 |  | 
 | 339 |     return recipient->linkToDeath(binder, cookie); | 
 | 340 | } | 
 | 341 |  | 
 | 342 | binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, | 
 | 343 |                                        void* cookie) { | 
 | 344 |     if (binder == nullptr || recipient == nullptr) { | 
 | 345 |         LOG(ERROR) << __func__ << ": Must provide binder and recipient."; | 
 | 346 |         return EX_NULL_POINTER; | 
 | 347 |     } | 
 | 348 |  | 
 | 349 |     return recipient->unlinkToDeath(binder, cookie); | 
 | 350 | } | 
 | 351 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 352 | void AIBinder_incStrong(AIBinder* binder) { | 
 | 353 |     if (binder == nullptr) { | 
 | 354 |         LOG(ERROR) << __func__ << ": on null binder"; | 
 | 355 |         return; | 
 | 356 |     } | 
 | 357 |  | 
 | 358 |     binder->incStrong(nullptr); | 
 | 359 | } | 
 | 360 | void AIBinder_decStrong(AIBinder* binder) { | 
 | 361 |     if (binder == nullptr) { | 
 | 362 |         LOG(ERROR) << __func__ << ": on null binder"; | 
 | 363 |         return; | 
 | 364 |     } | 
 | 365 |  | 
 | 366 |     binder->decStrong(nullptr); | 
 | 367 | } | 
 | 368 | int32_t AIBinder_debugGetRefCount(AIBinder* binder) { | 
 | 369 |     if (binder == nullptr) { | 
 | 370 |         LOG(ERROR) << __func__ << ": on null binder"; | 
 | 371 |         return -1; | 
 | 372 |     } | 
 | 373 |  | 
 | 374 |     return binder->getStrongCount(); | 
 | 375 | } | 
 | 376 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 377 | bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz) { | 
 | 378 |     if (binder == nullptr) { | 
 | 379 |         return false; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 380 |     } | 
 | 381 |  | 
| Steven Moreland | 71cddc3 | 2018-08-30 23:39:22 -0700 | [diff] [blame] | 382 |     return binder->associateClass(clazz); | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 383 | } | 
 | 384 |  | 
 | 385 | const AIBinder_Class* AIBinder_getClass(AIBinder* binder) { | 
 | 386 |     if (binder == nullptr) { | 
 | 387 |         return nullptr; | 
 | 388 |     } | 
 | 389 |  | 
 | 390 |     return binder->getClass(); | 
 | 391 | } | 
 | 392 |  | 
 | 393 | void* AIBinder_getUserData(AIBinder* binder) { | 
 | 394 |     if (binder == nullptr) { | 
 | 395 |         return nullptr; | 
 | 396 |     } | 
 | 397 |  | 
 | 398 |     ABBinder* bBinder = binder->asABBinder(); | 
 | 399 |     if (bBinder == nullptr) { | 
 | 400 |         return nullptr; | 
 | 401 |     } | 
 | 402 |  | 
 | 403 |     return bBinder->getUserData(); | 
 | 404 | } | 
 | 405 |  | 
 | 406 | binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) { | 
 | 407 |     if (binder == nullptr || in == nullptr) { | 
 | 408 |         LOG(ERROR) << __func__ << ": requires non-null parameters."; | 
 | 409 |         return EX_NULL_POINTER; | 
 | 410 |     } | 
 | 411 |     const AIBinder_Class* clazz = binder->getClass(); | 
 | 412 |     if (clazz == nullptr) { | 
 | 413 |         LOG(ERROR) << __func__ | 
 | 414 |                    << ": Class must be defined for a remote binder transaction. See " | 
 | 415 |                       "AIBinder_associateClass."; | 
 | 416 |         return EX_ILLEGAL_STATE; | 
 | 417 |     } | 
 | 418 |  | 
| Steven Moreland | 3527c2e | 2018-09-05 17:07:14 -0700 | [diff] [blame] | 419 |     if (!binder->isRemote()) { | 
| Steven Moreland | 74521c8 | 2018-09-07 14:50:40 -0700 | [diff] [blame] | 420 |         LOG(WARNING) << "A binder object at " << binder | 
 | 421 |                      << " is being transacted on, however, this object is in the same process as " | 
 | 422 |                         "its proxy. Transacting with this binder is expensive compared to just " | 
 | 423 |                         "calling the corresponding functionality in the same process."; | 
| Steven Moreland | 3527c2e | 2018-09-05 17:07:14 -0700 | [diff] [blame] | 424 |     } | 
 | 425 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 426 |     *in = new AParcel(binder); | 
 | 427 |     binder_status_t status = (**in)->writeInterfaceToken(clazz->getInterfaceDescriptor()); | 
 | 428 |     if (status != EX_NONE) { | 
 | 429 |         delete *in; | 
 | 430 |         *in = nullptr; | 
 | 431 |     } | 
 | 432 |  | 
 | 433 |     return status; | 
 | 434 | } | 
 | 435 |  | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 436 | binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in, | 
 | 437 |                                   AParcel** out, binder_flags_t flags) { | 
 | 438 |     if (in == nullptr) { | 
 | 439 |         LOG(ERROR) << __func__ << ": requires non-null in parameter"; | 
 | 440 |         return EX_NULL_POINTER; | 
 | 441 |     } | 
 | 442 |  | 
| Steven Moreland | caa776c | 2018-09-04 13:48:11 -0700 | [diff] [blame] | 443 |     using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>; | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 444 |     // This object is the input to the transaction. This function takes ownership of it and deletes | 
 | 445 |     // it. | 
| Steven Moreland | caa776c | 2018-09-04 13:48:11 -0700 | [diff] [blame] | 446 |     AutoParcelDestroyer forIn(in, AParcel_delete); | 
| Steven Moreland | 2e87adc | 2018-08-20 19:47:00 -0700 | [diff] [blame] | 447 |  | 
 | 448 |     if (!isUserCommand(code)) { | 
 | 449 |         LOG(ERROR) << __func__ << ": Only user-defined transactions can be made from the NDK."; | 
 | 450 |         return EX_UNSUPPORTED_OPERATION; | 
 | 451 |     } | 
 | 452 |  | 
 | 453 |     if ((flags & ~FLAG_ONEWAY) != 0) { | 
 | 454 |         LOG(ERROR) << __func__ << ": Unrecognized flags sent: " << flags; | 
 | 455 |         return EX_ILLEGAL_ARGUMENT; | 
 | 456 |     } | 
 | 457 |  | 
 | 458 |     if (binder == nullptr || *in == nullptr || out == nullptr) { | 
 | 459 |         LOG(ERROR) << __func__ << ": requires non-null parameters."; | 
 | 460 |         return EX_NULL_POINTER; | 
 | 461 |     } | 
 | 462 |  | 
 | 463 |     if ((*in)->getBinder() != binder) { | 
 | 464 |         LOG(ERROR) << __func__ << ": parcel is associated with binder object " << binder | 
 | 465 |                    << " but called with " << (*in)->getBinder(); | 
 | 466 |         return EX_ILLEGAL_STATE; | 
 | 467 |     } | 
 | 468 |  | 
 | 469 |     *out = new AParcel(binder); | 
 | 470 |  | 
 | 471 |     binder_status_t parcelStatus = | 
 | 472 |             binder->getBinder()->transact(code, *(*in)->operator->(), (*out)->operator->(), flags); | 
 | 473 |  | 
 | 474 |     if (parcelStatus != EX_NONE) { | 
 | 475 |         delete *out; | 
 | 476 |         *out = nullptr; | 
 | 477 |     } | 
 | 478 |  | 
 | 479 |     return parcelStatus; | 
 | 480 | } | 
| Steven Moreland | 901c745 | 2018-09-04 16:17:28 -0700 | [diff] [blame] | 481 |  | 
 | 482 | AIBinder_DeathRecipient* AIBinder_DeathRecipient_new( | 
 | 483 |         AIBinder_DeathRecipient_onBinderDied onBinderDied) { | 
 | 484 |     if (onBinderDied == nullptr) { | 
 | 485 |         LOG(ERROR) << __func__ << ": requires non-null onBinderDied parameter."; | 
 | 486 |         return nullptr; | 
 | 487 |     } | 
 | 488 |     return new AIBinder_DeathRecipient(onBinderDied); | 
 | 489 | } | 
 | 490 |  | 
 | 491 | void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient** recipient) { | 
 | 492 |     if (recipient == nullptr) { | 
 | 493 |         return; | 
 | 494 |     } | 
 | 495 |  | 
 | 496 |     delete *recipient; | 
 | 497 |     *recipient = nullptr; | 
 | 498 | } |