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 #include <binder/Binder.h>
     18 
     19 #include <utils/Atomic.h>
     20 #include <utils/misc.h>
     21 #include <binder/BpBinder.h>
     22 #include <binder/IInterface.h>
     23 #include <binder/Parcel.h>
     24 
     25 #include <stdio.h>
     26 
     27 namespace android {
     28 
     29 // ---------------------------------------------------------------------------
     30 
     31 IBinder::IBinder()
     32     : RefBase()
     33 {
     34 }
     35 
     36 IBinder::~IBinder()
     37 {
     38 }
     39 
     40 // ---------------------------------------------------------------------------
     41 
     42 sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
     43 {
     44     return NULL;
     45 }
     46 
     47 BBinder* IBinder::localBinder()
     48 {
     49     return NULL;
     50 }
     51 
     52 BpBinder* IBinder::remoteBinder()
     53 {
     54     return NULL;
     55 }
     56 
     57 bool IBinder::checkSubclass(const void* /*subclassID*/) const
     58 {
     59     return false;
     60 }
     61 
     62 // ---------------------------------------------------------------------------
     63 
     64 class BBinder::Extras
     65 {
     66 public:
     67     Mutex mLock;
     68     BpBinder::ObjectManager mObjects;
     69 };
     70 
     71 // ---------------------------------------------------------------------------
     72 
     73 BBinder::BBinder()
     74     : mExtras(NULL)
     75 {
     76 }
     77 
     78 bool BBinder::isBinderAlive() const
     79 {
     80     return true;
     81 }
     82 
     83 status_t BBinder::pingBinder()
     84 {
     85     return NO_ERROR;
     86 }
     87 
     88 const String16& BBinder::getInterfaceDescriptor() const
     89 {
     90     // This is a local static rather than a global static,
     91     // to avoid static initializer ordering issues.
     92     static String16 sEmptyDescriptor;
     93     ALOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
     94     return sEmptyDescriptor;
     95 }
     96 
     97 status_t BBinder::transact(
     98     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
     99 {
    100     data.setDataPosition(0);
    101 
    102     status_t err = NO_ERROR;
    103     switch (code) {
    104         case PING_TRANSACTION:
    105             reply->writeInt32(pingBinder());
    106             break;
    107         default:
    108             err = onTransact(code, data, reply, flags);
    109             break;
    110     }
    111 
    112     if (reply != NULL) {
    113         reply->setDataPosition(0);
    114     }
    115 
    116     return err;
    117 }
    118 
    119 status_t BBinder::linkToDeath(
    120     const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
    121 {
    122     return INVALID_OPERATION;
    123 }
    124 
    125 status_t BBinder::unlinkToDeath(
    126     const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
    127     wp<DeathRecipient>* outRecipient)
    128 {
    129     return INVALID_OPERATION;
    130 }
    131 
    132 status_t BBinder::dump(int fd, const Vector<String16>& args)
    133 {
    134     return NO_ERROR;
    135 }
    136 
    137 void BBinder::attachObject(
    138     const void* objectID, void* object, void* cleanupCookie,
    139     object_cleanup_func func)
    140 {
    141     Extras* e = mExtras;
    142 
    143     if (!e) {
    144         e = new Extras;
    145         if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
    146                 reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
    147             delete e;
    148             e = mExtras;
    149         }
    150         if (e == 0) return; // out of memory
    151     }
    152 
    153     AutoMutex _l(e->mLock);
    154     e->mObjects.attach(objectID, object, cleanupCookie, func);
    155 }
    156 
    157 void* BBinder::findObject(const void* objectID) const
    158 {
    159     Extras* e = mExtras;
    160     if (!e) return NULL;
    161 
    162     AutoMutex _l(e->mLock);
    163     return e->mObjects.find(objectID);
    164 }
    165 
    166 void BBinder::detachObject(const void* objectID)
    167 {
    168     Extras* e = mExtras;
    169     if (!e) return;
    170 
    171     AutoMutex _l(e->mLock);
    172     e->mObjects.detach(objectID);
    173 }
    174 
    175 BBinder* BBinder::localBinder()
    176 {
    177     return this;
    178 }
    179 
    180 BBinder::~BBinder()
    181 {
    182     if (mExtras) delete mExtras;
    183 }
    184 
    185 
    186 status_t BBinder::onTransact(
    187     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    188 {
    189     switch (code) {
    190         case INTERFACE_TRANSACTION:
    191             reply->writeString16(getInterfaceDescriptor());
    192             return NO_ERROR;
    193 
    194         case DUMP_TRANSACTION: {
    195             int fd = data.readFileDescriptor();
    196             int argc = data.readInt32();
    197             Vector<String16> args;
    198             for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
    199                args.add(data.readString16());
    200             }
    201             return dump(fd, args);
    202         }
    203 
    204         case SYSPROPS_TRANSACTION: {
    205             report_sysprop_change();
    206             return NO_ERROR;
    207         }
    208 
    209         default:
    210             return UNKNOWN_TRANSACTION;
    211     }
    212 }
    213 
    214 // ---------------------------------------------------------------------------
    215 
    216 enum {
    217     // This is used to transfer ownership of the remote binder from
    218     // the BpRefBase object holding it (when it is constructed), to the
    219     // owner of the BpRefBase object when it first acquires that BpRefBase.
    220     kRemoteAcquired = 0x00000001
    221 };
    222 
    223 BpRefBase::BpRefBase(const sp<IBinder>& o)
    224     : mRemote(o.get()), mRefs(NULL), mState(0)
    225 {
    226     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    227 
    228     if (mRemote) {
    229         mRemote->incStrong(this);           // Removed on first IncStrong().
    230         mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
    231     }
    232 }
    233 
    234 BpRefBase::~BpRefBase()
    235 {
    236     if (mRemote) {
    237         if (!(mState&kRemoteAcquired)) {
    238             mRemote->decStrong(this);
    239         }
    240         mRefs->decWeak(this);
    241     }
    242 }
    243 
    244 void BpRefBase::onFirstRef()
    245 {
    246     android_atomic_or(kRemoteAcquired, &mState);
    247 }
    248 
    249 void BpRefBase::onLastStrongRef(const void* id)
    250 {
    251     if (mRemote) {
    252         mRemote->decStrong(this);
    253     }
    254 }
    255 
    256 bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
    257 {
    258     return mRemote ? mRefs->attemptIncStrong(this) : false;
    259 }
    260 
    261 // ---------------------------------------------------------------------------
    262 
    263 }; // namespace android
    264