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