123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include <hwbinder/Binder.h>
- #include <atomic>
- #include <utils/misc.h>
- #include <hwbinder/BpHwBinder.h>
- #include <hwbinder/IInterface.h>
- #include <hwbinder/Parcel.h>
- #include <sched.h>
- #include <stdio.h>
- namespace android {
- namespace hardware {
- // ---------------------------------------------------------------------------
- IBinder::IBinder()
- : RefBase()
- {
- }
- IBinder::~IBinder()
- {
- }
- // ---------------------------------------------------------------------------
- BHwBinder* IBinder::localBinder()
- {
- return nullptr;
- }
- BpHwBinder* IBinder::remoteBinder()
- {
- return nullptr;
- }
- bool IBinder::checkSubclass(const void* /*subclassID*/) const
- {
- return false;
- }
- // ---------------------------------------------------------------------------
- class BHwBinder::Extras
- {
- public:
- // unlocked objects
- bool mRequestingSid = false;
- // for below objects
- Mutex mLock;
- BpHwBinder::ObjectManager mObjects;
- };
- // ---------------------------------------------------------------------------
- BHwBinder::BHwBinder() : mSchedPolicy(SCHED_NORMAL), mSchedPriority(0), mExtras(nullptr)
- {
- }
- int BHwBinder::getMinSchedulingPolicy() {
- return mSchedPolicy;
- }
- int BHwBinder::getMinSchedulingPriority() {
- return mSchedPriority;
- }
- bool BHwBinder::isRequestingSid() {
- Extras* e = mExtras.load(std::memory_order_acquire);
- return e && e->mRequestingSid;
- }
- void BHwBinder::setRequestingSid(bool requestingSid) {
- Extras* e = mExtras.load(std::memory_order_acquire);
- if (!e) {
- // default is false. Most things don't need sids, so avoiding allocations when possible.
- if (!requestingSid) {
- return;
- }
- e = getOrCreateExtras();
- if (!e) return; // out of memory
- }
- e->mRequestingSid = requestingSid;
- }
- status_t BHwBinder::transact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
- {
- data.setDataPosition(0);
- status_t err = NO_ERROR;
- switch (code) {
- default:
- err = onTransact(code, data, reply, flags,
- [&](auto &replyParcel) {
- replyParcel.setDataPosition(0);
- if (callback != nullptr) {
- callback(replyParcel);
- }
- });
- break;
- }
- return err;
- }
- status_t BHwBinder::linkToDeath(
- const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
- uint32_t /*flags*/)
- {
- return INVALID_OPERATION;
- }
- status_t BHwBinder::unlinkToDeath(
- const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
- uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
- {
- return INVALID_OPERATION;
- }
- void BHwBinder::attachObject(
- const void* objectID, void* object, void* cleanupCookie,
- object_cleanup_func func)
- {
- Extras* e = getOrCreateExtras();
- if (!e) return; // out of memory
- AutoMutex _l(e->mLock);
- e->mObjects.attach(objectID, object, cleanupCookie, func);
- }
- void* BHwBinder::findObject(const void* objectID) const
- {
- Extras* e = mExtras.load(std::memory_order_acquire);
- if (!e) return nullptr;
- AutoMutex _l(e->mLock);
- return e->mObjects.find(objectID);
- }
- void BHwBinder::detachObject(const void* objectID)
- {
- Extras* e = mExtras.load(std::memory_order_acquire);
- if (!e) return;
- AutoMutex _l(e->mLock);
- e->mObjects.detach(objectID);
- }
- BHwBinder* BHwBinder::localBinder()
- {
- return this;
- }
- BHwBinder::~BHwBinder()
- {
- Extras* e = mExtras.load(std::memory_order_relaxed);
- if (e) delete e;
- }
- status_t BHwBinder::onTransact(
- uint32_t /*code*/, const Parcel& /*data*/, Parcel* /*reply*/, uint32_t /*flags*/,
- TransactCallback /*callback*/)
- {
- return UNKNOWN_TRANSACTION;
- }
- BHwBinder::Extras* BHwBinder::getOrCreateExtras()
- {
- Extras* e = mExtras.load(std::memory_order_acquire);
- if (!e) {
- e = new Extras;
- Extras* expected = nullptr;
- if (!mExtras.compare_exchange_strong(expected, e,
- std::memory_order_release,
- std::memory_order_acquire)) {
- delete e;
- e = expected; // Filled in by CAS
- }
- if (e == nullptr) return nullptr; // out of memory
- }
- return e;
- }
- // ---------------------------------------------------------------------------
- enum {
- // This is used to transfer ownership of the remote binder from
- // the BpHwRefBase object holding it (when it is constructed), to the
- // owner of the BpHwRefBase object when it first acquires that BpHwRefBase.
- kRemoteAcquired = 0x00000001
- };
- BpHwRefBase::BpHwRefBase(const sp<IBinder>& o)
- : mRemote(o.get()), mRefs(nullptr), mState(0)
- {
- if (mRemote) {
- mRemote->incStrong(this); // Removed on first IncStrong().
- }
- }
- BpHwRefBase::~BpHwRefBase()
- {
- if (mRemote) {
- if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
- mRemote->decStrong(this);
- }
- }
- }
- void BpHwRefBase::onFirstRef()
- {
- mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
- }
- void BpHwRefBase::onLastStrongRef(const void* /*id*/)
- {
- if (mRemote) {
- mRemote->decStrong(this);
- }
- }
- bool BpHwRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
- {
- return false;
- }
- // ---------------------------------------------------------------------------
- }; // namespace hardware
- }; // namespace android
|