Merge "BQ: Modify consumer buffer count interfaces"
diff --git a/cmds/atrace/Android.mk b/cmds/atrace/Android.mk
index 028ca8f..a787e95 100644
--- a/cmds/atrace/Android.mk
+++ b/cmds/atrace/Android.mk
@@ -17,4 +17,6 @@
     libutils \
     libz \
 
+LOCAL_INIT_RC := atrace.rc
+
 include $(BUILD_EXECUTABLE)
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index cdf3a50..d63019b 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -277,9 +277,27 @@
 static void writeClockSyncMarker()
 {
   char buffer[128];
+  int len = 0;
+  int fd = open(k_traceMarkerPath, O_WRONLY);
+  if (fd == -1) {
+      fprintf(stderr, "error opening %s: %s (%d)\n", k_traceMarkerPath,
+              strerror(errno), errno);
+      return;
+  }
   float now_in_seconds = systemTime(CLOCK_MONOTONIC) / 1000000000.0f;
-  snprintf(buffer, 128, "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds);
-  writeStr(k_traceMarkerPath, buffer);
+
+  len = snprintf(buffer, 128, "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds);
+  if (write(fd, buffer, len) != len) {
+      fprintf(stderr, "error writing clock sync marker %s (%d)\n", strerror(errno), errno);
+  }
+
+  int64_t realtime_in_ms = systemTime(CLOCK_REALTIME) / 1000000;
+  len = snprintf(buffer, 128, "trace_event_clock_sync: realtime_ts=%" PRId64 "\n", realtime_in_ms);
+  if (write(fd, buffer, len) != len) {
+      fprintf(stderr, "error writing clock sync marker %s (%d)\n", strerror(errno), errno);
+  }
+
+  close(fd);
 }
 
 // Enable or disable a kernel option by writing a "1" or a "0" into a /sys
@@ -706,7 +724,6 @@
 // Disable tracing in the kernel.
 static void stopTrace()
 {
-    writeClockSyncMarker();
     setTracingEnabled(false);
 }
 
@@ -982,6 +999,7 @@
         // another.
         ok = clearTrace();
 
+        writeClockSyncMarker();
         if (ok && !async) {
             // Sleep to allow the trace to be captured.
             struct timespec timeLeft;
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
new file mode 100644
index 0000000..cde9c37
--- /dev/null
+++ b/cmds/atrace/atrace.rc
@@ -0,0 +1,62 @@
+## Permissions to allow system-wide tracing to the kernel trace buffer.
+##
+on boot
+
+# Allow writing to the kernel trace log.
+    chmod 0222 /sys/kernel/debug/tracing/trace_marker
+
+# Allow the shell group to enable (some) kernel tracing.
+    chown root shell /sys/kernel/debug/tracing/trace_clock
+    chown root shell /sys/kernel/debug/tracing/buffer_size_kb
+    chown root shell /sys/kernel/debug/tracing/options/overwrite
+    chown root shell /sys/kernel/debug/tracing/options/print-tgid
+    chown root shell /sys/kernel/debug/tracing/events/sched/sched_switch/enable
+    chown root shell /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
+    chown root shell /sys/kernel/debug/tracing/events/power/cpu_frequency/enable
+    chown root shell /sys/kernel/debug/tracing/events/power/cpu_idle/enable
+    chown root shell /sys/kernel/debug/tracing/events/power/clock_set_rate/enable
+    chown root shell /sys/kernel/debug/tracing/events/cpufreq_interactive/enable
+    chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin/enable
+    chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_end/enable
+    chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_wake/enable
+    chown root shell /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_sleep/enable
+    chown root shell /sys/kernel/debug/tracing/events/binder/binder_transaction/enable
+    chown root shell /sys/kernel/debug/tracing/events/binder/binder_transaction_received/enable
+    chown root shell /sys/kernel/debug/tracing/events/binder/binder_lock/enable
+    chown root shell /sys/kernel/debug/tracing/events/binder/binder_locked/enable
+    chown root shell /sys/kernel/debug/tracing/events/binder/binder_unlock/enable
+
+    chown root shell /sys/kernel/debug/tracing/tracing_on
+
+    chmod 0664 /sys/kernel/debug/tracing/trace_clock
+    chmod 0664 /sys/kernel/debug/tracing/buffer_size_kb
+    chmod 0664 /sys/kernel/debug/tracing/options/overwrite
+    chmod 0664 /sys/kernel/debug/tracing/options/print-tgid
+    chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_switch/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/power/cpu_frequency/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/power/cpu_idle/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/power/clock_set_rate/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/cpufreq_interactive/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_end/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_wake/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_kswapd_sleep/enable
+    chmod 0664 /sys/kernel/debug/tracing/tracing_on
+    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_transaction/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_transaction_received/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_lock/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_locked/enable
+    chmod 0664 /sys/kernel/debug/tracing/events/binder/binder_unlock/enable
+
+# 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
+
+on property:persist.debug.atrace.boottrace=1
+    start boottrace
+
+# Run atrace with the categories written in a file
+service boottrace /system/bin/atrace --async_start -f /data/misc/boottrace/categories
+    disabled
+    oneshot
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 0aa8fe9..713634c 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -437,8 +437,6 @@
     run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL);
     run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL);
 
-    run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL);
-
     run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
     run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
     run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL);
@@ -450,25 +448,29 @@
             SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL);
 
 #ifdef FWDUMP_bcmdhd
-    run_command("DUMP WIFI INTERNAL COUNTERS", 20,
+    run_command("ND OFFLOAD TABLE", 5,
+            SU_PATH, "root", "wlutil", "nd_hostip", NULL);
+
+    run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20,
             SU_PATH, "root", "wlutil", "counters", NULL);
+
+    run_command("ND OFFLOAD STATUS (1)", 5,
+            SU_PATH, "root", "wlutil", "nd_status", NULL);
+
 #endif
     dump_file("INTERRUPTS (1)", "/proc/interrupts");
 
-    property_get("dhcp.wlan0.gateway", network, "");
-    if (network[0])
-        run_command("PING GATEWAY", 10, "ping", "-c", "3", "-i", ".5", network, NULL);
-    property_get("dhcp.wlan0.dns1", network, "");
-    if (network[0])
-        run_command("PING DNS1", 10, "ping", "-c", "3", "-i", ".5", network, NULL);
-    property_get("dhcp.wlan0.dns2", network, "");
-    if (network[0])
-        run_command("PING DNS2", 10, "ping", "-c", "3", "-i", ".5", network, NULL);
+    run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL);
+
 #ifdef FWDUMP_bcmdhd
     run_command("DUMP WIFI STATUS", 20,
             SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL);
-    run_command("DUMP WIFI INTERNAL COUNTERS", 20,
+
+    run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20,
             SU_PATH, "root", "wlutil", "counters", NULL);
+
+    run_command("ND OFFLOAD STATUS (2)", 5,
+            SU_PATH, "root", "wlutil", "nd_status", NULL);
 #endif
     dump_file("INTERRUPTS (2)", "/proc/interrupts");
 
diff --git a/include/android/keycodes.h b/include/android/keycodes.h
index 56a89e7..ac07190 100644
--- a/include/android/keycodes.h
+++ b/include/android/keycodes.h
@@ -749,7 +749,9 @@
     AKEYCODE_MEDIA_STEP_FORWARD = 274,
     /** Step backward media key.
      * Steps media backward one from at a time. */
-    AKEYCODE_MEDIA_STEP_BACKWARD = 275
+    AKEYCODE_MEDIA_STEP_BACKWARD = 275,
+    /** Put device to sleep unless a wakelock is held. */
+    AKEYCODE_SOFT_SLEEP = 276
 
     // NOTE: If you add a new keycode here you must also add it to several other files.
     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/include/binder/IServiceManager.h b/include/binder/IServiceManager.h
index 2c297d6..7ccd9fe 100644
--- a/include/binder/IServiceManager.h
+++ b/include/binder/IServiceManager.h
@@ -81,20 +81,6 @@
                             int32_t* outPid, int32_t* outUid);
 bool checkPermission(const String16& permission, pid_t pid, uid_t uid);
 
-
-// ----------------------------------------------------------------------
-
-class BnServiceManager : public BnInterface<IServiceManager>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------
-
 }; // namespace android
 
 #endif // ANDROID_ISERVICE_MANAGER_H
diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h
index 145efe6..504ac64 100644
--- a/include/gui/BufferItem.h
+++ b/include/gui/BufferItem.h
@@ -98,13 +98,8 @@
         };
     };
 
-    union {
-        // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
-        int mSlot;
-
-        // mBuf is the former name for mSlot
-        int mBuf;
-    };
+    // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT).
+    int mSlot;
 
     // mIsDroppable whether this buffer was queued with the
     // property that it can be replaced by a new buffer for the purpose of
diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h
index 502912e..efc1687 100644
--- a/include/input/InputEventLabels.h
+++ b/include/input/InputEventLabels.h
@@ -315,6 +315,7 @@
     DEFINE_KEYCODE(MEDIA_SKIP_BACKWARD),
     DEFINE_KEYCODE(MEDIA_STEP_FORWARD),
     DEFINE_KEYCODE(MEDIA_STEP_BACKWARD),
+    DEFINE_KEYCODE(SOFT_SLEEP),
 
     { NULL, 0 }
 };
diff --git a/include/powermanager/IPowerManager.h b/include/powermanager/IPowerManager.h
index 91ecc5a..49ff637 100644
--- a/include/powermanager/IPowerManager.h
+++ b/include/powermanager/IPowerManager.h
@@ -25,12 +25,23 @@
 
 // ----------------------------------------------------------------------------
 
-// must be kept in sync with interface defined in IPowerManager.aidl
 class IPowerManager : public IInterface
 {
 public:
+    // These transaction IDs must be kept in sync with the method order from
+    // IPowerManager.aidl.
+    enum {
+        ACQUIRE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION,
+        ACQUIRE_WAKE_LOCK_UID = IBinder::FIRST_CALL_TRANSACTION + 1,
+        RELEASE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION + 2,
+        UPDATE_WAKE_LOCK_UIDS = IBinder::FIRST_CALL_TRANSACTION + 3,
+        POWER_HINT = IBinder::FIRST_CALL_TRANSACTION + 4,
+    };
+
     DECLARE_META_INTERFACE(PowerManager);
 
+    // The parcels created by these methods must be kept in sync with the
+    // corresponding methods from IPowerManager.aidl.
     // FIXME remove the bool isOneWay parameters as they are not oneway in the .aidl
     virtual status_t acquireWakeLock(int flags, const sp<IBinder>& lock, const String16& tag,
             const String16& packageName, bool isOneWay = false) = 0;
diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h
index 799944f..ad73ee7 100644
--- a/include/ui/DisplayInfo.h
+++ b/include/ui/DisplayInfo.h
@@ -36,6 +36,7 @@
     bool secure;
     nsecs_t appVsyncOffset;
     nsecs_t presentationDeadline;
+    int colorTransform;
 };
 
 /* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
diff --git a/include/ui/Region.h b/include/ui/Region.h
index 2a14918..e9b3a0b 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -130,11 +130,6 @@
     // Region object.
     Rect const* getArray(size_t* count) const;
 
-    // returns a SharedBuffer as well as the number of rects.
-    // ownership is transfered to the caller.
-    // the caller must call SharedBuffer::release() to free the memory.
-    SharedBuffer const* getSharedBuffer(size_t* count) const;
-
     /* no user serviceable parts here... */
 
             // add a rectangle to the internal list. This rectangle must
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index d5860ef..ce29ea6 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -43,6 +43,9 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := libbinder
 LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
+
+LOCAL_CLANG := true
+LOCAL_SANITIZE := integer
 LOCAL_SRC_FILES := $(sources)
 ifneq ($(TARGET_USES_64_BIT_BINDER),true)
 ifneq ($(TARGET_IS_64_BIT),true)
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 3c716df..134aadc 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -184,48 +184,4 @@
 
 IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
 
-// ----------------------------------------------------------------------
-
-status_t BnServiceManager::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    //printf("ServiceManager received: "); data.print();
-    switch(code) {
-        case GET_SERVICE_TRANSACTION: {
-            CHECK_INTERFACE(IServiceManager, data, reply);
-            String16 which = data.readString16();
-            sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);
-            reply->writeStrongBinder(b);
-            return NO_ERROR;
-        } break;
-        case CHECK_SERVICE_TRANSACTION: {
-            CHECK_INTERFACE(IServiceManager, data, reply);
-            String16 which = data.readString16();
-            sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);
-            reply->writeStrongBinder(b);
-            return NO_ERROR;
-        } break;
-        case ADD_SERVICE_TRANSACTION: {
-            CHECK_INTERFACE(IServiceManager, data, reply);
-            String16 which = data.readString16();
-            sp<IBinder> b = data.readStrongBinder();
-            status_t err = addService(which, b);
-            reply->writeInt32(err);
-            return NO_ERROR;
-        } break;
-        case LIST_SERVICES_TRANSACTION: {
-            CHECK_INTERFACE(IServiceManager, data, reply);
-            Vector<String16> list = listServices();
-            const size_t N = list.size();
-            reply->writeInt32(N);
-            for (size_t i=0; i<N; i++) {
-                reply->writeString16(list[i]);
-            }
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
 }; // namespace android
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 7a4ddc4..8315c58 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -350,13 +350,11 @@
 
 size_t Parcel::dataAvail() const
 {
-    // TODO: decide what to do about the possibility that this can
-    // report an available-data size that exceeds a Java int's max
-    // positive value, causing havoc.  Fortunately this will only
-    // happen if someone constructs a Parcel containing more than two
-    // gigabytes of data, which on typical phone hardware is simply
-    // not possible.
-    return dataSize() - dataPosition();
+    size_t result = dataSize() - dataPosition();
+    if (result > INT32_MAX) {
+        abort();
+    }
+    return result;
 }
 
 size_t Parcel::dataPosition() const
@@ -1645,8 +1643,14 @@
         if (mData) {
             LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
             pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
-            gParcelGlobalAllocSize -= mDataCapacity;
-            gParcelGlobalAllocCount--;
+            if (mDataCapacity <= gParcelGlobalAllocSize) {
+              gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
+            } else {
+              gParcelGlobalAllocSize = 0;
+            }
+            if (gParcelGlobalAllocCount > 0) {
+              gParcelGlobalAllocCount--;
+            }
             pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
             free(mData);
         }
@@ -1825,6 +1829,7 @@
                 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
                 gParcelGlobalAllocSize += desired;
                 gParcelGlobalAllocSize -= mDataCapacity;
+                gParcelGlobalAllocCount++;
                 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
                 mData = data;
                 mDataCapacity = desired;
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index 578b8d9..6f4c89d 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -78,7 +78,7 @@
         }
     }
 
-    item->mGraphicBuffer = mSlots[item->mBuf].mGraphicBuffer;
+    item->mGraphicBuffer = mSlots[item->mSlot].mGraphicBuffer;
 
     return OK;
 }
@@ -89,9 +89,9 @@
 
     Mutex::Autolock _l(mMutex);
 
-    err = addReleaseFenceLocked(item.mBuf, item.mGraphicBuffer, releaseFence);
+    err = addReleaseFenceLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
 
-    err = releaseBufferLocked(item.mBuf, item.mGraphicBuffer, EGL_NO_DISPLAY,
+    err = releaseBufferLocked(item.mSlot, item.mGraphicBuffer, EGL_NO_DISPLAY,
             EGL_NO_SYNC_KHR);
     if (err != OK) {
         BI_LOGE("Failed to release buffer: %s (%d)",
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 04ab06b..d01187f 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -239,14 +239,14 @@
     }
 
     if (item->mGraphicBuffer != NULL) {
-        mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer;
+        mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;
     }
 
-    mSlots[item->mBuf].mFrameNumber = item->mFrameNumber;
-    mSlots[item->mBuf].mFence = item->mFence;
+    mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;
+    mSlots[item->mSlot].mFence = item->mFence;
 
     CB_LOGV("acquireBufferLocked: -> slot=%d/%" PRIu64,
-            item->mBuf, item->mFrameNumber);
+            item->mSlot, item->mFrameNumber);
 
     return OK;
 }
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index e29b740..7ed3d0f 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -106,22 +106,22 @@
         }
     }
 
-    int buf = b.mBuf;
+    int slot = b.mSlot;
 
     void *bufferPointer = NULL;
     android_ycbcr ycbcr = android_ycbcr();
 
-    PixelFormat format = mSlots[buf].mGraphicBuffer->getPixelFormat();
+    PixelFormat format = mSlots[slot].mGraphicBuffer->getPixelFormat();
     PixelFormat flexFormat = format;
     if (isPossiblyYUV(format)) {
         if (b.mFence.get()) {
-            err = mSlots[buf].mGraphicBuffer->lockAsyncYCbCr(
+            err = mSlots[slot].mGraphicBuffer->lockAsyncYCbCr(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &ycbcr,
                 b.mFence->dup());
         } else {
-            err = mSlots[buf].mGraphicBuffer->lockYCbCr(
+            err = mSlots[slot].mGraphicBuffer->lockYCbCr(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &ycbcr);
@@ -141,13 +141,13 @@
 
     if (bufferPointer == NULL) { // not flexible YUV
         if (b.mFence.get()) {
-            err = mSlots[buf].mGraphicBuffer->lockAsync(
+            err = mSlots[slot].mGraphicBuffer->lockAsync(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &bufferPointer,
                 b.mFence->dup());
         } else {
-            err = mSlots[buf].mGraphicBuffer->lock(
+            err = mSlots[slot].mGraphicBuffer->lock(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &bufferPointer);
@@ -169,19 +169,19 @@
     assert(lockedIdx < mMaxLockedBuffers);
 
     AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
-    ab.mSlot = buf;
+    ab.mSlot = slot;
     ab.mBufferPointer = bufferPointer;
-    ab.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
+    ab.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
 
     nativeBuffer->data   =
             reinterpret_cast<uint8_t*>(bufferPointer);
-    nativeBuffer->width  = mSlots[buf].mGraphicBuffer->getWidth();
-    nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
+    nativeBuffer->width  = mSlots[slot].mGraphicBuffer->getWidth();
+    nativeBuffer->height = mSlots[slot].mGraphicBuffer->getHeight();
     nativeBuffer->format = format;
     nativeBuffer->flexFormat = flexFormat;
     nativeBuffer->stride = (ycbcr.y != NULL) ?
             static_cast<uint32_t>(ycbcr.ystride) :
-            mSlots[buf].mGraphicBuffer->getStride();
+            mSlots[slot].mGraphicBuffer->getStride();
 
     nativeBuffer->crop        = b.mCrop;
     nativeBuffer->transform   = b.mTransform;
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 5394fb6..1572a89 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -351,7 +351,7 @@
     // before, so any prior EglImage created is using a stale buffer. This
     // replaces any old EglImage with a new one (using the new buffer).
     if (item->mGraphicBuffer != NULL) {
-        int slot = item->mBuf;
+        int slot = item->mSlot;
         mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer);
     }
 
@@ -375,12 +375,12 @@
 {
     status_t err = NO_ERROR;
 
-    int buf = item.mBuf;
+    int slot = item.mSlot;
 
     if (!mAttached) {
         GLC_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL "
                 "ES context");
-        releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
+        releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer,
                 mEglDisplay, EGL_NO_SYNC_KHR);
         return INVALID_OPERATION;
     }
@@ -388,7 +388,7 @@
     // Confirm state.
     err = checkAndUpdateEglStateLocked();
     if (err != NO_ERROR) {
-        releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
+        releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer,
                 mEglDisplay, EGL_NO_SYNC_KHR);
         return err;
     }
@@ -398,11 +398,11 @@
     // ConsumerBase.
     // We may have to do this even when item.mGraphicBuffer == NULL (which
     // means the buffer was previously acquired).
-    err = mEglSlots[buf].mEglImage->createIfNeeded(mEglDisplay, item.mCrop);
+    err = mEglSlots[slot].mEglImage->createIfNeeded(mEglDisplay, item.mCrop);
     if (err != NO_ERROR) {
         GLC_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d",
-                mEglDisplay, buf);
-        releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
+                mEglDisplay, slot);
+        releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer,
                 mEglDisplay, EGL_NO_SYNC_KHR);
         return UNKNOWN_ERROR;
     }
@@ -414,7 +414,7 @@
         // release the old buffer, so instead we just drop the new frame.
         // As we are still under lock since acquireBuffer, it is safe to
         // release by slot.
-        releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
+        releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer,
                 mEglDisplay, EGL_NO_SYNC_KHR);
         return err;
     }
@@ -422,7 +422,7 @@
     GLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)",
             mCurrentTexture, mCurrentTextureImage != NULL ?
                     mCurrentTextureImage->graphicBufferHandle() : 0,
-            buf, mSlots[buf].mGraphicBuffer->handle);
+            slot, mSlots[slot].mGraphicBuffer->handle);
 
     // release old buffer
     if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
@@ -438,8 +438,8 @@
     }
 
     // Update the GLConsumer state.
-    mCurrentTexture = buf;
-    mCurrentTextureImage = mEglSlots[buf].mEglImage;
+    mCurrentTexture = slot;
+    mCurrentTextureImage = mEglSlots[slot].mEglImage;
     mCurrentCrop = item.mCrop;
     mCurrentTransform = item.mTransform;
     mCurrentScalingMode = item.mScalingMode;
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 1b40c87..81c0549 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -224,6 +224,10 @@
         }
         if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->requiredPermission) {
             mRequiredPermission = hwSensor->requiredPermission;
+            if (!strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS)) {
+                AppOpsManager appOps;
+                mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
+            }
         }
 
         if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp
index 43f9214..dce0e87 100644
--- a/libs/gui/StreamSplitter.cpp
+++ b/libs/gui/StreamSplitter.cpp
@@ -132,7 +132,7 @@
     ALOGV("acquired buffer %#" PRIx64 " from input",
             bufferItem.mGraphicBuffer->getId());
 
-    status = mInput->detachBuffer(bufferItem.mBuf);
+    status = mInput->detachBuffer(bufferItem.mSlot);
     LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
             "detaching buffer from input failed (%d)", status);
 
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 27f7ed6..de5c275 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -184,7 +184,9 @@
     va_list args;
     va_start(args, operation);
     Surface* c = getSelf(window);
-    return c->perform(operation, args);
+    int result = c->perform(operation, args);
+    va_end(args);
+    return result;
 }
 
 int Surface::setSwapInterval(int interval) {
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 514b5fc..8a3be3d 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -313,8 +313,8 @@
     BufferItem item;
     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
 
-    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
-    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mBuf)); // Not acquired
+    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
+    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired
 
     uint32_t* dataIn;
     ASSERT_EQ(OK, item.mGraphicBuffer->lock(
@@ -373,7 +373,7 @@
 
     BufferItem item;
     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
-    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
+    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
 
     int newSlot;
     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp
index 00cc39d..afd149e 100644
--- a/libs/gui/tests/StreamSplitter_test.cpp
+++ b/libs/gui/tests/StreamSplitter_test.cpp
@@ -128,7 +128,7 @@
     ASSERT_EQ(*dataOut, TEST_DATA);
     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
 
-    ASSERT_EQ(OK, outputConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
+    ASSERT_EQ(OK, outputConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
 
     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
@@ -196,7 +196,7 @@
         ASSERT_EQ(*dataOut, TEST_DATA);
         ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
 
-        ASSERT_EQ(OK, outputConsumers[output]->releaseBuffer(item.mBuf,
+        ASSERT_EQ(OK, outputConsumers[output]->releaseBuffer(item.mSlot,
                     item.mFrameNumber, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
                     Fence::NO_FENCE));
     }
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 1ce8626..54ff741 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -17,6 +17,7 @@
 
 LOCAL_CLANG := true
 LOCAL_CPPFLAGS := -std=c++1y -Weverything -Werror
+LOCAL_SANITIZE := integer
 
 # The static constructors and destructors in this library have not been noted to
 # introduce significant overheads
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 7792975..ac37990 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -835,18 +835,6 @@
     return begin();
 }
 
-SharedBuffer const* Region::getSharedBuffer(size_t* count) const {
-    // We can get to the SharedBuffer of a Vector<Rect> because Rect has
-    // a trivial destructor.
-    SharedBuffer const* sb = SharedBuffer::bufferFromData(mStorage.array());
-    if (count) {
-        size_t numRects = isRect() ? 1 : mStorage.size() - 1;
-        count[0] = numRects;
-    }
-    sb->acquire();
-    return sb;
-}
-
 // ----------------------------------------------------------------------------
 
 void Region::dump(String8& out, const char* what, uint32_t /* flags */) const
diff --git a/services/powermanager/Android.mk b/services/powermanager/Android.mk
index 7b24c65..4deb115 100644
--- a/services/powermanager/Android.mk
+++ b/services/powermanager/Android.mk
@@ -14,4 +14,6 @@
 
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
 
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../../include
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/powermanager/IPowerManager.cpp b/services/powermanager/IPowerManager.cpp
index ec864ee..0a4244f 100644
--- a/services/powermanager/IPowerManager.cpp
+++ b/services/powermanager/IPowerManager.cpp
@@ -27,15 +27,6 @@
 
 namespace android {
 
-// must be kept in sync with IPowerManager.aidl
-enum {
-    ACQUIRE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION,
-    ACQUIRE_WAKE_LOCK_UID = IBinder::FIRST_CALL_TRANSACTION + 1,
-    RELEASE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION + 2,
-    UPDATE_WAKE_LOCK_UIDS = IBinder::FIRST_CALL_TRANSACTION + 3,
-    POWER_HINT = IBinder::FIRST_CALL_TRANSACTION + 4,
-};
-
 class BpPowerManager : public BpInterface<IPowerManager>
 {
 public:
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 5574c7e..a6bc158 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -106,7 +106,7 @@
     // releaseBuffer call and we should be in the same state we'd be in if we
     // had released the old buffer first.
     if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
-        item.mBuf != mCurrentBufferSlot) {
+        item.mSlot != mCurrentBufferSlot) {
         // Release the previous buffer.
         err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer,
                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
@@ -115,7 +115,7 @@
             return err;
         }
     }
-    mCurrentBufferSlot = item.mBuf;
+    mCurrentBufferSlot = item.mSlot;
     mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
     outFence = item.mFence;
     outBuffer = mCurrentBuffer;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2dad005..d37fcb2 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -336,10 +336,20 @@
     HWC_DISPLAY_HEIGHT,
     HWC_DISPLAY_DPI_X,
     HWC_DISPLAY_DPI_Y,
+    HWC_DISPLAY_COLOR_TRANSFORM,
     HWC_DISPLAY_NO_ATTRIBUTE,
 };
 #define NUM_DISPLAY_ATTRIBUTES (sizeof(DISPLAY_ATTRIBUTES) / sizeof(DISPLAY_ATTRIBUTES)[0])
 
+static const uint32_t PRE_HWC15_DISPLAY_ATTRIBUTES[] = {
+    HWC_DISPLAY_VSYNC_PERIOD,
+    HWC_DISPLAY_WIDTH,
+    HWC_DISPLAY_HEIGHT,
+    HWC_DISPLAY_DPI_X,
+    HWC_DISPLAY_DPI_Y,
+    HWC_DISPLAY_NO_ATTRIBUTE,
+};
+
 status_t HWComposer::queryDisplayProperties(int disp) {
 
     LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
@@ -362,6 +372,12 @@
     for (size_t c = 0; c < numConfigs; ++c) {
         err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
                 DISPLAY_ATTRIBUTES, values);
+        // If this is a pre-1.5 HWC, it may not know about color transform, so
+        // try again with a smaller set of attributes
+        if (err != NO_ERROR) {
+            err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
+                    PRE_HWC15_DISPLAY_ATTRIBUTES, values);
+        }
         if (err != NO_ERROR) {
             // we can't get this display's info. turn it off.
             mDisplayData[disp].connected = false;
@@ -386,6 +402,9 @@
                 case HWC_DISPLAY_DPI_Y:
                     config.ydpi = values[i] / 1000.0f;
                     break;
+                case HWC_DISPLAY_COLOR_TRANSFORM:
+                    config.colorTransform = values[i];
+                    break;
                 default:
                     ALOG_ASSERT(false, "unknown display attribute[%zu] %#x",
                             i, DISPLAY_ATTRIBUTES[i]);
@@ -1017,12 +1036,10 @@
         }
     }
     virtual void setVisibleRegionScreen(const Region& reg) {
-        // Region::getSharedBuffer creates a reference to the underlying
-        // SharedBuffer of this Region, this reference is freed
-        // in onDisplayed()
         hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen;
-        SharedBuffer const* sb = reg.getSharedBuffer(&visibleRegion.numRects);
-        visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
+        mVisibleRegion = reg;
+        visibleRegion.rects = reinterpret_cast<hwc_rect_t const *>(
+                mVisibleRegion.getArray(&visibleRegion.numRects));
     }
     virtual void setSurfaceDamage(const Region& reg) {
         if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
@@ -1036,8 +1053,9 @@
             surfaceDamage.rects = NULL;
             return;
         }
-        SharedBuffer const* sb = reg.getSharedBuffer(&surfaceDamage.numRects);
-        surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(sb->data());
+        mSurfaceDamage = reg;
+        surfaceDamage.rects = reinterpret_cast<hwc_rect_t const *>(
+                mSurfaceDamage.getArray(&surfaceDamage.numRects));
     }
     virtual void setSidebandStream(const sp<NativeHandle>& stream) {
         ALOG_ASSERT(stream->handle() != NULL);
@@ -1059,29 +1077,15 @@
         }
     }
     virtual void onDisplayed() {
-        hwc_region_t& visibleRegion = getLayer()->visibleRegionScreen;
-        SharedBuffer const* sb = SharedBuffer::bufferFromData(visibleRegion.rects);
-        if (sb) {
-            sb->release();
-            // not technically needed but safer
-            visibleRegion.numRects = 0;
-            visibleRegion.rects = NULL;
-        }
-
         getLayer()->acquireFenceFd = -1;
-
-        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_5)) {
-            return;
-        }
-
-        hwc_region_t& surfaceDamage = getLayer()->surfaceDamage;
-        sb = SharedBuffer::bufferFromData(surfaceDamage.rects);
-        if (sb) {
-            sb->release();
-            surfaceDamage.numRects = 0;
-            surfaceDamage.rects = NULL;
-        }
     }
+
+protected:
+    // We need to hold "copies" of these for memory management purposes. The
+    // actual hwc_layer_1_t holds pointers to the memory within. Vector<>
+    // internally doesn't copy the memory unless one of the copies is modified.
+    Region mVisibleRegion;
+    Region mSurfaceDamage;
 };
 
 /*
@@ -1162,9 +1166,11 @@
             result.appendFormat("  Display[%zd] configurations (* current):\n", i);
             for (size_t c = 0; c < disp.configs.size(); ++c) {
                 const DisplayConfig& config(disp.configs[c]);
-                result.appendFormat("    %s%zd: %ux%u, xdpi=%f, ydpi=%f, refresh=%" PRId64 "\n",
-                        c == disp.currentConfig ? "* " : "", c, config.width, config.height,
-                        config.xdpi, config.ydpi, config.refresh);
+                result.appendFormat("    %s%zd: %ux%u, xdpi=%f, ydpi=%f"
+                        ", refresh=%" PRId64 ", colorTransform=%d\n",
+                        c == disp.currentConfig ? "* " : "", c,
+                        config.width, config.height, config.xdpi, config.ydpi,
+                        config.refresh, config.colorTransform);
             }
 
             if (disp.list) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index cc98b4c..5e0b3d8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -257,6 +257,7 @@
         float xdpi;
         float ydpi;
         nsecs_t refresh;
+        int colorTransform;
     };
 
     // Query display parameters.  Pass in a display index (e.g.
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 07ed57d..94f30d5 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -446,11 +446,11 @@
         result = acquireBufferLocked(&item, 0);
         if (result != NO_ERROR)
             return result;
-        VDS_LOGW_IF(item.mBuf != sslot,
+        VDS_LOGW_IF(item.mSlot != sslot,
                 "queueBuffer: acquired sslot %d from SCRATCH after queueing sslot %d",
-                item.mBuf, sslot);
-        mFbProducerSlot = mapSource2ProducerSlot(SOURCE_SCRATCH, item.mBuf);
-        mFbFence = mSlots[item.mBuf].mFence;
+                item.mSlot, sslot);
+        mFbProducerSlot = mapSource2ProducerSlot(SOURCE_SCRATCH, item.mSlot);
+        mFbFence = mSlots[item.mSlot].mFence;
 
     } else {
         LOG_FATAL_IF(mCompositionType != COMPOSITION_GLES,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 063d735..285b829 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -635,6 +635,7 @@
         info.ydpi = ydpi;
         info.fps = float(1e9 / hwConfig.refresh);
         info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
+        info.colorTransform = hwConfig.colorTransform;
 
         // This is how far in advance a buffer must be queued for
         // presentation at a given time.  If you want a buffer to appear
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index ed1f31b..930e7c7 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -72,9 +72,9 @@
     // We call the rejecter here, in case the caller has a reason to
     // not accept this buffer.  This is used by SurfaceFlinger to
     // reject buffers which have the wrong size
-    int buf = item.mBuf;
-    if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) {
-        releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);
+    int slot = item.mSlot;
+    if (rejecter && rejecter->reject(mSlots[slot].mGraphicBuffer, item)) {
+        releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer, EGL_NO_SYNC_KHR);
         return BUFFER_REJECTED;
     }