Loading libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h +91 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ */ #pragma once #include <android/binder_parcel_utils.h> #include <optional> namespace ndk { // Also see Parcelable.h in libbinder. Loading @@ -33,6 +35,95 @@ enum { STABILITY_LOCAL, STABILITY_VINTF, // corresponds to @VintfStability }; #define RETURN_ON_FAILURE(expr) \ do { \ binder_status_t _status = (expr); \ if (_status != STATUS_OK) return _status; \ } while (false) class AParcelableHolder { public: AParcelableHolder() = delete; explicit AParcelableHolder(parcelable_stability_t stability) : mParcel(AParcel_create()), mStability(stability) {} virtual ~AParcelableHolder() = default; binder_status_t writeToParcel(AParcel* parcel) const { std::lock_guard<std::mutex> l(mMutex); RETURN_ON_FAILURE(AParcel_writeInt32(parcel, static_cast<int32_t>(this->mStability))); RETURN_ON_FAILURE(AParcel_writeInt32(parcel, AParcel_getDataSize(this->mParcel.get()))); RETURN_ON_FAILURE(AParcel_appendFrom(this->mParcel.get(), parcel, 0, AParcel_getDataSize(this->mParcel.get()))); return STATUS_OK; } binder_status_t readFromParcel(const AParcel* parcel) { std::lock_guard<std::mutex> l(mMutex); AParcel_reset(mParcel.get()); RETURN_ON_FAILURE(AParcel_readInt32(parcel, &this->mStability)); int32_t dataSize; binder_status_t status = AParcel_readInt32(parcel, &dataSize); if (status != STATUS_OK || dataSize < 0) { return status != STATUS_OK ? status : STATUS_BAD_VALUE; } int32_t dataStartPos = AParcel_getDataPosition(parcel); if (dataStartPos > INT32_MAX - dataSize) { return STATUS_BAD_VALUE; } status = AParcel_appendFrom(parcel, mParcel.get(), dataStartPos, dataSize); if (status != STATUS_OK) { return status; } return AParcel_setDataPosition(parcel, dataStartPos + dataSize); } template <typename T> bool setParcelable(T* p) { std::lock_guard<std::mutex> l(mMutex); if (p && this->mStability > T::_aidl_stability) { return false; } AParcel_reset(mParcel.get()); AParcel_writeString(mParcel.get(), T::descriptor, strlen(T::descriptor)); p->writeToParcel(mParcel.get()); return true; } template <typename T> std::unique_ptr<T> getParcelable() const { std::lock_guard<std::mutex> l(mMutex); const std::string parcelableDesc(T::descriptor); AParcel_setDataPosition(mParcel.get(), 0); if (AParcel_getDataSize(mParcel.get()) == 0) { return nullptr; } std::string parcelableDescInParcel; binder_status_t status = AParcel_readString(mParcel.get(), &parcelableDescInParcel); if (status != STATUS_OK || parcelableDesc != parcelableDescInParcel) { return nullptr; } std::unique_ptr<T> ret = std::make_unique<T>(); status = ret->readFromParcel(this->mParcel.get()); if (status != STATUS_OK) { return nullptr; } return std::move(ret); } private: mutable ndk::ScopedAParcel mParcel; mutable std::mutex mMutex; parcelable_stability_t mStability; }; #undef RETURN_ON_FAILURE } // namespace ndk /** @} */ libs/binder/ndk/include_ndk/android/binder_parcel.h +47 −0 Original line number Diff line number Diff line Loading @@ -1120,6 +1120,53 @@ binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData, // @END-PRIMITIVE-READ-WRITE #endif //__ANDROID_API__ >= 29 #if __ANDROID_API__ >= 31 /** * Reset the parcel to the initial status. * * Available since API level 31. * * \param parcel The parcel of which to be reset. * * \return STATUS_OK on success. */ binder_status_t AParcel_reset(AParcel* parcel) __INTRODUCED_IN(31); /** * Gets the size of the parcel. * * Available since API level 31. * * \param parcel The parcel of which to get the size. * * \return The size of the parcel. */ int32_t AParcel_getDataSize(const AParcel* parcel) __INTRODUCED_IN(31); /** * Copy the data of a parcel to other parcel. * * Available since API level 31. * * \param from The source * \param to The detination * \param start The position where the copied data starts. * \param size The amount of data which will be copied. * * \return STATUS_OK on success. */ binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) __INTRODUCED_IN(31); /** * Creates a parcel. * * Available since API level 31. * * \return A parcel which is not related to any IBinder objects. */ AParcel* AParcel_create() __INTRODUCED_IN(31); #endif //__ANDROID_API__ >= 31 __END_DECLS /** @} */ libs/binder/ndk/libbinder_ndk.map.txt +5 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,11 @@ LIBBINDER_NDK31 { # introduced=31 AServiceManager_isDeclared; # apex llndk AServiceManager_registerLazyService; # llndk AServiceManager_waitForService; # apex llndk AParcel_reset; AParcel_getDataSize; AParcel_appendFrom; AParcel_create; }; LIBBINDER_NDK_PLATFORM { Loading libs/binder/ndk/parcel.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -647,4 +647,22 @@ bool AParcel_getAllowFds(const AParcel* parcel) { return parcel->get()->allowFds(); } binder_status_t AParcel_reset(AParcel* parcel) { parcel->get()->freeData(); return STATUS_OK; } int32_t AParcel_getDataSize(const AParcel* parcel) { return parcel->get()->dataSize(); } binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) { status_t status = to->get()->appendFrom(from->get(), start, size); return PruneStatusT(status); } AParcel* AParcel_create() { return new AParcel(nullptr); } // @END Loading
libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h +91 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ */ #pragma once #include <android/binder_parcel_utils.h> #include <optional> namespace ndk { // Also see Parcelable.h in libbinder. Loading @@ -33,6 +35,95 @@ enum { STABILITY_LOCAL, STABILITY_VINTF, // corresponds to @VintfStability }; #define RETURN_ON_FAILURE(expr) \ do { \ binder_status_t _status = (expr); \ if (_status != STATUS_OK) return _status; \ } while (false) class AParcelableHolder { public: AParcelableHolder() = delete; explicit AParcelableHolder(parcelable_stability_t stability) : mParcel(AParcel_create()), mStability(stability) {} virtual ~AParcelableHolder() = default; binder_status_t writeToParcel(AParcel* parcel) const { std::lock_guard<std::mutex> l(mMutex); RETURN_ON_FAILURE(AParcel_writeInt32(parcel, static_cast<int32_t>(this->mStability))); RETURN_ON_FAILURE(AParcel_writeInt32(parcel, AParcel_getDataSize(this->mParcel.get()))); RETURN_ON_FAILURE(AParcel_appendFrom(this->mParcel.get(), parcel, 0, AParcel_getDataSize(this->mParcel.get()))); return STATUS_OK; } binder_status_t readFromParcel(const AParcel* parcel) { std::lock_guard<std::mutex> l(mMutex); AParcel_reset(mParcel.get()); RETURN_ON_FAILURE(AParcel_readInt32(parcel, &this->mStability)); int32_t dataSize; binder_status_t status = AParcel_readInt32(parcel, &dataSize); if (status != STATUS_OK || dataSize < 0) { return status != STATUS_OK ? status : STATUS_BAD_VALUE; } int32_t dataStartPos = AParcel_getDataPosition(parcel); if (dataStartPos > INT32_MAX - dataSize) { return STATUS_BAD_VALUE; } status = AParcel_appendFrom(parcel, mParcel.get(), dataStartPos, dataSize); if (status != STATUS_OK) { return status; } return AParcel_setDataPosition(parcel, dataStartPos + dataSize); } template <typename T> bool setParcelable(T* p) { std::lock_guard<std::mutex> l(mMutex); if (p && this->mStability > T::_aidl_stability) { return false; } AParcel_reset(mParcel.get()); AParcel_writeString(mParcel.get(), T::descriptor, strlen(T::descriptor)); p->writeToParcel(mParcel.get()); return true; } template <typename T> std::unique_ptr<T> getParcelable() const { std::lock_guard<std::mutex> l(mMutex); const std::string parcelableDesc(T::descriptor); AParcel_setDataPosition(mParcel.get(), 0); if (AParcel_getDataSize(mParcel.get()) == 0) { return nullptr; } std::string parcelableDescInParcel; binder_status_t status = AParcel_readString(mParcel.get(), &parcelableDescInParcel); if (status != STATUS_OK || parcelableDesc != parcelableDescInParcel) { return nullptr; } std::unique_ptr<T> ret = std::make_unique<T>(); status = ret->readFromParcel(this->mParcel.get()); if (status != STATUS_OK) { return nullptr; } return std::move(ret); } private: mutable ndk::ScopedAParcel mParcel; mutable std::mutex mMutex; parcelable_stability_t mStability; }; #undef RETURN_ON_FAILURE } // namespace ndk /** @} */
libs/binder/ndk/include_ndk/android/binder_parcel.h +47 −0 Original line number Diff line number Diff line Loading @@ -1120,6 +1120,53 @@ binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData, // @END-PRIMITIVE-READ-WRITE #endif //__ANDROID_API__ >= 29 #if __ANDROID_API__ >= 31 /** * Reset the parcel to the initial status. * * Available since API level 31. * * \param parcel The parcel of which to be reset. * * \return STATUS_OK on success. */ binder_status_t AParcel_reset(AParcel* parcel) __INTRODUCED_IN(31); /** * Gets the size of the parcel. * * Available since API level 31. * * \param parcel The parcel of which to get the size. * * \return The size of the parcel. */ int32_t AParcel_getDataSize(const AParcel* parcel) __INTRODUCED_IN(31); /** * Copy the data of a parcel to other parcel. * * Available since API level 31. * * \param from The source * \param to The detination * \param start The position where the copied data starts. * \param size The amount of data which will be copied. * * \return STATUS_OK on success. */ binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) __INTRODUCED_IN(31); /** * Creates a parcel. * * Available since API level 31. * * \return A parcel which is not related to any IBinder objects. */ AParcel* AParcel_create() __INTRODUCED_IN(31); #endif //__ANDROID_API__ >= 31 __END_DECLS /** @} */
libs/binder/ndk/libbinder_ndk.map.txt +5 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,11 @@ LIBBINDER_NDK31 { # introduced=31 AServiceManager_isDeclared; # apex llndk AServiceManager_registerLazyService; # llndk AServiceManager_waitForService; # apex llndk AParcel_reset; AParcel_getDataSize; AParcel_appendFrom; AParcel_create; }; LIBBINDER_NDK_PLATFORM { Loading
libs/binder/ndk/parcel.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -647,4 +647,22 @@ bool AParcel_getAllowFds(const AParcel* parcel) { return parcel->get()->allowFds(); } binder_status_t AParcel_reset(AParcel* parcel) { parcel->get()->freeData(); return STATUS_OK; } int32_t AParcel_getDataSize(const AParcel* parcel) { return parcel->get()->dataSize(); } binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) { status_t status = to->get()->appendFrom(from->get(), start, size); return PruneStatusT(status); } AParcel* AParcel_create() { return new AParcel(nullptr); } // @END