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

Commit 3faaa000 authored by Devin Moore's avatar Devin Moore
Browse files

Add lookupOrCreateWeak to ObjectManager

This looks for an attached object on the binder, attempts to promote it,
and returns the object if it could be promoted.
Otherwise, it will create a new object and attach it to the binder.

Test: atest binderUnitTest aidl_integration_test
Bug: 220141324
Change-Id: I2c8baa211300fa3ada50f2b2c93862f8c968be26
parent fc20cdf5
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;
+3 −0
Original line number Diff line number Diff line
@@ -284,6 +284,9 @@ public:

    virtual BBinder*        localBinder();
    virtual BpBinder*       remoteBinder();
    typedef sp<IBinder> (*object_make_func)(const void* makeArgs);
    sp<IBinder> lookupOrCreateWeak(const void* objectID, object_make_func make,
                                   const void* makeArgs);

protected:
    virtual          ~IBinder();
Loading