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

Commit d56b3150 authored by Steven Moreland's avatar Steven Moreland Committed by Gerrit Code Review
Browse files

Merge "libbinder_ndk: finalizeTransaction->AParcel_delete"

parents c16ddeb1 caa776ce
Loading
Loading
Loading
Loading
+2 −37
Original line number Diff line number Diff line
@@ -279,12 +279,6 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) {
    return status;
}

using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>;
static void destroy_parcel(AParcel** parcel) {
    delete *parcel;
    *parcel = nullptr;
}

binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in,
                                  AParcel** out, binder_flags_t flags) {
    if (in == nullptr) {
@@ -292,9 +286,10 @@ binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, APa
        return EX_NULL_POINTER;
    }

    using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>;
    // This object is the input to the transaction. This function takes ownership of it and deletes
    // it.
    AutoParcelDestroyer forIn(in, destroy_parcel);
    AutoParcelDestroyer forIn(in, AParcel_delete);

    if (!isUserCommand(code)) {
        LOG(ERROR) << __func__ << ": Only user-defined transactions can be made from the NDK.";
@@ -329,33 +324,3 @@ binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, APa

    return parcelStatus;
}

binder_status_t AIBinder_finalizeTransaction(AIBinder* binder, AParcel** out) {
    if (out == nullptr) {
        LOG(ERROR) << __func__ << ": requires non-null out parameter";
        return EX_NULL_POINTER;
    }

    // This object is the input to the transaction. This function takes ownership of it and deletes
    // it.
    AutoParcelDestroyer forOut(out, destroy_parcel);

    if (binder == nullptr || *out == nullptr) {
        LOG(ERROR) << __func__ << ": requires non-null parameters.";
        return EX_NULL_POINTER;
    }

    if ((*out)->getBinder() != binder) {
        LOG(ERROR) << __func__ << ": parcel is associated with binder object " << binder
                   << " but called with " << (*out)->getBinder();
        return EX_ILLEGAL_STATE;
    }

    if ((**out)->dataAvail() != 0) {
        LOG(ERROR) << __func__
                   << ": Only part of this transaction was read. There is remaining data left.";
        return EX_ILLEGAL_STATE;
    }

    return EX_NONE;
}
+9 −0
Original line number Diff line number Diff line
@@ -25,6 +25,15 @@ using ::android::IBinder;
using ::android::Parcel;
using ::android::sp;

void AParcel_delete(AParcel** parcel) {
    if (parcel == nullptr) {
        return;
    }

    delete *parcel;
    *parcel = nullptr;
}

binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
    return (*parcel)->writeStrongBinder(binder->getBinder());
}
+8 −13
Original line number Diff line number Diff line
@@ -186,10 +186,9 @@ void* AIBinder_getUserData(AIBinder* binder);
/**
 * A transaction is a series of calls to these functions which looks this
 * - call AIBinder_prepareTransaction
 * - fill out parcel with in parameters (lifetime of the 'in' variable)
 * - fill out the in parcel with parameters (lifetime of the 'in' variable)
 * - call AIBinder_transact
 * - fill out parcel with out parameters (lifetime of the 'out' variable)
 * - call AIBinder_finalizeTransaction
 * - read results from the out parcel (lifetime of the 'out' variable)
 */

/**
@@ -200,7 +199,10 @@ void* AIBinder_getUserData(AIBinder* binder);
 * can be avoided. This AIBinder must be either built with a class or associated with a class before
 * using this API.
 *
 * This does not affect the ownership of binder.
 * This does not affect the ownership of binder. When this function succeeds, the in parcel's
 * ownership is passed to the caller. At this point, the parcel can be filled out and passed to
 * AIBinder_transact. Alternatively, if there is an error while filling out the parcel, it can be
 * deleted with AParcel_delete.
 */
binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in);

@@ -213,19 +215,12 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in);
 * remote process has processed the transaction, and the out parcel will contain the output data
 * from transaction.
 *
 * This does not affect the ownership of binder.
 * This does not affect the ownership of binder. The out parcel's ownership is passed to the caller
 * and must be released with AParcel_delete when finished reading.
 */
binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in,
                                  AParcel** out, binder_flags_t flags);

/**
 * This takes ownership of the out parcel and automatically deletes it. Additional checks for
 * security or debugging maybe performed internally.
 *
 * This does not affect the ownership of binder.
 */
binder_status_t AIBinder_finalizeTransaction(AIBinder* binder, AParcel** out);

/*
 * This does not take any ownership of the input binder, but it can be used to retrieve it if
 * something else in some process still holds a reference to it.
+5 −0
Original line number Diff line number Diff line
@@ -34,6 +34,11 @@ __BEGIN_DECLS
struct AParcel;
typedef struct AParcel AParcel;

/**
 * Cleans up a parcel and sets it to nullptr.
 */
void AParcel_delete(AParcel** parcel);

/**
 * Writes an AIBinder to the next location in a non-null parcel. Can be null.
 */
+2 −1
Original line number Diff line number Diff line
@@ -81,7 +81,8 @@ public:
        int32_t out;
        CHECK(EX_NONE == AParcel_readInt32(parcelOut, &out));

        CHECK(EX_NONE == AIBinder_finalizeTransaction(mBinder, &parcelOut));
        AParcel_delete(&parcelOut);

        return out;
    }