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 <stdatomic.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 {
     75     atomic_init(&mExtras, 0);
     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*/,
    121     uint32_t /*flags*/)
    122 {
    123     return INVALID_OPERATION;
    124 }
    125 
    126 status_t BBinder::unlinkToDeath(
    127     const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
    128     uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
    129 {
    130     return INVALID_OPERATION;
    131 }
    132 
    133     status_t BBinder::dump(int /*fd*/, const Vector<String16>& /*args*/)
    134 {
    135     return NO_ERROR;
    136 }
    137 
    138 void BBinder::attachObject(
    139     const void* objectID, void* object, void* cleanupCookie,
    140     object_cleanup_func func)
    141 {
    142     Extras* e = reinterpret_cast<Extras*>(
    143                     atomic_load_explicit(&mExtras, memory_order_acquire));
    144 
    145     if (!e) {
    146         e = new Extras;
    147         uintptr_t expected = 0;
    148         if (!atomic_compare_exchange_strong_explicit(
    149                                         &mExtras, &expected,
    150                                         reinterpret_cast<uintptr_t>(e),
    151                                         memory_order_release,
    152                                         memory_order_acquire)) {
    153             delete e;
    154             e = reinterpret_cast<Extras*>(expected);  // Filled in by CAS
    155         }
    156         if (e == 0) return; // out of memory
    157     }
    158 
    159     AutoMutex _l(e->mLock);
    160     e->mObjects.attach(objectID, object, cleanupCookie, func);
    161 }
    162 
    163 void* BBinder::findObject(const void* objectID) const
    164 {
    165     Extras* e = reinterpret_cast<Extras*>(
    166                     atomic_load_explicit(&mExtras, memory_order_acquire));
    167     if (!e) return NULL;
    168 
    169     AutoMutex _l(e->mLock);
    170     return e->mObjects.find(objectID);
    171 }
    172 
    173 void BBinder::detachObject(const void* objectID)
    174 {
    175     Extras* e = reinterpret_cast<Extras*>(
    176                     atomic_load_explicit(&mExtras, memory_order_acquire));
    177     if (!e) return;
    178 
    179     AutoMutex _l(e->mLock);
    180     e->mObjects.detach(objectID);
    181 }
    182 
    183 BBinder* BBinder::localBinder()
    184 {
    185     return this;
    186 }
    187 
    188 BBinder::~BBinder()
    189 {
    190     Extras* e = reinterpret_cast<Extras*>(
    191                     atomic_load_explicit(&mExtras, memory_order_relaxed));
    192     if (e) delete e;
    193 }
    194 
    195 
    196 status_t BBinder::onTransact(
    197     uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
    198 {
    199     switch (code) {
    200         case INTERFACE_TRANSACTION:
    201             reply->writeString16(getInterfaceDescriptor());
    202             return NO_ERROR;
    203 
    204         case DUMP_TRANSACTION: {
    205             int fd = data.readFileDescriptor();
    206             int argc = data.readInt32();
    207             Vector<String16> args;
    208             for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
    209                args.add(data.readString16());
    210             }
    211             return dump(fd, args);
    212         }
    213 
    214         case SYSPROPS_TRANSACTION: {
    215             report_sysprop_change();
    216             return NO_ERROR;
    217         }
    218 
    219         default:
    220             return UNKNOWN_TRANSACTION;
    221     }
    222 }
    223 
    224 // ---------------------------------------------------------------------------
    225 
    226 enum {
    227     // This is used to transfer ownership of the remote binder from
    228     // the BpRefBase object holding it (when it is constructed), to the
    229     // owner of the BpRefBase object when it first acquires that BpRefBase.
    230     kRemoteAcquired = 0x00000001
    231 };
    232 
    233 BpRefBase::BpRefBase(const sp<IBinder>& o)
    234     : mRemote(o.get()), mRefs(NULL), mState(0)
    235 {
    236     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    237 
    238     if (mRemote) {
    239         mRemote->incStrong(this);           // Removed on first IncStrong().
    240         mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
    241     }
    242 }
    243 
    244 BpRefBase::~BpRefBase()
    245 {
    246     if (mRemote) {
    247         if (!(mState&kRemoteAcquired)) {
    248             mRemote->decStrong(this);
    249         }
    250         mRefs->decWeak(this);
    251     }
    252 }
    253 
    254 void BpRefBase::onFirstRef()
    255 {
    256     android_atomic_or(kRemoteAcquired, &mState);
    257 }
    258 
    259 void BpRefBase::onLastStrongRef(const void* /*id*/)
    260 {
    261     if (mRemote) {
    262         mRemote->decStrong(this);
    263     }
    264 }
    265 
    266 bool BpRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
    267 {
    268     return mRemote ? mRefs->attemptIncStrong(this) : false;
    269 }
    270 
    271 // ---------------------------------------------------------------------------
    272 
    273 }; // namespace android
    274