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

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

Merge "libbinder_ndk: support dump" am: 36415570 am: 937202b7

am: 59183ae5

Change-Id: I1a043b40b5c47048a8a81ad749d93be9d121d903
parents 24934da6 59183ae5
Loading
Loading
Loading
Loading
+59 −2
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ using ::android::Parcel;
using ::android::sp;
using ::android::sp;
using ::android::status_t;
using ::android::status_t;
using ::android::String16;
using ::android::String16;
using ::android::String8;
using ::android::wp;
using ::android::wp;


namespace ABBinderTag {
namespace ABBinderTag {
@@ -67,8 +68,6 @@ AIBinder::AIBinder(const AIBinder_Class* clazz) : mClazz(clazz) {}
AIBinder::~AIBinder() {}
AIBinder::~AIBinder() {}


bool AIBinder::associateClass(const AIBinder_Class* clazz) {
bool AIBinder::associateClass(const AIBinder_Class* clazz) {
    using ::android::String8;

    if (clazz == nullptr) return false;
    if (clazz == nullptr) return false;
    if (mClazz == clazz) return true;
    if (mClazz == clazz) return true;


@@ -119,6 +118,33 @@ const String16& ABBinder::getInterfaceDescriptor() const {
    return getClass()->getInterfaceDescriptor();
    return getClass()->getInterfaceDescriptor();
}
}


status_t ABBinder::dump(int fd, const ::android::Vector<String16>& args) {
    AIBinder_onDump onDump = getClass()->onDump;

    if (onDump == nullptr) {
        return STATUS_OK;
    }

    // technically UINT32_MAX would be okay here, but INT32_MAX is expected since this may be
    // null in Java
    if (args.size() > INT32_MAX) {
        LOG(ERROR) << "ABBinder::dump received too many arguments: " << args.size();
        return STATUS_BAD_VALUE;
    }

    std::vector<String8> utf8Args;  // owns memory of utf8s
    utf8Args.reserve(args.size());
    std::vector<const char*> utf8Pointers;  // what can be passed over NDK API
    utf8Pointers.reserve(args.size());

    for (size_t i = 0; i < args.size(); i++) {
        utf8Args.push_back(String8(args[i]));
        utf8Pointers.push_back(utf8Args[i].c_str());
    }

    return onDump(this, fd, utf8Pointers.data(), utf8Pointers.size());
}

status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply,
status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply,
                              binder_flags_t flags) {
                              binder_flags_t flags) {
    if (isUserCommand(code)) {
    if (isUserCommand(code)) {
@@ -232,6 +258,13 @@ AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor,
    return new AIBinder_Class(interfaceDescriptor, onCreate, onDestroy, onTransact);
    return new AIBinder_Class(interfaceDescriptor, onCreate, onDestroy, onTransact);
}
}


void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) {
    CHECK(clazz != nullptr) << "setOnDump requires non-null clazz";

    // this is required to be called before instances are instantiated
    clazz->onDump = onDump;
}

void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) {
void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) {
    CHECK(who == mWho);
    CHECK(who == mWho);


@@ -325,6 +358,30 @@ binder_status_t AIBinder_ping(AIBinder* binder) {
    return PruneStatusT(binder->getBinder()->pingBinder());
    return PruneStatusT(binder->getBinder()->pingBinder());
}
}


binder_status_t AIBinder_dump(AIBinder* binder, int fd, const char** args, uint32_t numArgs) {
    if (binder == nullptr) {
        return STATUS_UNEXPECTED_NULL;
    }

    ABBinder* bBinder = binder->asABBinder();
    if (bBinder != nullptr) {
        AIBinder_onDump onDump = binder->getClass()->onDump;
        if (onDump == nullptr) {
            return STATUS_OK;
        }
        return PruneStatusT(onDump(bBinder, fd, args, numArgs));
    }

    ::android::Vector<String16> utf16Args;
    utf16Args.setCapacity(numArgs);
    for (uint32_t i = 0; i < numArgs; i++) {
        utf16Args.push(String16(String8(args[i])));
    }

    status_t status = binder->getBinder()->dump(fd, utf16Args);
    return PruneStatusT(status);
}

binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                     void* cookie) {
                                     void* cookie) {
    if (binder == nullptr || recipient == nullptr) {
    if (binder == nullptr || recipient == nullptr) {
+6 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@


#include <binder/Binder.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IBinder.h>
#include <utils/Vector.h>


inline bool isUserCommand(transaction_code_t code) {
inline bool isUserCommand(transaction_code_t code) {
    return code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION;
    return code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION;
@@ -66,6 +67,7 @@ struct ABBinder : public AIBinder, public ::android::BBinder {
    ABBinder* asABBinder() override { return this; }
    ABBinder* asABBinder() override { return this; }


    const ::android::String16& getInterfaceDescriptor() const override;
    const ::android::String16& getInterfaceDescriptor() const override;
    ::android::status_t dump(int fd, const ::android::Vector<::android::String16>& args) override;
    ::android::status_t onTransact(uint32_t code, const ::android::Parcel& data,
    ::android::status_t onTransact(uint32_t code, const ::android::Parcel& data,
                                   ::android::Parcel* reply, binder_flags_t flags) override;
                                   ::android::Parcel* reply, binder_flags_t flags) override;


@@ -106,10 +108,14 @@ struct AIBinder_Class {


    const ::android::String16& getInterfaceDescriptor() const { return mInterfaceDescriptor; }
    const ::android::String16& getInterfaceDescriptor() const { return mInterfaceDescriptor; }


    // required to be non-null, implemented for every class
    const AIBinder_Class_onCreate onCreate;
    const AIBinder_Class_onCreate onCreate;
    const AIBinder_Class_onDestroy onDestroy;
    const AIBinder_Class_onDestroy onDestroy;
    const AIBinder_Class_onTransact onTransact;
    const AIBinder_Class_onTransact onTransact;


    // optional methods for a class
    AIBinder_onDump onDump;

   private:
   private:
    // This must be a String16 since BBinder virtual getInterfaceDescriptor returns a reference to
    // This must be a String16 since BBinder virtual getInterfaceDescriptor returns a reference to
    // one.
    // one.
+40 −0
Original line number Original line Diff line number Diff line
@@ -178,6 +178,31 @@ __attribute__((warn_unused_result)) AIBinder_Class* AIBinder_Class_define(
        AIBinder_Class_onDestroy onDestroy, AIBinder_Class_onTransact onTransact)
        AIBinder_Class_onDestroy onDestroy, AIBinder_Class_onTransact onTransact)
        __INTRODUCED_IN(29);
        __INTRODUCED_IN(29);


/**
 * Dump information about an AIBinder (usually for debugging).
 *
 * When no arguments are provided, a brief overview of the interview should be given.
 *
 * \param binder interface being dumped
 * \param fd file descriptor to be dumped to, should be flushed, ownership is not passed.
 * \param args array of null-terminated strings for dump (may be null if numArgs is 0)
 * \param numArgs number of args to be sent
 *
 * \return binder_status_t result of transaction (if remote, for instance)
 */
typedef binder_status_t (*AIBinder_onDump)(AIBinder* binder, int fd, const char** args,
                                           uint32_t numArgs);

/**
 * This sets the implementation of the dump method for a class.
 *
 * If this isn't set, nothing will be dumped when dump is called (for instance with
 * android.os.Binder#dump). Must be called before any instance of the class is created.
 *
 * \param dump function to call when an instance of this binder class is being dumped.
 */
void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) __INTRODUCED_IN(29);

/**
/**
 * Creates a new binder object of the appropriate class.
 * Creates a new binder object of the appropriate class.
 *
 *
@@ -236,6 +261,21 @@ bool AIBinder_isAlive(const AIBinder* binder) __INTRODUCED_IN(29);
 */
 */
binder_status_t AIBinder_ping(AIBinder* binder) __INTRODUCED_IN(29);
binder_status_t AIBinder_ping(AIBinder* binder) __INTRODUCED_IN(29);


/**
 * Built-in transaction for all binder objects. This dumps information about a given binder.
 *
 * See also AIBinder_Class_setOnDump, AIBinder_onDump
 *
 * \param binder the binder to dump information about
 * \param fd where information should be dumped to
 * \param args null-terminated arguments to pass (may be null if numArgs is 0)
 * \param numArgs number of args to send
 *
 * \return STATUS_OK if dump succeeds (or if there is nothing to dump)
 */
binder_status_t AIBinder_dump(AIBinder* binder, int fd, const char** args, uint32_t numArgs)
        __INTRODUCED_IN(29);

/**
/**
 * Registers for notifications that the associated binder is dead. The same death recipient may be
 * Registers for notifications that the associated binder is dead. The same death recipient may be
 * associated with multiple different binders. If the binder is local, then no death recipient will
 * associated with multiple different binders. If the binder is local, then no death recipient will
+28 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,30 @@ class ICInterface : public SharedRefBase {
     * this will be checked using AIBinder_isRemote.
     * this will be checked using AIBinder_isRemote.
     */
     */
    virtual bool isRemote() = 0;
    virtual bool isRemote() = 0;

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

    /**
     * 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;
    }
};
};


/**
/**
@@ -144,6 +168,10 @@ class BpCInterface : public INTERFACE {


    bool isRemote() override { return AIBinder_isRemote(mBinder.get()); }
    bool isRemote() override { return AIBinder_isRemote(mBinder.get()); }


    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override {
        return AIBinder_dump(asBinder().get(), fd, args, numArgs);
    }

   private:
   private:
    SpAIBinder mBinder;
    SpAIBinder mBinder;
};
};
+2 −0
Original line number Original line Diff line number Diff line
@@ -2,10 +2,12 @@ LIBBINDER_NDK { # introduced=29
  global:
  global:
    AIBinder_associateClass;
    AIBinder_associateClass;
    AIBinder_Class_define;
    AIBinder_Class_define;
    AIBinder_Class_setOnDump;
    AIBinder_DeathRecipient_delete;
    AIBinder_DeathRecipient_delete;
    AIBinder_DeathRecipient_new;
    AIBinder_DeathRecipient_new;
    AIBinder_debugGetRefCount;
    AIBinder_debugGetRefCount;
    AIBinder_decStrong;
    AIBinder_decStrong;
    AIBinder_dump;
    AIBinder_fromJavaBinder;
    AIBinder_fromJavaBinder;
    AIBinder_getCallingPid;
    AIBinder_getCallingPid;
    AIBinder_getCallingUid;
    AIBinder_getCallingUid;