Loading libs/binder/ndk/include_ndk/android/binder_parcel.h +37 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,43 @@ binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status 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. */ binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) __INTRODUCED_IN(29); /** * This is called to allocate a buffer * * 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'. * * If allocation fails, null should be returned. */ typedef void* (*AParcel_string_reallocator)(void* stringData, size_t length); /** * This is called to get the buffer from a stringData object. */ typedef char* (*AParcel_string_getter)(void* stringData); /** * 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. */ binder_status_t AParcel_readString(const AParcel* parcel, AParcel_string_reallocator reallocator, AParcel_string_getter getter, void** stringData) __INTRODUCED_IN(29); // @START /** * Writes int32_t value to the next location in a non-null parcel. Loading libs/binder/ndk/include_ndk/android/binder_parcel_utils.h 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @addtogroup NdkBinder * @{ */ /** * @file binder_parcel_utils.h * @brief A collection of helper wrappers for AParcel. */ #pragma once #include <android/binder_parcel.h> #ifdef __cplusplus #include <string> /** * Takes a std::string and reallocates it to the specified length. For use with AParcel_readString. * See use below in AParcel_readString. */ static inline void* AParcel_std_string_reallocator(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_std_string_getter(void* stringData) { std::string* str = static_cast<std::string*>(stringData); return &(*str)[0]; } /** * Convenience API for writing a std::string. */ static inline binder_status_t AParcel_writeString(AParcel* parcel, const std::string& str) { return AParcel_writeString(parcel, str.c_str(), str.size()); } /** * Convenience API for reading a std::string. */ static inline binder_status_t AParcel_readString(const AParcel* parcel, std::string* str) { void* stringData = static_cast<void*>(str); return AParcel_readString(parcel, AParcel_std_string_reallocator, AParcel_std_string_getter, &stringData); } #endif // __cplusplus /** @} */ libs/binder/ndk/libbinder_ndk.map.txt +2 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_readInt64; AParcel_readNullableStrongBinder; AParcel_readStatusHeader; AParcel_readString; AParcel_readStrongBinder; AParcel_readUint32; AParcel_readUint64; Loading @@ -43,6 +44,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_writeInt32; AParcel_writeInt64; AParcel_writeStatusHeader; AParcel_writeString; AParcel_writeStrongBinder; AParcel_writeUint32; AParcel_writeUint64; Loading libs/binder/ndk/parcel.cpp +65 −0 Original line number Diff line number Diff line Loading @@ -20,7 +20,11 @@ #include "ibinder_internal.h" #include "status_internal.h" #include <limits> #include <android-base/logging.h> #include <binder/Parcel.h> #include <utils/Unicode.h> using ::android::IBinder; using ::android::Parcel; Loading Loading @@ -69,6 +73,67 @@ binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status return ret; } binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) { const uint8_t* str8 = (uint8_t*)string; const ssize_t len16 = utf8_to_utf16_length(str8, length); if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) { LOG(WARNING) << __func__ << ": Invalid string length: " << len16; return STATUS_BAD_VALUE; } status_t err = parcel->get()->writeInt32(len16); if (err) { return PruneStatusT(err); } void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t)); if (str16 == nullptr) { return STATUS_NO_MEMORY; } utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1); return STATUS_OK; } binder_status_t AParcel_readString(const AParcel* parcel, AParcel_string_reallocator reallocator, AParcel_string_getter getter, void** stringData) { size_t len16; const char16_t* str16 = parcel->get()->readString16Inplace(&len16); if (str16 == nullptr) { LOG(WARNING) << __func__ << ": Failed to read string in place."; return STATUS_UNEXPECTED_NULL; } ssize_t len8; if (len16 == 0) { len8 = 1; } else { len8 = utf16_to_utf8_length(str16, len16) + 1; } if (len8 <= 0 || len8 >= std::numeric_limits<int32_t>::max()) { LOG(WARNING) << __func__ << ": Invalid string length: " << len8; return STATUS_BAD_VALUE; } *stringData = reallocator(*stringData, len8); char* str8 = getter(*stringData); if (str8 == nullptr) { LOG(WARNING) << __func__ << ": AParcel_string_allocator failed to allocate."; return STATUS_NO_MEMORY; } utf16_to_utf8(str16, len16, str8, len8); 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 Loading
libs/binder/ndk/include_ndk/android/binder_parcel.h +37 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,43 @@ binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status 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. */ binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) __INTRODUCED_IN(29); /** * This is called to allocate a buffer * * 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'. * * If allocation fails, null should be returned. */ typedef void* (*AParcel_string_reallocator)(void* stringData, size_t length); /** * This is called to get the buffer from a stringData object. */ typedef char* (*AParcel_string_getter)(void* stringData); /** * 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. */ binder_status_t AParcel_readString(const AParcel* parcel, AParcel_string_reallocator reallocator, AParcel_string_getter getter, void** stringData) __INTRODUCED_IN(29); // @START /** * Writes int32_t value to the next location in a non-null parcel. Loading
libs/binder/ndk/include_ndk/android/binder_parcel_utils.h 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @addtogroup NdkBinder * @{ */ /** * @file binder_parcel_utils.h * @brief A collection of helper wrappers for AParcel. */ #pragma once #include <android/binder_parcel.h> #ifdef __cplusplus #include <string> /** * Takes a std::string and reallocates it to the specified length. For use with AParcel_readString. * See use below in AParcel_readString. */ static inline void* AParcel_std_string_reallocator(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_std_string_getter(void* stringData) { std::string* str = static_cast<std::string*>(stringData); return &(*str)[0]; } /** * Convenience API for writing a std::string. */ static inline binder_status_t AParcel_writeString(AParcel* parcel, const std::string& str) { return AParcel_writeString(parcel, str.c_str(), str.size()); } /** * Convenience API for reading a std::string. */ static inline binder_status_t AParcel_readString(const AParcel* parcel, std::string* str) { void* stringData = static_cast<void*>(str); return AParcel_readString(parcel, AParcel_std_string_reallocator, AParcel_std_string_getter, &stringData); } #endif // __cplusplus /** @} */
libs/binder/ndk/libbinder_ndk.map.txt +2 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_readInt64; AParcel_readNullableStrongBinder; AParcel_readStatusHeader; AParcel_readString; AParcel_readStrongBinder; AParcel_readUint32; AParcel_readUint64; Loading @@ -43,6 +44,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_writeInt32; AParcel_writeInt64; AParcel_writeStatusHeader; AParcel_writeString; AParcel_writeStrongBinder; AParcel_writeUint32; AParcel_writeUint64; Loading
libs/binder/ndk/parcel.cpp +65 −0 Original line number Diff line number Diff line Loading @@ -20,7 +20,11 @@ #include "ibinder_internal.h" #include "status_internal.h" #include <limits> #include <android-base/logging.h> #include <binder/Parcel.h> #include <utils/Unicode.h> using ::android::IBinder; using ::android::Parcel; Loading Loading @@ -69,6 +73,67 @@ binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status return ret; } binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) { const uint8_t* str8 = (uint8_t*)string; const ssize_t len16 = utf8_to_utf16_length(str8, length); if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) { LOG(WARNING) << __func__ << ": Invalid string length: " << len16; return STATUS_BAD_VALUE; } status_t err = parcel->get()->writeInt32(len16); if (err) { return PruneStatusT(err); } void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t)); if (str16 == nullptr) { return STATUS_NO_MEMORY; } utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1); return STATUS_OK; } binder_status_t AParcel_readString(const AParcel* parcel, AParcel_string_reallocator reallocator, AParcel_string_getter getter, void** stringData) { size_t len16; const char16_t* str16 = parcel->get()->readString16Inplace(&len16); if (str16 == nullptr) { LOG(WARNING) << __func__ << ": Failed to read string in place."; return STATUS_UNEXPECTED_NULL; } ssize_t len8; if (len16 == 0) { len8 = 1; } else { len8 = utf16_to_utf8_length(str16, len16) + 1; } if (len8 <= 0 || len8 >= std::numeric_limits<int32_t>::max()) { LOG(WARNING) << __func__ << ": Invalid string length: " << len8; return STATUS_BAD_VALUE; } *stringData = reallocator(*stringData, len8); char* str8 = getter(*stringData); if (str8 == nullptr) { LOG(WARNING) << __func__ << ": AParcel_string_allocator failed to allocate."; return STATUS_NO_MEMORY; } utf16_to_utf8(str16, len16, str8, len8); 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