Revert "Add new sensor types."

This reverts commit bc03a348d78326dee779a8ecc325799c9fceac98.
diff --git a/api/current.txt b/api/current.txt
index be104a0..1668170 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10045,20 +10045,16 @@
     field public static final int TYPE_ACCELEROMETER = 1; // 0x1
     field public static final int TYPE_ALL = -1; // 0xffffffff
     field public static final int TYPE_AMBIENT_TEMPERATURE = 13; // 0xd
-    field public static final int TYPE_GAME_ROTATION_VECTOR = 15; // 0xf
     field public static final int TYPE_GRAVITY = 9; // 0x9
     field public static final int TYPE_GYROSCOPE = 4; // 0x4
-    field public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16; // 0x10
     field public static final int TYPE_LIGHT = 5; // 0x5
     field public static final int TYPE_LINEAR_ACCELERATION = 10; // 0xa
     field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2
-    field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe
     field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3
     field public static final int TYPE_PRESSURE = 6; // 0x6
     field public static final int TYPE_PROXIMITY = 8; // 0x8
     field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
     field public static final int TYPE_ROTATION_VECTOR = 11; // 0xb
-    field public static final int TYPE_SIGNIFICANT_MOTION = 17; // 0x11
     field public static final deprecated int TYPE_TEMPERATURE = 7; // 0x7
   }
 
@@ -10080,7 +10076,6 @@
   }
 
   public abstract class SensorManager {
-    method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
     method public static float getAltitude(float, float);
     method public static void getAngleChange(float[], float[], float[]);
     method public android.hardware.Sensor getDefaultSensor(int);
@@ -10096,7 +10091,6 @@
     method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int);
     method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, android.os.Handler);
     method public static boolean remapCoordinateSystem(float[], int, int, float[]);
-    method public boolean requestTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
     method public deprecated void unregisterListener(android.hardware.SensorListener);
     method public deprecated void unregisterListener(android.hardware.SensorListener, int);
     method public void unregisterListener(android.hardware.SensorEventListener, android.hardware.Sensor);
@@ -10160,17 +10154,6 @@
     field public static final float STANDARD_GRAVITY = 9.80665f;
   }
 
-  public final class TriggerEvent {
-    field public android.hardware.Sensor sensor;
-    field public long timestamp;
-    field public final float[] values;
-  }
-
-  public abstract class TriggerEventListener {
-    ctor public TriggerEventListener();
-    method public abstract void onTrigger(android.hardware.TriggerEvent);
-  }
-
 }
 
 package android.hardware.display {
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index af4c074..41384d2 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -114,90 +114,11 @@
     /** A constant describing an ambient temperature sensor type */
     public static final int TYPE_AMBIENT_TEMPERATURE = 13;
 
-    /**
-     * A constant describing a magnetic field uncalibrated sensor type. See
-     * {@link android.hardware.SensorEvent#values SensorEvent.values} for more
-     * details.
-     * <p>
-     * No periodic calibration is performed (ie: there are no discontinuities
-     * in the data stream while using this sensor). Assumptions that the
-     * magnetic field is due to the Earth's poles is avoided. Factory calibration
-     * and temperature compensation is still performed.
-     * </p>
-     */
-    public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14;
-
-    /**
-     * Identical to {@link #TYPE_ROTATION_VECTOR} except that it doesn't
-     * use the geomagnetic field. Therefore the Y axis doesn't
-     * point north, but instead to some other reference, that reference is
-     * allowed to drift by the same order of magnitude as the gyroscope
-     * drift around the Z axis.
-     * <p>
-     * In the ideal case, a phone rotated and returning to the same real-world
-     * orientation should report the same game rotation vector
-     * (without using the earth's geomagnetic field). However, the orientation
-     * may drift somewhat over time.
-     * </p>
-     */
-
-    public static final int TYPE_GAME_ROTATION_VECTOR = 15;
-
-    /**
-     * A constant describing a gyroscope uncalibrated sensor type. See
-     * {@link android.hardware.SensorEvent#values SensorEvent.values} for more
-     * details.
-     * <p>
-     * No gyro-drift compensation is performed.
-     * Factory calibration and temperature compensation is still applied
-     * to the rate of rotation (angular speeds).
-     * </p>
-     */
-    public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16;
-
-    /**
-     * A constant describing the significant motion trigger sensor.
-     * See {@link android.hardware.SensorEvent#values} for more details.
-     * <p>
-     * It triggers when an event occurs and then automatically disables
-     * itself. The sensor continues to operate while the device is asleep
-     * and will automatically wake the device to notify when significant
-     * motion is detected. The application does not need to hold any wake
-     * locks for this sensor to trigger.
-     * </p>
-     */
-    public static final int TYPE_SIGNIFICANT_MOTION = 17;
-
-    /**
+    /** 
      * A constant describing all sensor types.
      */
     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;
-
-    // Events are reported only when the value changes.
-    static int REPORTING_MODE_ON_CHANGE = 2;
-
-    // Upon detection of an event, the sensor deactivates itself and then sends a single event.
-    static int REPORTING_MODE_ONE_SHOT = 3;
-
-    // Note: This needs to be updated, whenever a new sensor is added.
-    private static int[] sSensorReportingModes = {
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_ON_CHANGE, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE,
-            REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ONE_SHOT };
-
-    static int getReportingMode(Sensor sensor) {
-        // mType starts from offset 1.
-        return sSensorReportingModes[sensor.mType - 1];
-    }
-
     /* Some of these fields are set only by the native bindings in
      * SensorManager.
      */
@@ -211,6 +132,7 @@
     private float   mPower;
     private int     mMinDelay;
 
+
     Sensor() {
     }
 
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 84c9131..51a17c1 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -17,9 +17,11 @@
 package android.hardware;
 
 /**
+ * <p>
  * This class represents a {@link android.hardware.Sensor Sensor} event and
  * holds informations such as the sensor's type, the time-stamp, accuracy and of
  * course the sensor's {@link SensorEvent#values data}.
+ * </p>
  *
  * <p>
  * <u>Definition of the coordinate system used by the SensorEvent API.</u>
@@ -65,9 +67,15 @@
      * Sensor.TYPE_ACCELEROMETER}:</h4> All values are in SI units (m/s^2)
      * 
      * <ul>
-     * <li> values[0]: Acceleration minus Gx on the x-axis </li>
-     * <li> values[1]: Acceleration minus Gy on the y-axis </li>
-     * <li> values[2]: Acceleration minus Gz on the z-axis </li>
+     * <p>
+     * values[0]: Acceleration minus Gx on the x-axis
+     * </p>
+     * <p>
+     * values[1]: Acceleration minus Gy on the y-axis
+     * </p>
+     * <p>
+     * values[2]: Acceleration minus Gz on the z-axis
+     * </p>
      * </ul>
      * 
      * <p>
@@ -157,9 +165,15 @@
      * definition of positive rotation and does not agree with the definition of
      * roll given earlier.
      * <ul>
-     * <li> values[0]: Angular speed around the x-axis </li>
-     * <li> values[1]: Angular speed around the y-axis </li>
-     * <li> values[2]: Angular speed around the z-axis </li>
+     * <p>
+     * values[0]: Angular speed around the x-axis
+     * </p>
+     * <p>
+     * values[1]: Angular speed around the y-axis
+     * </p>
+     * <p>
+     * values[2]: Angular speed around the z-axis
+     * </p>
      * </ul>
      * <p>
      * Typically the output of the gyroscope is integrated over time to
@@ -219,19 +233,22 @@
      * </p>
      * <h4>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:</h4>
      * <ul>
-     * <li>values[0]: Ambient light level in SI lux units </li>
+     * <p>
+     * values[0]: Ambient light level in SI lux units
      * </ul>
      * 
      * <h4>{@link android.hardware.Sensor#TYPE_PRESSURE Sensor.TYPE_PRESSURE}:</h4>
      * <ul>
-     * <li>values[0]: Atmospheric pressure in hPa (millibar) </li>
+     * <p>
+     * values[0]: Atmospheric pressure in hPa (millibar)
      * </ul>
      *
      * <h4>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}:
      * </h4>
      * 
      * <ul>
-     * <li>values[0]: Proximity sensor distance measured in centimeters </li>
+     * <p>
+     * values[0]: Proximity sensor distance measured in centimeters
      * </ul>
      * 
      * <p>
@@ -287,23 +304,39 @@
      * </p>
      *
      * <ul>
-     * <li> values[0]: x*sin(&#952/2) </li>
-     * <li> values[1]: y*sin(&#952/2) </li>
-     * <li> values[2]: z*sin(&#952/2) </li>
-     * <li> values[3]: cos(&#952/2) <i>(optional: only if value.length = 4)</i> </li>
+     * <p>
+     * values[0]: x*sin(&#952/2)
+     * </p>
+     * <p>
+     * values[1]: y*sin(&#952/2)
+     * </p>
+     * <p>
+     * values[2]: z*sin(&#952/2)
+     * </p>
+     * <p>
+     * values[3]: cos(&#952/2) <i>(optional: only if value.length = 4)</i>
+     * </p>
      * </ul>
      *
      * <h4>{@link android.hardware.Sensor#TYPE_ORIENTATION
      * Sensor.TYPE_ORIENTATION}:</h4> All values are angles in degrees.
      * 
      * <ul>
-     * <li> values[0]: Azimuth, angle between the magnetic north direction and the
+     * <p>
+     * values[0]: Azimuth, angle between the magnetic north direction and the
      * y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South,
-     * 270=West </li>
-     * <li> values[1]: Pitch, rotation around x-axis (-180 to 180), with positive
-     * values when the z-axis moves <b>toward</b> the y-axis. </li>
-     * <li> values[2]: Roll, rotation around y-axis (-90 to 90), with positive values
-     * when the x-axis moves <b>toward</b> the z-axis. </li>
+     * 270=West
+     * </p>
+     * 
+     * <p>
+     * values[1]: Pitch, rotation around x-axis (-180 to 180), with positive
+     * values when the z-axis moves <b>toward</b> the y-axis.
+     * </p>
+     * 
+     * <p>
+     * values[2]: Roll, rotation around y-axis (-90 to 90), with positive values
+     * when the x-axis moves <b>toward</b> the z-axis.
+     * </p>
      * </ul>
      * 
      * <p>
@@ -331,7 +364,9 @@
      * <h4>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY
      * Sensor.TYPE_RELATIVE_HUMIDITY}:</h4>
      * <ul>
-     * <li> values[0]: Relative ambient air humidity in percent </li>
+     * <p>
+     * values[0]: Relative ambient air humidity in percent
+     * </p>
      * </ul>
      * <p>
      * When relative ambient air humidity and ambient temperature are
@@ -388,58 +423,21 @@
      * </h4>
      *
      * <ul>
-     * <li> values[0]: ambient (room) temperature in degree Celsius.</li>
+     * <p>
+     * values[0]: ambient (room) temperature in degree Celsius.
      * </ul>
      *
      * @see SensorEvent
      * @see GeomagneticField
-     *
-     * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED} </h4>
-     * All values are in micro-Tesla (uT) and measure the ambient magnetic field
-     * in the X, Y and Z axis.
-     * <p>
-     * No periodic calibration is performed (ie: there are no discontinuities
-     * in the data stream while using this sensor). Assumptions that the the
-     * magnetic field is due to the Earth's poles is avoided. Factory calibration
-     * and temperature compensation is still performed.
-     * </p>
-     *
-     * <h4> {@link android.hardware.Sensor#TYPE_GYROSCOPE_UNCALIBRATED} </h4>
-     * All values are in radians/second and measure the rate of rotation
-     * around the X, Y and Z axis. An estimation of the drift on each axis is
-     * reported as well.
-     * <p>
-     * No gyro-drift compensation is performed. Factory calibration and temperature
-     * compensation is still applied to the rate of rotation (angular speeds).
-     * </p>
-     * <p>
-     * The coordinate system is the same as is used for the
-     * {@link android.hardware.Sensor#TYPE_ACCELEROMETER}
-     * Rotation is positive in the counter-clockwise direction (right-hand rule).
-     * That is, an observer looking from some positive location on the x, y or z axis
-     * at a device positioned on the origin would report positive rotation if the device
-     * appeared to be rotating counter clockwise.
-     * The range would at least be 17.45 rad/s (ie: ~1000 deg/s).
-     * <ul>
-     * <li> values[0] : angular speed (w/o drift compensation) around the X axis in rad/s </li>
-     * <li> values[1] : angular speed (w/o drift compensation) around the Y axis in rad/s </li>
-     * <li> values[2] : angular speed (w/o drift compensation) around the Z axis in rad/s </li>
-     * <li> values[3] : estimated drift around X axis in rad/s </li>
-     * <li> values[4] : estimated drift around Y axis in rad/s </li>
-     * <li> values[5] : estimated drift around Z axis in rad/s </li>
-     * </ul>
-     * </p>
-     * <h4></h4>
-     * <h4> Pro Tip: Always use the length of the values array while performing operations
-     * on it. In earlier versions, this used to be always 3 which has changed now. </h4>
      */
+
     public final float[] values;
 
     /**
      * The sensor that generated this event. See
      * {@link android.hardware.SensorManager SensorManager} for details.
      */
-    public Sensor sensor;
+   public Sensor sensor;
 
     /**
      * The accuracy of this event. See {@link android.hardware.SensorManager
@@ -447,11 +445,13 @@
      */
     public int accuracy;
 
+
     /**
      * The time in nanosecond at which the event happened
      */
     public long timestamp;
 
+
     SensorEvent(int size) {
         values = new float[size];
     }
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index ce7bc7e..c0d2fae 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -38,11 +38,7 @@
  * hours. Note that the system will <i>not</i> disable sensors automatically when
  * the screen turns off.
  * </p>
- * <p class="note">
- * Note: Don't use this mechanism with a Trigger Sensor, have a look
- * at {@link TriggerEventListener}. {@link Sensor#TYPE_SIGNIFICANT_MOTION}
- * is an example of a trigger sensor.
- * </p>
+ *
  * <pre class="prettyprint">
  * public class SensorActivity extends Activity, implements SensorEventListener {
  *     private final SensorManager mSensorManager;
@@ -519,12 +515,6 @@
     /**
      * Unregisters a listener for the sensors with which it is registered.
      *
-     * <p class="note"></p>
-     * Note: Don't use this method with a one shot trigger sensor such as
-     * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
-     * Use {@link #cancelTriggerSensor(TriggerEventListener, Sensor)} instead.
-     * </p>
-     *
      * @param listener
      *        a SensorEventListener object
      *
@@ -534,7 +524,6 @@
      * @see #unregisterListener(SensorEventListener)
      * @see #registerListener(SensorEventListener, Sensor, int)
      *
-     * @throws IllegalArgumentException when sensor is a trigger sensor.
      */
     public void unregisterListener(SensorEventListener listener, Sensor sensor) {
         if (listener == null || sensor == null) {
@@ -569,12 +558,6 @@
      * Registers a {@link android.hardware.SensorEventListener
      * SensorEventListener} for the given sensor.
      *
-     * <p class="note"></p>
-     * Note: Don't use this method with a one shot trigger sensor such as
-     * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
-     * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
-     * </p>
-     *
      * @param listener
      *        A {@link android.hardware.SensorEventListener SensorEventListener}
      *        object.
@@ -598,7 +581,6 @@
      * @see #unregisterListener(SensorEventListener)
      * @see #unregisterListener(SensorEventListener, Sensor)
      *
-     * @throws IllegalArgumentException when sensor is null or a trigger sensor
      */
     public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) {
         return registerListener(listener, sensor, rate, null);
@@ -608,12 +590,6 @@
      * Registers a {@link android.hardware.SensorEventListener
      * SensorEventListener} for the given sensor.
      *
-     * <p class="note"></p>
-     * Note: Don't use this method with a one shot trigger sensor such as
-     * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
-     * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
-     * </p>
-     *
      * @param listener
      *        A {@link android.hardware.SensorEventListener SensorEventListener}
      *        object.
@@ -641,7 +617,6 @@
      * @see #unregisterListener(SensorEventListener)
      * @see #unregisterListener(SensorEventListener, Sensor)
      *
-     * @throws IllegalArgumentException when sensor is null or a trigger sensor
      */
     public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate,
             Handler handler) {
@@ -1329,68 +1304,6 @@
         Q[3] = rv[2];
     }
 
-    /**
-     * Requests receiving trigger events for a trigger sensor.
-     *
-     * <p>
-     * When the sensor detects a trigger event condition, such as significant motion in
-     * the case of the {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the provided trigger listener
-     * will be invoked once and then its request to receive trigger events will be canceled.
-     * To continue receiving trigger events, the application must request to receive trigger
-     * events again.
-     * </p>
-     *
-     * @param listener The listener on which the
-     *        {@link TriggerEventListener#onTrigger(TriggerEvent)} will be delivered.
-     * @param sensor The sensor to be enabled.
-     *
-     * @return true if the sensor was successfully enabled.
-     *
-     * @throws IllegalArgumentException when sensor is null or not a trigger sensor.
-     */
-    public boolean requestTriggerSensor(TriggerEventListener listener, Sensor sensor) {
-        return requestTriggerSensorImpl(listener, sensor);
-    }
-
-    /**
-     * @hide
-     */
-    protected abstract boolean requestTriggerSensorImpl(TriggerEventListener listener,
-            Sensor sensor);
-
-    /**
-     * Cancels receiving trigger events for a trigger sensor.
-     *
-     * <p>
-     * Note that a Trigger sensor will be auto disabled if
-     * {@link TriggerEventListener#onTrigger(TriggerEvent)} has triggered.
-     * This method is provided in case the user wants to explicitly cancel the request
-     * to receive trigger events.
-     * </p>
-     *
-     * @param listener The listener on which the
-     *        {@link TriggerEventListener#onTrigger(TriggerEvent)}
-     *        is delivered.It should be the same as the one used
-     *        in {@link #requestTriggerSensor(TriggerEventListener, Sensor)}
-     * @param sensor The sensor for which the trigger request should be canceled.
-     *        If null, it cancels receiving trigger for all sensors associated
-     *        with the listener.
-     *
-     * @return true if successfully canceled.
-     *
-     * @throws IllegalArgumentException when sensor is a trigger sensor.
-     */
-    public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) {
-        return cancelTriggerSensorImpl(listener, sensor);
-    }
-
-    /**
-     * @hide
-     */
-    protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener,
-            Sensor sensor);
-
-
     private LegacySensorManager getLegacySensorManager() {
         synchronized (mSensorListByType) {
             if (mLegacySensorManager == null) {
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 3c231e5..9591631 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -16,19 +16,18 @@
 
 package android.hardware;
 
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import dalvik.system.CloseGuard;
+
 import android.os.Handler;
 import android.os.Looper;
 import android.os.MessageQueue;
-import android.util.Log;
-import android.util.Pools;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
-import dalvik.system.CloseGuard;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
 
 /**
  * Sensor manager implementation that communicates with the built-in
@@ -46,21 +45,22 @@
     private static final SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>();
 
     // Listener list
-    private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =
-            new HashMap<SensorEventListener, SensorEventQueue>();
-    private final HashMap<TriggerEventListener, TriggerEventQueue> mTriggerListeners =
-            new HashMap<TriggerEventListener, TriggerEventQueue>();
+    private final ArrayList<SensorEventListenerSensorPair> mListenerDelegates = new ArrayList<SensorEventListenerSensorPair>();
 
-    private static final int MAX_EVENTS = 16;
-    private static Pools.SynchronizedPool<SensorEvent> sSensorEventPool;
-    private static Pools.SynchronizedPool<TriggerEvent> sTriggerEventPool;
+    // Common pool of sensor events.
+    private static SensorEventPool sPool;
 
     // Looper associated with the context in which this instance was created.
     private final Looper mMainLooper;
 
+    // maps a SensorEventListener to a SensorEventQueue
+    private final Hashtable<SensorEventListener, SensorEventQueue> mSensorEventQueueMap;
+
     /** {@hide} */
     public SystemSensorManager(Looper mainLooper) {
         mMainLooper = mainLooper;
+        mSensorEventQueueMap = new Hashtable<SensorEventListener, SensorEventQueue>();
+
         synchronized(sSensorModuleLock) {
             if (!sSensorModuleInitialized) {
                 sSensorModuleInitialized = true;
@@ -81,10 +81,7 @@
                     }
                 } while (i>0);
 
-                sSensorEventPool = new Pools.SynchronizedPool<SensorEvent>(
-                        sFullSensorsList.size()*2);
-                sTriggerEventPool = new Pools.SynchronizedPool<TriggerEvent>(
-                        sFullSensorsList.size()*2);
+                sPool = new SensorEventPool( sFullSensorsList.size()*2 );
             }
         }
     }
@@ -105,133 +102,128 @@
         // Invariants to preserve:
         // - one Looper per SensorEventListener
         // - one Looper per SensorEventQueue
-        // We map SensorEventListener to a SensorEventQueue, which holds the looper
-        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+        // We map SensorEventListeners to a SensorEventQueue, which holds the looper
 
-        // Trigger Sensors should use the requestTriggerSensor call.
-        if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) return false;
+        if (sensor == null) throw new NullPointerException("sensor cannot be null");
 
-        synchronized (mSensorListeners) {
-            SensorEventQueue queue = mSensorListeners.get(listener);
-            if (queue == null) {
-                Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
-                queue = new SensorEventQueue(listener, looper);
-                if (!queue.addSensor(sensor, delay)) {
-                    queue.dispose();
-                    return false;
+        boolean result;
+        synchronized (mSensorEventQueueMap) {
+            // check if we already have this SensorEventListener, Sensor pair
+            // registered -- if so, we ignore the register. This is not ideal
+            // but this is what the implementation has always been doing.
+            for (SensorEventListenerSensorPair l : mListenerDelegates) {
+                if (l.isSameListenerSensorPair(listener, sensor)) {
+                    // already added, just return silently.
+                    return true;
                 }
-                mSensorListeners.put(listener, queue);
-                return true;
+            }
+
+            // now find the SensorEventQueue associated to this listener
+            SensorEventQueue queue = mSensorEventQueueMap.get(listener);
+            if (queue != null) {
+                result = queue.addSensor(sensor, delay);
+                if (result) {
+                    // create a new ListenerDelegate for this pair
+                    mListenerDelegates.add(new SensorEventListenerSensorPair(listener, sensor));
+                }
             } else {
-                return queue.addSensor(sensor, delay);
+                Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
+                queue = new SensorEventQueue(listener, looper.getQueue());
+                result = queue.addSensor(sensor, delay);
+                if (result) {
+                    // create a new ListenerDelegate for this pair
+                    mListenerDelegates.add(new SensorEventListenerSensorPair(listener, sensor));
+                    mSensorEventQueueMap.put(listener, queue);
+                } else {
+                    queue.dispose();
+                }
             }
         }
+        return result;
     }
 
     /** @hide */
     @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) {
-            return;
-        }
+        synchronized (mSensorEventQueueMap) {
 
-        synchronized (mSensorListeners) {
-            SensorEventQueue queue = mSensorListeners.get(listener);
-            if (queue != null) {
-                boolean result;
-                if (sensor == null) {
-                    result = queue.removeAllSensors();
-                } else {
-                    result = queue.removeSensor(sensor);
+            // remove this listener/sensor from our list
+            final ArrayList<SensorEventListenerSensorPair> copy =
+                    new ArrayList<SensorEventListenerSensorPair>(mListenerDelegates);
+            int lastIndex = copy.size()-1;
+            for (int i=lastIndex ; i>= 0 ; i--) {
+                if (copy.get(i).isSameListenerSensorPair(listener, sensor)) {
+                    mListenerDelegates.remove(i);
                 }
-                if (result && !queue.hasSensors()) {
-                    mSensorListeners.remove(listener);
+            }
+
+            // find the SensorEventQueue associated to this SensorEventListener
+            SensorEventQueue queue = mSensorEventQueueMap.get(listener);
+            if (queue != null) {
+                if (sensor != null) {
+                    queue.removeSensor(sensor);
+                } else {
+                    queue.removeAllSensors();
+                }
+                if (!queue.hasSensors()) {
+                    mSensorEventQueueMap.remove(listener);
                     queue.dispose();
                 }
             }
         }
     }
 
-    /** @hide */
-    @Override
-    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;
-
-        synchronized (mTriggerListeners) {
-            TriggerEventQueue queue = mTriggerListeners.get(listener);
-            if (queue == null) {
-                queue = new TriggerEventQueue(listener, mMainLooper, this);
-                if (!queue.addSensor(sensor, 0)) {
-                    queue.dispose();
-                    return false;
-                }
-                mTriggerListeners.put(listener, queue);
-                return true;
+    /*
+     * ListenerDelegate is essentially a SensorEventListener, Sensor pair
+     * and is associated with a single SensorEventQueue.
+     */
+    private static final class SensorEventListenerSensorPair {
+        private final SensorEventListener mSensorEventListener;
+        private final Sensor mSensor;
+        public SensorEventListenerSensorPair(SensorEventListener listener, Sensor sensor) {
+            mSensorEventListener = listener;
+            mSensor = sensor;
+        }
+        public boolean isSameListenerSensorPair(SensorEventListener listener, Sensor sensor) {
+            // if sensor is null, we match only on the listener
+            if (sensor != null) {
+                return (listener == mSensorEventListener) &&
+                        (sensor.getHandle() == mSensor.getHandle());
             } else {
-                return queue.addSensor(sensor, 0);
+                return (listener == mSensorEventListener);
             }
         }
     }
 
-    /** @hide */
-    @Override
-    protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
-        if (sensor != null && Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) {
-            return false;
-        }
-        synchronized (mTriggerListeners) {
-            TriggerEventQueue queue = mTriggerListeners.get(listener);
-            if (queue != null) {
-                boolean result;
-                if (sensor == null) {
-                    result = queue.removeAllSensors();
-                } else {
-                    result = queue.removeSensor(sensor);
-                }
-                if (result && !queue.hasSensors()) {
-                    mTriggerListeners.remove(listener);
-                    queue.dispose();
-                }
-                return result;
-            }
-            return false;
-        }
-    }
-
     /*
-     * BaseEventQueue is the communication channel with the sensor service,
-     * SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between
-     * the queues and the listeners.
+     * SensorEventQueue is the communication channel with the sensor service,
+     * there is a one-to-one mapping between SensorEventQueue and
+     * SensorEventListener.
      */
-    private static abstract class BaseEventQueue {
-        private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
-                float[] scratch);
+    private static final class SensorEventQueue {
+        private static native int nativeInitSensorEventQueue(SensorEventQueue eventQ, MessageQueue msgQ, float[] scratch);
         private static native int nativeEnableSensor(int eventQ, int handle, int us);
         private static native int nativeDisableSensor(int eventQ, int handle);
         private static native void nativeDestroySensorEventQueue(int eventQ);
         private int nSensorEventQueue;
+        private final SensorEventListener mListener;
         private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
-        protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
-        protected final SparseBooleanArray mFirstEvent = new SparseBooleanArray();
+        private final SparseIntArray mSensorAccuracies = new SparseIntArray();
+        private final SparseBooleanArray mFirstEvent = new SparseBooleanArray();
         private final CloseGuard mCloseGuard = CloseGuard.get();
         private final float[] mScratch = new float[16];
 
-        BaseEventQueue(Looper looper) {
-            nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch);
+        public SensorEventQueue(SensorEventListener listener, MessageQueue msgQ) {
+            nSensorEventQueue = nativeInitSensorEventQueue(this, msgQ, mScratch);
+            mListener = listener;
             mCloseGuard.open("dispose");
         }
-
         public void dispose() {
             dispose(false);
         }
 
         public boolean addSensor(Sensor sensor, int delay) {
-            // Check if already present.
-            if (mActiveSensors.get(sensor.getHandle())) return false;
-
             if (enableSensor(sensor, delay) == 0) {
                 mActiveSensors.put(sensor.getHandle(), true);
                 return true;
@@ -239,7 +231,7 @@
             return false;
         }
 
-        public boolean removeAllSensors() {
+        public void removeAllSensors() {
             for (int i=0 ; i<mActiveSensors.size(); i++) {
                 if (mActiveSensors.valueAt(i) == true) {
                     int handle = mActiveSensors.keyAt(i);
@@ -252,24 +244,21 @@
                     }
                 }
             }
-            return true;
         }
 
-        public boolean removeSensor(Sensor sensor) {
+        public void removeSensor(Sensor sensor) {
             final int handle = sensor.getHandle();
             if (mActiveSensors.get(handle)) {
                 disableSensor(sensor);
                 mActiveSensors.put(sensor.getHandle(), false);
-                return true;
             }
-            return false;
         }
 
         public boolean hasSensors() {
             // no more sensors are set
             return mActiveSensors.indexOfValue(true) >= 0;
         }
-
+        
         @Override
         protected void finalize() throws Throwable {
             try {
@@ -302,30 +291,17 @@
             if (sensor == null) throw new NullPointerException();
             return nativeDisableSensor(nSensorEventQueue, sensor.getHandle());
         }
-        protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
-                long timestamp);
-    }
-
-    static final class SensorEventQueue extends BaseEventQueue {
-        private final SensorEventListener mListener;
-
-        public SensorEventQueue(SensorEventListener listener, Looper looper) {
-            super(looper);
-            mListener = listener;
-        }
 
         // Called from native code.
         @SuppressWarnings("unused")
-        @Override
-        protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
-                long timestamp) {
-            final Sensor sensor = sHandleToSensor.get(handle);
-            SensorEvent t = sSensorEventPool.acquire();
-            if (t == null) t = new SensorEvent(MAX_EVENTS);
+        private void dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp) {
+            // this is always called on the same thread.
+            final SensorEvent t = sPool.getFromPool();
             try {
-                // Copy the entire values array.
-                // Any changes in length will be handled at the native layer.
-                System.arraycopy(values, 0, t.values, 0, t.values.length);
+                final Sensor sensor = sHandleToSensor.get(handle);
+                final SensorEventListener listener = mListener;
+                // FIXME: handle more than 3 values
+                System.arraycopy(values, 0, t.values, 0, 3);
                 t.timestamp = timestamp;
                 t.accuracy = inAccuracy;
                 t.sensor = sensor;
@@ -337,57 +313,72 @@
                         final int accuracy = mSensorAccuracies.get(handle);
                         if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
                             mSensorAccuracies.put(handle, t.accuracy);
-                            mListener.onAccuracyChanged(t.sensor, t.accuracy);
+                            listener.onAccuracyChanged(t.sensor, t.accuracy);
                         }
                         break;
                     default:
                         // For other sensors, just report the accuracy once
                         if (mFirstEvent.get(handle) == false) {
                             mFirstEvent.put(handle, true);
-                            mListener.onAccuracyChanged(
+                            listener.onAccuracyChanged(
                                     t.sensor, SENSOR_STATUS_ACCURACY_HIGH);
                         }
                         break;
                 }
-                mListener.onSensorChanged(t);
+                listener.onSensorChanged(t);
             } finally {
-                sSensorEventPool.release(t);
+                sPool.returnToPool(t);
             }
         }
     }
 
-    static final class TriggerEventQueue extends BaseEventQueue {
-        private final TriggerEventListener mListener;
-        private SensorManager mManager;
+    /*
+     * A dumb pool of SensorEvent
+     */
+    private static final class SensorEventPool {
+        private final int mPoolSize;
+        private final SensorEvent mPool[];
+        private int mNumItemsInPool;
 
-        public TriggerEventQueue(TriggerEventListener listener, Looper looper,
-                SensorManager manager) {
-            super(looper);
-            mListener = listener;
-            mManager = manager;
+        private SensorEvent createSensorEvent() {
+            // maximal size for all legacy events is 3
+            return new SensorEvent(3);
         }
 
-        // Called from native code.
-        @SuppressWarnings("unused")
-        @Override
-        protected void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp) {
-            final Sensor sensor = sHandleToSensor.get(handle);
-            TriggerEvent t = sTriggerEventPool.acquire();
-            if (t == null) t = new TriggerEvent(MAX_EVENTS);
+        SensorEventPool(int poolSize) {
+            mPoolSize = poolSize;
+            mNumItemsInPool = poolSize;
+            mPool = new SensorEvent[poolSize];
+        }
 
-            try {
-                // Copy the entire values array.
-                // Any changes in length will be handled at the native layer.
-                System.arraycopy(values, 0, t.values, 0, t.values.length);
-                t.timestamp = timestamp;
-                t.sensor = sensor;
+        SensorEvent getFromPool() {
+            SensorEvent t = null;
+            synchronized (this) {
+                if (mNumItemsInPool > 0) {
+                    // remove the "top" item from the pool
+                    final int index = mPoolSize - mNumItemsInPool;
+                    t = mPool[index];
+                    mPool[index] = null;
+                    mNumItemsInPool--;
+                }
+            }
+            if (t == null) {
+                // the pool was empty or this item was removed from the pool for
+                // the first time. In any case, we need to create a new item.
+                t = createSensorEvent();
+            }
+            return t;
+        }
 
-                // A trigger sensor should be auto disabled.
-                mManager.cancelTriggerSensorImpl(mListener, sensor);
-
-                mListener.onTrigger(t);
-            } finally {
-                sTriggerEventPool.release(t);
+        void returnToPool(SensorEvent t) {
+            synchronized (this) {
+                // is there space left in the pool?
+                if (mNumItemsInPool < mPoolSize) {
+                    // if so, return the item to the pool
+                    mNumItemsInPool++;
+                    final int index = mPoolSize - mNumItemsInPool;
+                    mPool[index] = t;
+                }
             }
         }
     }
diff --git a/core/java/android/hardware/TriggerEvent.java b/core/java/android/hardware/TriggerEvent.java
deleted file mode 100644
index bdd39f3..0000000
--- a/core/java/android/hardware/TriggerEvent.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-/**
- * This class represents a Trigger Event - the event
- * associated with a Trigger Sensor. When the sensor detects a trigger
- * event condition, such as significant motion in the case of the
- * {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the {@link TriggerEventListener}
- * is called with the TriggerEvent. The sensor is automatically canceled
- * after the trigger.
- * <p>
- * This class holds information such as the value of the sensor
- * when the trigger happened, the timestamp along with detailed
- * information regarding the Sensor itself.
- * </p>
- * @see android.hardware.SensorManager
- * @see android.hardware.TriggerEvent
- * @see android.hardware.Sensor
- */
-public final class TriggerEvent {
-    /**
-     * <p>
-     * The length and contents of the {@link #values values} array depends on
-     * which {@link android.hardware.Sensor sensor} type is being monitored (see
-     * also {@link SensorEvent} for a definition of the coordinate system used).
-     * </p>
-     * <h4> {@link Sensor#TYPE_SIGNIFICANT_MOTION} </h4>
-     * The value field is of length 1. value[0] = 1.0 when the sensor triggers.
-     * 1.0 is the only allowed value.
-     */
-    public final float[] values;
-
-    /**
-     * The sensor that generated this event. See
-     * {@link android.hardware.SensorManager SensorManager} for details.
-     */
-    public Sensor sensor;
-
-    /**
-     * The time in nanosecond at which the event happened
-     */
-    public long timestamp;
-
-    TriggerEvent(int size) {
-        values = new float[size];
-    }
-}
diff --git a/core/java/android/hardware/TriggerEventListener.java b/core/java/android/hardware/TriggerEventListener.java
deleted file mode 100644
index 82b8907..0000000
--- a/core/java/android/hardware/TriggerEventListener.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware;
-
-/**
- * This class is the listener used to handle Trigger Sensors.
- * Trigger Sensors are sensors that trigger an event and are automatically
- * disabled. {@link Sensor#TYPE_SIGNIFICANT_MOTION} is one such example.
- * <p>
- * SensorManager lets you access the device's {@link android.hardware.Sensor
- * sensors}. Get an instance of this class by calling
- * {@link android.content.Context#getSystemService(java.lang.String)
- * Context.getSystemService()} with the argument
- * {@link android.content.Context#SENSOR_SERVICE}.
- * Usage details are explained in the example below.
- * </p>
- *
- * <pre class="prettyprint">
- * class TriggerListener extends TriggerEventListener {
- *     @Override
- *     public void onTrigger(TriggerEvent event) {
- *          // Do Work.
- *
- *     // As it is a one shot sensor, it will be canceled automatically.
- *     // SensorManager.requestTriggerSensor(this, mSigMotion); needs to
- *     // be called again, if needed.
- *     }
- * }
- * public class SensorActivity extends Activity {
- *     private final SensorManager mSensorManager;
- *     private final Sensor mSigMotion;
- *     private final TriggerEventListener mListener = new TriggerEventListener();
- *
- *     public SensorActivity() {
- *         mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
- *         mSigMotion = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
- *     }
- *
- *     protected void onResume() {
- *         super.onResume();
- *         mSensorManager.requestTriggerSensor(mListener, mSigMotion);
- *     }
- *
- *     protected void onPause() {
- *         super.onPause();
- *         // Call disable to ensure that the trigger request has been canceled.
- *         mSensorManager.cancelTriggerSensor(mListener, mSigMotion);
- *     }
- *
- * }
- * </pre>
- *
- * @see TriggerEvent
- * @see Sensor
- */
-public abstract class TriggerEventListener {
-    /**
-     * The method that will be called when the sensor
-     * is triggered. Override this method in your implementation
-     * of this class.
-     *
-     * @param event The details of the event.
-     */
-    public abstract void onTrigger(TriggerEvent event);
-}
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 6374494..3083cb1 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -31,7 +31,7 @@
 static struct {
     jclass clazz;
     jmethodID dispatchSensorEvent;
-} gBaseEventQueueClassInfo;
+} gSensorEventQueueClassInfo;
 
 namespace android {
 
@@ -145,7 +145,7 @@
                 env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
 
                 env->CallVoidMethod(mReceiverObject,
-                        gBaseEventQueueClassInfo.dispatchSensorEvent,
+                        gSensorEventQueueClassInfo.dispatchSensorEvent,
                         buffer[i].sensor,
                         mScratch,
                         buffer[i].vector.status,
@@ -209,9 +209,9 @@
             (void*)nativeGetNextSensor },
 };
 
-static JNINativeMethod gBaseEventQueueMethods[] = {
-    {"nativeInitBaseEventQueue",
-            "(Landroid/hardware/SystemSensorManager$BaseEventQueue;Landroid/os/MessageQueue;[F)I",
+static JNINativeMethod gSensorEventQueueMethods[] = {
+    {"nativeInitSensorEventQueue",
+            "(Landroid/hardware/SystemSensorManager$SensorEventQueue;Landroid/os/MessageQueue;[F)I",
             (void*)nativeInitSensorEventQueue },
 
     {"nativeEnableSensor",
@@ -245,13 +245,13 @@
     jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager",
             gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));
 
-    jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$BaseEventQueue",
-            gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
+    jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$SensorEventQueue",
+            gSensorEventQueueMethods, NELEM(gSensorEventQueueMethods));
 
-    FIND_CLASS(gBaseEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$BaseEventQueue");
+    FIND_CLASS(gSensorEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$SensorEventQueue");
 
-    GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchSensorEvent,
-            gBaseEventQueueClassInfo.clazz,
+    GET_METHOD_ID(gSensorEventQueueClassInfo.dispatchSensorEvent,
+            gSensorEventQueueClassInfo.clazz,
             "dispatchSensorEvent", "(I[FIJ)V");
 
     return 0;