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