Merge changes from topic 'single_buffer_mode'

* changes:
  SF: Force refresh when in single buffer mode
  BQ: Add support for single buffer mode
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 7324907..8bba81b 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -99,6 +99,7 @@
     } },
     { "irq",        "IRQ Events",   0, {
         { REQ,      "/sys/kernel/debug/tracing/events/irq/enable" },
+        { OPT,      "/sys/kernel/debug/tracing/events/ipi/enable" },
     } },
     { "freq",       "CPU Frequency",    0, {
         { REQ,      "/sys/kernel/debug/tracing/events/power/cpu_frequency/enable" },
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 1da7308..e460059 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -314,9 +314,7 @@
     dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
     dump_file("KERNEL SYNC", "/d/sync");
 
-    run_command("PROCESSES", 10, "ps", "-P", NULL);
-    run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
-    run_command("PROCESSES (SELINUX LABELS)", 10, "ps", "-Z", NULL);
+    run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL);
     run_command("LIBRANK", 10, "librank", NULL);
 
     do_dmesg();
diff --git a/include/batteryservice/BatteryService.h b/include/batteryservice/BatteryService.h
index 9a8e2f7..912dcf6 100644
--- a/include/batteryservice/BatteryService.h
+++ b/include/batteryservice/BatteryService.h
@@ -58,6 +58,7 @@
     bool chargerUsbOnline;
     bool chargerWirelessOnline;
     int maxChargingCurrent;
+    int maxChargingVoltage;
     int batteryStatus;
     int batteryHealth;
     bool batteryPresent;
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index ae76ffb..430c3ff 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -125,6 +125,8 @@
     status_t            writeCharVector(const std::vector<char16_t>& val);
     status_t            writeString16Vector(const std::vector<String16>& val);
 
+    status_t            writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
+
     template<typename T>
     status_t            write(const Flattenable<T>& val);
 
@@ -202,7 +204,9 @@
     wp<IBinder>         readWeakBinder() const;
 
     template<typename T>
-    status_t readStrongBinder(sp<T>* val) const;
+    status_t            readStrongBinder(sp<T>* val) const;
+
+    status_t            readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
 
     status_t            readByteVector(std::vector<int8_t>* val) const;
     status_t            readInt32Vector(std::vector<int32_t>* val) const;
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index f9d0e7d..b7aa463 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -74,7 +74,7 @@
             height(0),
             format(PIXEL_FORMAT_NONE),
             stride(0),
-            crop(0, 0, 0, 0),
+            crop(Rect::EMPTY_RECT),
             transform(0),
             scalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
             timestamp(0),
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 4c80f43..56cde8a 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -745,25 +745,25 @@
 
 status_t Parcel::writeByteVector(const std::vector<int8_t>& val)
 {
+    status_t status;
     if (val.size() > std::numeric_limits<int32_t>::max()) {
-        return BAD_VALUE;
+        status = BAD_VALUE;
+        return status;
     }
 
-    status_t status = writeInt32(val.size());
-
+    status = writeInt32(val.size());
     if (status != OK) {
         return status;
     }
 
-    for (const auto& item : val) {
-        status = writeByte(item);
-
-        if (status != OK) {
-            return status;
-        }
+    void* data = writeInplace(val.size());
+    if (!data) {
+        status = BAD_VALUE;
+        return status;
     }
 
-    return OK;
+    memcpy(data, val.data(), val.size());
+    return status;
 }
 
 status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
@@ -1071,6 +1071,56 @@
     return flatten_binder(ProcessState::self(), val, this);
 }
 
+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;
+}
+
+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;
+}
+
 status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
 {
     return flatten_binder(ProcessState::self(), val, this);
@@ -1367,21 +1417,19 @@
         return status;
     }
 
-    if (size < 0) {
-        return BAD_VALUE;
+    if (size < 0 || size_t(size) > dataAvail()) {
+        status = BAD_VALUE;
+        return status;
     }
-
+    const void* data = readInplace(size);
+    if (!data) {
+        status = BAD_VALUE;
+        return status;
+    }
     val->resize(size);
+    memcpy(val->data(), data, size);
 
-    for (auto& v : *val) {
-        status = readByte(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return status;
 }
 
 status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
diff --git a/services/batteryservice/BatteryProperties.cpp b/services/batteryservice/BatteryProperties.cpp
index f13d6e8..07cc797 100644
--- a/services/batteryservice/BatteryProperties.cpp
+++ b/services/batteryservice/BatteryProperties.cpp
@@ -34,6 +34,7 @@
     chargerUsbOnline = p->readInt32() == 1 ? true : false;
     chargerWirelessOnline = p->readInt32() == 1 ? true : false;
     maxChargingCurrent = p->readInt32();
+    maxChargingVoltage = p->readInt32();
     batteryStatus = p->readInt32();
     batteryHealth = p->readInt32();
     batteryPresent = p->readInt32() == 1 ? true : false;
@@ -49,6 +50,7 @@
     p->writeInt32(chargerUsbOnline ? 1 : 0);
     p->writeInt32(chargerWirelessOnline ? 1 : 0);
     p->writeInt32(maxChargingCurrent);
+    p->writeInt32(maxChargingVoltage);
     p->writeInt32(batteryStatus);
     p->writeInt32(batteryHealth);
     p->writeInt32(batteryPresent ? 1 : 0);
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 3738a55..5ba387d 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -56,15 +56,17 @@
             mStop(false),
             mPeriod(0),
             mPhase(0),
+            mReferenceTime(0),
             mWakeupLatency(0) {
     }
 
     virtual ~DispSyncThread() {}
 
-    void updateModel(nsecs_t period, nsecs_t phase) {
+    void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {
         Mutex::Autolock lock(mMutex);
         mPeriod = period;
         mPhase = phase;
+        mReferenceTime = referenceTime;
         mCond.signal();
     }
 
@@ -246,7 +248,7 @@
             ref = lastEventTime;
         }
 
-        nsecs_t phase = mPhase + listener.mPhase;
+        nsecs_t phase = mReferenceTime + mPhase + listener.mPhase;
         nsecs_t t = (((ref - phase) / mPeriod) + 1) * mPeriod + phase;
 
         if (t - listener.mLastEventTime < mPeriod / 2) {
@@ -266,6 +268,7 @@
 
     nsecs_t mPeriod;
     nsecs_t mPhase;
+    nsecs_t mReferenceTime;
     nsecs_t mWakeupLatency;
 
     Vector<EventListener> mEventListeners;
@@ -313,6 +316,9 @@
 void DispSync::reset() {
     Mutex::Autolock lock(mMutex);
 
+    mPhase = 0;
+    mReferenceTime = 0;
+    mModelUpdated = false;
     mNumResyncSamples = 0;
     mFirstResyncSample = 0;
     mNumResyncSamplesSincePresent = 0;
@@ -340,12 +346,13 @@
 
     updateErrorLocked();
 
-    return mPeriod == 0 || mError > kErrorThreshold;
+    return !mModelUpdated || mError > kErrorThreshold;
 }
 
 void DispSync::beginResync() {
     Mutex::Autolock lock(mMutex);
 
+    mModelUpdated = false;
     mNumResyncSamples = 0;
 }
 
@@ -354,6 +361,10 @@
 
     size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
     mResyncSamples[idx] = timestamp;
+    if (mNumResyncSamples == 0) {
+        mPhase = 0;
+        mReferenceTime = timestamp;
+    }
 
     if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
         mNumResyncSamples++;
@@ -376,7 +387,7 @@
         return mThread->hasAnyEventListeners();
     }
 
-    return mPeriod == 0 || mError > kErrorThreshold;
+    return !mModelUpdated || mError > kErrorThreshold;
 }
 
 void DispSync::endResync() {
@@ -405,7 +416,8 @@
     Mutex::Autolock lock(mMutex);
     mPeriod = period;
     mPhase = 0;
-    mThread->updateModel(mPeriod, mPhase);
+    mReferenceTime = 0;
+    mThread->updateModel(mPeriod, mPhase, mReferenceTime);
 }
 
 nsecs_t DispSync::getPeriod() {
@@ -430,7 +442,7 @@
         double scale = 2.0 * M_PI / double(mPeriod);
         for (size_t i = 0; i < mNumResyncSamples; i++) {
             size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
-            nsecs_t sample = mResyncSamples[idx];
+            nsecs_t sample = mResyncSamples[idx] - mReferenceTime;
             double samplePhase = double(sample % mPeriod) * scale;
             sampleAvgX += cos(samplePhase);
             sampleAvgY += sin(samplePhase);
@@ -453,12 +465,13 @@
         // Artificially inflate the period if requested.
         mPeriod += mPeriod * mRefreshSkipCount;
 
-        mThread->updateModel(mPeriod, mPhase);
+        mThread->updateModel(mPeriod, mPhase, mReferenceTime);
+        mModelUpdated = true;
     }
 }
 
 void DispSync::updateErrorLocked() {
-    if (mPeriod == 0) {
+    if (!mModelUpdated) {
         return;
     }
 
@@ -470,7 +483,7 @@
     nsecs_t sqErrSum = 0;
 
     for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
-        nsecs_t sample = mPresentTimes[i];
+        nsecs_t sample = mPresentTimes[i] - mReferenceTime;
         if (sample > mPhase) {
             nsecs_t sampleErr = (sample - mPhase) % period;
             if (sampleErr > period / 2) {
@@ -504,7 +517,8 @@
 nsecs_t DispSync::computeNextRefresh(int periodOffset) const {
     Mutex::Autolock lock(mMutex);
     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-    return (((now - mPhase) / mPeriod) + periodOffset + 1) * mPeriod + mPhase;
+    nsecs_t phase = mReferenceTime + mPhase;
+    return (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase;
 }
 
 void DispSync::dump(String8& result) const {
diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h
index 67142b6..a8524b9 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -149,11 +149,18 @@
     // number of nanoseconds from time 0 to the first vsync event.
     nsecs_t mPhase;
 
+    // mReferenceTime is the reference time of the modeled vsync events.
+    // It is the nanosecond timestamp of the first vsync event after a resync.
+    nsecs_t mReferenceTime;
+
     // mError is the computed model error.  It is based on the difference
     // between the estimated vsync event times and those observed in the
     // mPresentTimes array.
     nsecs_t mError;
 
+    // Whether we have updated the vsync event model since the last resync.
+    bool mModelUpdated;
+
     // These member variables are the state used during the resynchronization
     // process to store information about the hardware vsync event times used
     // to compute the model.