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