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

Commit 71872f8a authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder_ndk: recombine allocators/getters

Since they are tightly coupled, these have been combined together.

Primitive arrays/strings look like this:
    AParcel_write...(parcel, T*, length);
    AParcel_read...(parcel, void*, allocator);

With the exception of boolean which looks like this:
    AParcel_write...(parcel, void*, length, getter)
    AParcel_read...(parcel, void*, allocator, setter)

The difference in boolean is because boolean values are not necessarily
stored contiguously in memory in most implementations (rather they are
stored in more complicated bitsets), and so this representation easily
allows for this efficient storage when these items are not being
transported over binder.

Bug: 111445392
Test: atest android.binder.cts
Change-Id: Ic1645a315f31c8ef35c0a90aa42b96ec55515912
parent eddf8dd3
Loading
Loading
Loading
Loading
+123 −68
Original line number Diff line number Diff line
@@ -50,98 +50,128 @@ typedef struct AParcel AParcel;
 */
void AParcel_delete(AParcel* parcel) __INTRODUCED_IN(29);

// @START-PRIMITIVE-VECTOR-GETTERS
/**
 * This is called to allocate an array with a given length. If allocation fails, null should be
 * This is called to get the underlying data from an arrayData object.
 *
 * The implementation of this function should allocate a contiguous array of length length and
 * return that underlying buffer to be filled out. If there is an error or length is 0, null may be
 * returned.
 *
 * See also AParcel_readInt32Array
 */
typedef void* (*AParcel_arrayReallocator)(void* vectorData, size_t length);
typedef int32_t* (*AParcel_int32Allocator)(void* arrayData, size_t length);

// @START-PRIMITIVE-VECTOR-GETTERS
/**
 * This is called to get the underlying data from an arrayData object.
 *
 * This will never be called for an empty array.
 * The implementation of this function should allocate a contiguous array of length length and
 * return that underlying buffer to be filled out. If there is an error or length is 0, null may be
 * returned.
 *
 * See also AParcel_readUint32Array
 */
typedef int32_t* (*AParcel_int32ArrayGetter)(void* arrayData);
typedef uint32_t* (*AParcel_uint32Allocator)(void* arrayData, size_t length);

/**
 * This is called to get the underlying data from an arrayData object.
 *
 * This will never be called for an empty array.
 * The implementation of this function should allocate a contiguous array of length length and
 * return that underlying buffer to be filled out. If there is an error or length is 0, null may be
 * returned.
 *
 * See also AParcel_readInt64Array
 */
typedef uint32_t* (*AParcel_uint32ArrayGetter)(void* arrayData);
typedef int64_t* (*AParcel_int64Allocator)(void* arrayData, size_t length);

/**
 * This is called to get the underlying data from an arrayData object.
 *
 * This will never be called for an empty array.
 * The implementation of this function should allocate a contiguous array of length length and
 * return that underlying buffer to be filled out. If there is an error or length is 0, null may be
 * returned.
 *
 * See also AParcel_readUint64Array
 */
typedef int64_t* (*AParcel_int64ArrayGetter)(void* arrayData);
typedef uint64_t* (*AParcel_uint64Allocator)(void* arrayData, size_t length);

/**
 * This is called to get the underlying data from an arrayData object.
 *
 * This will never be called for an empty array.
 * The implementation of this function should allocate a contiguous array of length length and
 * return that underlying buffer to be filled out. If there is an error or length is 0, null may be
 * returned.
 *
 * See also AParcel_readFloatArray
 */
typedef uint64_t* (*AParcel_uint64ArrayGetter)(void* arrayData);
typedef float* (*AParcel_floatAllocator)(void* arrayData, size_t length);

/**
 * This is called to get the underlying data from an arrayData object.
 *
 * This will never be called for an empty array.
 * The implementation of this function should allocate a contiguous array of length length and
 * return that underlying buffer to be filled out. If there is an error or length is 0, null may be
 * returned.
 *
 * See also AParcel_readDoubleArray
 */
typedef float* (*AParcel_floatArrayGetter)(void* arrayData);
typedef double* (*AParcel_doubleAllocator)(void* arrayData, size_t length);

/**
 * This is called to get the underlying data from an arrayData object.
 * This allocates an array of length length inside of arrayData and returns whether or not there was
 * a success.
 *
 * This will never be called for an empty array.
 * See also AParcel_readBoolArray
 */
typedef double* (*AParcel_doubleArrayGetter)(void* arrayData);
typedef bool (*AParcel_boolAllocator)(void* arrayData, size_t length);

/**
 * This is called to get the underlying data from an arrayData object.
 * This is called to get the underlying data from an arrayData object at index.
 *
 * This will never be called for an empty array.
 * See also AParcel_writeBoolArray
 */
typedef bool (*AParcel_boolArrayGetter)(const void* arrayData, size_t index);

/**
 * This is called to set an underlying value in an arrayData object at index.
 *
 * See also AParcel_readBoolArray
 */
typedef void (*AParcel_boolArraySetter)(void* arrayData, size_t index, bool value);

/**
 * This is called to get the underlying data from an arrayData object.
 *
 * This will never be called for an empty array.
 * The implementation of this function should allocate a contiguous array of length length and
 * return that underlying buffer to be filled out. If there is an error or length is 0, null may be
 * returned.
 *
 * See also AParcel_readCharArray
 */
typedef char16_t* (*AParcel_charArrayGetter)(void* arrayData);
typedef char16_t* (*AParcel_charAllocator)(void* arrayData, size_t length);

/**
 * This is called to get the underlying data from an arrayData object.
 *
 * This will never be called for an empty array.
 * The implementation of this function should allocate a contiguous array of length length and
 * return that underlying buffer to be filled out. If there is an error or length is 0, null may be
 * returned.
 *
 * See also AParcel_readByteArray
 */
typedef int8_t* (*AParcel_byteArrayGetter)(void* arrayData);
typedef int8_t* (*AParcel_byteAllocator)(void* arrayData, size_t length);

// @END-PRIMITIVE-VECTOR-GETTERS

/**
 * This is called to allocate a buffer
 * This is called to allocate a buffer for a C-style string (null-terminated). The buffer should be
 * of length length which includes space for the null-terminator.
 *
 * The length here includes the space required to insert a '\0' for a properly formed c-str. If the
 * buffer returned from this function is retStr, it will be filled by AParcel_readString with the
 * data from the remote process, and it will be filled such that retStr[length] == '\0'.
 * See also AParcel_readString.
 *
 * If allocation fails, null should be returned.
 */
typedef void* (*AParcel_stringReallocator)(void* stringData, size_t length);

/**
 * This is called to get the buffer from a stringData object.
 */
typedef char* (*AParcel_stringGetter)(void* stringData);
typedef char* (*AParcel_stringAllocator)(void* stringData, size_t length);

/**
 * Writes an AIBinder to the next location in a non-null parcel. Can be null.
@@ -190,17 +220,12 @@ binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t
/**
 * Reads and allocates string value from the next location in a non-null parcel.
 *
 * Data is passed to the string allocator once the string size is known. This data should be used to
 * point to some kind of string data. For instance, it could be a char*, and the string allocator
 * could be realloc. Then the getter would simply be a cast to char*. In more complicated cases,
 * stringData could be a structure containing additional string data.
 *
 * If this function returns a success, the buffer returned by allocator when passed stringData will
 * contain a null-terminated c-str read from the binder.
 * Data is passed to the string allocator once the string size is known. This size includes the
 * space for the null-terminator of this string. This allocator returns a buffer which is used as
 * the output buffer from this read.
 */
binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringReallocator reallocator,
                                   AParcel_stringGetter getter, void** stringData)
        __INTRODUCED_IN(29);
binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringAllocator allocator,
                                   void* stringData) __INTRODUCED_IN(29);

// @START-PRIMITIVE-READ-WRITE
/**
@@ -331,6 +356,9 @@ binder_status_t AParcel_writeDoubleArray(AParcel* parcel, const double* value, s

/**
 * Writes an array of bool to the next location in a non-null parcel.
 *
 * getter(arrayData, i) will be called for each i in [0, length) in order to get the underlying
 * values to write to the parcel.
 */
binder_status_t AParcel_writeBoolArray(AParcel* parcel, const void* arrayData,
                                       AParcel_boolArrayGetter getter, size_t length)
@@ -350,66 +378,93 @@ binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* value, siz

/**
 * Reads an array of int32_t from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. If the allocation succeeds and the
 * length is greater than zero, the buffer returned by the allocator will be filled with the
 * corresponding data
 */
binder_status_t AParcel_readInt32Array(const AParcel* parcel, void** arrayData,
                                       AParcel_arrayReallocator reallocator,
                                       AParcel_int32ArrayGetter getter) __INTRODUCED_IN(29);
binder_status_t AParcel_readInt32Array(const AParcel* parcel, void* arrayData,
                                       AParcel_int32Allocator allocator) __INTRODUCED_IN(29);

/**
 * Reads an array of uint32_t from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. If the allocation succeeds and the
 * length is greater than zero, the buffer returned by the allocator will be filled with the
 * corresponding data
 */
binder_status_t AParcel_readUint32Array(const AParcel* parcel, void** arrayData,
                                        AParcel_arrayReallocator reallocator,
                                        AParcel_uint32ArrayGetter getter) __INTRODUCED_IN(29);
binder_status_t AParcel_readUint32Array(const AParcel* parcel, void* arrayData,
                                        AParcel_uint32Allocator allocator) __INTRODUCED_IN(29);

/**
 * Reads an array of int64_t from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. If the allocation succeeds and the
 * length is greater than zero, the buffer returned by the allocator will be filled with the
 * corresponding data
 */
binder_status_t AParcel_readInt64Array(const AParcel* parcel, void** arrayData,
                                       AParcel_arrayReallocator reallocator,
                                       AParcel_int64ArrayGetter getter) __INTRODUCED_IN(29);
binder_status_t AParcel_readInt64Array(const AParcel* parcel, void* arrayData,
                                       AParcel_int64Allocator allocator) __INTRODUCED_IN(29);

/**
 * Reads an array of uint64_t from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. If the allocation succeeds and the
 * length is greater than zero, the buffer returned by the allocator will be filled with the
 * corresponding data
 */
binder_status_t AParcel_readUint64Array(const AParcel* parcel, void** arrayData,
                                        AParcel_arrayReallocator reallocator,
                                        AParcel_uint64ArrayGetter getter) __INTRODUCED_IN(29);
binder_status_t AParcel_readUint64Array(const AParcel* parcel, void* arrayData,
                                        AParcel_uint64Allocator allocator) __INTRODUCED_IN(29);

/**
 * Reads an array of float from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. If the allocation succeeds and the
 * length is greater than zero, the buffer returned by the allocator will be filled with the
 * corresponding data
 */
binder_status_t AParcel_readFloatArray(const AParcel* parcel, void** arrayData,
                                       AParcel_arrayReallocator reallocator,
                                       AParcel_floatArrayGetter getter) __INTRODUCED_IN(29);
binder_status_t AParcel_readFloatArray(const AParcel* parcel, void* arrayData,
                                       AParcel_floatAllocator allocator) __INTRODUCED_IN(29);

/**
 * Reads an array of double from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. If the allocation succeeds and the
 * length is greater than zero, the buffer returned by the allocator will be filled with the
 * corresponding data
 */
binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void** arrayData,
                                        AParcel_arrayReallocator reallocator,
                                        AParcel_doubleArrayGetter getter) __INTRODUCED_IN(29);
binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void* arrayData,
                                        AParcel_doubleAllocator allocator) __INTRODUCED_IN(29);

/**
 * Reads an array of bool from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. Then, for every i in [0, length),
 * setter(arrayData, i, x) will be called where x is the value at the associated index.
 */
binder_status_t AParcel_readBoolArray(const AParcel* parcel, void** arrayData,
                                      AParcel_arrayReallocator reallocator,
binder_status_t AParcel_readBoolArray(const AParcel* parcel, void* arrayData,
                                      AParcel_boolAllocator allocator,
                                      AParcel_boolArraySetter setter) __INTRODUCED_IN(29);

/**
 * Reads an array of char16_t from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. If the allocation succeeds and the
 * length is greater than zero, the buffer returned by the allocator will be filled with the
 * corresponding data
 */
binder_status_t AParcel_readCharArray(const AParcel* parcel, void** arrayData,
                                      AParcel_arrayReallocator reallocator,
                                      AParcel_charArrayGetter getter) __INTRODUCED_IN(29);
binder_status_t AParcel_readCharArray(const AParcel* parcel, void* arrayData,
                                      AParcel_charAllocator allocator) __INTRODUCED_IN(29);

/**
 * Reads an array of int8_t from the next location in a non-null parcel.
 *
 * First, allocator will be called with the length of the array. If the allocation succeeds and the
 * length is greater than zero, the buffer returned by the allocator will be filled with the
 * corresponding data
 */
binder_status_t AParcel_readByteArray(const AParcel* parcel, void** arrayData,
                                      AParcel_arrayReallocator reallocator,
                                      AParcel_byteArrayGetter getter) __INTRODUCED_IN(29);
binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData,
                                      AParcel_byteAllocator allocator) __INTRODUCED_IN(29);

// @END-PRIMITIVE-READ-WRITE

+23 −38
Original line number Diff line number Diff line
@@ -36,24 +36,26 @@
namespace ndk {

/**
 * This resizes a std::vector of some underlying type to the given length.
 * This retrieves and allocates a vector to length length and returns the underlying buffer.
 */
template <typename T>
static inline void* AParcel_stdVectorReallocator(void* vectorData, size_t length) {
static inline T* AParcel_stdVectorAllocator(void* vectorData, size_t length) {
    std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
    if (length > vec->max_size()) return nullptr;

    vec->resize(length);
    return vec;
    return vec->data();
}

/**
 * This retrieves the underlying contiguous vector from a corresponding vectorData.
 * This allocates a vector to length length and returns whether the allocation is successful.
 */
template <typename T>
static inline T* AParcel_stdVectorGetter(void* vectorData) {
    std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
    return vec->data();
static inline bool AParcel_stdVectorBoolAllocator(void* vectorData, size_t length) {
    std::vector<bool>* vec = static_cast<std::vector<bool>*>(vectorData);
    if (length > vec->max_size()) return false;

    vec->resize(length);
    return true;
}

/**
@@ -89,8 +91,7 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<in
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int32_t>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readInt32Array(parcel, &vectorData, &AParcel_stdVectorReallocator<int32_t>,
                                  AParcel_stdVectorGetter<int32_t>);
    return AParcel_readInt32Array(parcel, vectorData, AParcel_stdVectorAllocator<int32_t>);
}

/**
@@ -105,8 +106,7 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<ui
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint32_t>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readUint32Array(parcel, &vectorData, &AParcel_stdVectorReallocator<uint32_t>,
                                   AParcel_stdVectorGetter<uint32_t>);
    return AParcel_readUint32Array(parcel, vectorData, AParcel_stdVectorAllocator<uint32_t>);
}

/**
@@ -121,8 +121,7 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<in
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int64_t>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readInt64Array(parcel, &vectorData, &AParcel_stdVectorReallocator<int64_t>,
                                  AParcel_stdVectorGetter<int64_t>);
    return AParcel_readInt64Array(parcel, vectorData, AParcel_stdVectorAllocator<int64_t>);
}

/**
@@ -137,8 +136,7 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<ui
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint64_t>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readUint64Array(parcel, &vectorData, &AParcel_stdVectorReallocator<uint64_t>,
                                   AParcel_stdVectorGetter<uint64_t>);
    return AParcel_readUint64Array(parcel, vectorData, AParcel_stdVectorAllocator<uint64_t>);
}

/**
@@ -153,8 +151,7 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<fl
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<float>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readFloatArray(parcel, &vectorData, &AParcel_stdVectorReallocator<float>,
                                  AParcel_stdVectorGetter<float>);
    return AParcel_readFloatArray(parcel, vectorData, AParcel_stdVectorAllocator<float>);
}

/**
@@ -169,8 +166,7 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<do
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<double>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readDoubleArray(parcel, &vectorData, &AParcel_stdVectorReallocator<double>,
                                   AParcel_stdVectorGetter<double>);
    return AParcel_readDoubleArray(parcel, vectorData, AParcel_stdVectorAllocator<double>);
}

/**
@@ -186,7 +182,7 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<bo
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<bool>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readBoolArray(parcel, &vectorData, &AParcel_stdVectorReallocator<bool>,
    return AParcel_readBoolArray(parcel, vectorData, AParcel_stdVectorBoolAllocator,
                                 AParcel_stdVectorSetter<bool>);
}

@@ -202,8 +198,7 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<ch
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<char16_t>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readCharArray(parcel, &vectorData, &AParcel_stdVectorReallocator<char16_t>,
                                 AParcel_stdVectorGetter<char16_t>);
    return AParcel_readCharArray(parcel, vectorData, AParcel_stdVectorAllocator<char16_t>);
}

/**
@@ -218,27 +213,18 @@ inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<in
 */
inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int8_t>* vec) {
    void* vectorData = static_cast<void*>(vec);
    return AParcel_readByteArray(parcel, &vectorData, &AParcel_stdVectorReallocator<int8_t>,
                                 AParcel_stdVectorGetter<int8_t>);
    return AParcel_readByteArray(parcel, vectorData, AParcel_stdVectorAllocator<int8_t>);
}

// @END

/**
 * Takes a std::string and reallocates it to the specified length. For use with AParcel_readString.
 * See use below in AParcel_readString.
 * Allocates a std::string to length and returns the underlying buffer. For use with
 * AParcel_readString. See use below in AParcel_readString(const AParcel*, std::string*).
 */
static inline void* AParcel_stdStringReallocator(void* stringData, size_t length) {
static inline char* AParcel_stdStringAllocator(void* stringData, size_t length) {
    std::string* str = static_cast<std::string*>(stringData);
    str->resize(length - 1);
    return stringData;
}

/**
 * Takes a std::string and returns the inner char*.
 */
static inline char* AParcel_stdStringGetter(void* stringData) {
    std::string* str = static_cast<std::string*>(stringData);
    return &(*str)[0];
}

@@ -254,8 +240,7 @@ static inline binder_status_t AParcel_writeString(AParcel* parcel, const std::st
 */
static inline binder_status_t AParcel_readString(const AParcel* parcel, std::string* str) {
    void* stringData = static_cast<void*>(str);
    return AParcel_readString(parcel, AParcel_stdStringReallocator, AParcel_stdStringGetter,
                              &stringData);
    return AParcel_readString(parcel, AParcel_stdStringAllocator, stringData);
}

template <typename T>
+45 −67

File changed.

Preview size limit exceeded, changes collapsed.

+57 −29

File changed.

Preview size limit exceeded, changes collapsed.