Merge "Volume panel changes."
diff --git a/include/ui/Input.h b/include/ui/Input.h
index c9f694a..f1385a0 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -206,10 +206,17 @@
 
     float getAxisValue(int32_t axis) const;
     status_t setAxisValue(int32_t axis, float value);
-    float* editAxisValue(int32_t axis);
 
     void scale(float scale);
 
+    inline float getX() const {
+        return getAxisValue(AMOTION_EVENT_AXIS_X);
+    }
+
+    inline float getY() const {
+        return getAxisValue(AMOTION_EVENT_AXIS_Y);
+    }
+
 #ifdef HAVE_ANDROID_OS
     status_t readFromParcel(Parcel* parcel);
     status_t writeToParcel(Parcel* parcel) const;
diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h
index 600017e..9452e86 100644
--- a/include/utils/BitSet.h
+++ b/include/utils/BitSet.h
@@ -68,6 +68,30 @@
     // Result is undefined if all bits are unmarked.
     inline uint32_t lastMarkedBit() const { return 31 - __builtin_ctz(value); }
 
+    // Finds the first marked bit in the set and clears it.  Returns the bit index.
+    // Result is undefined if all bits are unmarked.
+    inline uint32_t clearFirstMarkedBit() {
+        uint32_t n = firstMarkedBit();
+        clearBit(n);
+        return n;
+    }
+
+    // Finds the first unmarked bit in the set and marks it.  Returns the bit index.
+    // Result is undefined if all bits are marked.
+    inline uint32_t markFirstUnmarkedBit() {
+        uint32_t n = firstUnmarkedBit();
+        markBit(n);
+        return n;
+    }
+
+    // Finds the last marked bit in the set and clears it.  Returns the bit index.
+    // Result is undefined if all bits are unmarked.
+    inline uint32_t clearLastMarkedBit() {
+        uint32_t n = lastMarkedBit();
+        clearBit(n);
+        return n;
+    }
+
     // Gets the index of the specified bit in the set, which is the number of
     // marked bits that appear before the specified bit.
     inline uint32_t getIndexOfBit(uint32_t n) const {
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 0af7f80..688b998 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -280,6 +280,9 @@
     uint64_t axisBit = 1LL << axis;
     uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
     if (!(bits & axisBit)) {
+        if (value == 0) {
+            return OK; // axes with value 0 do not need to be stored
+        }
         uint32_t count = __builtin_popcountll(bits);
         if (count >= MAX_AXES) {
             tooManyAxes(axis);
@@ -294,23 +297,10 @@
     return OK;
 }
 
-float* PointerCoords::editAxisValue(int32_t axis) {
-    if (axis < 0 || axis > 63) {
-        return NULL;
-    }
-
-    uint64_t axisBit = 1LL << axis;
-    if (!(bits & axisBit)) {
-        return NULL;
-    }
-    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
-    return &values[index];
-}
-
 static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
-    float* value = c.editAxisValue(axis);
-    if (value) {
-        *value *= scaleFactor;
+    float value = c.getAxisValue(axis);
+    if (value != 0) {
+        c.setAxisValue(axis, value * scaleFactor);
     }
 }
 
@@ -574,20 +564,14 @@
     size_t numSamples = mSamplePointerCoords.size();
     for (size_t i = 0; i < numSamples; i++) {
         PointerCoords& c = mSamplePointerCoords.editItemAt(i);
-        float* xPtr = c.editAxisValue(AMOTION_EVENT_AXIS_X);
-        float* yPtr = c.editAxisValue(AMOTION_EVENT_AXIS_Y);
-        if (xPtr && yPtr) {
-            float x = *xPtr + oldXOffset;
-            float y = *yPtr + oldYOffset;
-            matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
-            *xPtr = SkScalarToFloat(point.fX) - newXOffset;
-            *yPtr = SkScalarToFloat(point.fY) - newYOffset;
-        }
+        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
+        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
+        matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
+        c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
+        c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
 
-        float* orientationPtr = c.editAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
-        if (orientationPtr) {
-            *orientationPtr = transformAngle(matrix, *orientationPtr);
-        }
+        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
+        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
     }
 }
 
@@ -727,7 +711,7 @@
     }
 
     while (idBits.count() > MAX_POINTERS) {
-        idBits.clearBit(idBits.lastMarkedBit());
+        idBits.clearLastMarkedBit();
     }
 
     Movement& movement = mMovements[mIndex];
@@ -776,7 +760,7 @@
         // We do this on down instead of on up because the client may want to query the
         // final velocity for a pointer that just went up.
         BitSet32 downIdBits;
-        downIdBits.markBit(event->getActionIndex());
+        downIdBits.markBit(event->getPointerId(event->getActionIndex()));
         clearPointers(downIdBits);
         break;
     }
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp
index e48d5b7..e21c464 100644
--- a/libs/ui/tests/InputEvent_test.cpp
+++ b/libs/ui/tests/InputEvent_test.cpp
@@ -52,9 +52,6 @@
     ASSERT_EQ(0, coords.getAxisValue(1))
             << "getAxisValue should return zero because axis is not present";
 
-    ASSERT_EQ(NULL, coords.editAxisValue(0))
-            << "editAxisValue should return null because axis is not present";
-
     // Set first axis.
     ASSERT_EQ(OK, coords.setAxisValue(1, 5));
     ASSERT_EQ(0x00000002ULL, coords.bits);
@@ -96,26 +93,17 @@
     ASSERT_EQ(2, coords.getAxisValue(3))
             << "getAxisValue should return value of axis";
 
-    // Edit an existing axis value in place.
-    valuePtr = coords.editAxisValue(1);
-    ASSERT_EQ(5, *valuePtr)
-            << "editAxisValue should return pointer to axis value";
-
-    *valuePtr = 7;
-    ASSERT_EQ(7, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-
     // Set an axis with an id between the others.  (inserting value in the middle)
     ASSERT_EQ(OK, coords.setAxisValue(2, 1));
     ASSERT_EQ(0x0000000fULL, coords.bits);
     ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(7, coords.values[1]);
+    ASSERT_EQ(5, coords.values[1]);
     ASSERT_EQ(1, coords.values[2]);
     ASSERT_EQ(2, coords.values[3]);
 
     ASSERT_EQ(4, coords.getAxisValue(0))
             << "getAxisValue should return value of axis";
-    ASSERT_EQ(7, coords.getAxisValue(1))
+    ASSERT_EQ(5, coords.getAxisValue(1))
             << "getAxisValue should return value of axis";
     ASSERT_EQ(1, coords.getAxisValue(2))
             << "getAxisValue should return value of axis";