Loading libs/binder/include/binder/Parcel.h +8 −6 Original line number Diff line number Diff line Loading @@ -246,8 +246,9 @@ public: 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); } status_t writeNullableParcelable(const std::unique_ptr<T>& parcelable) { return writeData(parcelable); } status_t writeParcelable(const Parcelable& parcelable); Loading Loading @@ -402,8 +403,9 @@ public: 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); } 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. Loading libs/binder/ndk/include_cpp/android/binder_parcel_utils.h +35 −0 Original line number Diff line number Diff line Loading @@ -468,6 +468,22 @@ static inline binder_status_t AParcel_writeNullableParcelable(AParcel* parcel, return p->writeToParcel(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. */ Loading @@ -487,6 +503,25 @@ static inline binder_status_t AParcel_readNullableParcelable(const AParcel* parc return (*p)->readFromParcel(parcel); } /** * 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'. */ Loading libs/binder/rust/src/parcel/parcelable.rs +24 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
libs/binder/include/binder/Parcel.h +8 −6 Original line number Diff line number Diff line Loading @@ -246,8 +246,9 @@ public: 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); } status_t writeNullableParcelable(const std::unique_ptr<T>& parcelable) { return writeData(parcelable); } status_t writeParcelable(const Parcelable& parcelable); Loading Loading @@ -402,8 +403,9 @@ public: 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); } 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. Loading
libs/binder/ndk/include_cpp/android/binder_parcel_utils.h +35 −0 Original line number Diff line number Diff line Loading @@ -468,6 +468,22 @@ static inline binder_status_t AParcel_writeNullableParcelable(AParcel* parcel, return p->writeToParcel(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. */ Loading @@ -487,6 +503,25 @@ static inline binder_status_t AParcel_readNullableParcelable(const AParcel* parc return (*p)->readFromParcel(parcel); } /** * 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'. */ Loading
libs/binder/rust/src/parcel/parcelable.rs +24 −0 Original line number Diff line number Diff line Loading @@ -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; Loading