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