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

Commit d29ec5fa authored by Steven Moreland's avatar Steven Moreland Committed by android-build-merger
Browse files

libbinder_ndk: define userdata class in headers am: 304f9d37 am: e6c1c6f3

am: 38d28441

Change-Id: I4aea4d02db99a4ca25019a9f6e5e8399cf2389a9
parents 99e2e66b 38d28441
Loading
Loading
Loading
Loading
+75 −17
Original line number Diff line number Diff line
@@ -106,28 +106,37 @@ class ICInterface : public SharedRefBase {
    virtual bool isRemote() = 0;

    /**
     * Dumps information about the interface.
     * Dumps information about the interface. By default, dumps nothing.
     */
    virtual binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
        return STATUS_OK;
    }
    virtual inline binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);

    /**
     * Interprets this binder as this underlying interface if this has stored an ICInterface in the
     * binder's user data.
     *
     * This does not do type checking and should only be used when the binder is known to originate
     * from ICInterface. Most likely, you want to use I*::fromBinder.
     */
    static inline std::shared_ptr<ICInterface> asInterface(AIBinder* binder);

    /**
     * Helper method to create a class
     */
    static AIBinder_Class* defineClass(const char* interfaceDescriptor,
                                       AIBinder_Class_onCreate onCreate,
                                       AIBinder_Class_onDestroy onDestroy,
                                       AIBinder_Class_onTransact onTransact,
                                       AIBinder_onDump onDump = nullptr) {
        AIBinder_Class* clazz =
                AIBinder_Class_define(interfaceDescriptor, onCreate, onDestroy, onTransact);
        if (clazz == nullptr) {
            return nullptr;
        }
        AIBinder_Class_setOnDump(clazz, onDump);
        return clazz;
    }
    static inline AIBinder_Class* defineClass(const char* interfaceDescriptor,
                                              AIBinder_Class_onTransact onTransact);

   private:
    class ICInterfaceData {
       public:
        std::shared_ptr<ICInterface> interface;

        static inline std::shared_ptr<ICInterface> getInterface(AIBinder* binder);

        static inline void* onCreate(void* args);
        static inline void onDestroy(void* userData);
        static inline binder_status_t onDump(AIBinder* binder, int fd, const char** args,
                                             uint32_t numArgs);
    };
};

/**
@@ -176,6 +185,55 @@ class BpCInterface : public INTERFACE {
    SpAIBinder mBinder;
};

// END OF CLASS DECLARATIONS

binder_status_t ICInterface::dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
    return STATUS_OK;
}

std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) {
    return ICInterfaceData::getInterface(binder);
}

AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
                                         AIBinder_Class_onTransact onTransact) {
    AIBinder_Class* clazz = AIBinder_Class_define(interfaceDescriptor, ICInterfaceData::onCreate,
                                                  ICInterfaceData::onDestroy, onTransact);
    if (clazz == nullptr) {
        return nullptr;
    }

    // We can't know if this method is overriden by a subclass interface, so we must register
    // ourselves. The default (nothing to dump) is harmless.
    AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump);
    return clazz;
}

std::shared_ptr<ICInterface> ICInterface::ICInterfaceData::getInterface(AIBinder* binder) {
    if (binder == nullptr) return nullptr;

    void* userData = AIBinder_getUserData(binder);
    if (userData == nullptr) return nullptr;

    return static_cast<ICInterfaceData*>(userData)->interface;
}

void* ICInterface::ICInterfaceData::onCreate(void* args) {
    std::shared_ptr<ICInterface> interface = static_cast<ICInterface*>(args)->ref<ICInterface>();
    ICInterfaceData* data = new ICInterfaceData{interface};
    return static_cast<void*>(data);
}

void ICInterface::ICInterfaceData::onDestroy(void* userData) {
    delete static_cast<ICInterfaceData*>(userData);
}

binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, const char** args,
                                                     uint32_t numArgs) {
    std::shared_ptr<ICInterface> interface = getInterface(binder);
    return interface->dump(fd, args, numArgs);
}

template <typename INTERFACE>
SpAIBinder BnCInterface<INTERFACE>::asBinder() {
    std::lock_guard<std::mutex> l(mMutex);