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 30 namespace android { 31 namespace hardware { 32 33 // --------------------------------------------------------------------------- 34 35 BpHwBinder::ObjectManager::ObjectManager() 36 { 37 } 38 39 BpHwBinder::ObjectManager::~ObjectManager() 40 { 41 kill(); 42 } 43 44 void 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 62 void* BpHwBinder::ObjectManager::find(const void* objectID) const 63 { 64 const ssize_t i = mObjects.indexOfKey(objectID); 65 if (i < 0) return nullptr; 66 return mObjects.valueAt(i).object; 67 } 68 69 void BpHwBinder::ObjectManager::detach(const void* objectID) 70 { 71 mObjects.removeItem(objectID); 72 } 73 74 void 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 != nullptr) { 81 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie); 82 } 83 } 84 85 mObjects.clear(); 86 } 87 88 // --------------------------------------------------------------------------- 89 90 BpHwBinder::BpHwBinder(int32_t handle) 91 : mHandle(handle) 92 , mAlive(1) 93 , mObitsSent(0) 94 , mObituaries(nullptr) 95 { 96 ALOGV("Creating BpHwBinder %p handle %d\n", this, mHandle); 97 98 extendObjectLifetime(OBJECT_LIFETIME_WEAK); 99 IPCThreadState::self()->incWeakHandle(handle, this); 100 } 101 102 status_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 110 if (status == ::android::OK && callback != nullptr) { 111 callback(*reply); 112 } 113 114 if (status == DEAD_OBJECT) mAlive = 0; 115 return status; 116 } 117 118 return DEAD_OBJECT; 119 } 120 121 status_t BpHwBinder::linkToDeath( 122 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) 123 { 124 Obituary ob; 125 ob.recipient = recipient; 126 ob.cookie = cookie; 127 ob.flags = flags; 128 129 LOG_ALWAYS_FATAL_IF(recipient == nullptr, 130 "linkToDeath(): recipient must be non-NULL"); 131 132 { 133 AutoMutex _l(mLock); 134 135 if (!mObitsSent) { 136 if (!mObituaries) { 137 mObituaries = new Vector<Obituary>; 138 if (!mObituaries) { 139 return NO_MEMORY; 140 } 141 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle); 142 getWeakRefs()->incWeak(this); 143 IPCThreadState* self = IPCThreadState::self(); 144 self->requestDeathNotification(mHandle, this); 145 self->flushCommands(); 146 } 147 ssize_t res = mObituaries->add(ob); 148 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res; 149 } 150 } 151 152 return DEAD_OBJECT; 153 } 154 155 status_t BpHwBinder::unlinkToDeath( 156 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, 157 wp<DeathRecipient>* outRecipient) 158 { 159 AutoMutex _l(mLock); 160 161 if (mObitsSent) { 162 return DEAD_OBJECT; 163 } 164 165 const size_t N = mObituaries ? mObituaries->size() : 0; 166 for (size_t i=0; i<N; i++) { 167 const Obituary& obit = mObituaries->itemAt(i); 168 if ((obit.recipient == recipient 169 || (recipient == nullptr && obit.cookie == cookie)) 170 && obit.flags == flags) { 171 if (outRecipient != nullptr) { 172 *outRecipient = mObituaries->itemAt(i).recipient; 173 } 174 mObituaries->removeAt(i); 175 if (mObituaries->size() == 0) { 176 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle); 177 IPCThreadState* self = IPCThreadState::self(); 178 self->clearDeathNotification(mHandle, this); 179 self->flushCommands(); 180 delete mObituaries; 181 mObituaries = nullptr; 182 } 183 return NO_ERROR; 184 } 185 } 186 187 return NAME_NOT_FOUND; 188 } 189 190 void BpHwBinder::sendObituary() 191 { 192 ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", 193 this, mHandle, mObitsSent ? "true" : "false"); 194 195 mAlive = 0; 196 if (mObitsSent) return; 197 198 mLock.lock(); 199 Vector<Obituary>* obits = mObituaries; 200 if(obits != nullptr) { 201 ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle); 202 IPCThreadState* self = IPCThreadState::self(); 203 self->clearDeathNotification(mHandle, this); 204 self->flushCommands(); 205 mObituaries = nullptr; 206 } 207 mObitsSent = 1; 208 mLock.unlock(); 209 210 ALOGV("Reporting death of proxy %p for %zu recipients\n", 211 this, obits ? obits->size() : 0U); 212 213 if (obits != nullptr) { 214 const size_t N = obits->size(); 215 for (size_t i=0; i<N; i++) { 216 reportOneDeath(obits->itemAt(i)); 217 } 218 219 delete obits; 220 } 221 } 222 223 // Returns the strong refcount on the object this proxy points to, or 224 // -1 in case of failure. 225 ssize_t BpHwBinder::getNodeStrongRefCount() 226 { 227 return ProcessState::self()->getStrongRefCountForNodeByHandle(mHandle); 228 } 229 230 void BpHwBinder::reportOneDeath(const Obituary& obit) 231 { 232 sp<DeathRecipient> recipient = obit.recipient.promote(); 233 ALOGV("Reporting death to recipient: %p\n", recipient.get()); 234 if (recipient == nullptr) return; 235 236 recipient->binderDied(this); 237 } 238 239 240 void BpHwBinder::attachObject( 241 const void* objectID, void* object, void* cleanupCookie, 242 object_cleanup_func func) 243 { 244 AutoMutex _l(mLock); 245 ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects); 246 mObjects.attach(objectID, object, cleanupCookie, func); 247 } 248 249 void* BpHwBinder::findObject(const void* objectID) const 250 { 251 AutoMutex _l(mLock); 252 return mObjects.find(objectID); 253 } 254 255 void BpHwBinder::detachObject(const void* objectID) 256 { 257 AutoMutex _l(mLock); 258 mObjects.detach(objectID); 259 } 260 261 BpHwBinder* BpHwBinder::remoteBinder() 262 { 263 return this; 264 } 265 266 BpHwBinder::~BpHwBinder() 267 { 268 ALOGV("Destroying BpHwBinder %p handle %d\n", this, mHandle); 269 270 IPCThreadState* ipc = IPCThreadState::self(); 271 272 if (ipc) { 273 ipc->expungeHandle(mHandle, this); 274 ipc->decWeakHandle(mHandle); 275 } 276 } 277 278 void BpHwBinder::onFirstRef() 279 { 280 ALOGV("onFirstRef BpHwBinder %p handle %d\n", this, mHandle); 281 IPCThreadState* ipc = IPCThreadState::self(); 282 if (ipc) ipc->incStrongHandle(mHandle, this); 283 } 284 285 void BpHwBinder::onLastStrongRef(const void* /*id*/) 286 { 287 ALOGV("onLastStrongRef BpHwBinder %p handle %d\n", this, mHandle); 288 IF_ALOGV() { 289 printRefs(); 290 } 291 IPCThreadState* ipc = IPCThreadState::self(); 292 if (ipc) { 293 ipc->decStrongHandle(mHandle); 294 ipc->flushCommands(); 295 } 296 297 mLock.lock(); 298 Vector<Obituary>* obits = mObituaries; 299 if(obits != nullptr) { 300 if (!obits->isEmpty()) { 301 ALOGI("onLastStrongRef automatically unlinking death recipients"); 302 } 303 304 if (ipc) ipc->clearDeathNotification(mHandle, this); 305 mObituaries = nullptr; 306 } 307 mLock.unlock(); 308 309 if (obits != nullptr) { 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 obits = nullptr; 315 } 316 } 317 318 bool BpHwBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/) 319 { 320 ALOGV("onIncStrongAttempted BpHwBinder %p handle %d\n", this, mHandle); 321 IPCThreadState* ipc = IPCThreadState::self(); 322 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false; 323 } 324 325 // --------------------------------------------------------------------------- 326 327 } // namespace hardware 328 } // namespace android 329