Merge "Added option (-z) to generate a zipfile with the bugreport."
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index cf02647..369a29f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -306,7 +306,7 @@
     run_command("UPTIME", 10, "uptime", NULL);
     dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
     dump_file("MEMORY INFO", "/proc/meminfo");
-    run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
+    run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL);
     run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL);
     dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
     dump_file("VMALLOC INFO", "/proc/vmallocinfo");
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index e6594ec..2ebd39f 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -50,6 +50,7 @@
         "/system/bin/mediaserver",
         "/system/bin/sdcard",
         "/system/bin/surfaceflinger",
+        "/system/bin/vehicle_network_service",
         NULL,
 };
 
diff --git a/include/media/openmax/OMX_Core.h b/include/media/openmax/OMX_Core.h
index 521c223..f746a69 100644
--- a/include/media/openmax/OMX_Core.h
+++ b/include/media/openmax/OMX_Core.h
@@ -509,7 +509,7 @@
     OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
 
-    /** Event when tunneled decoder has rendered an output
+    /** Event when tunneled decoder has rendered an output or reached EOS
      *  nData1 must contain the number of timestamps returned
      *  pEventData must point to an array of the OMX_VIDEO_RENDEREVENTTYPE structs containing the
      *  render-timestamps of each frame. Component may batch rendered timestamps using this event,
@@ -518,6 +518,10 @@
      *
      *  If component is doing frame-rate conversion, it must signal the render time of each
      *  converted frame, and must interpolate media timestamps for in-between frames.
+     *
+     *  When the component reached EOS, it must signal an EOS timestamp using the same mechanism.
+     *  This is in addition to the timestamp of the last rendered frame, and should follow that
+     *  frame.
      */
     OMX_EventOutputRendered = 0x7F000001,
     OMX_EventMax = 0x7FFFFFFF
diff --git a/include/media/openmax/OMX_VideoExt.h b/include/media/openmax/OMX_VideoExt.h
index 34c0405..3971bc5 100644
--- a/include/media/openmax/OMX_VideoExt.h
+++ b/include/media/openmax/OMX_VideoExt.h
@@ -203,10 +203,17 @@
     OMX_BOOL bEnableLoopFilterAcrossSlices;
 } OMX_VIDEO_SLICESEGMENTSTYPE;
 
-/** Structure to return timestamps of rendered output frames for tunneled components */
+/** Structure to return timestamps of rendered output frames as well as EOS
+ *  for tunneled components.
+ */
 typedef struct OMX_VIDEO_RENDEREVENTTYPE {
     OMX_S64 nMediaTimeUs;  // timestamp of rendered video frame
     OMX_S64 nSystemTimeNs; // system monotonic time at the time frame was rendered
+                           // Use INT64_MAX for nMediaTimeUs to signal that the EOS
+                           // has been reached. In this case, nSystemTimeNs MUST be
+                           // the system time when the last frame was rendered.
+                           // This MUST be done in addition to returning (and
+                           // following) the render information for the last frame.
 } OMX_VIDEO_RENDEREVENTTYPE;
 
 #ifdef __cplusplus
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 56cde8a..b8f5436 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -338,6 +338,39 @@
     return BAD_TYPE;
 }
 
+namespace {
+
+template<typename T>
+status_t readTypedVector(std::vector<T>* val, const Parcel* p,
+                         status_t(Parcel::*read_func)(T*) const) {
+    val->clear();
+
+    int32_t size;
+    status_t status = p->readInt32(&size);
+
+    if (status != OK) {
+        return status;
+    }
+
+    if (size < 0) {
+        return UNEXPECTED_NULL;
+    }
+
+    val->resize(size);
+
+    for (auto& v: *val) {
+        status = (p->*read_func)(&v);
+
+        if (status != OK) {
+            return status;
+        }
+    }
+
+    return OK;
+}
+
+}  // namespace
+
 // ---------------------------------------------------------------------------
 
 Parcel::Parcel()
@@ -743,6 +776,46 @@
     return NULL;
 }
 
+namespace {
+
+template<typename T, typename U>
+status_t unsafeWriteTypedVector(const std::vector<T>& val, Parcel* p,
+                                status_t(Parcel::*write_func)(U)) {
+    if (val.size() > std::numeric_limits<int32_t>::max()) {
+        return BAD_VALUE;
+    }
+
+    status_t status = p->writeInt32(val.size());
+
+    if (status != OK) {
+        return status;
+    }
+
+    for (const auto& item : val) {
+        status = (p->*write_func)(item);
+
+        if (status != OK) {
+            return status;
+        }
+    }
+
+    return OK;
+}
+
+template<typename T>
+status_t writeTypedVector(const std::vector<T>& val, Parcel* p,
+                          status_t(Parcel::*write_func)(const T&)) {
+    return unsafeWriteTypedVector(val, p, write_func);
+}
+
+template<typename T>
+status_t writeTypedVector(const std::vector<T>& val, Parcel* p,
+                          status_t(Parcel::*write_func)(T)) {
+    return unsafeWriteTypedVector(val, p, write_func);
+}
+
+}  // namespace
+
 status_t Parcel::writeByteVector(const std::vector<int8_t>& val)
 {
     status_t status;
@@ -768,163 +841,37 @@
 
 status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
 {
-    if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    status_t status = writeInt32(val.size());
-
-    if (status != OK) {
-        return status;
-    }
-
-    for (const auto& item : val) {
-        status = writeInt32(item);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return writeTypedVector(val, this, &Parcel::writeInt32);
 }
 
 status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
 {
-    if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    status_t status = writeInt32(val.size());
-
-    if (status != OK) {
-        return status;
-    }
-
-    for (const auto& item : val) {
-        status = writeInt64(item);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return writeTypedVector(val, this, &Parcel::writeInt64);
 }
 
 status_t Parcel::writeFloatVector(const std::vector<float>& val)
 {
-    if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    status_t status = writeInt32(val.size());
-
-    if (status != OK) {
-        return status;
-    }
-
-    for (const auto& item : val) {
-        status = writeFloat(item);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return writeTypedVector(val, this, &Parcel::writeFloat);
 }
 
 status_t Parcel::writeDoubleVector(const std::vector<double>& val)
 {
-    if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    status_t status = writeInt32(val.size());
-
-    if (status != OK) {
-        return status;
-    }
-
-    for (const auto& item : val) {
-        status = writeDouble(item);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return writeTypedVector(val, this, &Parcel::writeDouble);
 }
 
 status_t Parcel::writeBoolVector(const std::vector<bool>& val)
 {
-    if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    status_t status = writeInt32(val.size());
-
-    if (status != OK) {
-        return status;
-    }
-
-    for (const auto& item : val) {
-        status = writeBool(item);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return writeTypedVector(val, this, &Parcel::writeBool);
 }
 
 status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
 {
-    if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    status_t status = writeInt32(val.size());
-
-    if (status != OK) {
-        return status;
-    }
-
-    for (const auto& item : val) {
-        status = writeChar(item);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return writeTypedVector(val, this, &Parcel::writeChar);
 }
 
 status_t Parcel::writeString16Vector(const std::vector<String16>& val)
 {
-    if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    status_t status = writeInt32(val.size());
-
-    if (status != OK) {
-        return status;
-    }
-
-    for (const auto& item : val) {
-        status = writeString16(item);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return writeTypedVector(val, this, &Parcel::writeString16);
 }
 
 status_t Parcel::writeInt32(int32_t val)
@@ -1073,52 +1020,11 @@
 
 status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
 {
-    if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    status_t status = writeInt32(val.size());
-
-    if (status != OK) {
-        return status;
-    }
-
-    for (const auto& item : val) {
-        status = writeStrongBinder(item);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return writeTypedVector(val, this, &Parcel::writeStrongBinder);
 }
 
 status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readStrongBinder(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readStrongBinder);
 }
 
 status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
@@ -1417,10 +1323,15 @@
         return status;
     }
 
-    if (size < 0 || size_t(size) > dataAvail()) {
+    if (size < 0) {
+        status = UNEXPECTED_NULL;
+        return status;
+    }
+    if (size_t(size) > dataAvail()) {
         status = BAD_VALUE;
         return status;
     }
+
     const void* data = readInplace(size);
     if (!data) {
         status = BAD_VALUE;
@@ -1433,111 +1344,19 @@
 }
 
 status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v: *val) {
-        status = readInt32(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readInt32);
 }
 
 status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readInt64(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readInt64);
 }
 
 status_t Parcel::readFloatVector(std::vector<float>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readFloat(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readFloat);
 }
 
 status_t Parcel::readDoubleVector(std::vector<double>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readDouble(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readDouble);
 }
 
 status_t Parcel::readBoolVector(std::vector<bool>* val) const {
@@ -1551,7 +1370,7 @@
     }
 
     if (size < 0) {
-        return BAD_VALUE;
+        return UNEXPECTED_NULL;
     }
 
     val->resize(size);
@@ -1573,61 +1392,11 @@
 }
 
 status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readChar(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readChar);
 }
 
 status_t Parcel::readString16Vector(std::vector<String16>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->reserve(size);
-
-    while (size-- > 0) {
-        const char16_t *data;
-        size_t size;
-        data = readString16Inplace(&size);
-
-        if (data == nullptr) {
-            return UNKNOWN_ERROR;
-        }
-
-        val->emplace_back(data, size);
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readString16);
 }
 
 
@@ -1834,7 +1603,7 @@
         return 0;
     } else {
         *pArg = String16();
-        return UNKNOWN_ERROR;
+        return UNEXPECTED_NULL;
     }
 }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index ad53226..1c2c05d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -86,7 +86,8 @@
         mQueueItemCondition(),
         mQueueItems(),
         mLastFrameNumberReceived(0),
-        mUpdateTexImageFailed(false)
+        mUpdateTexImageFailed(false),
+        mSingleBufferMode(false)
 {
     mCurrentCrop.makeInvalid();
     mFlinger->getRenderEngine().genTextures(1, &mTextureName);