Allow null values for Parcel readers and writers

Test: AIDL integration tests pass
Bug: 25969194
Change-Id: Ib7023c8e02af49e08c9921f1d097e5967c1d378e
Signed-off-by: Casey Dahlin <sadmac@google.com>
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 16a4790..0abf8f3 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -109,6 +109,7 @@
     status_t            writeCString(const char* str);
     status_t            writeString8(const String8& str);
     status_t            writeString16(const String16& str);
+    status_t            writeString16(const std::unique_ptr<String16>& str);
     status_t            writeString16(const char16_t* str, size_t len);
     status_t            writeStrongBinder(const sp<IBinder>& val);
     status_t            writeWeakBinder(const wp<IBinder>& val);
@@ -118,19 +119,35 @@
     status_t            writeChar(char16_t val);
     status_t            writeByte(int8_t val);
 
+    status_t            writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val);
     status_t            writeByteVector(const std::vector<int8_t>& val);
+    status_t            writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val);
     status_t            writeInt32Vector(const std::vector<int32_t>& val);
+    status_t            writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val);
     status_t            writeInt64Vector(const std::vector<int64_t>& val);
+    status_t            writeFloatVector(const std::unique_ptr<std::vector<float>>& val);
     status_t            writeFloatVector(const std::vector<float>& val);
+    status_t            writeDoubleVector(const std::unique_ptr<std::vector<double>>& val);
     status_t            writeDoubleVector(const std::vector<double>& val);
+    status_t            writeBoolVector(const std::unique_ptr<std::vector<bool>>& val);
     status_t            writeBoolVector(const std::vector<bool>& val);
+    status_t            writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val);
     status_t            writeCharVector(const std::vector<char16_t>& val);
+    status_t            writeString16Vector(
+                            const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val);
     status_t            writeString16Vector(const std::vector<String16>& val);
 
+    status_t            writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);
     status_t            writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
 
     template<typename T>
+    status_t            writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val);
+    template<typename T>
     status_t            writeParcelableVector(const std::vector<T>& val);
+
+    template<typename T>
+    status_t            writeNullableParcelable(const std::unique_ptr<T>& parcelable);
+
     status_t            writeParcelable(const Parcelable& parcelable);
 
     template<typename T>
@@ -164,6 +181,8 @@
     // Place a vector of file desciptors into the parcel. Each descriptor is
     // dup'd as in writeDupFileDescriptor
     status_t            writeUniqueFileDescriptorVector(
+                            const std::unique_ptr<std::vector<ScopedFd>>& val);
+    status_t            writeUniqueFileDescriptorVector(
                             const std::vector<ScopedFd>& val);
 
     // Writes a blob to the parcel.
@@ -215,27 +234,45 @@
     String8             readString8() const;
     String16            readString16() const;
     status_t            readString16(String16* pArg) const;
+    status_t            readString16(std::unique_ptr<String16>* pArg) const;
     const char16_t*     readString16Inplace(size_t* outLen) const;
     sp<IBinder>         readStrongBinder() const;
     status_t            readStrongBinder(sp<IBinder>* val) const;
     wp<IBinder>         readWeakBinder() const;
 
     template<typename T>
+    status_t            readParcelableVector(
+                            std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const;
+    template<typename T>
     status_t            readParcelableVector(std::vector<T>* val) const;
+
     status_t            readParcelable(Parcelable* parcelable) const;
 
     template<typename T>
+    status_t            readParcelable(std::unique_ptr<T>* parcelable) const;
+
+    template<typename T>
     status_t            readStrongBinder(sp<T>* val) const;
 
+    status_t            readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const;
     status_t            readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
 
+    status_t            readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const;
     status_t            readByteVector(std::vector<int8_t>* val) const;
+    status_t            readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const;
     status_t            readInt32Vector(std::vector<int32_t>* val) const;
+    status_t            readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const;
     status_t            readInt64Vector(std::vector<int64_t>* val) const;
+    status_t            readFloatVector(std::unique_ptr<std::vector<float>>* val) const;
     status_t            readFloatVector(std::vector<float>* val) const;
+    status_t            readDoubleVector(std::unique_ptr<std::vector<double>>* val) const;
     status_t            readDoubleVector(std::vector<double>* val) const;
+    status_t            readBoolVector(std::unique_ptr<std::vector<bool>>* val) const;
     status_t            readBoolVector(std::vector<bool>* val) const;
+    status_t            readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const;
     status_t            readCharVector(std::vector<char16_t>* val) const;
+    status_t            readString16Vector(
+                            std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const;
     status_t            readString16Vector(std::vector<String16>* val) const;
 
     template<typename T>
@@ -269,6 +306,8 @@
 
     // Retrieve a vector of smart file descriptors from the parcel.
     status_t            readUniqueFileDescriptorVector(
+                            std::unique_ptr<std::vector<ScopedFd>>* val) const;
+    status_t            readUniqueFileDescriptorVector(
                             std::vector<ScopedFd>* val) const;
 
     // Reads a blob from the parcel.
@@ -326,16 +365,28 @@
     template<class T>
     status_t            writeAligned(T val);
 
+    status_t            writeRawNullableParcelable(const Parcelable*
+                                                   parcelable);
+
     template<typename T, typename U>
     status_t            unsafeReadTypedVector(std::vector<T>* val,
                                               status_t(Parcel::*read_func)(U*) const) const;
     template<typename T>
+    status_t            readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
+                                                status_t(Parcel::*read_func)(T*) const) const;
+    template<typename T>
     status_t            readTypedVector(std::vector<T>* val,
                                         status_t(Parcel::*read_func)(T*) const) const;
     template<typename T, typename U>
     status_t            unsafeWriteTypedVector(const std::vector<T>& val,
                                                status_t(Parcel::*write_func)(U));
     template<typename T>
+    status_t            writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
+                                                 status_t(Parcel::*write_func)(const T&));
+    template<typename T>
+    status_t            writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
+                                                 status_t(Parcel::*write_func)(T));
+    template<typename T>
     status_t            writeTypedVector(const std::vector<T>& val,
                                          status_t(Parcel::*write_func)(const T&));
     template<typename T>
@@ -506,9 +557,8 @@
 
 template<typename T, typename U>
 status_t Parcel::unsafeReadTypedVector(
-        std::vector<T>* val, status_t(Parcel::*read_func)(U*) const) const {
-    val->clear();
-
+        std::vector<T>* val,
+        status_t(Parcel::*read_func)(U*) const) const {
     int32_t size;
     status_t status = this->readInt32(&size);
 
@@ -539,6 +589,30 @@
     return unsafeReadTypedVector(val, read_func);
 }
 
+template<typename T>
+status_t Parcel::readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
+                                         status_t(Parcel::*read_func)(T*) const) const {
+    const int32_t start = dataPosition();
+    int32_t size;
+    status_t status = readInt32(&size);
+    val->reset();
+
+    if (status != OK || size < 0) {
+        return status;
+    }
+
+    setDataPosition(start);
+    val->reset(new std::vector<T>());
+
+    status = unsafeReadTypedVector(val->get(), read_func);
+
+    if (status != OK) {
+        val->reset();
+    }
+
+    return status;
+}
+
 template<typename T, typename U>
 status_t Parcel::unsafeWriteTypedVector(const std::vector<T>& val,
                                         status_t(Parcel::*write_func)(U)) {
@@ -565,24 +639,104 @@
 
 template<typename T>
 status_t Parcel::writeTypedVector(const std::vector<T>& val,
-                          status_t(Parcel::*write_func)(const T&)) {
+                                  status_t(Parcel::*write_func)(const T&)) {
     return unsafeWriteTypedVector(val, write_func);
 }
 
 template<typename T>
 status_t Parcel::writeTypedVector(const std::vector<T>& val,
-                          status_t(Parcel::*write_func)(T)) {
+                                  status_t(Parcel::*write_func)(T)) {
     return unsafeWriteTypedVector(val, write_func);
 }
 
 template<typename T>
+status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
+                                          status_t(Parcel::*write_func)(const T&)) {
+    if (val.get() == nullptr) {
+        return this->writeInt32(-1);
+    }
+
+    return unsafeWriteTypedVector(*val, write_func);
+}
+
+template<typename T>
+status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
+                                          status_t(Parcel::*write_func)(T)) {
+    if (val.get() == nullptr) {
+        return this->writeInt32(-1);
+    }
+
+    return unsafeWriteTypedVector(*val, write_func);
+}
+
+template<typename T>
 status_t Parcel::readParcelableVector(std::vector<T>* val) const {
-    return unsafeReadTypedVector(val, &Parcel::readParcelable);
+    return unsafeReadTypedVector<T, Parcelable>(val, &Parcel::readParcelable);
+}
+
+template<typename T>
+status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const {
+    const int32_t start = dataPosition();
+    int32_t size;
+    status_t status = readInt32(&size);
+    val->reset();
+
+    if (status != OK || size < 0) {
+        return status;
+    }
+
+    setDataPosition(start);
+    val->reset(new std::vector<T>());
+
+    status = unsafeReadTypedVector(val->get(), &Parcel::readParcelable);
+
+    if (status != OK) {
+        val->reset();
+    }
+
+    return status;
+}
+
+template<typename T>
+status_t Parcel::readParcelable(std::unique_ptr<T>* parcelable) const {
+    const int32_t start = dataPosition();
+    int32_t present;
+    status_t status = readInt32(&present);
+    parcelable->reset();
+
+    if (status != OK || !present) {
+        return status;
+    }
+
+    setDataPosition(start);
+    parcelable->reset(new T());
+
+    status = readParcelable(parcelable->get());
+
+    if (status != OK) {
+        parcelable->reset();
+    }
+
+    return status;
+}
+
+template<typename T>
+status_t Parcel::writeNullableParcelable(const std::unique_ptr<T>& parcelable) {
+    return writeRawNullableParcelable(parcelable.get());
 }
 
 template<typename T>
 status_t Parcel::writeParcelableVector(const std::vector<T>& val) {
-    return unsafeWriteTypedVector(val, &Parcel::writeParcelable);
+    return unsafeWriteTypedVector<T,const Parcelable&>(val, &Parcel::writeParcelable);
+}
+
+template<typename T>
+status_t Parcel::writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val) {
+    if (val.get() == nullptr) {
+        return this->writeInt32(-1);
+    }
+
+    return unsafeWriteTypedVector(*val, &Parcel::writeParcelable);
 }
 
 // ---------------------------------------------------------------------------