Merge "Add support for PersistableBundle in C++"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 5a66bc30..81c8967 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -94,6 +94,7 @@
     { "power",      "Power Management", ATRACE_TAG_POWER, { } },
     { "pm",         "Package Manager",  ATRACE_TAG_PACKAGE_MANAGER, { } },
     { "ss",         "System Server",    ATRACE_TAG_SYSTEM_SERVER, { } },
+    { "database",   "Database",         ATRACE_TAG_DATABASE, { } },
     { "sched",      "CPU Scheduling",   0, {
         { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" },
         { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" },
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 3373192..74c8d43 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -51,6 +51,9 @@
     chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_locked/enable
     chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_unlock/enable
 
+    # Tracing disabled by default
+    write /sys/kernel/debug/tracing/tracing_on 0
+
 # Allow only the shell group to read and truncate the kernel trace.
     chown root shell /sys/kernel/debug/tracing/trace
     chmod 0660 /sys/kernel/debug/tracing/trace
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index 8c7c4a8..6442701 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -1,6 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := libdumpstate_default.c
+LOCAL_SRC_FILES := libdumpstate_default.cpp
 LOCAL_MODULE := libdumpstate.default
 include $(BUILD_STATIC_LIBRARY)
 
@@ -10,7 +10,7 @@
 LOCAL_CFLAGS := -DFWDUMP_$(BOARD_WLAN_DEVICE)
 endif
 
-LOCAL_SRC_FILES := dumpstate.c utils.c
+LOCAL_SRC_FILES := dumpstate.cpp utils.cpp
 
 LOCAL_MODULE := dumpstate
 
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.cpp
similarity index 98%
rename from cmds/dumpstate/dumpstate.c
rename to cmds/dumpstate/dumpstate.cpp
index e0fd655..12ad220 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -229,7 +229,7 @@
 }
 
 /* timeout in ms */
-static unsigned long logcat_timeout(char *name) {
+static unsigned long logcat_timeout(const char *name) {
     static const char global_tuneable[] = "persist.logd.size"; // Settings App
     static const char global_default[] = "ro.logd.size";       // BoardConfig.mk
     char key[PROP_NAME_MAX];
@@ -340,11 +340,12 @@
                                                         "-v", "printable",
                                                         "-d",
                                                         "*:v", NULL);
-    timeout = logcat_timeout("events");
+    timeout = logcat_timeout("events") + logcat_timeout("security");
     if (timeout < 20000) {
         timeout = 20000;
     }
     run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events",
+                                                       "-b", "security",
                                                        "-v", "threadtime",
                                                        "-v", "printable",
                                                        "-d",
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 228f09c..3b6abc1 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -24,6 +24,10 @@
 
 #define SU_PATH "/system/xbin/su"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef void (for_each_pid_func)(int, const char *);
 typedef void (for_each_tid_func)(int, int, const char *);
 
@@ -87,4 +91,8 @@
 /* dump eMMC Extended CSD data */
 void dump_emmc_ecsd(const char *ext_csd_path);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _DUMPSTATE_H_ */
diff --git a/cmds/dumpstate/libdumpstate_default.c b/cmds/dumpstate/libdumpstate_default.cpp
similarity index 99%
rename from cmds/dumpstate/libdumpstate_default.c
rename to cmds/dumpstate/libdumpstate_default.cpp
index fd840df..415ecdc 100644
--- a/cmds/dumpstate/libdumpstate_default.c
+++ b/cmds/dumpstate/libdumpstate_default.cpp
@@ -19,4 +19,3 @@
 void dumpstate_board(void)
 {
 }
-
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.cpp
similarity index 97%
rename from cmds/dumpstate/utils.c
rename to cmds/dumpstate/utils.cpp
index 47acb63..c3e0262 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.cpp
@@ -117,19 +117,19 @@
 }
 
 static void for_each_pid_helper(int pid, const char *cmdline, void *arg) {
-    for_each_pid_func *func = arg;
+    for_each_pid_func *func = (for_each_pid_func*) arg;
     func(pid, cmdline);
 }
 
 void for_each_pid(for_each_pid_func func, const char *header) {
-    __for_each_pid(for_each_pid_helper, header, func);
+    __for_each_pid(for_each_pid_helper, header, (void *) func);
 }
 
 static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {
     DIR *d;
     struct dirent *de;
     char taskpath[255];
-    for_each_tid_func *func = arg;
+    for_each_tid_func *func = (for_each_tid_func*) arg;
 
     sprintf(taskpath, "/proc/%d/task", pid);
 
@@ -174,7 +174,7 @@
 }
 
 void for_each_tid(for_each_tid_func func, const char *header) {
-    __for_each_pid(for_each_tid_helper, header, func);
+    __for_each_pid(for_each_tid_helper, header, (void *) func);
 }
 
 void show_wchan(int pid, int tid, const char *name) {
@@ -322,7 +322,7 @@
     DIR *dirp;
     struct dirent *d;
     char *newpath = NULL;
-    char *slash = "/";
+    const char *slash = "/";
     int fd, retval = 0;
 
     if (title) {
@@ -640,6 +640,10 @@
         return NULL;
     }
 
+    /* Variables below must be initialized before 'goto' statements */
+    int dalvik_found = 0;
+    int ifd, wfd = -1;
+
     /* walk /proc and kill -QUIT all Dalvik processes */
     DIR *proc = opendir("/proc");
     if (proc == NULL) {
@@ -648,20 +652,19 @@
     }
 
     /* use inotify to find when processes are done dumping */
-    int ifd = inotify_init();
+    ifd = inotify_init();
     if (ifd < 0) {
         fprintf(stderr, "inotify_init: %s\n", strerror(errno));
         goto error_close_fd;
     }
 
-    int wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE);
+    wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE);
     if (wfd < 0) {
         fprintf(stderr, "inotify_add_watch(%s): %s\n", traces_path, strerror(errno));
         goto error_close_ifd;
     }
 
     struct dirent *d;
-    int dalvik_found = 0;
     while ((d = readdir(proc))) {
         int pid = atoi(d->d_name);
         if (pid <= 0) continue;
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 43b6543..d98d4c5 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -23,8 +23,12 @@
 #include <utils/Vector.h>
 
 
+// linux/binder.h already defines this, but we can't just include it from there
+// because there are host builds that include this file.
+#ifndef B_PACK_CHARS
 #define B_PACK_CHARS(c1, c2, c3, c4) \
     ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
+#endif  // B_PACK_CHARS
 
 // ---------------------------------------------------------------------------
 namespace android {
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);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 3abb44f..e30e65d 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -743,6 +743,15 @@
     return NULL;
 }
 
+status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
+{
+    if (!val) {
+        return writeInt32(-1);
+    }
+
+    return writeByteVector(*val);
+}
+
 status_t Parcel::writeByteVector(const std::vector<int8_t>& val)
 {
     status_t status;
@@ -771,36 +780,72 @@
     return writeTypedVector(val, &Parcel::writeInt32);
 }
 
+status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeInt32);
+}
+
 status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
 {
     return writeTypedVector(val, &Parcel::writeInt64);
 }
 
+status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeInt64);
+}
+
 status_t Parcel::writeFloatVector(const std::vector<float>& val)
 {
     return writeTypedVector(val, &Parcel::writeFloat);
 }
 
+status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeFloat);
+}
+
 status_t Parcel::writeDoubleVector(const std::vector<double>& val)
 {
     return writeTypedVector(val, &Parcel::writeDouble);
 }
 
+status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeDouble);
+}
+
 status_t Parcel::writeBoolVector(const std::vector<bool>& val)
 {
     return writeTypedVector(val, &Parcel::writeBool);
 }
 
+status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeBool);
+}
+
 status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
 {
     return writeTypedVector(val, &Parcel::writeChar);
 }
 
+status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeChar);
+}
+
 status_t Parcel::writeString16Vector(const std::vector<String16>& val)
 {
     return writeTypedVector(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::writeInt32(int32_t val)
 {
     return writeAligned(val);
@@ -917,6 +962,15 @@
     return err;
 }
 
+status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
+{
+    if (!str) {
+        return writeInt32(-1);
+    }
+
+    return writeString16(*str);
+}
+
 status_t Parcel::writeString16(const String16& str)
 {
     return writeString16(str.string(), str.size());
@@ -950,6 +1004,15 @@
     return writeTypedVector(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::unique_ptr<std::vector<sp<IBinder>>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readStrongBinder);
+}
+
 status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
     return readTypedVector(val, &Parcel::readStrongBinder);
 }
@@ -959,6 +1022,14 @@
     return flatten_binder(ProcessState::self(), val, this);
 }
 
+status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
+    if (!parcelable) {
+        return writeInt32(0);
+    }
+
+    return writeParcelable(*parcelable);
+}
+
 status_t Parcel::writeParcelable(const Parcelable& parcelable) {
     status_t status = writeInt32(1);  // parcelable is not null.
     if (status != OK) {
@@ -1022,6 +1093,10 @@
     return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
 }
 
+status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<ScopedFd>>& val) {
+    return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
+}
+
 status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
 {
     if (len > INT32_MAX) {
@@ -1287,25 +1362,83 @@
     return status;
 }
 
+status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_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<int8_t>());
+
+    status = readByteVector(val->get());
+
+    if (status != OK) {
+        val->reset();
+    }
+
+    return status;
+}
+
+status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readInt32);
+}
+
 status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
     return readTypedVector(val, &Parcel::readInt32);
 }
 
+status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readInt64);
+}
+
 status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
     return readTypedVector(val, &Parcel::readInt64);
 }
 
+status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readFloat);
+}
+
 status_t Parcel::readFloatVector(std::vector<float>* val) const {
     return readTypedVector(val, &Parcel::readFloat);
 }
 
+status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readDouble);
+}
+
 status_t Parcel::readDoubleVector(std::vector<double>* val) const {
     return readTypedVector(val, &Parcel::readDouble);
 }
 
-status_t Parcel::readBoolVector(std::vector<bool>* val) const {
-    val->clear();
+status_t Parcel::readBoolVector(std::unique_ptr<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->reset(new std::vector<bool>());
+
+    status = readBoolVector(val->get());
+
+    if (status != OK) {
+        val->reset();
+    }
+
+    return status;
+}
+
+status_t Parcel::readBoolVector(std::vector<bool>* val) const {
     int32_t size;
     status_t status = readInt32(&size);
 
@@ -1335,10 +1468,19 @@
     return OK;
 }
 
+status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readChar);
+}
+
 status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
     return readTypedVector(val, &Parcel::readChar);
 }
 
+status_t Parcel::readString16Vector(
+        std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readString16);
+}
+
 status_t Parcel::readString16Vector(std::vector<String16>* val) const {
     return readTypedVector(val, &Parcel::readString16);
 }
@@ -1538,6 +1680,29 @@
     return String16();
 }
 
+status_t Parcel::readString16(std::unique_ptr<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->reset(new String16());
+
+    status = readString16(pArg->get());
+
+    if (status != OK) {
+        pArg->reset();
+    }
+
+    return status;
+}
+
 status_t Parcel::readString16(String16* pArg) const
 {
     size_t len;
@@ -1661,6 +1826,10 @@
 }
 
 
+status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<ScopedFd>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
+}
+
 status_t Parcel::readUniqueFileDescriptorVector(std::vector<ScopedFd>* val) const {
     return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
 }