Loading libs/binder/ndk/include_ndk/android/binder_parcel.h +78 −23 Original line number Diff line number Diff line Loading @@ -50,11 +50,51 @@ typedef struct AParcel AParcel; */ void AParcel_delete(AParcel* parcel) __INTRODUCED_IN(29); /** * This is called to allocate a buffer for a C-style string (null-terminated). The returned buffer * should be at least length bytes. This includes space for a null terminator. length will always be * strictly less than or equal to the maximum size that can be held in a size_t and will always be * greater than 0. * * See also AParcel_readString. * * If allocation fails, null should be returned. */ typedef char* (*AParcel_stringAllocator)(void* stringData, size_t length); /** * This is called to allocate an array of size 'length'. * * See also AParcel_readStringArray */ typedef bool (*AParcel_stringArrayAllocator)(void* arrayData, size_t length); /** * This is called to allocate a string inside of an array that was allocated by an * AParcel_stringArrayAllocator. * * The index returned will always be within the range [0, length of arrayData). The returned buffer * should be at least length bytes. This includes space for a null-terminator. length will always be * strictly less than or equal to the maximum size that can be held in a size_t and will always be * greater than 0. * * See also AParcel_readStringArray */ typedef char* (*AParcel_stringArrayElementAllocator)(void* arrayData, size_t index, size_t length); /** * This returns the length and buffer of an array at a specific index in an arrayData object. * * See also AParcel_writeStringArray */ typedef const char* (*AParcel_stringArrayElementGetter)(const void* arrayData, size_t index, size_t* outLength); // @START-PRIMITIVE-VECTOR-GETTERS /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -65,7 +105,7 @@ typedef int32_t* (*AParcel_int32ArrayAllocator)(void* arrayData, size_t length); /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -76,7 +116,7 @@ typedef uint32_t* (*AParcel_uint32ArrayAllocator)(void* arrayData, size_t length /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -87,7 +127,7 @@ typedef int64_t* (*AParcel_int64ArrayAllocator)(void* arrayData, size_t length); /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -98,7 +138,7 @@ typedef uint64_t* (*AParcel_uint64ArrayAllocator)(void* arrayData, size_t length /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -109,7 +149,7 @@ typedef float* (*AParcel_floatArrayAllocator)(void* arrayData, size_t length); /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -118,7 +158,7 @@ typedef float* (*AParcel_floatArrayAllocator)(void* arrayData, size_t length); typedef double* (*AParcel_doubleArrayAllocator)(void* arrayData, size_t length); /** * This allocates an array of length length inside of arrayData and returns whether or not there was * This allocates an array of size 'length' inside of arrayData and returns whether or not there was * a success. * * See also AParcel_readBoolArray Loading @@ -142,7 +182,7 @@ typedef void (*AParcel_boolArraySetter)(void* arrayData, size_t index, bool valu /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -153,7 +193,7 @@ typedef char16_t* (*AParcel_charArrayAllocator)(void* arrayData, size_t length); /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -163,16 +203,6 @@ typedef int8_t* (*AParcel_byteArrayAllocator)(void* arrayData, size_t length); // @END-PRIMITIVE-VECTOR-GETTERS /** * 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. * * See also AParcel_readString. * * If allocation fails, null should be returned. */ typedef char* (*AParcel_stringAllocator)(void* stringData, size_t length); /** * Writes an AIBinder to the next location in a non-null parcel. Can be null. */ Loading Loading @@ -229,20 +259,45 @@ binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status __INTRODUCED_IN(29); /** * Writes string value to the next location in a non-null parcel. * Writes utf-8 string value to the next location in a non-null parcel. */ binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) __INTRODUCED_IN(29); /** * Reads and allocates string value from the next location in a non-null parcel. * Reads and allocates utf-8 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 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_stringAllocator allocator, void* stringData) __INTRODUCED_IN(29); binder_status_t AParcel_readString(const AParcel* parcel, void* stringData, AParcel_stringAllocator allocator) __INTRODUCED_IN(29); /** * Writes utf-8 string array data to the next location in a non-null parcel. * * length is the length of the array. AParcel_stringArrayElementGetter will be called for all * indices in range [0, length) with the arrayData provided here. The string length and buffer * returned from this function will be used to fill out the data from the parcel. */ binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, size_t length, AParcel_stringArrayElementGetter getter) __INTRODUCED_IN(29); /** * Reads and allocates utf-8 string array value from the next location in a non-null parcel. * * First, AParcel_stringArrayAllocator will be called with the size of the array to be read where * length is the length of the array to be read from the parcel. Then, for each index i in [0, * length), AParcel_stringArrayElementAllocator will be called with the length of the string to be * read from the parcel. The resultant buffer from each of these calls will be filled according to * the contents of the string that is read. */ binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData, AParcel_stringArrayAllocator allocator, AParcel_stringArrayElementAllocator elementAllocator) __INTRODUCED_IN(29); // @START-PRIMITIVE-READ-WRITE /** Loading libs/binder/ndk/include_ndk/android/binder_parcel_utils.h +61 −6 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ namespace ndk { /** * This retrieves and allocates a vector to length length and returns the underlying buffer. * This retrieves and allocates a vector to size 'length' and returns the underlying buffer. */ template <typename T> static inline T* AParcel_stdVectorAllocator(void* vectorData, size_t length) { Loading @@ -48,10 +48,18 @@ static inline T* AParcel_stdVectorAllocator(void* vectorData, size_t length) { } /** * This allocates a vector to length length and returns whether the allocation is successful. * This allocates a vector to size 'length' and returns whether the allocation is successful. * * See also AParcel_stdVectorAllocator. Types used with this allocator have their sizes defined * externally with respect to the NDK, and that size information is not passed into the NDK. * Instead, it is used in cases where callbacks are used. * * See AParcel_readVector(const AParcel* parcel, std::vector<bool>) * See AParcel_readVector(const AParcel* parcel, std::vector<std::string>) */ static inline bool AParcel_stdVectorBoolAllocator(void* vectorData, size_t length) { std::vector<bool>* vec = static_cast<std::vector<bool>*>(vectorData); template <typename T> static inline bool AParcel_stdVectorExternalAllocator(void* vectorData, size_t length) { std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData); if (length > vec->max_size()) return false; vec->resize(length); Loading Loading @@ -182,7 +190,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_stdVectorBoolAllocator, return AParcel_readBoolArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<bool>, AParcel_stdVectorSetter<bool>); } Loading Loading @@ -228,6 +236,32 @@ static inline char* AParcel_stdStringAllocator(void* stringData, size_t length) return &(*str)[0]; } /** * Allocates a std::string inside of a std::vector<std::string> at index index to size 'length'. */ static inline char* AParcel_stdVectorStringElementAllocator(void* vectorData, size_t index, size_t length) { std::vector<std::string>* vec = static_cast<std::vector<std::string>*>(vectorData); std::string& element = vec->at(index); element.resize(length - 1); return &element[0]; } /** * This gets the length and buffer of a std::string inside of a std::vector<std::string> at index * index. */ static inline const char* AParcel_stdVectorStringElementGetter(const void* vectorData, size_t index, size_t* outLength) { const std::vector<std::string>* vec = static_cast<const std::vector<std::string>*>(vectorData); const std::string& element = vec->at(index); *outLength = element.size(); return element.c_str(); } /** * Convenience API for writing a std::string. */ Loading @@ -240,7 +274,28 @@ 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_stdStringAllocator, stringData); return AParcel_readString(parcel, stringData, AParcel_stdStringAllocator); } /** * Convenience API for writing a std::vector<std::string> */ static inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<std::string>& vec) { const void* vectorData = static_cast<const void*>(&vec); return AParcel_writeStringArray(parcel, vectorData, vec.size(), AParcel_stdVectorStringElementGetter); } /** * Convenience API for reading a std::vector<std::string> */ static inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<std::string>* vec) { void* vectorData = static_cast<void*>(vec); return AParcel_readStringArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<std::string>, AParcel_stdVectorStringElementAllocator); } template <typename T> Loading libs/binder/ndk/libbinder_ndk.map.txt +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_readParcelFileDescriptor; AParcel_readStatusHeader; AParcel_readString; AParcel_readStringArray; AParcel_readStrongBinder; AParcel_readUint32; AParcel_readUint32Array; Loading @@ -63,6 +64,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_writeParcelFileDescriptor; AParcel_writeStatusHeader; AParcel_writeString; AParcel_writeStringArray; AParcel_writeStrongBinder; AParcel_writeUint32; AParcel_writeUint32Array; Loading libs/binder/ndk/parcel.cpp +65 −3 Original line number Diff line number Diff line Loading @@ -273,8 +273,8 @@ binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t return STATUS_OK; } binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringAllocator allocator, void* stringData) { binder_status_t AParcel_readString(const AParcel* parcel, void* stringData, AParcel_stringAllocator allocator) { size_t len16; const char16_t* str16 = parcel->get()->readString16Inplace(&len16); Loading @@ -291,7 +291,7 @@ binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringAllocato len8 = utf16_to_utf8_length(str16, len16) + 1; } if (len8 <= 0 || len8 >= std::numeric_limits<int32_t>::max()) { if (len8 <= 0 || len8 > std::numeric_limits<int32_t>::max()) { LOG(WARNING) << __func__ << ": Invalid string length: " << len8; return STATUS_BAD_VALUE; } Loading @@ -308,6 +308,68 @@ binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringAllocato return STATUS_OK; } binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, size_t length, AParcel_stringArrayElementGetter getter) { if (length > std::numeric_limits<int32_t>::max()) return STATUS_BAD_VALUE; Parcel* rawParcel = parcel->get(); status_t status = rawParcel->writeInt32(static_cast<int32_t>(length)); if (status != STATUS_OK) return PruneStatusT(status); for (size_t i = 0; i < length; i++) { size_t length = 0; const char* str = getter(arrayData, i, &length); if (str == nullptr) return STATUS_BAD_VALUE; binder_status_t status = AParcel_writeString(parcel, str, length); if (status != STATUS_OK) return status; } return STATUS_OK; } // This implements AParcel_stringAllocator for a string using an array, index, and element // allocator. struct StringArrayElementAllocationAdapter { void* arrayData; // stringData from the NDK size_t index; // index into the string array AParcel_stringArrayElementAllocator elementAllocator; static char* Allocator(void* stringData, size_t length) { StringArrayElementAllocationAdapter* adapter = static_cast<StringArrayElementAllocationAdapter*>(stringData); return adapter->elementAllocator(adapter->arrayData, adapter->index, length); } }; binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData, AParcel_stringArrayAllocator allocator, AParcel_stringArrayElementAllocator elementAllocator) { const Parcel* rawParcel = parcel->get(); int32_t length; status_t status = rawParcel->readInt32(&length); if (status != STATUS_OK) return PruneStatusT(status); if (length < 0) return STATUS_UNEXPECTED_NULL; if (!allocator(arrayData, length)) return STATUS_NO_MEMORY; StringArrayElementAllocationAdapter adapter{ .arrayData = arrayData, .index = 0, .elementAllocator = elementAllocator, }; for (; adapter.index < length; adapter.index++) { AParcel_readString(parcel, static_cast<void*>(&adapter), StringArrayElementAllocationAdapter::Allocator); } return STATUS_OK; } // See gen_parcel_helper.py. These auto-generated read/write methods use the same types for // libbinder and this library. // @START Loading libs/binder/ndk/scripts/gen_parcel_helper.py +3 −3 Original line number Diff line number Diff line Loading @@ -117,7 +117,7 @@ def main(): if nca: pre_header += "/**\n" pre_header += " * This allocates an array of length length inside of arrayData and returns whether or not there was " pre_header += " * This allocates an array of size 'length' inside of arrayData and returns whether or not there was " pre_header += "a success.\n" pre_header += " *\n" pre_header += " * See also " + read_func + "\n" Loading @@ -141,7 +141,7 @@ def main(): pre_header += "/**\n" pre_header += " * This is called to get the underlying data from an arrayData object.\n" pre_header += " *\n" pre_header += " * The implementation of this function should allocate a contiguous array of length length and " pre_header += " * The implementation of this function should allocate a contiguous array of size 'length' and " pre_header += "return that underlying buffer to be filled out. If there is an error or length is 0, null may be " pre_header += "returned.\n" pre_header += " *\n" Loading Loading @@ -192,7 +192,7 @@ def main(): read_args += ["parcel"] read_args += ["vectorData"] if nca: read_args += ["AParcel_stdVectorBoolAllocator"] read_args += ["AParcel_stdVectorExternalAllocator<bool>"] read_args += ["AParcel_stdVectorSetter<" + cpp + ">"] else: read_args += ["AParcel_stdVectorAllocator<" + cpp + ">"] Loading Loading
libs/binder/ndk/include_ndk/android/binder_parcel.h +78 −23 Original line number Diff line number Diff line Loading @@ -50,11 +50,51 @@ typedef struct AParcel AParcel; */ void AParcel_delete(AParcel* parcel) __INTRODUCED_IN(29); /** * This is called to allocate a buffer for a C-style string (null-terminated). The returned buffer * should be at least length bytes. This includes space for a null terminator. length will always be * strictly less than or equal to the maximum size that can be held in a size_t and will always be * greater than 0. * * See also AParcel_readString. * * If allocation fails, null should be returned. */ typedef char* (*AParcel_stringAllocator)(void* stringData, size_t length); /** * This is called to allocate an array of size 'length'. * * See also AParcel_readStringArray */ typedef bool (*AParcel_stringArrayAllocator)(void* arrayData, size_t length); /** * This is called to allocate a string inside of an array that was allocated by an * AParcel_stringArrayAllocator. * * The index returned will always be within the range [0, length of arrayData). The returned buffer * should be at least length bytes. This includes space for a null-terminator. length will always be * strictly less than or equal to the maximum size that can be held in a size_t and will always be * greater than 0. * * See also AParcel_readStringArray */ typedef char* (*AParcel_stringArrayElementAllocator)(void* arrayData, size_t index, size_t length); /** * This returns the length and buffer of an array at a specific index in an arrayData object. * * See also AParcel_writeStringArray */ typedef const char* (*AParcel_stringArrayElementGetter)(const void* arrayData, size_t index, size_t* outLength); // @START-PRIMITIVE-VECTOR-GETTERS /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -65,7 +105,7 @@ typedef int32_t* (*AParcel_int32ArrayAllocator)(void* arrayData, size_t length); /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -76,7 +116,7 @@ typedef uint32_t* (*AParcel_uint32ArrayAllocator)(void* arrayData, size_t length /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -87,7 +127,7 @@ typedef int64_t* (*AParcel_int64ArrayAllocator)(void* arrayData, size_t length); /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -98,7 +138,7 @@ typedef uint64_t* (*AParcel_uint64ArrayAllocator)(void* arrayData, size_t length /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -109,7 +149,7 @@ typedef float* (*AParcel_floatArrayAllocator)(void* arrayData, size_t length); /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -118,7 +158,7 @@ typedef float* (*AParcel_floatArrayAllocator)(void* arrayData, size_t length); typedef double* (*AParcel_doubleArrayAllocator)(void* arrayData, size_t length); /** * This allocates an array of length length inside of arrayData and returns whether or not there was * This allocates an array of size 'length' inside of arrayData and returns whether or not there was * a success. * * See also AParcel_readBoolArray Loading @@ -142,7 +182,7 @@ typedef void (*AParcel_boolArraySetter)(void* arrayData, size_t index, bool valu /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -153,7 +193,7 @@ typedef char16_t* (*AParcel_charArrayAllocator)(void* arrayData, size_t length); /** * 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 * The implementation of this function should allocate a contiguous array of size 'length' and * return that underlying buffer to be filled out. If there is an error or length is 0, null may be * returned. * Loading @@ -163,16 +203,6 @@ typedef int8_t* (*AParcel_byteArrayAllocator)(void* arrayData, size_t length); // @END-PRIMITIVE-VECTOR-GETTERS /** * 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. * * See also AParcel_readString. * * If allocation fails, null should be returned. */ typedef char* (*AParcel_stringAllocator)(void* stringData, size_t length); /** * Writes an AIBinder to the next location in a non-null parcel. Can be null. */ Loading Loading @@ -229,20 +259,45 @@ binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status __INTRODUCED_IN(29); /** * Writes string value to the next location in a non-null parcel. * Writes utf-8 string value to the next location in a non-null parcel. */ binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) __INTRODUCED_IN(29); /** * Reads and allocates string value from the next location in a non-null parcel. * Reads and allocates utf-8 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 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_stringAllocator allocator, void* stringData) __INTRODUCED_IN(29); binder_status_t AParcel_readString(const AParcel* parcel, void* stringData, AParcel_stringAllocator allocator) __INTRODUCED_IN(29); /** * Writes utf-8 string array data to the next location in a non-null parcel. * * length is the length of the array. AParcel_stringArrayElementGetter will be called for all * indices in range [0, length) with the arrayData provided here. The string length and buffer * returned from this function will be used to fill out the data from the parcel. */ binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, size_t length, AParcel_stringArrayElementGetter getter) __INTRODUCED_IN(29); /** * Reads and allocates utf-8 string array value from the next location in a non-null parcel. * * First, AParcel_stringArrayAllocator will be called with the size of the array to be read where * length is the length of the array to be read from the parcel. Then, for each index i in [0, * length), AParcel_stringArrayElementAllocator will be called with the length of the string to be * read from the parcel. The resultant buffer from each of these calls will be filled according to * the contents of the string that is read. */ binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData, AParcel_stringArrayAllocator allocator, AParcel_stringArrayElementAllocator elementAllocator) __INTRODUCED_IN(29); // @START-PRIMITIVE-READ-WRITE /** Loading
libs/binder/ndk/include_ndk/android/binder_parcel_utils.h +61 −6 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ namespace ndk { /** * This retrieves and allocates a vector to length length and returns the underlying buffer. * This retrieves and allocates a vector to size 'length' and returns the underlying buffer. */ template <typename T> static inline T* AParcel_stdVectorAllocator(void* vectorData, size_t length) { Loading @@ -48,10 +48,18 @@ static inline T* AParcel_stdVectorAllocator(void* vectorData, size_t length) { } /** * This allocates a vector to length length and returns whether the allocation is successful. * This allocates a vector to size 'length' and returns whether the allocation is successful. * * See also AParcel_stdVectorAllocator. Types used with this allocator have their sizes defined * externally with respect to the NDK, and that size information is not passed into the NDK. * Instead, it is used in cases where callbacks are used. * * See AParcel_readVector(const AParcel* parcel, std::vector<bool>) * See AParcel_readVector(const AParcel* parcel, std::vector<std::string>) */ static inline bool AParcel_stdVectorBoolAllocator(void* vectorData, size_t length) { std::vector<bool>* vec = static_cast<std::vector<bool>*>(vectorData); template <typename T> static inline bool AParcel_stdVectorExternalAllocator(void* vectorData, size_t length) { std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData); if (length > vec->max_size()) return false; vec->resize(length); Loading Loading @@ -182,7 +190,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_stdVectorBoolAllocator, return AParcel_readBoolArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<bool>, AParcel_stdVectorSetter<bool>); } Loading Loading @@ -228,6 +236,32 @@ static inline char* AParcel_stdStringAllocator(void* stringData, size_t length) return &(*str)[0]; } /** * Allocates a std::string inside of a std::vector<std::string> at index index to size 'length'. */ static inline char* AParcel_stdVectorStringElementAllocator(void* vectorData, size_t index, size_t length) { std::vector<std::string>* vec = static_cast<std::vector<std::string>*>(vectorData); std::string& element = vec->at(index); element.resize(length - 1); return &element[0]; } /** * This gets the length and buffer of a std::string inside of a std::vector<std::string> at index * index. */ static inline const char* AParcel_stdVectorStringElementGetter(const void* vectorData, size_t index, size_t* outLength) { const std::vector<std::string>* vec = static_cast<const std::vector<std::string>*>(vectorData); const std::string& element = vec->at(index); *outLength = element.size(); return element.c_str(); } /** * Convenience API for writing a std::string. */ Loading @@ -240,7 +274,28 @@ 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_stdStringAllocator, stringData); return AParcel_readString(parcel, stringData, AParcel_stdStringAllocator); } /** * Convenience API for writing a std::vector<std::string> */ static inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<std::string>& vec) { const void* vectorData = static_cast<const void*>(&vec); return AParcel_writeStringArray(parcel, vectorData, vec.size(), AParcel_stdVectorStringElementGetter); } /** * Convenience API for reading a std::vector<std::string> */ static inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<std::string>* vec) { void* vectorData = static_cast<void*>(vec); return AParcel_readStringArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<std::string>, AParcel_stdVectorStringElementAllocator); } template <typename T> Loading
libs/binder/ndk/libbinder_ndk.map.txt +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_readParcelFileDescriptor; AParcel_readStatusHeader; AParcel_readString; AParcel_readStringArray; AParcel_readStrongBinder; AParcel_readUint32; AParcel_readUint32Array; Loading @@ -63,6 +64,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_writeParcelFileDescriptor; AParcel_writeStatusHeader; AParcel_writeString; AParcel_writeStringArray; AParcel_writeStrongBinder; AParcel_writeUint32; AParcel_writeUint32Array; Loading
libs/binder/ndk/parcel.cpp +65 −3 Original line number Diff line number Diff line Loading @@ -273,8 +273,8 @@ binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t return STATUS_OK; } binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringAllocator allocator, void* stringData) { binder_status_t AParcel_readString(const AParcel* parcel, void* stringData, AParcel_stringAllocator allocator) { size_t len16; const char16_t* str16 = parcel->get()->readString16Inplace(&len16); Loading @@ -291,7 +291,7 @@ binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringAllocato len8 = utf16_to_utf8_length(str16, len16) + 1; } if (len8 <= 0 || len8 >= std::numeric_limits<int32_t>::max()) { if (len8 <= 0 || len8 > std::numeric_limits<int32_t>::max()) { LOG(WARNING) << __func__ << ": Invalid string length: " << len8; return STATUS_BAD_VALUE; } Loading @@ -308,6 +308,68 @@ binder_status_t AParcel_readString(const AParcel* parcel, AParcel_stringAllocato return STATUS_OK; } binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, size_t length, AParcel_stringArrayElementGetter getter) { if (length > std::numeric_limits<int32_t>::max()) return STATUS_BAD_VALUE; Parcel* rawParcel = parcel->get(); status_t status = rawParcel->writeInt32(static_cast<int32_t>(length)); if (status != STATUS_OK) return PruneStatusT(status); for (size_t i = 0; i < length; i++) { size_t length = 0; const char* str = getter(arrayData, i, &length); if (str == nullptr) return STATUS_BAD_VALUE; binder_status_t status = AParcel_writeString(parcel, str, length); if (status != STATUS_OK) return status; } return STATUS_OK; } // This implements AParcel_stringAllocator for a string using an array, index, and element // allocator. struct StringArrayElementAllocationAdapter { void* arrayData; // stringData from the NDK size_t index; // index into the string array AParcel_stringArrayElementAllocator elementAllocator; static char* Allocator(void* stringData, size_t length) { StringArrayElementAllocationAdapter* adapter = static_cast<StringArrayElementAllocationAdapter*>(stringData); return adapter->elementAllocator(adapter->arrayData, adapter->index, length); } }; binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData, AParcel_stringArrayAllocator allocator, AParcel_stringArrayElementAllocator elementAllocator) { const Parcel* rawParcel = parcel->get(); int32_t length; status_t status = rawParcel->readInt32(&length); if (status != STATUS_OK) return PruneStatusT(status); if (length < 0) return STATUS_UNEXPECTED_NULL; if (!allocator(arrayData, length)) return STATUS_NO_MEMORY; StringArrayElementAllocationAdapter adapter{ .arrayData = arrayData, .index = 0, .elementAllocator = elementAllocator, }; for (; adapter.index < length; adapter.index++) { AParcel_readString(parcel, static_cast<void*>(&adapter), StringArrayElementAllocationAdapter::Allocator); } return STATUS_OK; } // See gen_parcel_helper.py. These auto-generated read/write methods use the same types for // libbinder and this library. // @START Loading
libs/binder/ndk/scripts/gen_parcel_helper.py +3 −3 Original line number Diff line number Diff line Loading @@ -117,7 +117,7 @@ def main(): if nca: pre_header += "/**\n" pre_header += " * This allocates an array of length length inside of arrayData and returns whether or not there was " pre_header += " * This allocates an array of size 'length' inside of arrayData and returns whether or not there was " pre_header += "a success.\n" pre_header += " *\n" pre_header += " * See also " + read_func + "\n" Loading @@ -141,7 +141,7 @@ def main(): pre_header += "/**\n" pre_header += " * This is called to get the underlying data from an arrayData object.\n" pre_header += " *\n" pre_header += " * The implementation of this function should allocate a contiguous array of length length and " pre_header += " * The implementation of this function should allocate a contiguous array of size 'length' and " pre_header += "return that underlying buffer to be filled out. If there is an error or length is 0, null may be " pre_header += "returned.\n" pre_header += " *\n" Loading Loading @@ -192,7 +192,7 @@ def main(): read_args += ["parcel"] read_args += ["vectorData"] if nca: read_args += ["AParcel_stdVectorBoolAllocator"] read_args += ["AParcel_stdVectorExternalAllocator<bool>"] read_args += ["AParcel_stdVectorSetter<" + cpp + ">"] else: read_args += ["AParcel_stdVectorAllocator<" + cpp + ">"] Loading