Use std::optional for @nullable (AIDL)

Previously, nullable types were mapped to std::unique_ptr for C++
backend. But std::unique_ptr typically involves unnecessary alloc/dealloc.

For example, if nullable string is represented in unique_ptr<string>, we
should do "unique_ptr<string>(new string(value))" to set a value.

To avoid breaking all hand-written parcelables, only new read/write
functions are added to Parcel class and they are used only by
aidl-generated code and their implementations.

Bug: 144773267
Test: build/flash/boot
      atest --test-mapping frameworks/native/libs/binder

Merged-In: I2c801e3b69f2f8ccf44267f15cbf79e1d8fbf19e
Change-Id: I2c801e3b69f2f8ccf44267f15cbf79e1d8fbf19e
(cherry picked from commit 1e1c5fbbbe8a76150fe832c8f974cbd543aa0860)

Exempt-From-Owner-Approval: CP from master
diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp
index b2bd9e5..e5f0a11 100644
--- a/libs/binder/IAppOpsService.cpp
+++ b/libs/binder/IAppOpsService.cpp
@@ -22,6 +22,8 @@
 #include <binder/Parcel.h>
 #include <utils/String8.h>
 
+#include <optional>
+
 namespace android {
 
 // ----------------------------------------------------------------------
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index f1077ae..1d94bd6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -749,6 +749,13 @@
     return NO_ERROR;
 }
 
+status_t Parcel::writeUtf8AsUtf16(const std::optional<std::string>& str) {
+  if (!str) {
+    return writeInt32(-1);
+  }
+  return writeUtf8AsUtf16(*str);
+}
+
 status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
   if (!str) {
     return writeInt32(-1);
@@ -773,6 +780,12 @@
     return writeByteVectorInternal(val.data(), val.size());
 }
 
+status_t Parcel::writeByteVector(const std::optional<std::vector<int8_t>>& val)
+{
+    if (!val) return writeInt32(-1);
+    return writeByteVectorInternal(val->data(), val->size());
+}
+
 status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
 {
     if (!val) return writeInt32(-1);
@@ -783,6 +796,12 @@
     return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
 }
 
+status_t Parcel::writeByteVector(const std::optional<std::vector<uint8_t>>& val)
+{
+    if (!val) return writeInt32(-1);
+    return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
+}
+
 status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
 {
     if (!val) return writeInt32(-1);
@@ -794,6 +813,11 @@
     return writeTypedVector(val, &Parcel::writeInt32);
 }
 
+status_t Parcel::writeInt32Vector(const std::optional<std::vector<int32_t>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeInt32);
+}
+
 status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeInt32);
@@ -804,6 +828,11 @@
     return writeTypedVector(val, &Parcel::writeInt64);
 }
 
+status_t Parcel::writeInt64Vector(const std::optional<std::vector<int64_t>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeInt64);
+}
+
 status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeInt64);
@@ -814,6 +843,11 @@
     return writeTypedVector(val, &Parcel::writeUint64);
 }
 
+status_t Parcel::writeUint64Vector(const std::optional<std::vector<uint64_t>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeUint64);
+}
+
 status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeUint64);
@@ -824,6 +858,11 @@
     return writeTypedVector(val, &Parcel::writeFloat);
 }
 
+status_t Parcel::writeFloatVector(const std::optional<std::vector<float>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeFloat);
+}
+
 status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeFloat);
@@ -834,6 +873,11 @@
     return writeTypedVector(val, &Parcel::writeDouble);
 }
 
+status_t Parcel::writeDoubleVector(const std::optional<std::vector<double>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeDouble);
+}
+
 status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeDouble);
@@ -844,6 +888,11 @@
     return writeTypedVector(val, &Parcel::writeBool);
 }
 
+status_t Parcel::writeBoolVector(const std::optional<std::vector<bool>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeBool);
+}
+
 status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeBool);
@@ -854,6 +903,11 @@
     return writeTypedVector(val, &Parcel::writeChar);
 }
 
+status_t Parcel::writeCharVector(const std::optional<std::vector<char16_t>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeChar);
+}
+
 status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeChar);
@@ -865,12 +919,23 @@
 }
 
 status_t Parcel::writeString16Vector(
+        const std::optional<std::vector<std::optional<String16>>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeString16);
+}
+
+status_t Parcel::writeString16Vector(
         const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeString16);
 }
 
 status_t Parcel::writeUtf8VectorAsUtf16Vector(
+                        const std::optional<std::vector<std::optional<std::string>>>& val) {
+    return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
+}
+
+status_t Parcel::writeUtf8VectorAsUtf16Vector(
                         const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
     return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
 }
@@ -995,6 +1060,15 @@
     return err;
 }
 
+status_t Parcel::writeString16(const std::optional<String16>& str)
+{
+    if (!str) {
+        return writeInt32(-1);
+    }
+
+    return writeString16(*str);
+}
+
 status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
 {
     if (!str) {
@@ -1037,11 +1111,20 @@
     return writeTypedVector(val, &Parcel::writeStrongBinder);
 }
 
+status_t Parcel::writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
+}
+
 status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
 {
     return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
 }
 
+status_t Parcel::readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
+}
+
 status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
     return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
 }
@@ -1140,6 +1223,10 @@
     return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
 }
 
+status_t Parcel::writeUniqueFileDescriptorVector(const std::optional<std::vector<base::unique_fd>>& val) {
+    return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
+}
+
 status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
     return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
 }
@@ -1471,6 +1558,17 @@
     return readByteVectorInternal(val, size);
 }
 
+status_t Parcel::readByteVector(std::optional<std::vector<int8_t>>* val) const {
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
+    if (!*val) {
+        // reserveOutVector does not create the out vector if size is < 0.
+        // This occurs when writing a null byte vector.
+        return OK;
+    }
+    return readByteVectorInternal(&**val, size);
+}
+
 status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
     size_t size;
     if (status_t status = reserveOutVector(val, &size); status != OK) return status;
@@ -1482,6 +1580,17 @@
     return readByteVectorInternal(val->get(), size);
 }
 
+status_t Parcel::readByteVector(std::optional<std::vector<uint8_t>>* val) const {
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
+    if (!*val) {
+        // reserveOutVector does not create the out vector if size is < 0.
+        // This occurs when writing a null byte vector.
+        return OK;
+    }
+    return readByteVectorInternal(&**val, size);
+}
+
 status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
     size_t size;
     if (status_t status = reserveOutVector(val, &size); status != OK) return status;
@@ -1493,6 +1602,10 @@
     return readByteVectorInternal(val->get(), size);
 }
 
+status_t Parcel::readInt32Vector(std::optional<std::vector<int32_t>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readInt32);
+}
+
 status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
     return readNullableTypedVector(val, &Parcel::readInt32);
 }
@@ -1501,6 +1614,10 @@
     return readTypedVector(val, &Parcel::readInt32);
 }
 
+status_t Parcel::readInt64Vector(std::optional<std::vector<int64_t>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readInt64);
+}
+
 status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
     return readNullableTypedVector(val, &Parcel::readInt64);
 }
@@ -1509,6 +1626,10 @@
     return readTypedVector(val, &Parcel::readInt64);
 }
 
+status_t Parcel::readUint64Vector(std::optional<std::vector<uint64_t>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readUint64);
+}
+
 status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
     return readNullableTypedVector(val, &Parcel::readUint64);
 }
@@ -1517,6 +1638,10 @@
     return readTypedVector(val, &Parcel::readUint64);
 }
 
+status_t Parcel::readFloatVector(std::optional<std::vector<float>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readFloat);
+}
+
 status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
     return readNullableTypedVector(val, &Parcel::readFloat);
 }
@@ -1525,6 +1650,10 @@
     return readTypedVector(val, &Parcel::readFloat);
 }
 
+status_t Parcel::readDoubleVector(std::optional<std::vector<double>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readDouble);
+}
+
 status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
     return readNullableTypedVector(val, &Parcel::readDouble);
 }
@@ -1533,6 +1662,28 @@
     return readTypedVector(val, &Parcel::readDouble);
 }
 
+status_t Parcel::readBoolVector(std::optional<std::vector<bool>>* 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->emplace();
+
+    status = readBoolVector(&**val);
+
+    if (status != OK) {
+        val->reset();
+    }
+
+    return status;
+}
+
 status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
     const int32_t start = dataPosition();
     int32_t size;
@@ -1585,6 +1736,10 @@
     return OK;
 }
 
+status_t Parcel::readCharVector(std::optional<std::vector<char16_t>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readChar);
+}
+
 status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
     return readNullableTypedVector(val, &Parcel::readChar);
 }
@@ -1594,6 +1749,11 @@
 }
 
 status_t Parcel::readString16Vector(
+        std::optional<std::vector<std::optional<String16>>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readString16);
+}
+
+status_t Parcel::readString16Vector(
         std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
     return readNullableTypedVector(val, &Parcel::readString16);
 }
@@ -1603,6 +1763,11 @@
 }
 
 status_t Parcel::readUtf8VectorFromUtf16Vector(
+        std::optional<std::vector<std::optional<std::string>>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
+}
+
+status_t Parcel::readUtf8VectorFromUtf16Vector(
         std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
     return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
 }
@@ -1794,6 +1959,21 @@
     return NO_ERROR;
 }
 
+status_t Parcel::readUtf8FromUtf16(std::optional<std::string>* str) const {
+    const int32_t start = dataPosition();
+    int32_t size;
+    status_t status = readInt32(&size);
+    str->reset();
+
+    if (status != OK || size < 0) {
+        return status;
+    }
+
+    setDataPosition(start);
+    str->emplace();
+    return readUtf8FromUtf16(&**str);
+}
+
 status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
     const int32_t start = dataPosition();
     int32_t size;
@@ -1870,6 +2050,29 @@
     return String16();
 }
 
+status_t Parcel::readString16(std::optional<String16>* pArg) const
+{
+    const int32_t start = dataPosition();
+    int32_t size;
+    status_t status = readInt32(&size);
+    pArg->reset();
+
+    if (status != OK || size < 0) {
+        return status;
+    }
+
+    setDataPosition(start);
+    pArg->emplace();
+
+    status = readString16(&**pArg);
+
+    if (status != OK) {
+        pArg->reset();
+    }
+
+    return status;
+}
+
 status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
 {
     const int32_t start = dataPosition();
@@ -2075,6 +2278,10 @@
     return OK;
 }
 
+status_t Parcel::readUniqueFileDescriptorVector(std::optional<std::vector<base::unique_fd>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
+}
+
 status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
     return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
 }
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 4b1a758..97f1aee 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -120,6 +120,7 @@
     status_t            writeCString(const char* str);
     status_t            writeString8(const String8& str);
     status_t            writeString16(const String16& str);
+    status_t            writeString16(const std::optional<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);
@@ -131,33 +132,48 @@
 
     // Take a UTF8 encoded string, convert to UTF16, write it to the parcel.
     status_t            writeUtf8AsUtf16(const std::string& str);
+    status_t            writeUtf8AsUtf16(const std::optional<std::string>& str);
     status_t            writeUtf8AsUtf16(const std::unique_ptr<std::string>& str);
 
+    status_t            writeByteVector(const std::optional<std::vector<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            writeByteVector(const std::optional<std::vector<uint8_t>>& val);
     status_t            writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val);
     status_t            writeByteVector(const std::vector<uint8_t>& val);
+    status_t            writeInt32Vector(const std::optional<std::vector<int32_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::optional<std::vector<int64_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            writeUint64Vector(const std::optional<std::vector<uint64_t>>& val);
     status_t            writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val);
     status_t            writeUint64Vector(const std::vector<uint64_t>& val);
+    status_t            writeFloatVector(const std::optional<std::vector<float>>& 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::optional<std::vector<double>>& 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::optional<std::vector<bool>>& 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::optional<std::vector<char16_t>>& 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::optional<std::vector<std::optional<String16>>>& 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            writeUtf8VectorAsUtf16Vector(
+                            const std::optional<std::vector<std::optional<std::string>>>& val);
+    status_t            writeUtf8VectorAsUtf16Vector(
                             const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val);
     status_t            writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val);
 
+    status_t            writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val);
     status_t            writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);
     status_t            writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
 
@@ -166,14 +182,20 @@
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            writeEnumVector(const std::vector<T>& val);
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+    status_t            writeEnumVector(const std::optional<std::vector<T>>& val);
+    template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
     // Write an Enum vector with underlying type != int8_t.
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            writeEnumVector(const std::vector<T>& val);
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+    status_t            writeEnumVector(const std::optional<std::vector<T>>& val);
+    template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
 
     template<typename T>
+    status_t            writeParcelableVector(const std::optional<std::vector<std::optional<T>>>& 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::shared_ptr<std::vector<std::unique_ptr<T>>>& val);
@@ -181,6 +203,8 @@
     status_t            writeParcelableVector(const std::vector<T>& val);
 
     template<typename T>
+    status_t            writeNullableParcelable(const std::optional<T>& parcelable);
+    template<typename T>
     status_t            writeNullableParcelable(const std::unique_ptr<T>& parcelable);
 
     status_t            writeParcelable(const Parcelable& parcelable);
@@ -194,6 +218,8 @@
     template<typename T>
     status_t            writeVectorSize(const std::vector<T>& val);
     template<typename T>
+    status_t            writeVectorSize(const std::optional<std::vector<T>>& val);
+    template<typename T>
     status_t            writeVectorSize(const std::unique_ptr<std::vector<T>>& val);
 
     // Place a native_handle into the parcel (the native_handle's file-
@@ -229,6 +255,8 @@
     // Place a vector of file desciptors into the parcel. Each descriptor is
     // dup'd as in writeDupFileDescriptor
     status_t            writeUniqueFileDescriptorVector(
+                            const std::optional<std::vector<base::unique_fd>>& val);
+    status_t            writeUniqueFileDescriptorVector(
                             const std::unique_ptr<std::vector<base::unique_fd>>& val);
     status_t            writeUniqueFileDescriptorVector(
                             const std::vector<base::unique_fd>& val);
@@ -278,6 +306,7 @@
 
     // Read a UTF16 encoded string, convert to UTF8
     status_t            readUtf8FromUtf16(std::string* str) const;
+    status_t            readUtf8FromUtf16(std::optional<std::string>* str) const;
     status_t            readUtf8FromUtf16(std::unique_ptr<std::string>* str) const;
 
     const char*         readCString() const;
@@ -285,27 +314,34 @@
     status_t            readString8(String8* pArg) const;
     String16            readString16() const;
     status_t            readString16(String16* pArg) const;
+    status_t            readString16(std::optional<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;
     status_t            readNullableStrongBinder(sp<IBinder>* val) const;
 
-
     // Read an Enum vector with underlying type int8_t.
     // Does not use padding; each byte is contiguous.
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            readEnumVector(std::vector<T>* val) const;
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
+    template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+    status_t            readEnumVector(std::optional<std::vector<T>>* val) const;
     // Read an Enum vector with underlying type != int8_t.
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            readEnumVector(std::vector<T>* val) const;
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
+    template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
+    status_t            readEnumVector(std::optional<std::vector<T>>* val) const;
 
     template<typename T>
     status_t            readParcelableVector(
+                            std::optional<std::vector<std::optional<T>>>* val) 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;
@@ -313,6 +349,8 @@
     status_t            readParcelable(Parcelable* parcelable) const;
 
     template<typename T>
+    status_t            readParcelable(std::optional<T>* parcelable) const;
+    template<typename T>
     status_t            readParcelable(std::unique_ptr<T>* parcelable) const;
 
     template<typename T>
@@ -321,31 +359,45 @@
     template<typename T>
     status_t            readNullableStrongBinder(sp<T>* val) const;
 
+    status_t            readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* 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::optional<std::vector<int8_t>>* 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            readByteVector(std::optional<std::vector<uint8_t>>* val) const;
     status_t            readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const;
     status_t            readByteVector(std::vector<uint8_t>* val) const;
+    status_t            readInt32Vector(std::optional<std::vector<int32_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::optional<std::vector<int64_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            readUint64Vector(std::optional<std::vector<uint64_t>>* val) const;
     status_t            readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const;
     status_t            readUint64Vector(std::vector<uint64_t>* val) const;
+    status_t            readFloatVector(std::optional<std::vector<float>>* 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::optional<std::vector<double>>* 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::optional<std::vector<bool>>* 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::optional<std::vector<char16_t>>* 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::optional<std::vector<std::optional<String16>>>* val) const;
+    status_t            readString16Vector(
                             std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const;
     status_t            readString16Vector(std::vector<String16>* val) const;
     status_t            readUtf8VectorFromUtf16Vector(
+                            std::optional<std::vector<std::optional<std::string>>>* val) const;
+    status_t            readUtf8VectorFromUtf16Vector(
                             std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const;
     status_t            readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const;
 
@@ -358,10 +410,15 @@
     template<typename T>
     status_t            resizeOutVector(std::vector<T>* val) const;
     template<typename T>
+    status_t            resizeOutVector(std::optional<std::vector<T>>* val) const;
+    template<typename T>
     status_t            resizeOutVector(std::unique_ptr<std::vector<T>>* val) const;
     template<typename T>
     status_t            reserveOutVector(std::vector<T>* val, size_t* size) const;
     template<typename T>
+    status_t            reserveOutVector(std::optional<std::vector<T>>* val,
+                                         size_t* size) const;
+    template<typename T>
     status_t            reserveOutVector(std::unique_ptr<std::vector<T>>* val,
                                          size_t* size) const;
 
@@ -397,6 +454,8 @@
 
     // Retrieve a vector of smart file descriptors from the parcel.
     status_t            readUniqueFileDescriptorVector(
+                            std::optional<std::vector<base::unique_fd>>* val) const;
+    status_t            readUniqueFileDescriptorVector(
                             std::unique_ptr<std::vector<base::unique_fd>>* val) const;
     status_t            readUniqueFileDescriptorVector(
                             std::vector<base::unique_fd>* val) const;
@@ -490,6 +549,9 @@
     status_t            unsafeReadTypedVector(std::vector<T>* val,
                                               status_t(Parcel::*read_func)(U*) const) const;
     template<typename T>
+    status_t            readNullableTypedVector(std::optional<std::vector<T>>* val,
+                                                status_t(Parcel::*read_func)(T*) 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>
@@ -499,9 +561,15 @@
     status_t            unsafeWriteTypedVector(const std::vector<T>& val,
                                                status_t(Parcel::*write_func)(U));
     template<typename T>
+    status_t            writeNullableTypedVector(const std::optional<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)(const T&));
     template<typename T>
+    status_t            writeNullableTypedVector(const std::optional<std::vector<T>>& val,
+                                                 status_t(Parcel::*write_func)(T));
+    template<typename T>
     status_t            writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
                                                  status_t(Parcel::*write_func)(T));
     template<typename T>
@@ -689,6 +757,15 @@
 }
 
 template<typename T>
+status_t Parcel::writeVectorSize(const std::optional<std::vector<T>>& val) {
+    if (!val) {
+        return writeInt32(-1);
+    }
+
+    return writeVectorSize(*val);
+}
+
+template<typename T>
 status_t Parcel::writeVectorSize(const std::unique_ptr<std::vector<T>>& val) {
     if (!val) {
         return writeInt32(-1);
@@ -713,6 +790,22 @@
 }
 
 template<typename T>
+status_t Parcel::resizeOutVector(std::optional<std::vector<T>>* val) const {
+    int32_t size;
+    status_t err = readInt32(&size);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    val->reset();
+    if (size >= 0) {
+        val->emplace(size_t(size));
+    }
+
+    return OK;
+}
+
+template<typename T>
 status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
     int32_t size;
     status_t err = readInt32(&size);
@@ -745,6 +838,25 @@
 }
 
 template<typename T>
+status_t Parcel::reserveOutVector(std::optional<std::vector<T>>* val, size_t* size) const {
+    int32_t read_size;
+    status_t err = readInt32(&read_size);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    if (read_size >= 0) {
+        *size = static_cast<size_t>(read_size);
+        val->emplace();
+        (*val)->reserve(*size);
+    } else {
+        val->reset();
+    }
+
+    return OK;
+}
+
+template<typename T>
 status_t Parcel::reserveOutVector(std::unique_ptr<std::vector<T>>* val,
                                   size_t* size) const {
     int32_t read_size;
@@ -839,6 +951,30 @@
 }
 
 template<typename T>
+status_t Parcel::readNullableTypedVector(std::optional<std::vector<T>>* val,
+                                         status_t(Parcel::*read_func)(T*) const) const {
+    const size_t start = dataPosition();
+    int32_t size;
+    status_t status = readInt32(&size);
+    val->reset();
+
+    if (status != OK || size < 0) {
+        return status;
+    }
+
+    setDataPosition(start);
+    val->emplace();
+
+    status = unsafeReadTypedVector(&**val, read_func);
+
+    if (status != OK) {
+       val->reset();
+    }
+
+    return status;
+}
+
+template<typename T>
 status_t Parcel::readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
                                          status_t(Parcel::*read_func)(T*) const) const {
     const size_t start = dataPosition();
@@ -899,6 +1035,16 @@
 }
 
 template<typename T>
+status_t Parcel::writeNullableTypedVector(const std::optional<std::vector<T>>& val,
+                                          status_t(Parcel::*write_func)(const T&)) {
+    if (!val) {
+        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)(const T&)) {
     if (val.get() == nullptr) {
@@ -909,6 +1055,16 @@
 }
 
 template<typename T>
+status_t Parcel::writeNullableTypedVector(const std::optional<std::vector<T>>& val,
+                                          status_t(Parcel::*write_func)(T)) {
+    if (!val) {
+        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) {
@@ -924,6 +1080,30 @@
 }
 
 template<typename T>
+status_t Parcel::readParcelableVector(std::optional<std::vector<std::optional<T>>>* val) const {
+    const size_t start = dataPosition();
+    int32_t size;
+    status_t status = readInt32(&size);
+    val->reset();
+
+    if (status != OK || size < 0) {
+        return status;
+    }
+
+    setDataPosition(start);
+    val->emplace();
+
+    using NullableT = std::optional<T>;
+    status = unsafeReadTypedVector<NullableT, NullableT>(&**val, &Parcel::readParcelable);
+
+    if (status != OK) {
+        val->reset();
+    }
+
+    return status;
+}
+
+template<typename T>
 status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const {
     const size_t start = dataPosition();
     int32_t size;
@@ -937,7 +1117,8 @@
     setDataPosition(start);
     val->reset(new std::vector<std::unique_ptr<T>>());
 
-    status = unsafeReadTypedVector(val->get(), &Parcel::readParcelable<T>);
+    using NullableT = std::unique_ptr<T>;
+    status = unsafeReadTypedVector<NullableT, NullableT>(val->get(), &Parcel::readParcelable);
 
     if (status != OK) {
         val->reset();
@@ -947,6 +1128,29 @@
 }
 
 template<typename T>
+status_t Parcel::readParcelable(std::optional<T>* parcelable) const {
+    const size_t start = dataPosition();
+    int32_t present;
+    status_t status = readInt32(&present);
+    parcelable->reset();
+
+    if (status != OK || !present) {
+        return status;
+    }
+
+    setDataPosition(start);
+    parcelable->emplace();
+
+    status = readParcelable(&**parcelable);
+
+    if (status != OK) {
+        parcelable->reset();
+    }
+
+    return status;
+}
+
+template<typename T>
 status_t Parcel::readParcelable(std::unique_ptr<T>* parcelable) const {
     const size_t start = dataPosition();
     int32_t present;
@@ -970,6 +1174,11 @@
 }
 
 template<typename T>
+status_t Parcel::writeNullableParcelable(const std::optional<T>& parcelable) {
+    return writeRawNullableParcelable(parcelable ? &*parcelable : nullptr);
+}
+
+template<typename T>
 status_t Parcel::writeNullableParcelable(const std::unique_ptr<T>& parcelable) {
     return writeRawNullableParcelable(parcelable.get());
 }
@@ -980,6 +1189,16 @@
 }
 
 template<typename T>
+status_t Parcel::writeParcelableVector(const std::optional<std::vector<std::optional<T>>>& val) {
+    if (!val) {
+        return this->writeInt32(-1);
+    }
+
+    using NullableT = std::optional<T>;
+    return unsafeWriteTypedVector<NullableT, const NullableT&>(*val, &Parcel::writeNullableParcelable);
+}
+
+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);
@@ -994,7 +1213,8 @@
         return this->writeInt32(-1);
     }
 
-    return unsafeWriteTypedVector(*val, &Parcel::writeNullableParcelable<T>);
+    using NullableT = std::unique_ptr<T>;
+    return unsafeWriteTypedVector<NullableT, const NullableT&>(*val, &Parcel::writeNullableParcelable);
 }
 
 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>>
@@ -1011,6 +1231,11 @@
     return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
 }
 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::writeEnumVector(const std::optional<std::vector<T>>& val) {
+    if (!val) return writeInt32(-1);
+    return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
 status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) {
     if (!val) return writeInt32(-1);
     return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
@@ -1020,6 +1245,10 @@
     return writeTypedVector(val, &Parcel::writeEnum);
 }
 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::writeEnumVector(const std::optional<std::vector<T>>& val) {
+    return writeNullableTypedVector(val, &Parcel::writeEnum);
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
 status_t Parcel::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) {
     return writeNullableTypedVector(val, &Parcel::writeEnum);
 }
@@ -1051,6 +1280,17 @@
     return readByteVectorInternal(val, size);
 }
 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::readEnumVector(std::optional<std::vector<T>>* val) const {
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
+    if (!*val) {
+        // reserveOutVector does not create the out vector if size is < 0.
+        // This occurs when writing a null Enum vector.
+        return OK;
+    }
+    return readByteVectorInternal(&**val, size);
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
 status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const {
     size_t size;
     if (status_t status = reserveOutVector(val, &size); status != OK) return status;
@@ -1066,6 +1306,10 @@
     return readTypedVector(val, &Parcel::readEnum);
 }
 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
+status_t Parcel::readEnumVector(std::optional<std::vector<T>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readEnum);
+}
+template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
 status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const {
     return readNullableTypedVector(val, &Parcel::readEnum);
 }
diff --git a/libs/binder/include/binder/ParcelFileDescriptor.h b/libs/binder/include/binder/ParcelFileDescriptor.h
index 4635ad8..2ede6c4 100644
--- a/libs/binder/include/binder/ParcelFileDescriptor.h
+++ b/libs/binder/include/binder/ParcelFileDescriptor.h
@@ -32,6 +32,7 @@
     ParcelFileDescriptor();
     explicit ParcelFileDescriptor(android::base::unique_fd fd);
     ParcelFileDescriptor(ParcelFileDescriptor&& other) : mFd(std::move(other.mFd)) { }
+    ParcelFileDescriptor& operator=(ParcelFileDescriptor&& other) = default;
     ~ParcelFileDescriptor() override;
 
     int get() const { return mFd.get(); }