Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 231bda61 authored by Jooyung Han's avatar Jooyung Han Committed by Gerrit Code Review
Browse files

Merge "Parcel: support unique_ptr for recursive types"

parents 8395fee2 83401fe3
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -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);

@@ -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.
+35 −0
Original line number Diff line number Diff line
@@ -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.
 */
@@ -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'.
 */
+24 −0
Original line number Diff line number Diff line
@@ -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;