diff options
| -rw-r--r-- | libs/binder/include/binder/Parcel.h | 14 | ||||
| -rw-r--r-- | libs/binder/ndk/include_cpp/android/binder_parcel_utils.h | 35 | ||||
| -rw-r--r-- | libs/binder/rust/src/parcel/parcelable.rs | 24 |
3 files changed, 67 insertions, 6 deletions
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 02052ad77e..fd8ac622a5 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -245,9 +245,10 @@ public: template<typename T> status_t writeNullableParcelable(const std::optional<T>& parcelable) { return writeData(parcelable); } - template<typename T> - status_t writeNullableParcelable(const std::unique_ptr<T>& parcelable) __attribute__((deprecated("use std::optional version instead"))) - { return writeData(parcelable); } + template <typename T> + status_t writeNullableParcelable(const std::unique_ptr<T>& parcelable) { + return writeData(parcelable); + } status_t writeParcelable(const Parcelable& parcelable); @@ -401,9 +402,10 @@ public: template<typename T> status_t readParcelable(std::optional<T>* parcelable) const { return readData(parcelable); } - template<typename T> - status_t readParcelable(std::unique_ptr<T>* parcelable) const __attribute__((deprecated("use std::optional version instead"))) - { return readData(parcelable); } + template <typename T> + status_t readParcelable(std::unique_ptr<T>* parcelable) const { + return readData(parcelable); + } // If strong binder would be nullptr, readStrongBinder() returns an error. // TODO: T must be derived from IInterface, fix for clarity. diff --git a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h index 5092d872fa..563d011adc 100644 --- a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h +++ b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h @@ -469,6 +469,22 @@ static inline binder_status_t AParcel_writeNullableParcelable(AParcel* parcel, } /** + * Convenience API for writing a nullable parcelable. + */ +template <typename P> +static inline binder_status_t AParcel_writeNullableParcelable(AParcel* parcel, + const std::unique_ptr<P>& p) { + if (!p) { + return AParcel_writeInt32(parcel, 0); // null + } + binder_status_t status = AParcel_writeInt32(parcel, 1); // non-null + if (status != STATUS_OK) { + return status; + } + return p->writeToParcel(parcel); +} + +/** * Convenience API for reading a nullable parcelable. */ template <typename P> @@ -488,6 +504,25 @@ static inline binder_status_t AParcel_readNullableParcelable(const AParcel* parc } /** + * Convenience API for reading a nullable parcelable. + */ +template <typename P> +static inline binder_status_t AParcel_readNullableParcelable(const AParcel* parcel, + std::unique_ptr<P>* p) { + int32_t null; + binder_status_t status = AParcel_readInt32(parcel, &null); + if (status != STATUS_OK) { + return status; + } + if (null == 0) { + p->reset(); + return STATUS_OK; + } + *p = std::make_unique<P>(); + return (*p)->readFromParcel(parcel); +} + +/** * Writes a parcelable object of type P inside a std::vector<P> at index 'index' to 'parcel'. */ template <typename P> diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs index 956ecfe998..56c61651cf 100644 --- a/libs/binder/rust/src/parcel/parcelable.rs +++ b/libs/binder/rust/src/parcel/parcelable.rs @@ -764,6 +764,30 @@ macro_rules! impl_deserialize_for_parcelable { } } +impl<T: Serialize> Serialize for Box<T> { + fn serialize(&self, parcel: &mut Parcel) -> Result<()> { + Serialize::serialize(&**self, parcel) + } +} + +impl<T: Deserialize> Deserialize for Box<T> { + fn deserialize(parcel: &Parcel) -> Result<Self> { + Deserialize::deserialize(parcel).map(Box::new) + } +} + +impl<T: SerializeOption> SerializeOption for Box<T> { + fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> { + SerializeOption::serialize_option(this.map(|inner| &**inner), parcel) + } +} + +impl<T: DeserializeOption> DeserializeOption for Box<T> { + fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> { + DeserializeOption::deserialize_option(parcel).map(|t| t.map(Box::new)) + } +} + #[test] fn test_custom_parcelable() { use crate::binder::Interface; |