Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2a06c49 authored by Devin Moore's avatar Devin Moore Committed by Automerger Merge Worker
Browse files

Merge changes from topic "auto_delegator" am: 549bf76e am: 4d88872f

parents 37e296a4 4d88872f
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -202,6 +202,17 @@ void IBinder::withLock(const std::function<void()>& doWithLock) {
    proxy->withLock(doWithLock);
}

sp<IBinder> IBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
                                        const void* makeArgs) {
    BBinder* local = localBinder();
    if (local) {
        return local->lookupOrCreateWeak(objectID, make, makeArgs);
    }
    BpBinder* proxy = this->remoteBinder();
    LOG_ALWAYS_FATAL_IF(proxy == nullptr, "binder object must be either local or remote");
    return proxy->lookupOrCreateWeak(objectID, make, makeArgs);
}

// ---------------------------------------------------------------------------

class BBinder::RpcServerLink : public IBinder::DeathRecipient {
@@ -378,6 +389,14 @@ void BBinder::withLock(const std::function<void()>& doWithLock) {
    doWithLock();
}

sp<IBinder> BBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
                                        const void* makeArgs) {
    Extras* e = getOrCreateExtras();
    LOG_ALWAYS_FATAL_IF(!e, "no memory");
    AutoMutex _l(e->mLock);
    return e->mObjects.lookupOrCreateWeak(objectID, make, makeArgs);
}

BBinder* BBinder::localBinder()
{
    return this;
+36 −0
Original line number Diff line number Diff line
@@ -100,6 +100,36 @@ void* BpBinder::ObjectManager::detach(const void* objectID) {
    return value;
}

namespace {
struct Tag {
    wp<IBinder> binder;
};
} // namespace

static void cleanWeak(const void* /* id */, void* obj, void* /* cookie */) {
    delete static_cast<Tag*>(obj);
}

sp<IBinder> BpBinder::ObjectManager::lookupOrCreateWeak(const void* objectID, object_make_func make,
                                                        const void* makeArgs) {
    entry_t& e = mObjects[objectID];
    if (e.object != nullptr) {
        if (auto attached = static_cast<Tag*>(e.object)->binder.promote()) {
            return attached;
        }
    } else {
        e.object = new Tag;
        LOG_ALWAYS_FATAL_IF(!e.object, "no more memory");
    }
    sp<IBinder> newObj = make(makeArgs);

    static_cast<Tag*>(e.object)->binder = newObj;
    e.cleanupCookie = nullptr;
    e.func = cleanWeak;

    return newObj;
}

void BpBinder::ObjectManager::kill()
{
    const size_t N = mObjects.size();
@@ -516,6 +546,12 @@ void BpBinder::withLock(const std::function<void()>& doWithLock) {
    doWithLock();
}

sp<IBinder> BpBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
                                         const void* makeArgs) {
    AutoMutex _l(mLock);
    return mObjects.lookupOrCreateWeak(objectID, make, makeArgs);
}

BpBinder* BpBinder::remoteBinder()
{
    return this;
+2 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ public:
    virtual void*       findObject(const void* objectID) const final;
    virtual void* detachObject(const void* objectID) final;
    void withLock(const std::function<void()>& doWithLock);
    sp<IBinder> lookupOrCreateWeak(const void* objectID, IBinder::object_make_func make,
                                   const void* makeArgs);

    virtual BBinder*    localBinder();

+7 −3
Original line number Diff line number Diff line
@@ -72,6 +72,8 @@ public:
    virtual void*       findObject(const void* objectID) const final;
    virtual void* detachObject(const void* objectID) final;
    void withLock(const std::function<void()>& doWithLock);
    sp<IBinder> lookupOrCreateWeak(const void* objectID, IBinder::object_make_func make,
                                   const void* makeArgs);

    virtual BpBinder*   remoteBinder();

@@ -96,6 +98,8 @@ public:
                     IBinder::object_cleanup_func func);
        void* find(const void* objectID) const;
        void* detach(const void* objectID);
        sp<IBinder> lookupOrCreateWeak(const void* objectID, IBinder::object_make_func make,
                                       const void* makeArgs);

        void kill();

@@ -104,9 +108,9 @@ public:
        ObjectManager& operator=(const ObjectManager&);

        struct entry_t {
            void* object;
            void* cleanupCookie;
            IBinder::object_cleanup_func func;
            void* object = nullptr;
            void* cleanupCookie = nullptr;
            IBinder::object_cleanup_func func = nullptr;
        };

        std::map<const void*, entry_t> mObjects;
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.
 */

#pragma once

#include <binder/IBinder.h>

#ifndef __BIONIC__
#ifndef __assert

// defined differently by liblog
#pragma push_macro("LOG_PRI")
#ifdef LOG_PRI
#undef LOG_PRI
#endif
#include <syslog.h>
#pragma pop_macro("LOG_PRI")

#define __assert(a, b, c)          \
    do {                           \
        syslog(LOG_ERR, a ": " c); \
        abort();                   \
    } while (false)
#endif // __assert
#endif // __BIONIC__

namespace android {

/*
 * Used to manage AIDL's *Delegator types.
 * This is used to:
 * - create a new *Delegator object that delegates to the binder argument.
 * - or return an existing *Delegator object that already delegates to the
 * binder argument.
 * - or return the underlying delegate binder if the binder argument is a
 * *Delegator itself.
 *
 * @param binder - the binder to delegate to or unwrap
 *
 * @return pointer to the *Delegator object or the unwrapped binder object
 */
template <typename T>
sp<T> delegate(const sp<T>& binder) {
    const void* isDelegatorId = &T::descriptor;
    const void* hasDelegatorId = &T::descriptor + 1;
    // is binder itself a delegator?
    if (T::asBinder(binder)->findObject(isDelegatorId)) {
        if (T::asBinder(binder)->findObject(hasDelegatorId)) {
            __assert(__FILE__, __LINE__,
                     "This binder has a delegator and is also delegator itself! This is "
                     "likely an unintended mixing of binders.");
            return nullptr;
        }
        // unwrap the delegator
        return static_cast<typename T::DefaultDelegator*>(binder.get())->getImpl();
    }

    struct MakeArgs {
        const sp<T>* binder;
        const void* id;
    } makeArgs;
    makeArgs.binder = &binder;
    makeArgs.id = isDelegatorId;

    // the binder is not a delegator, so construct one
    sp<IBinder> newDelegator = T::asBinder(binder)->lookupOrCreateWeak(
            hasDelegatorId,
            [](const void* args) -> sp<IBinder> {
                auto delegator = sp<typename T::DefaultDelegator>::make(
                        *static_cast<const MakeArgs*>(args)->binder);
                // make sure we know this binder is a delegator by attaching a unique ID
                (void)delegator->attachObject(static_cast<const MakeArgs*>(args)->id,
                                              reinterpret_cast<void*>(0x1), nullptr, nullptr);
                return delegator;
            },
            static_cast<const void*>(&makeArgs));
    return sp<typename T::DefaultDelegator>::cast(newDelegator);
}

} // namespace android
Loading