Home | History | Annotate | Download | only in binder
      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 
     31 namespace android {
     32 
     33 // ---------------------------------------------------------------------------
     34 
     35 BpBinder::ObjectManager::ObjectManager()
     36 {
     37 }
     38 
     39 BpBinder::ObjectManager::~ObjectManager()
     40 {
     41     kill();
     42 }
     43 
     44 void 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 
     62 void* 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 
     69 void BpBinder::ObjectManager::detach(const void* objectID)
     70 {
     71     mObjects.removeItem(objectID);
     72 }
     73 
     74 void 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 
     90 BpBinder::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 
    102 bool BpBinder::isDescriptorCached() const {
    103     Mutex::Autolock _l(mLock);
    104     return mDescriptorCache.size() ? true : false;
    105 }
    106 
    107 const 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 
    131 bool BpBinder::isBinderAlive() const
    132 {
    133     return mAlive != 0;
    134 }
    135 
    136 status_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 
    146 status_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 
    160 status_t BpBinder::transact(
    161     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    162 {
    163     // Once a binder has died, it will never come back to life.
    164     if (mAlive) {
    165         status_t status = IPCThreadState::self()->transact(
    166             mHandle, code, data, reply, flags);
    167         if (status == DEAD_OBJECT) mAlive = 0;
    168         return status;
    169     }
    170 
    171     return DEAD_OBJECT;
    172 }
    173 
    174 status_t BpBinder::linkToDeath(
    175     const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
    176 {
    177     Obituary ob;
    178     ob.recipient = recipient;
    179     ob.cookie = cookie;
    180     ob.flags = flags;
    181 
    182     LOG_ALWAYS_FATAL_IF(recipient == NULL,
    183                         "linkToDeath(): recipient must be non-NULL");
    184 
    185     {
    186         AutoMutex _l(mLock);
    187 
    188         if (!mObitsSent) {
    189             if (!mObituaries) {
    190                 mObituaries = new Vector<Obituary>;
    191                 if (!mObituaries) {
    192                     return NO_MEMORY;
    193                 }
    194                 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
    195                 getWeakRefs()->incWeak(this);
    196                 IPCThreadState* self = IPCThreadState::self();
    197                 self->requestDeathNotification(mHandle, this);
    198                 self->flushCommands();
    199             }
    200             ssize_t res = mObituaries->add(ob);
    201             return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
    202         }
    203     }
    204 
    205     return DEAD_OBJECT;
    206 }
    207 
    208 status_t BpBinder::unlinkToDeath(
    209     const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
    210     wp<DeathRecipient>* outRecipient)
    211 {
    212     AutoMutex _l(mLock);
    213 
    214     if (mObitsSent) {
    215         return DEAD_OBJECT;
    216     }
    217 
    218     const size_t N = mObituaries ? mObituaries->size() : 0;
    219     for (size_t i=0; i<N; i++) {
    220         const Obituary& obit = mObituaries->itemAt(i);
    221         if ((obit.recipient == recipient
    222                     || (recipient == NULL && obit.cookie == cookie))
    223                 && obit.flags == flags) {
    224             if (outRecipient != NULL) {
    225                 *outRecipient = mObituaries->itemAt(i).recipient;
    226             }
    227             mObituaries->removeAt(i);
    228             if (mObituaries->size() == 0) {
    229                 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
    230                 IPCThreadState* self = IPCThreadState::self();
    231                 self->clearDeathNotification(mHandle, this);
    232                 self->flushCommands();
    233                 delete mObituaries;
    234                 mObituaries = NULL;
    235             }
    236             return NO_ERROR;
    237         }
    238     }
    239 
    240     return NAME_NOT_FOUND;
    241 }
    242 
    243 void BpBinder::sendObituary()
    244 {
    245     ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
    246         this, mHandle, mObitsSent ? "true" : "false");
    247 
    248     mAlive = 0;
    249     if (mObitsSent) return;
    250 
    251     mLock.lock();
    252     Vector<Obituary>* obits = mObituaries;
    253     if(obits != NULL) {
    254         ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
    255         IPCThreadState* self = IPCThreadState::self();
    256         self->clearDeathNotification(mHandle, this);
    257         self->flushCommands();
    258         mObituaries = NULL;
    259     }
    260     mObitsSent = 1;
    261     mLock.unlock();
    262 
    263     ALOGV("Reporting death of proxy %p for %zu recipients\n",
    264         this, obits ? obits->size() : 0U);
    265 
    266     if (obits != NULL) {
    267         const size_t N = obits->size();
    268         for (size_t i=0; i<N; i++) {
    269             reportOneDeath(obits->itemAt(i));
    270         }
    271 
    272         delete obits;
    273     }
    274 }
    275 
    276 void BpBinder::reportOneDeath(const Obituary& obit)
    277 {
    278     sp<DeathRecipient> recipient = obit.recipient.promote();
    279     ALOGV("Reporting death to recipient: %p\n", recipient.get());
    280     if (recipient == NULL) return;
    281 
    282     recipient->binderDied(this);
    283 }
    284 
    285 
    286 void BpBinder::attachObject(
    287     const void* objectID, void* object, void* cleanupCookie,
    288     object_cleanup_func func)
    289 {
    290     AutoMutex _l(mLock);
    291     ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
    292     mObjects.attach(objectID, object, cleanupCookie, func);
    293 }
    294 
    295 void* BpBinder::findObject(const void* objectID) const
    296 {
    297     AutoMutex _l(mLock);
    298     return mObjects.find(objectID);
    299 }
    300 
    301 void BpBinder::detachObject(const void* objectID)
    302 {
    303     AutoMutex _l(mLock);
    304     mObjects.detach(objectID);
    305 }
    306 
    307 BpBinder* BpBinder::remoteBinder()
    308 {
    309     return this;
    310 }
    311 
    312 BpBinder::~BpBinder()
    313 {
    314     ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
    315 
    316     IPCThreadState* ipc = IPCThreadState::self();
    317 
    318     mLock.lock();
    319     Vector<Obituary>* obits = mObituaries;
    320     if(obits != NULL) {
    321         if (ipc) ipc->clearDeathNotification(mHandle, this);
    322         mObituaries = NULL;
    323     }
    324     mLock.unlock();
    325 
    326     if (obits != NULL) {
    327         // XXX Should we tell any remaining DeathRecipient
    328         // objects that the last strong ref has gone away, so they
    329         // are no longer linked?
    330         delete obits;
    331     }
    332 
    333     if (ipc) {
    334         ipc->expungeHandle(mHandle, this);
    335         ipc->decWeakHandle(mHandle);
    336     }
    337 }
    338 
    339 void BpBinder::onFirstRef()
    340 {
    341     ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
    342     IPCThreadState* ipc = IPCThreadState::self();
    343     if (ipc) ipc->incStrongHandle(mHandle);
    344 }
    345 
    346 void BpBinder::onLastStrongRef(const void* /*id*/)
    347 {
    348     ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
    349     IF_ALOGV() {
    350         printRefs();
    351     }
    352     IPCThreadState* ipc = IPCThreadState::self();
    353     if (ipc) ipc->decStrongHandle(mHandle);
    354 }
    355 
    356 bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
    357 {
    358     ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
    359     IPCThreadState* ipc = IPCThreadState::self();
    360     return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
    361 }
    362 
    363 // ---------------------------------------------------------------------------
    364 
    365 }; // namespace android
    366