Add java APIs for Sensor reportingMode.

Change-Id: Iba6bb11f990d9966b86bf02d70ced7312f3e64a8
diff --git a/api/current.txt b/api/current.txt
index fe4ab945..f366a17 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11966,14 +11966,18 @@
     method public int getMinDelay();
     method public java.lang.String getName();
     method public float getPower();
+    method public int getReportingMode();
     method public float getResolution();
     method public java.lang.String getStringType();
     method public int getType();
     method public java.lang.String getVendor();
     method public int getVersion();
     method public boolean isWakeUpSensor();
+    field public static final int REPORTING_MODE_CONTINUOUS = 0; // 0x0
+    field public static final int REPORTING_MODE_ONE_SHOT = 2; // 0x2
+    field public static final int REPORTING_MODE_ON_CHANGE = 1; // 0x1
+    field public static final int REPORTING_MODE_SPECIAL_TRIGGER = 3; // 0x3
     field public static final java.lang.String SENSOR_STRING_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR = "android.sensor.non_wake_up_proximity_sensor";
-    field public static final java.lang.String SENSOR_STRING_TYPE_WAKE_UP_TILT_DETECTOR = "android.sensor.wake_up_tilt_detector";
     field public static final java.lang.String STRING_TYPE_ACCELEROMETER = "android.sensor.accelerometer";
     field public static final java.lang.String STRING_TYPE_AMBIENT_TEMPERATURE = "android.sensor.ambient_temperature";
     field public static final java.lang.String STRING_TYPE_GAME_ROTATION_VECTOR = "android.sensor.game_rotation_vector";
@@ -12054,7 +12058,6 @@
     field public static final int TYPE_WAKE_UP_ROTATION_VECTOR = 31; // 0x1f
     field public static final int TYPE_WAKE_UP_STEP_COUNTER = 38; // 0x26
     field public static final int TYPE_WAKE_UP_STEP_DETECTOR = 37; // 0x25
-    field public static final int TYPE_WAKE_UP_TILT_DETECTOR = 41; // 0x29
   }
 
   public class SensorEvent {
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index c8de2f1..de2cc67 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -708,6 +708,7 @@
      * is generated if the direction of the 2-seconds window average gravity changed by at
      * least 35 degrees since the activation of the sensor. It is a wake up sensor.
      *
+     * @hide
      * @see #isWakeUpSensor()
      */
     public static final int TYPE_WAKE_UP_TILT_DETECTOR = 41;
@@ -715,6 +716,7 @@
     /**
      * A constant string describing a wake up tilt detector sensor type.
      *
+     * @hide
      * @see #TYPE_WAKE_UP_TILT_DETECTOR
      */
     public static final String SENSOR_STRING_TYPE_WAKE_UP_TILT_DETECTOR =
@@ -752,16 +754,47 @@
      */
     public static final int TYPE_ALL = -1;
 
-    /* Reporting mode constants for sensors. Each sensor will have exactly one
-       reporting mode associated with it. */
-    // Events are reported at a constant rate.
-    static int REPORTING_MODE_CONTINUOUS = 1;
+    // If this flag is set, the sensor defined as a wake up sensor. This field and REPORTING_MODE_*
+    // constants are defined as flags in sensors.h. Modify at both places if needed.
+    private static final int SENSOR_FLAG_WAKE_UP_SENSOR = 1;
 
-    // Events are reported only when the value changes.
-    static int REPORTING_MODE_ON_CHANGE = 2;
+    /**
+     * Events are reported at a constant rate which is set by the rate parameter of
+     * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)}. Note: If other
+     * applications are requesting a higher rate, the sensor data might be delivered at faster rates
+     * than requested.
+     */
+    public static final int REPORTING_MODE_CONTINUOUS = 0;
 
-    // Upon detection of an event, the sensor deactivates itself and then sends a single event.
-    static int REPORTING_MODE_ONE_SHOT = 3;
+    /**
+     * Events are reported only when the value changes. Event delivery rate can be limited by
+     * setting appropriate value for rate parameter of
+     * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} Note: If other
+     * applications are requesting a higher rate, the sensor data might be delivered at faster rates
+     * than requested.
+     */
+    public static final int REPORTING_MODE_ON_CHANGE = 1;
+
+    /**
+     * Events are reported in one-shot mode. Upon detection of an event, the sensor deactivates
+     * itself and then sends a single event. Sensors of this reporting mode must be registered to
+     * using {@link SensorManager#requestTriggerSensor(TriggerEventListener, Sensor)}.
+     */
+    public static final int REPORTING_MODE_ONE_SHOT = 2;
+
+    /**
+     * Events are reported as described in the description of the sensor. The rate passed to
+     * registerListener might not have an impact on the rate of event delivery. See the sensor
+     * definition for more information on when and how frequently the events are reported. For
+     * example, step detectors report events when a step is detected.
+     *
+     * @see SensorManager#registerListener(SensorEventListener, Sensor, int, int)
+     */
+    public static final int REPORTING_MODE_SPECIAL_TRIGGER = 3;
+
+    // Mask for the LSB 2nd, 3rd and fourth bits.
+    private static final int REPORTING_MODE_MASK = 0xE;
+    private static final int REPORTING_MODE_SHIFT = 1;
 
     // TODO(): The following arrays are fragile and error-prone. This needs to be refactored.
 
@@ -770,80 +803,74 @@
     // associated with
     // {@link SensorEvent} or {@link TriggerEvent} for the Sensor
     private static final int[] sSensorReportingModes = {
-            0, 0, // padding because sensor types start at 1
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_ACCELEROMETER
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GEOMAGNETIC_FIELD
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_ORIENTATION
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GYROSCOPE
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_LIGHT
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_PRESSURE
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_TEMPERATURE
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_PROXIMITY
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GRAVITY
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_LINEAR_ACCELERATION
-            REPORTING_MODE_CONTINUOUS, 5, // SENSOR_TYPE_ROTATION_VECTOR
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_RELATIVE_HUMIDITY
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_AMBIENT_TEMPERATURE
-            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
-            REPORTING_MODE_CONTINUOUS, 4, // SENSOR_TYPE_GAME_ROTATION_VECTOR
-            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
-            REPORTING_MODE_ONE_SHOT,   1, // SENSOR_TYPE_SIGNIFICANT_MOTION
-            // added post 4.3
-            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_STEP_DETECTOR
-            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_STEP_COUNTER
-            REPORTING_MODE_CONTINUOUS, 5, // SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
-            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_HEART_RATE_MONITOR
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR
+            0, // padding because sensor types start at 1
+            3, // SENSOR_TYPE_ACCELEROMETER
+            3, // SENSOR_TYPE_GEOMAGNETIC_FIELD
+            3, // SENSOR_TYPE_ORIENTATION
+            3, // SENSOR_TYPE_GYROSCOPE
+            3, // SENSOR_TYPE_LIGHT
+            3, // SENSOR_TYPE_PRESSURE
+            3, // SENSOR_TYPE_TEMPERATURE
+            3, // SENSOR_TYPE_PROXIMITY
+            3, // SENSOR_TYPE_GRAVITY
+            3, // SENSOR_TYPE_LINEAR_ACCELERATION
+            5, // SENSOR_TYPE_ROTATION_VECTOR
+            3, // SENSOR_TYPE_RELATIVE_HUMIDITY
+            3, // SENSOR_TYPE_AMBIENT_TEMPERATURE
+            6, // SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
+            4, // SENSOR_TYPE_GAME_ROTATION_VECTOR
+            6, // SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+            1, // SENSOR_TYPE_SIGNIFICANT_MOTION
+            1, // SENSOR_TYPE_STEP_DETECTOR
+            1, // SENSOR_TYPE_STEP_COUNTER
+            5, // SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
+            1, // SENSOR_TYPE_HEART_RATE_MONITOR
+            3, // SENSOR_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR
             // wake up variants of base sensors
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_WAKE_UP_ACCELEROMETER
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_WAKE_UP_ORIENTATION
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_WAKE_UP_GYROSCOPE
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_WAKE_UP_LIGHT
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_WAKE_UP_PRESSURE
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_WAKE_UP_GRAVITY
-            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_WAKE_UP_LINEAR_ACCELERATION
-            REPORTING_MODE_CONTINUOUS, 5, // SENSOR_TYPE_WAKE_UP_ROTATION_VECTOR
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_WAKE_UP_RELATIVE_HUMIDITY
-            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_WAKE_UP_AMBIENT_TEMPERATURE
-            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD_UNCALIBRATED
-            REPORTING_MODE_CONTINUOUS, 4, // SENSOR_TYPE_WAKE_UP_GAME_ROTATION_VECTOR
-            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_WAKE_UP_GYROSCOPE_UNCALIBRATED
-            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_WAKE_UP_STEP_DETECTOR
-            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_WAKE_UP_STEP_COUNTER
-            REPORTING_MODE_CONTINUOUS, 5, // SENSOR_TYPE_WAKE_UP_GEOMAGNETIC_ROTATION_VECTOR
-            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_WAKE_UP_HEART_RATE_MONITOR
-            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_WAKE_UP_TILT_DETECTOR
-            REPORTING_MODE_ONE_SHOT,   1, // SENSOR_TYPE_WAKE_GESTURE
+            3, // SENSOR_TYPE_WAKE_UP_ACCELEROMETER
+            3, // SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD
+            3, // SENSOR_TYPE_WAKE_UP_ORIENTATION
+            3, // SENSOR_TYPE_WAKE_UP_GYROSCOPE
+            3, // SENSOR_TYPE_WAKE_UP_LIGHT
+            3, // SENSOR_TYPE_WAKE_UP_PRESSURE
+            3, // SENSOR_TYPE_WAKE_UP_GRAVITY
+            3, // SENSOR_TYPE_WAKE_UP_LINEAR_ACCELERATION
+            5, // SENSOR_TYPE_WAKE_UP_ROTATION_VECTOR
+            3, // SENSOR_TYPE_WAKE_UP_RELATIVE_HUMIDITY
+            3, // SENSOR_TYPE_WAKE_UP_AMBIENT_TEMPERATURE
+            6, // SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD_UNCALIBRATED
+            4, // SENSOR_TYPE_WAKE_UP_GAME_ROTATION_VECTOR
+            6, // SENSOR_TYPE_WAKE_UP_GYROSCOPE_UNCALIBRATED
+            1, // SENSOR_TYPE_WAKE_UP_STEP_DETECTOR
+            1, // SENSOR_TYPE_WAKE_UP_STEP_COUNTER
+            5, // SENSOR_TYPE_WAKE_UP_GEOMAGNETIC_ROTATION_VECTOR
+            1, // SENSOR_TYPE_WAKE_UP_HEART_RATE_MONITOR
+            1, // SENSOR_TYPE_WAKE_UP_TILT_DETECTOR
+            1, // SENSOR_TYPE_WAKE_GESTURE
     };
 
-    static int getReportingMode(Sensor sensor) {
-        int offset = sensor.mType * 2;
-        if (offset >= sSensorReportingModes.length) {
-            // we don't know about this sensor, so this is probably a
-            // vendor-defined sensor, in that case, we figure out the reporting
-            // mode from the sensor meta-data.
-            int minDelay = sensor.mMinDelay;
-            if (minDelay == 0) {
-                return REPORTING_MODE_ON_CHANGE;
-            } else if (minDelay < 0) {
-                return REPORTING_MODE_ONE_SHOT;
-            } else {
-                return REPORTING_MODE_CONTINUOUS;
-            }
-        }
-        return sSensorReportingModes[offset];
+    /**
+     * Each sensor has exactly one reporting mode associated with it. This method returns the
+     * reporting mode constant for this sensor type.
+     *
+     * @return Reporting mode for the input sensor, one of REPORTING_MODE_* constants.
+     * @see #REPORTING_MODE_CONTINUOUS
+     * @see #REPORTING_MODE_ON_CHANGE
+     * @see #REPORTING_MODE_ONE_SHOT
+     * @see #REPORTING_MODE_SPECIAL_TRIGGER
+     */
+    public int getReportingMode() {
+        return ((mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT);
     }
 
     static int getMaxLengthValuesArray(Sensor sensor, int sdkLevel) {
-        int type = sensor.mType;
         // RotationVector length has changed to 3 to 5 for API level 18
         // Set it to 3 for backward compatibility.
-        if (type == Sensor.TYPE_ROTATION_VECTOR &&
+        if (sensor.mType == Sensor.TYPE_ROTATION_VECTOR &&
                 sdkLevel <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
             return 3;
         }
-        int offset = type * 2 + 1;
+        int offset = sensor.mType;
         if (offset >= sSensorReportingModes.length) {
             // we don't know about this sensor, so this is probably a
             // vendor-defined sensor, in that case, we don't know how many value
@@ -873,7 +900,7 @@
     private String  mStringType;
     private String  mRequiredPermission;
     private int     mMaxDelay;
-    private boolean mWakeUpSensor;
+    private int     mFlags;
 
     Sensor() {
     }
@@ -1016,7 +1043,7 @@
      * @return true if this is a wake up sensor, false otherwise.
      */
     public boolean isWakeUpSensor() {
-        return mWakeUpSensor;
+        return (mFlags & SENSOR_FLAG_WAKE_UP_SENSOR) != 0;
     }
 
     void setRange(float max, float res) {
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index b66ec86..a6c3ea4 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -99,7 +99,7 @@
             return false;
         }
         // Trigger Sensors should use the requestTriggerSensor call.
-        if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) {
+        if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
             Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
             return false;
         }
@@ -133,7 +133,7 @@
     @Override
     protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
         // Trigger Sensors should use the cancelTriggerSensor call.
-        if (sensor != null && Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) {
+        if (sensor != null && sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
             return;
         }
 
@@ -159,7 +159,7 @@
     protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
         if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
 
-        if (Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) return false;
+        if (sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) return false;
 
         synchronized (mTriggerListeners) {
             TriggerEventQueue queue = mTriggerListeners.get(listener);
@@ -181,7 +181,7 @@
     @Override
     protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
             boolean disable) {
-        if (sensor != null && Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) {
+        if (sensor != null && sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) {
             return false;
         }
         synchronized (mTriggerListeners) {
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index ddcc396..c588942 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -52,7 +52,7 @@
     jfieldID    stringType;
     jfieldID    requiredPermission;
     jfieldID    maxDelay;
-    jfieldID    isWakeUpSensor;
+    jfieldID    flags;
 } gSensorOffsets;
 
 
@@ -81,7 +81,7 @@
     sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission",
                                                         "Ljava/lang/String;");
     sensorOffsets.maxDelay    = _env->GetFieldID(sensorClass, "mMaxDelay",  "I");
-    sensorOffsets.isWakeUpSensor = _env->GetFieldID(sensorClass, "mWakeUpSensor",  "Z");
+    sensorOffsets.flags = _env->GetFieldID(sensorClass, "mFlags",  "I");
 }
 
 static jint
@@ -117,7 +117,7 @@
     env->SetObjectField(sensor, sensorOffsets.requiredPermission,
                         requiredPermission);
     env->SetIntField(sensor, sensorOffsets.maxDelay, list->getMaxDelay());
-    env->SetBooleanField(sensor, sensorOffsets.isWakeUpSensor, list->isWakeUpSensor());
+    env->SetIntField(sensor, sensorOffsets.flags, list->getFlags());
     next++;
     return size_t(next) < count ? next : 0;
 }
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index 3f37ed1..b09bc2e 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -171,3 +171,8 @@
 {
     return static_cast<Sensor const*>(sensor)->getStringType().string();
 }
+
+int ASensor_getReportingMode(ASensor const* sensor)
+{
+    return static_cast<Sensor const*>(sensor)->getReportingMode();
+}