Home | History | Annotate | Download | only in libhwbinder
      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 <hwbinder/Binder.h>
     18 
     19 #include <atomic>
     20 #include <utils/misc.h>
     21 #include <hwbinder/BpHwBinder.h>
     22 #include <hwbinder/IInterface.h>
     23 #include <hwbinder/Parcel.h>
     24 
     25 #include <sched.h>
     26 #include <stdio.h>
     27 
     28 namespace android {
     29 namespace hardware {
     30 
     31 // ---------------------------------------------------------------------------
     32 
     33 IBinder::IBinder()
     34     : RefBase()
     35 {
     36 }
     37 
     38 IBinder::~IBinder()
     39 {
     40 }
     41 
     42 // ---------------------------------------------------------------------------
     43 
     44 BHwBinder* IBinder::localBinder()
     45 {
     46     return NULL;
     47 }
     48 
     49 BpHwBinder* IBinder::remoteBinder()
     50 {
     51     return NULL;
     52 }
     53 
     54 bool IBinder::checkSubclass(const void* /*subclassID*/) const
     55 {
     56     return false;
     57 }
     58 
     59 // ---------------------------------------------------------------------------
     60 
     61 class BHwBinder::Extras
     62 {
     63 public:
     64     Mutex mLock;
     65     BpHwBinder::ObjectManager mObjects;
     66 };
     67 
     68 // ---------------------------------------------------------------------------
     69 
     70 BHwBinder::BHwBinder() : mSchedPolicy(SCHED_NORMAL), mSchedPriority(0), mExtras(nullptr)
     71 {
     72 }
     73 
     74 int BHwBinder::getMinSchedulingPolicy() {
     75     return mSchedPolicy;
     76 }
     77 
     78 int BHwBinder::getMinSchedulingPriority() {
     79     return mSchedPriority;
     80 }
     81 
     82 status_t BHwBinder::transact(
     83     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
     84 {
     85     data.setDataPosition(0);
     86 
     87     status_t err = NO_ERROR;
     88     switch (code) {
     89         default:
     90             err = onTransact(code, data, reply, flags,
     91                     [&](auto &replyParcel) {
     92                         replyParcel.setDataPosition(0);
     93                         if (callback != NULL) {
     94                             callback(replyParcel);
     95                         }
     96                     });
     97             break;
     98     }
     99 
    100     return err;
    101 }
    102 
    103 status_t BHwBinder::linkToDeath(
    104     const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
    105     uint32_t /*flags*/)
    106 {
    107     return INVALID_OPERATION;
    108 }
    109 
    110 status_t BHwBinder::unlinkToDeath(
    111     const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
    112     uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
    113 {
    114     return INVALID_OPERATION;
    115 }
    116 
    117 void BHwBinder::attachObject(
    118     const void* objectID, void* object, void* cleanupCookie,
    119     object_cleanup_func func)
    120 {
    121     Extras* e = mExtras.load(std::memory_order_acquire);
    122 
    123     if (!e) {
    124         e = new Extras;
    125         Extras* expected = nullptr;
    126         if (!mExtras.compare_exchange_strong(expected, e,
    127                                              std::memory_order_release,
    128                                              std::memory_order_acquire)) {
    129             delete e;
    130             e = expected;  // Filled in by CAS
    131         }
    132         if (e == 0) return; // out of memory
    133     }
    134 
    135     AutoMutex _l(e->mLock);
    136     e->mObjects.attach(objectID, object, cleanupCookie, func);
    137 }
    138 
    139 void* BHwBinder::findObject(const void* objectID) const
    140 {
    141     Extras* e = mExtras.load(std::memory_order_acquire);
    142     if (!e) return NULL;
    143 
    144     AutoMutex _l(e->mLock);
    145     return e->mObjects.find(objectID);
    146 }
    147 
    148 void BHwBinder::detachObject(const void* objectID)
    149 {
    150     Extras* e = mExtras.load(std::memory_order_acquire);
    151     if (!e) return;
    152 
    153     AutoMutex _l(e->mLock);
    154     e->mObjects.detach(objectID);
    155 }
    156 
    157 BHwBinder* BHwBinder::localBinder()
    158 {
    159     return this;
    160 }
    161 
    162 BHwBinder::~BHwBinder()
    163 {
    164     Extras* e = mExtras.load(std::memory_order_relaxed);
    165     if (e) delete e;
    166 }
    167 
    168 
    169 status_t BHwBinder::onTransact(
    170     uint32_t /*code*/, const Parcel& /*data*/, Parcel* /*reply*/, uint32_t /*flags*/,
    171     TransactCallback /*callback*/)
    172 {
    173     return UNKNOWN_TRANSACTION;
    174 }
    175 
    176 // ---------------------------------------------------------------------------
    177 
    178 enum {
    179     // This is used to transfer ownership of the remote binder from
    180     // the BpHwRefBase object holding it (when it is constructed), to the
    181     // owner of the BpHwRefBase object when it first acquires that BpHwRefBase.
    182     kRemoteAcquired = 0x00000001
    183 };
    184 
    185 BpHwRefBase::BpHwRefBase(const sp<IBinder>& o)
    186     : mRemote(o.get()), mRefs(NULL), mState(0)
    187 {
    188     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    189 
    190     if (mRemote) {
    191         mRemote->incStrong(this);           // Removed on first IncStrong().
    192         mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
    193     }
    194 }
    195 
    196 BpHwRefBase::~BpHwRefBase()
    197 {
    198     if (mRemote) {
    199         if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
    200             mRemote->decStrong(this);
    201         }
    202         mRefs->decWeak(this);
    203     }
    204 }
    205 
    206 void BpHwRefBase::onFirstRef()
    207 {
    208     mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
    209 }
    210 
    211 void BpHwRefBase::onLastStrongRef(const void* /*id*/)
    212 {
    213     if (mRemote) {
    214         mRemote->decStrong(this);
    215     }
    216 }
    217 
    218 bool BpHwRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
    219 {
    220     return mRemote ? mRefs->attemptIncStrong(this) : false;
    221 }
    222 
    223 // ---------------------------------------------------------------------------
    224 
    225 }; // namespace hardware
    226 }; // namespace android
    227