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

Commit fb39f9c0 authored by Yu Shan's avatar Yu Shan
Browse files

Add marshal() and unmarshal() APIs.

Expose marshal/unmarshal APIs from binder_ndk because we need
to pass large data that exceeds binder memory limitation across
binder for auto use case. We need to serialize parcel to a shared
memory file and unmarshal it into a parcel. We would only marshal
stable AIDL generated parcelable.

Test: Add a unit test to CTS.
Bug: 197781220
Change-Id: I774663d619ad0ca04f23044d2245021b265b32c1
parent 33e1d32c
Loading
Loading
Loading
Loading
+35 −0
Original line number Original line Diff line number Diff line
@@ -1163,6 +1163,41 @@ binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t sta
 * \return A parcel which is not related to any IBinder objects.
 * \return A parcel which is not related to any IBinder objects.
 */
 */
AParcel* AParcel_create() __INTRODUCED_IN(31);
AParcel* AParcel_create() __INTRODUCED_IN(31);

/**
 * Marshals the raw bytes of the Parcel to a buffer.
 *
 * The parcel must not contain any binders or file descriptors.
 *
 * The data you retrieve here must not be placed in any kind of persistent storage. (on local disk,
 * across a network, etc). For that, you should use standard serialization or another kind of
 * general serialization mechanism. The Parcel marshalled representation is highly optimized for
 * local IPC, and as such does not attempt to maintain compatibility with data created in different
 * versions of the platform.
 *
 * \param parcel The parcel of which to get the data.
 * \param buffer The buffer to copy the raw bytes to.
 * \param start The start position in the buffer to copy from.
 * \param len The size of the data to copy, buffer size must be larger or equal to this.
 *
 * \return STATUS_OK on success, STATUS_INVALID_OPERATION if parcel contains binders or file
 * descriptors. STATUS_BAD_VALUE if the buffer size is less than parcel size.
 */
binder_status_t AParcel_marshal(const AParcel* parcel, uint8_t* buffer, size_t start, size_t len)
        __INTRODUCED_IN(33);

/**
 * Set the data in the parcel to the raw bytes from the buffer.
 *
 * \param parcel The parcel to set data.
 * \param buffer The data buffer to set.
 * \param len The size of the data to set.
 *
 * \return STATUS_OK on success.
 */
binder_status_t AParcel_unmarshal(AParcel* parcel, const uint8_t* buffer, size_t len)
        __INTRODUCED_IN(33);

__END_DECLS
__END_DECLS


/** @} */
/** @} */
+2 −0
Original line number Original line Diff line number Diff line
@@ -144,6 +144,8 @@ LIBBINDER_NDK31 { # introduced=31
LIBBINDER_NDK33 { # introduced=33
LIBBINDER_NDK33 { # introduced=33
  global:
  global:
    AIBinder_Class_disableInterfaceTokenHeader;
    AIBinder_Class_disableInterfaceTokenHeader;
    AParcel_marshal;
    AParcel_unmarshal;
};
};


LIBBINDER_NDK_PLATFORM {
LIBBINDER_NDK_PLATFORM {
+28 −0
Original line number Original line Diff line number Diff line
@@ -673,4 +673,32 @@ AParcel* AParcel_create() {
    return new AParcel(nullptr);
    return new AParcel(nullptr);
}
}


binder_status_t AParcel_marshal(const AParcel* parcel, uint8_t* buffer, size_t start, size_t len) {
    if (parcel->get()->objectsCount()) {
        return STATUS_INVALID_OPERATION;
    }
    int32_t dataSize = AParcel_getDataSize(parcel);
    if (len > static_cast<size_t>(dataSize) || start > static_cast<size_t>(dataSize) - len) {
        return STATUS_BAD_VALUE;
    }
    const uint8_t* internalBuffer = parcel->get()->data();
    memcpy(buffer, internalBuffer + start, len);
    return STATUS_OK;
}

binder_status_t AParcel_unmarshal(AParcel* parcel, const uint8_t* buffer, size_t len) {
    status_t status = parcel->get()->setDataSize(len);
    if (status != ::android::OK) {
        return PruneStatusT(status);
    }
    parcel->get()->setDataPosition(0);

    void* raw = parcel->get()->writeInplace(len);
    if (raw == nullptr) {
        return STATUS_NO_MEMORY;
    }
    memcpy(raw, buffer, len);
    return STATUS_OK;
}

// @END
// @END