am 70278fbf: Merge "Add error message for hints when exceptions occur during binder transactions."

* commit '70278fbfe012c1fce3e63a41ffb9feaf1e53a64a':
  Add error message for hints when exceptions occur during binder transactions.
diff --git a/cmds/flatland/Android.mk b/cmds/flatland/Android.mk
index 5e57f02..d9478fe 100644
--- a/cmds/flatland/Android.mk
+++ b/cmds/flatland/Android.mk
@@ -1,3 +1,4 @@
+local_target_dir := $(TARGET_OUT_DATA)/local/tmp
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
@@ -11,6 +12,8 @@
 
 LOCAL_MODULE_TAGS := tests
 
+LOCAL_MODULE_PATH := $(local_target_dir)
+
 LOCAL_SHARED_LIBRARIES := \
     libEGL      \
     libGLESv2   \
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index ed2e7df..ce630bd 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -105,6 +105,7 @@
     status_t            writeStrongBinder(const sp<IBinder>& val);
     status_t            writeWeakBinder(const wp<IBinder>& val);
     status_t            writeInt32Array(size_t len, const int32_t *val);
+    status_t            writeByteArray(size_t len, const uint8_t *val);
 
     template<typename T>
     status_t            write(const Flattenable<T>& val);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 169e503..db6369d 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -632,6 +632,16 @@
     }
     return ret;
 }
+status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
+    if (!val) {
+        return writeAligned(-1);
+    }
+    status_t ret = writeAligned(len);
+    if (ret == NO_ERROR) {
+        ret = write(val, len * sizeof(*val));
+    }
+    return ret;
+}
 
 status_t Parcel::writeInt64(int64_t val)
 {
@@ -908,7 +918,8 @@
 
 status_t Parcel::read(void* outData, size_t len) const
 {
-    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize
+            && len <= PAD_SIZE(len)) {
         memcpy(outData, mData+mDataPos, len);
         mDataPos += PAD_SIZE(len);
         ALOGV("read Setting data pos of %p to %d\n", this, mDataPos);
@@ -919,7 +930,8 @@
 
 const void* Parcel::readInplace(size_t len) const
 {
-    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize
+            && len <= PAD_SIZE(len)) {
         const void* data = mData+mDataPos;
         mDataPos += PAD_SIZE(len);
         ALOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
@@ -1348,7 +1360,7 @@
 void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
     const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
 {
-    binder_size_t minOffset = 0;
+    size_t minOffset = 0;
     freeDataNoInit();
     mError = NO_ERROR;
     mData = const_cast<uint8_t*>(data);
@@ -1362,10 +1374,10 @@
     mOwner = relFunc;
     mOwnerCookie = relCookie;
     for (size_t i = 0; i < mObjectsSize; i++) {
-        binder_size_t offset = mObjects[i];
+        size_t offset = mObjects[i];
         if (offset < minOffset) {
-            ALOGE("%s: bad object offset %"PRIu64" < %"PRIu64"\n",
-                  __func__, (uint64_t)offset, (uint64_t)minOffset);
+            ALOGE("%s: bad object offset %zu < %zu\n",
+                  __func__, offset, minOffset);
             mObjectsSize = 0;
             break;
         }
diff --git a/services/sensorservice/SensorFusion.cpp b/services/sensorservice/SensorFusion.cpp
index bb97286..6d93009 100644
--- a/services/sensorservice/SensorFusion.cpp
+++ b/services/sensorservice/SensorFusion.cpp
@@ -102,15 +102,6 @@
         }
     }
 
-    if (enabled) {
-        ALOGD_IF(DEBUG_CONNECTIONS, "SensorFusion calling batch ident=%p ", ident);
-        // Activating a sensor in continuous mode is equivalent to calling batch with the default
-        // period and timeout equal to ZERO, followed by a call to activate.
-        mSensorDevice.batch(ident, mAcc.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
-        mSensorDevice.batch(ident, mMag.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
-        mSensorDevice.batch(ident, mGyro.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
-    }
-
     mSensorDevice.activate(ident, mAcc.getHandle(), enabled);
     mSensorDevice.activate(ident, mMag.getHandle(), enabled);
     mSensorDevice.activate(ident, mGyro.getHandle(), enabled);
@@ -127,9 +118,10 @@
 }
 
 status_t SensorFusion::setDelay(void* ident, int64_t ns) {
-    mSensorDevice.setDelay(ident, mAcc.getHandle(), ns);
-    mSensorDevice.setDelay(ident, mMag.getHandle(), ms2ns(20));
-    mSensorDevice.setDelay(ident, mGyro.getHandle(), mTargetDelayNs);
+    // Call batch with timeout zero instead of setDelay().
+    mSensorDevice.batch(ident, mAcc.getHandle(), 0, ns, 0);
+    mSensorDevice.batch(ident, mMag.getHandle(), 0, ms2ns(20), 0);
+    mSensorDevice.batch(ident, mGyro.getHandle(), 0, mTargetDelayNs, 0);
     return NO_ERROR;
 }
 
diff --git a/services/sensorservice/SensorFusion.h b/services/sensorservice/SensorFusion.h
index b8f360f..432adbc 100644
--- a/services/sensorservice/SensorFusion.h
+++ b/services/sensorservice/SensorFusion.h
@@ -37,7 +37,6 @@
 
 class SensorFusion : public Singleton<SensorFusion> {
     friend class Singleton<SensorFusion>;
-    static const nsecs_t DEFAULT_EVENTS_PERIOD = 200000000;  //  5 Hz
 
     SensorDevice& mSensorDevice;
     Sensor mAcc;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 9cc75c6..6df6315 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -427,20 +427,21 @@
 }
 
 void SensorService::recordLastValue(
-        sensors_event_t const * buffer, size_t count)
-{
+        const sensors_event_t* buffer, size_t count) {
     Mutex::Autolock _l(mLock);
-    // record the last event for each sensor
-    int32_t prev = buffer[0].sensor;
-    for (size_t i=1 ; i<count ; i++) {
-        // record the last event of each sensor type in this buffer
-        int32_t curr = buffer[i].sensor;
-        if (curr != prev) {
-            mLastEventSeen.editValueFor(prev) = buffer[i-1];
-            prev = curr;
+    const sensors_event_t* last = NULL;
+    for (size_t i = 0; i < count; i++) {
+        const sensors_event_t* event = &buffer[i];
+        if (event->type != SENSOR_TYPE_META_DATA) {
+            if (last && event->sensor != last->sensor) {
+                mLastEventSeen.editValueFor(last->sensor) = *last;
+            }
+            last = event;
         }
     }
-    mLastEventSeen.editValueFor(prev) = buffer[count-1];
+    if (last) {
+        mLastEventSeen.editValueFor(last->sensor) = *last;
+    }
 }
 
 void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index c968319..1dc2dd3 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -131,7 +131,7 @@
 
     String8 getSensorName(int handle) const;
     bool isVirtualSensor(int handle) const;
-    void recordLastValue(sensors_event_t const * buffer, size_t count);
+    void recordLastValue(const sensors_event_t* buffer, size_t count);
     static void sortEventBuffer(sensors_event_t* buffer, size_t count);
     Sensor registerSensor(SensorInterface* sensor);
     Sensor registerVirtualSensor(SensorInterface* sensor);