Home | History | Annotate | Download | only in libhwbinder
      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 NULL;
     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 != NULL) {
     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(NULL)
     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         if (status == DEAD_OBJECT) mAlive = 0;
    110         return status;
    111     }
    112 
    113     return DEAD_OBJECT;
    114 }
    115 
    116 status_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 
    150 status_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 
    185 void 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 
    218 void 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 
    228 void 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 
    237 void* BpHwBinder::findObject(const void* objectID) const
    238 {
    239     AutoMutex _l(mLock);
    240     return mObjects.find(objectID);
    241 }
    242 
    243 void BpHwBinder::detachObject(const void* objectID)
    244 {
    245     AutoMutex _l(mLock);
    246     mObjects.detach(objectID);
    247 }
    248 
    249 BpHwBinder* BpHwBinder::remoteBinder()
    250 {
    251     return this;
    252 }
    253 
    254 BpHwBinder::~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 
    281 void BpHwBinder::onFirstRef()
    282 {
    283     ALOGV("onFirstRef BpHwBinder %p handle %d\n", this, mHandle);
    284     IPCThreadState* ipc = IPCThreadState::self();
    285     if (ipc) ipc->incStrongHandle(mHandle, this);
    286 }
    287 
    288 void 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 
    301 bool 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