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