Merge "Fix format specifiers for size_t types"
am: 0d77698233

* commit '0d77698233ffcbc812c2586693546355ce521603':
  Fix format specifiers for size_t types
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 12ad220..08c6aa7 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -362,7 +362,7 @@
 
     run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL);
 
-    run_command("RAFT LOGS", 300, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL);
+    run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL);
 
     /* show the traces we collected in main(), if that was done */
     if (dump_traces_path != NULL) {
diff --git a/include/android/input.h b/include/android/input.h
index 5ab4e29..5eeb7fc 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -644,6 +644,13 @@
      */
     AMOTION_EVENT_AXIS_TILT = 25,
     /**
+     * Axis constant:  Generic scroll axis of a motion event.
+     *
+     * - This is used for scroll axis motion events that can't be classified as strictly
+     *   vertical or horizontal. The movement of a rotating scroller is an example of this.
+     */
+    AMOTION_EVENT_AXIS_SCROLL = 26,
+    /**
      * Axis constant: Generic 1 axis of a motion event.
      * The interpretation of a generic axis is device-specific.
      */
@@ -817,6 +824,8 @@
     AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,
     /** joystick */
     AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
+    /** rotary encoder */
+    AINPUT_SOURCE_ROTARY_ENCODER = 0x00400000 | AINPUT_SOURCE_CLASS_NONE,
 
     /** any */
     AINPUT_SOURCE_ANY = 0xffffff00,
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/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 e30e65d..10cdee6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -376,13 +376,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
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/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 5859606..2a53dec 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -1191,6 +1191,15 @@
         device->classes |= INPUT_DEVICE_CLASS_CURSOR;
     }
 
+    // See if this is a rotary encoder type device.
+    String8 deviceType = String8();
+    if (device->configuration &&
+        device->configuration->tryGetProperty(String8("device.type"), deviceType)) {
+            if (!deviceType.compare(String8("rotaryEncoder"))) {
+                device->classes |= INPUT_DEVICE_CLASS_ROTARY_ENCODER;
+            }
+    }
+
     // See if this is a touch pad.
     // Is this a new modern multi-touch driver?
     if (test_bit(ABS_MT_POSITION_X, device->absBitmask)
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h
index 0f94c77..6869253 100644
--- a/services/inputflinger/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -137,6 +137,9 @@
     /* The input device is an external stylus (has data we want to fuse with touch data). */
     INPUT_DEVICE_CLASS_EXTERNAL_STYLUS = 0x00000800,
 
+    /* The input device has a rotary encoder */
+    INPUT_DEVICE_CLASS_ROTARY_ENCODER = 0x00001000,
+
     /* The input device is virtual (not a real device, not part of UI configuration). */
     INPUT_DEVICE_CLASS_VIRTUAL       = 0x40000000,
 
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index b2cbfe8..3ba38b5 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -450,6 +450,11 @@
         device->addMapper(new SwitchInputMapper(device));
     }
 
+    // Scroll wheel-like devices.
+    if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
+        device->addMapper(new RotaryEncoderInputMapper(device));
+    }
+
     // Vibrator-like devices.
     if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
         device->addMapper(new VibratorInputMapper(device));
@@ -2728,6 +2733,92 @@
     }
 }
 
+// --- RotaryEncoderInputMapper ---
+
+RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDevice* device) :
+        InputMapper(device) {
+    mSource = AINPUT_SOURCE_ROTARY_ENCODER;
+}
+
+RotaryEncoderInputMapper::~RotaryEncoderInputMapper() {
+}
+
+uint32_t RotaryEncoderInputMapper::getSources() {
+    return mSource;
+}
+
+void RotaryEncoderInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    if (mRotaryEncoderScrollAccumulator.haveRelativeVWheel()) {
+        info->addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+    }
+}
+
+void RotaryEncoderInputMapper::dump(String8& dump) {
+    dump.append(INDENT2 "Rotary Encoder Input Mapper:\n");
+    dump.appendFormat(INDENT3 "HaveWheel: %s\n",
+            toString(mRotaryEncoderScrollAccumulator.haveRelativeVWheel()));
+}
+
+void RotaryEncoderInputMapper::configure(nsecs_t when,
+        const InputReaderConfiguration* config, uint32_t changes) {
+    InputMapper::configure(when, config, changes);
+    if (!changes) {
+        mRotaryEncoderScrollAccumulator.configure(getDevice());
+    }
+}
+
+void RotaryEncoderInputMapper::reset(nsecs_t when) {
+    mRotaryEncoderScrollAccumulator.reset(getDevice());
+
+    InputMapper::reset(when);
+}
+
+void RotaryEncoderInputMapper::process(const RawEvent* rawEvent) {
+    mRotaryEncoderScrollAccumulator.process(rawEvent);
+
+    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
+        sync(rawEvent->when);
+    }
+}
+
+void RotaryEncoderInputMapper::sync(nsecs_t when) {
+    PointerCoords pointerCoords;
+    pointerCoords.clear();
+
+    PointerProperties pointerProperties;
+    pointerProperties.clear();
+    pointerProperties.id = 0;
+    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+
+    float scroll = mRotaryEncoderScrollAccumulator.getRelativeVWheel();
+    bool scrolled = scroll != 0;
+
+    // This is not a pointer, so it's not associated with a display.
+    int32_t displayId = ADISPLAY_ID_NONE;
+
+    // Moving the rotary encoder should wake the device (if specified).
+    uint32_t policyFlags = 0;
+    if (scrolled && getDevice()->isExternal()) {
+        policyFlags |= POLICY_FLAG_WAKE;
+    }
+
+    // Send motion event.
+    if (scrolled) {
+        int32_t metaState = mContext->getGlobalMetaState();
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll);
+
+        NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+                AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, 0,
+                AMOTION_EVENT_EDGE_FLAG_NONE,
+                displayId, 1, &pointerProperties, &pointerCoords,
+                0, 0, 0);
+        getListener()->notifyMotion(&scrollArgs);
+    }
+
+    mRotaryEncoderScrollAccumulator.finishSync();
+}
 
 // --- TouchInputMapper ---
 
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 30c84b1..3e931fe 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -1231,6 +1231,26 @@
 };
 
 
+class RotaryEncoderInputMapper : public InputMapper {
+public:
+    RotaryEncoderInputMapper(InputDevice* device);
+    virtual ~RotaryEncoderInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void dump(String8& dump);
+    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
+    virtual void reset(nsecs_t when);
+    virtual void process(const RawEvent* rawEvent);
+
+private:
+    CursorScrollAccumulator mRotaryEncoderScrollAccumulator;
+
+    int32_t mSource;
+
+    void sync(nsecs_t when);
+};
+
 class TouchInputMapper : public InputMapper {
 public:
     TouchInputMapper(InputDevice* device);
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 1a486a3..db4a4db 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -912,10 +912,15 @@
     status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
                                  maxBatchReportLatencyNs);
 
-    // Call flush() before calling activate() on the sensor. Wait for a first flush complete
-    // event before sending events on this connection. Ignore one-shot sensors which don't
-    // support flush(). Also if this sensor isn't already active, don't call flush().
-    if (err == NO_ERROR && sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT &&
+    // Call flush() before calling activate() on the sensor. Wait for a first
+    // flush complete event before sending events on this connection. Ignore
+    // one-shot sensors which don't support flush(). Ignore on-change sensors
+    // to maintain the on-change logic (any on-change events except the initial
+    // one should be trigger by a change in value). Also if this sensor isn't
+    // already active, don't call flush().
+    if (err == NO_ERROR &&
+            sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT &&
+            sensor->getSensor().getReportingMode() != AREPORTING_MODE_ON_CHANGE &&
             rec->getNumConnections() > 1) {
         connection->setFirstFlushPending(handle, true);
         status_t err_flush = sensor->flush(connection.get(), handle);
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index eb9bd25..1d6e20f 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -3,4 +3,4 @@
     user system
     group graphics drmrpc readproc
     onrestart restart zygote
-    writepid /dev/cpuset/system-background/tasks
+    writepid /dev/cpuset/system-background/tasks /sys/fs/cgroup/stune/foreground/tasks