1 /* 2 * Copyright (C) 2005 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 #define LOG_TAG "BpBinder" 18 //#define LOG_NDEBUG 0 19 20 #include <binder/BpBinder.h> 21 22 #include <binder/IPCThreadState.h> 23 #include <utils/Log.h> 24 25 #include <stdio.h> 26 27 //#undef ALOGV 28 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__) 29 30 namespace android { 31 32 // --------------------------------------------------------------------------- 33 34 BpBinder::ObjectManager::ObjectManager() 35 { 36 } 37 38 BpBinder::ObjectManager::~ObjectManager() 39 { 40 kill(); 41 } 42 43 void BpBinder::ObjectManager::attach( 44 const void* objectID, void* object, void* cleanupCookie, 45 IBinder::object_cleanup_func func) 46 { 47 entry_t e; 48 e.object = object; 49 e.cleanupCookie = cleanupCookie; 50 e.func = func; 51 52 if (mObjects.indexOfKey(objectID) >= 0) { 53 ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use", 54 objectID, this, object); 55 return; 56 } 57 58 mObjects.add(objectID, e); 59 } 60 61 void* BpBinder::ObjectManager::find(const void* objectID) const 62 { 63 const ssize_t i = mObjects.indexOfKey(objectID); 64 if (i < 0) return NULL; 65 return mObjects.valueAt(i).object; 66 } 67 68 void BpBinder::ObjectManager::detach(const void* objectID) 69 { 70 mObjects.removeItem(objectID); 71 } 72 73 void BpBinder::ObjectManager::kill() 74 { 75 const size_t N = mObjects.size(); 76 ALOGV("Killing %zu objects in manager %p", N, this); 77 for (size_t i=0; i<N; i++) { 78 const entry_t& e = mObjects.valueAt(i); 79 if (e.func != NULL) { 80 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie); 81 } 82 } 83 84 mObjects.clear(); 85 } 86 87 // --------------------------------------------------------------------------- 88 89 BpBinder::BpBinder(int32_t handle) 90 : mHandle(handle) 91 , mAlive(1) 92 , mObitsSent(0) 93 , mObituaries(NULL) 94 { 95 ALOGV("Creating BpBinder %p handle %d\n", this, mHandle); 96 97 extendObjectLifetime(OBJECT_LIFETIME_WEAK); 98 IPCThreadState::self()->incWeakHandle(handle); 99 } 100 101 bool BpBinder::isDescriptorCached() const { 102 Mutex::Autolock _l(mLock); 103 return mDescriptorCache.size() ? true : false; 104 } 105 106 const String16& BpBinder::getInterfaceDescriptor() const 107 { 108 if (isDescriptorCached() == false) { 109 Parcel send, reply; 110 // do the IPC without a lock held. 111 status_t err = const_cast<BpBinder*>(this)->transact( 112 INTERFACE_TRANSACTION, send, &reply); 113 if (err == NO_ERROR) { 114 String16 res(reply.readString16()); 115 Mutex::Autolock _l(mLock); 116 // mDescriptorCache could have been assigned while the lock was 117 // released. 118 if (mDescriptorCache.size() == 0) 119 mDescriptorCache = res; 120 } 121 } 122 123 // we're returning a reference to a non-static object here. Usually this 124 // is not something smart to do, however, with binder objects it is 125 // (usually) safe because they are reference-counted. 126 127 return mDescriptorCache; 128 } 129 130 bool BpBinder::isBinderAlive() const 131 { 132 return mAlive != 0; 133 } 134 135 status_t BpBinder::pingBinder() 136 { 137 Parcel send; 138 Parcel reply; 139 status_t err = transact(PING_TRANSACTION, send, &reply); 140 if (err != NO_ERROR) return err; 141 if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA; 142 return (status_t)reply.readInt32(); 143 } 144 145 status_t BpBinder::dump(int fd, const Vector<String16>& args) 146 { 147 Parcel send; 148 Parcel reply; 149 send.writeFileDescriptor(fd); 150 const size_t numArgs = args.size(); 151 send.writeInt32(numArgs); 152 for (size_t i = 0; i < numArgs; i++) { 153 send.writeString16(args[i]); 154 } 155 status_t err = transact(DUMP_TRANSACTION, send, &reply); 156 return err; 157 } 158 159 status_t BpBinder::transact( 160 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 161 { 162 // Once a binder has died, it will never come back to life. 163 if (mAlive) { 164 status_t status = IPCThreadState::self()->transact( 165 mHandle, code, data, reply, flags); 166 if (status == DEAD_OBJECT) mAlive = 0; 167 return status; 168 } 169 170 return DEAD_OBJECT; 171 } 172 173 status_t BpBinder::linkToDeath( 174 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) 175 { 176 Obituary ob; 177 ob.recipient = recipient; 178 ob.cookie = cookie; 179 ob.flags = flags; 180 181 LOG_ALWAYS_FATAL_IF(recipient == NULL, 182 "linkToDeath(): recipient must be non-NULL"); 183 184 { 185 AutoMutex _l(mLock); 186 187 if (!mObitsSent) { 188 if (!mObituaries) { 189 mObituaries = new Vector<Obituary>; 190 if (!mObituaries) { 191 return NO_MEMORY; 192 } 193 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle); 194 getWeakRefs()->incWeak(this); 195 IPCThreadState* self = IPCThreadState::self(); 196 self->requestDeathNotification(mHandle, this); 197 self->flushCommands(); 198 } 199 ssize_t res = mObituaries->add(ob); 200 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res; 201 } 202 } 203 204 return DEAD_OBJECT; 205 } 206 207 status_t BpBinder::unlinkToDeath( 208 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, 209 wp<DeathRecipient>* outRecipient) 210 { 211 AutoMutex _l(mLock); 212 213 if (mObitsSent) { 214 return DEAD_OBJECT; 215 } 216 217 const size_t N = mObituaries ? mObituaries->size() : 0; 218 for (size_t i=0; i<N; i++) { 219 const Obituary& obit = mObituaries->itemAt(i); 220 if ((obit.recipient == recipient 221 || (recipient == NULL && obit.cookie == cookie)) 222 && obit.flags == flags) { 223 if (outRecipient != NULL) { 224 *outRecipient = mObituaries->itemAt(i).recipient; 225 } 226 mObituaries->removeAt(i); 227 if (mObituaries->size() == 0) { 228 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle); 229 IPCThreadState* self = IPCThreadState::self(); 230 self->clearDeathNotification(mHandle, this); 231 self->flushCommands(); 232 delete mObituaries; 233 mObituaries = NULL; 234 } 235 return NO_ERROR; 236 } 237 } 238 239 return NAME_NOT_FOUND; 240 } 241 242 void BpBinder::sendObituary() 243 { 244 ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", 245 this, mHandle, mObitsSent ? "true" : "false"); 246 247 mAlive = 0; 248 if (mObitsSent) return; 249 250 mLock.lock(); 251 Vector<Obituary>* obits = mObituaries; 252 if(obits != NULL) { 253 ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle); 254 IPCThreadState* self = IPCThreadState::self(); 255 self->clearDeathNotification(mHandle, this); 256 self->flushCommands(); 257 mObituaries = NULL; 258 } 259 mObitsSent = 1; 260 mLock.unlock(); 261 262 ALOGV("Reporting death of proxy %p for %zu recipients\n", 263 this, obits ? obits->size() : 0U); 264 265 if (obits != NULL) { 266 const size_t N = obits->size(); 267 for (size_t i=0; i<N; i++) { 268 reportOneDeath(obits->itemAt(i)); 269 } 270 271 delete obits; 272 } 273 } 274 275 void BpBinder::reportOneDeath(const Obituary& obit) 276 { 277 sp<DeathRecipient> recipient = obit.recipient.promote(); 278 ALOGV("Reporting death to recipient: %p\n", recipient.get()); 279 if (recipient == NULL) return; 280 281 recipient->binderDied(this); 282 } 283 284 285 void BpBinder::attachObject( 286 const void* objectID, void* object, void* cleanupCookie, 287 object_cleanup_func func) 288 { 289 AutoMutex _l(mLock); 290 ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects); 291 mObjects.attach(objectID, object, cleanupCookie, func); 292 } 293 294 void* BpBinder::findObject(const void* objectID) const 295 { 296 AutoMutex _l(mLock); 297 return mObjects.find(objectID); 298 } 299 300 void BpBinder::detachObject(const void* objectID) 301 { 302 AutoMutex _l(mLock); 303 mObjects.detach(objectID); 304 } 305 306 BpBinder* BpBinder::remoteBinder() 307 { 308 return this; 309 } 310 311 BpBinder::~BpBinder() 312 { 313 ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle); 314 315 IPCThreadState* ipc = IPCThreadState::self(); 316 317 mLock.lock(); 318 Vector<Obituary>* obits = mObituaries; 319 if(obits != NULL) { 320 if (ipc) ipc->clearDeathNotification(mHandle, this); 321 mObituaries = NULL; 322 } 323 mLock.unlock(); 324 325 if (obits != NULL) { 326 // XXX Should we tell any remaining DeathRecipient 327 // objects that the last strong ref has gone away, so they 328 // are no longer linked? 329 delete obits; 330 } 331 332 if (ipc) { 333 ipc->expungeHandle(mHandle, this); 334 ipc->decWeakHandle(mHandle); 335 } 336 } 337 338 void BpBinder::onFirstRef() 339 { 340 ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle); 341 IPCThreadState* ipc = IPCThreadState::self(); 342 if (ipc) ipc->incStrongHandle(mHandle); 343 } 344 345 void BpBinder::onLastStrongRef(const void* /*id*/) 346 { 347 ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle); 348 IF_ALOGV() { 349 printRefs(); 350 } 351 IPCThreadState* ipc = IPCThreadState::self(); 352 if (ipc) ipc->decStrongHandle(mHandle); 353 } 354 355 bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/) 356 { 357 ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle); 358 IPCThreadState* ipc = IPCThreadState::self(); 359 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false; 360 } 361 362 // --------------------------------------------------------------------------- 363 364 }; // namespace android 365