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

Commit 86bd9358 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5389215 from 8760599e to qt-release

Change-Id: Id50b186e840b32d792a06f0932acbd3687514324
parents 04bcf4ee 8760599e
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -63,6 +63,26 @@ Status Status::fromStatusT(status_t status) {
    return ret;
}

std::string Status::exceptionToString(int32_t exceptionCode) {
    switch (exceptionCode) {
        #define EXCEPTION_TO_CASE(EXCEPTION) case EXCEPTION: return #EXCEPTION;
        EXCEPTION_TO_CASE(EX_NONE)
        EXCEPTION_TO_CASE(EX_SECURITY)
        EXCEPTION_TO_CASE(EX_BAD_PARCELABLE)
        EXCEPTION_TO_CASE(EX_ILLEGAL_ARGUMENT)
        EXCEPTION_TO_CASE(EX_NULL_POINTER)
        EXCEPTION_TO_CASE(EX_ILLEGAL_STATE)
        EXCEPTION_TO_CASE(EX_NETWORK_MAIN_THREAD)
        EXCEPTION_TO_CASE(EX_UNSUPPORTED_OPERATION)
        EXCEPTION_TO_CASE(EX_SERVICE_SPECIFIC)
        EXCEPTION_TO_CASE(EX_PARCELABLE)
        EXCEPTION_TO_CASE(EX_HAS_REPLY_HEADER)
        EXCEPTION_TO_CASE(EX_TRANSACTION_FAILED)
        #undef EXCEPTION_TO_CASE
        default: return std::to_string(exceptionCode);
    }
}

Status::Status(int32_t exceptionCode, int32_t errorCode)
    : mException(exceptionCode),
      mErrorCode(errorCode) {}
@@ -184,7 +204,7 @@ String8 Status::toString8() const {
    if (mException == EX_NONE) {
        ret.append("No error");
    } else {
        ret.appendFormat("Status(%d): '", mException);
        ret.appendFormat("Status(%d, %s): '", mException, exceptionToString(mException).c_str());
        if (mException == EX_SERVICE_SPECIFIC ||
            mException == EX_TRANSACTION_FAILED) {
            ret.appendFormat("%d: ", mErrorCode);
+3 −0
Original line number Diff line number Diff line
@@ -143,6 +143,9 @@ public:
     * dies.  The @a cookie is optional.  If non-NULL, you can
     * supply a NULL @a recipient, and the recipient previously
     * added with that cookie will be unlinked.
     *
     * If the binder is dead, this will return DEAD_OBJECT. Deleting
     * the object will also unlink all death recipients.
     */
    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t        unlinkToDeath(  const wp<DeathRecipient>& recipient,
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

#include <binder/Parcel.h>
#include <utils/String8.h>
#include <string>

namespace android {
namespace binder {
@@ -97,6 +98,8 @@ public:

    static Status fromStatusT(status_t status);

    static std::string exceptionToString(status_t exceptionCode);

    Status() = default;
    ~Status() = default;

+38 −10
Original line number Diff line number Diff line
@@ -269,6 +269,18 @@ void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinde
    CHECK(who == mWho);

    mOnDied(mCookie);

    sp<AIBinder_DeathRecipient> recipient = mParentRecipient.promote();
    sp<IBinder> strongWho = who.promote();

    // otherwise this will be cleaned up later with pruneDeadTransferEntriesLocked
    if (recipient != nullptr && strongWho != nullptr) {
        status_t result = recipient->unlinkToDeath(strongWho, mCookie);
        if (result != ::android::DEAD_OBJECT) {
            LOG(WARNING) << "Unlinking to dead binder resulted in: " << result;
        }
    }

    mWho = nullptr;
}

@@ -277,24 +289,34 @@ AIBinder_DeathRecipient::AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinde
    CHECK(onDied != nullptr);
}

binder_status_t AIBinder_DeathRecipient::linkToDeath(AIBinder* binder, void* cookie) {
void AIBinder_DeathRecipient::pruneDeadTransferEntriesLocked() {
    mDeathRecipients.erase(std::remove_if(mDeathRecipients.begin(), mDeathRecipients.end(),
                                          [](const sp<TransferDeathRecipient>& tdr) {
                                              return tdr->getWho() == nullptr;
                                          }),
                           mDeathRecipients.end());
}

binder_status_t AIBinder_DeathRecipient::linkToDeath(sp<IBinder> binder, void* cookie) {
    CHECK(binder != nullptr);

    std::lock_guard<std::mutex> l(mDeathRecipientsMutex);

    sp<TransferDeathRecipient> recipient =
            new TransferDeathRecipient(binder->getBinder(), cookie, mOnDied);
            new TransferDeathRecipient(binder, cookie, this, mOnDied);

    status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/);
    status_t status = binder->linkToDeath(recipient, cookie, 0 /*flags*/);
    if (status != STATUS_OK) {
        return PruneStatusT(status);
    }

    mDeathRecipients.push_back(recipient);

    pruneDeadTransferEntriesLocked();
    return STATUS_OK;
}

binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* cookie) {
binder_status_t AIBinder_DeathRecipient::unlinkToDeath(sp<IBinder> binder, void* cookie) {
    CHECK(binder != nullptr);

    std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
@@ -302,10 +324,10 @@ binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* c
    for (auto it = mDeathRecipients.rbegin(); it != mDeathRecipients.rend(); ++it) {
        sp<TransferDeathRecipient> recipient = *it;

        if (recipient->getCookie() == cookie && recipient->getWho() == binder->getBinder()) {
        if (recipient->getCookie() == cookie && recipient->getWho() == binder) {
            mDeathRecipients.erase(it.base() - 1);

            status_t status = binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/);
            status_t status = binder->unlinkToDeath(recipient, cookie, 0 /*flags*/);
            if (status != ::android::OK) {
                LOG(ERROR) << __func__
                           << ": removed reference to death recipient but unlink failed.";
@@ -390,7 +412,7 @@ binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient*
    }

    // returns binder_status_t
    return recipient->linkToDeath(binder, cookie);
    return recipient->linkToDeath(binder->getBinder(), cookie);
}

binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
@@ -401,7 +423,7 @@ binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient
    }

    // returns binder_status_t
    return recipient->unlinkToDeath(binder, cookie);
    return recipient->unlinkToDeath(binder->getBinder(), cookie);
}

uid_t AIBinder_getCallingUid() {
@@ -555,9 +577,15 @@ AIBinder_DeathRecipient* AIBinder_DeathRecipient_new(
        LOG(ERROR) << __func__ << ": requires non-null onBinderDied parameter.";
        return nullptr;
    }
    return new AIBinder_DeathRecipient(onBinderDied);
    auto ret = new AIBinder_DeathRecipient(onBinderDied);
    ret->incStrong(nullptr);
    return ret;
}

void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) {
    delete recipient;
    if (recipient == nullptr) {
        return;
    }

    recipient->decStrong(nullptr);
}
+15 −4
Original line number Diff line number Diff line
@@ -128,13 +128,14 @@ struct AIBinder_Class {
//
// When the AIBinder_DeathRecipient is dropped, so are the actual underlying death recipients. When
// the IBinder dies, only a wp to it is kept.
struct AIBinder_DeathRecipient {
struct AIBinder_DeathRecipient : ::android::RefBase {
    // One of these is created for every linkToDeath. This is to be able to recover data when a
    // binderDied receipt only gives us information about the IBinder.
    struct TransferDeathRecipient : ::android::IBinder::DeathRecipient {
        TransferDeathRecipient(const ::android::wp<::android::IBinder>& who, void* cookie,
                               const ::android::wp<AIBinder_DeathRecipient>& parentRecipient,
                               const AIBinder_DeathRecipient_onBinderDied onDied)
            : mWho(who), mCookie(cookie), mOnDied(onDied) {}
            : mWho(who), mCookie(cookie), mParentRecipient(parentRecipient), mOnDied(onDied) {}

        void binderDied(const ::android::wp<::android::IBinder>& who) override;

@@ -144,14 +145,24 @@ struct AIBinder_DeathRecipient {
       private:
        ::android::wp<::android::IBinder> mWho;
        void* mCookie;

        ::android::wp<AIBinder_DeathRecipient> mParentRecipient;

        // This is kept separately from AIBinder_DeathRecipient in case the death recipient is
        // deleted while the death notification is fired
        const AIBinder_DeathRecipient_onBinderDied mOnDied;
    };

    explicit AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied);
    binder_status_t linkToDeath(AIBinder* binder, void* cookie);
    binder_status_t unlinkToDeath(AIBinder* binder, void* cookie);
    binder_status_t linkToDeath(::android::sp<::android::IBinder>, void* cookie);
    binder_status_t unlinkToDeath(::android::sp<::android::IBinder> binder, void* cookie);

   private:
    // When the user of this API deletes a Bp object but not the death recipient, the
    // TransferDeathRecipient object can't be cleaned up. This is called whenever a new
    // TransferDeathRecipient is linked, and it ensures that mDeathRecipients can't grow unbounded.
    void pruneDeadTransferEntriesLocked();

    std::mutex mDeathRecipientsMutex;
    std::vector<::android::sp<TransferDeathRecipient>> mDeathRecipients;
    AIBinder_DeathRecipient_onBinderDied mOnDied;
Loading