Home | History | Annotate | Download | only in hardware
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.hardware;
     18 
     19 import android.os.Handler;
     20 import android.util.Log;
     21 import android.util.SparseArray;
     22 
     23 import java.util.ArrayList;
     24 import java.util.Collections;
     25 import java.util.List;
     26 
     27 /**
     28  * <p>
     29  * SensorManager lets you access the device's {@link android.hardware.Sensor
     30  * sensors}. Get an instance of this class by calling
     31  * {@link android.content.Context#getSystemService(java.lang.String)
     32  * Context.getSystemService()} with the argument
     33  * {@link android.content.Context#SENSOR_SERVICE}.
     34  * </p>
     35  * <p>
     36  * Always make sure to disable sensors you don't need, especially when your
     37  * activity is paused. Failing to do so can drain the battery in just a few
     38  * hours. Note that the system will <i>not</i> disable sensors automatically when
     39  * the screen turns off.
     40  * </p>
     41  * <p class="note">
     42  * Note: Don't use this mechanism with a Trigger Sensor, have a look
     43  * at {@link TriggerEventListener}. {@link Sensor#TYPE_SIGNIFICANT_MOTION}
     44  * is an example of a trigger sensor.
     45  * </p>
     46  * <pre class="prettyprint">
     47  * public class SensorActivity extends Activity, implements SensorEventListener {
     48  *     private final SensorManager mSensorManager;
     49  *     private final Sensor mAccelerometer;
     50  *
     51  *     public SensorActivity() {
     52  *         mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
     53  *         mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
     54  *     }
     55  *
     56  *     protected void onResume() {
     57  *         super.onResume();
     58  *         mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
     59  *     }
     60  *
     61  *     protected void onPause() {
     62  *         super.onPause();
     63  *         mSensorManager.unregisterListener(this);
     64  *     }
     65  *
     66  *     public void onAccuracyChanged(Sensor sensor, int accuracy) {
     67  *     }
     68  *
     69  *     public void onSensorChanged(SensorEvent event) {
     70  *     }
     71  * }
     72  * </pre>
     73  *
     74  * @see SensorEventListener
     75  * @see SensorEvent
     76  * @see Sensor
     77  *
     78  */
     79 public abstract class SensorManager {
     80     /** @hide */
     81     protected static final String TAG = "SensorManager";
     82 
     83     private static final float[] mTempMatrix = new float[16];
     84 
     85     // Cached lists of sensors by type.  Guarded by mSensorListByType.
     86     private final SparseArray<List<Sensor>> mSensorListByType =
     87             new SparseArray<List<Sensor>>();
     88 
     89     // Legacy sensor manager implementation.  Guarded by mSensorListByType during initialization.
     90     private LegacySensorManager mLegacySensorManager;
     91 
     92     /* NOTE: sensor IDs must be a power of 2 */
     93 
     94     /**
     95      * A constant describing an orientation sensor. See
     96      * {@link android.hardware.SensorListener SensorListener} for more details.
     97      *
     98      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
     99      */
    100     @Deprecated
    101     public static final int SENSOR_ORIENTATION = 1 << 0;
    102 
    103     /**
    104      * A constant describing an accelerometer. See
    105      * {@link android.hardware.SensorListener SensorListener} for more details.
    106      *
    107      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    108      */
    109     @Deprecated
    110     public static final int SENSOR_ACCELEROMETER = 1 << 1;
    111 
    112     /**
    113      * A constant describing a temperature sensor See
    114      * {@link android.hardware.SensorListener SensorListener} for more details.
    115      *
    116      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    117      */
    118     @Deprecated
    119     public static final int SENSOR_TEMPERATURE = 1 << 2;
    120 
    121     /**
    122      * A constant describing a magnetic sensor See
    123      * {@link android.hardware.SensorListener SensorListener} for more details.
    124      *
    125      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    126      */
    127     @Deprecated
    128     public static final int SENSOR_MAGNETIC_FIELD = 1 << 3;
    129 
    130     /**
    131      * A constant describing an ambient light sensor See
    132      * {@link android.hardware.SensorListener SensorListener} for more details.
    133      *
    134      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    135      */
    136     @Deprecated
    137     public static final int SENSOR_LIGHT = 1 << 4;
    138 
    139     /**
    140      * A constant describing a proximity sensor See
    141      * {@link android.hardware.SensorListener SensorListener} for more details.
    142      *
    143      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    144      */
    145     @Deprecated
    146     public static final int SENSOR_PROXIMITY = 1 << 5;
    147 
    148     /**
    149      * A constant describing a Tricorder See
    150      * {@link android.hardware.SensorListener SensorListener} for more details.
    151      *
    152      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    153      */
    154     @Deprecated
    155     public static final int SENSOR_TRICORDER = 1 << 6;
    156 
    157     /**
    158      * A constant describing an orientation sensor. See
    159      * {@link android.hardware.SensorListener SensorListener} for more details.
    160      *
    161      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    162      */
    163     @Deprecated
    164     public static final int SENSOR_ORIENTATION_RAW = 1 << 7;
    165 
    166     /**
    167      * A constant that includes all sensors
    168      *
    169      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    170      */
    171     @Deprecated
    172     public static final int SENSOR_ALL = 0x7F;
    173 
    174     /**
    175      * Smallest sensor ID
    176      *
    177      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    178      */
    179     @Deprecated
    180     public static final int SENSOR_MIN = SENSOR_ORIENTATION;
    181 
    182     /**
    183      * Largest sensor ID
    184      *
    185      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    186      */
    187     @Deprecated
    188     public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1);
    189 
    190 
    191     /**
    192      * Index of the X value in the array returned by
    193      * {@link android.hardware.SensorListener#onSensorChanged}
    194      *
    195      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    196      */
    197     @Deprecated
    198     public static final int DATA_X = 0;
    199 
    200     /**
    201      * Index of the Y value in the array returned by
    202      * {@link android.hardware.SensorListener#onSensorChanged}
    203      *
    204      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    205      */
    206     @Deprecated
    207     public static final int DATA_Y = 1;
    208 
    209     /**
    210      * Index of the Z value in the array returned by
    211      * {@link android.hardware.SensorListener#onSensorChanged}
    212      *
    213      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    214      */
    215     @Deprecated
    216     public static final int DATA_Z = 2;
    217 
    218     /**
    219      * Offset to the untransformed values in the array returned by
    220      * {@link android.hardware.SensorListener#onSensorChanged}
    221      *
    222      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    223      */
    224     @Deprecated
    225     public static final int RAW_DATA_INDEX = 3;
    226 
    227     /**
    228      * Index of the untransformed X value in the array returned by
    229      * {@link android.hardware.SensorListener#onSensorChanged}
    230      *
    231      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    232      */
    233     @Deprecated
    234     public static final int RAW_DATA_X = 3;
    235 
    236     /**
    237      * Index of the untransformed Y value in the array returned by
    238      * {@link android.hardware.SensorListener#onSensorChanged}
    239      *
    240      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    241      */
    242     @Deprecated
    243     public static final int RAW_DATA_Y = 4;
    244 
    245     /**
    246      * Index of the untransformed Z value in the array returned by
    247      * {@link android.hardware.SensorListener#onSensorChanged}
    248      *
    249      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    250      */
    251     @Deprecated
    252     public static final int RAW_DATA_Z = 5;
    253 
    254     /** Standard gravity (g) on Earth. This value is equivalent to 1G */
    255     public static final float STANDARD_GRAVITY = 9.80665f;
    256 
    257     /** Sun's gravity in SI units (m/s^2) */
    258     public static final float GRAVITY_SUN             = 275.0f;
    259     /** Mercury's gravity in SI units (m/s^2) */
    260     public static final float GRAVITY_MERCURY         = 3.70f;
    261     /** Venus' gravity in SI units (m/s^2) */
    262     public static final float GRAVITY_VENUS           = 8.87f;
    263     /** Earth's gravity in SI units (m/s^2) */
    264     public static final float GRAVITY_EARTH           = 9.80665f;
    265     /** The Moon's gravity in SI units (m/s^2) */
    266     public static final float GRAVITY_MOON            = 1.6f;
    267     /** Mars' gravity in SI units (m/s^2) */
    268     public static final float GRAVITY_MARS            = 3.71f;
    269     /** Jupiter's gravity in SI units (m/s^2) */
    270     public static final float GRAVITY_JUPITER         = 23.12f;
    271     /** Saturn's gravity in SI units (m/s^2) */
    272     public static final float GRAVITY_SATURN          = 8.96f;
    273     /** Uranus' gravity in SI units (m/s^2) */
    274     public static final float GRAVITY_URANUS          = 8.69f;
    275     /** Neptune's gravity in SI units (m/s^2) */
    276     public static final float GRAVITY_NEPTUNE         = 11.0f;
    277     /** Pluto's gravity in SI units (m/s^2) */
    278     public static final float GRAVITY_PLUTO           = 0.6f;
    279     /** Gravity (estimate) on the first Death Star in Empire units (m/s^2) */
    280     public static final float GRAVITY_DEATH_STAR_I    = 0.000000353036145f;
    281     /** Gravity on the island */
    282     public static final float GRAVITY_THE_ISLAND      = 4.815162342f;
    283 
    284 
    285     /** Maximum magnetic field on Earth's surface */
    286     public static final float MAGNETIC_FIELD_EARTH_MAX = 60.0f;
    287     /** Minimum magnetic field on Earth's surface */
    288     public static final float MAGNETIC_FIELD_EARTH_MIN = 30.0f;
    289 
    290 
    291     /** Standard atmosphere, or average sea-level pressure in hPa (millibar) */
    292     public static final float PRESSURE_STANDARD_ATMOSPHERE = 1013.25f;
    293 
    294 
    295     /** Maximum luminance of sunlight in lux */
    296     public static final float LIGHT_SUNLIGHT_MAX = 120000.0f;
    297     /** luminance of sunlight in lux */
    298     public static final float LIGHT_SUNLIGHT     = 110000.0f;
    299     /** luminance in shade in lux */
    300     public static final float LIGHT_SHADE        = 20000.0f;
    301     /** luminance under an overcast sky in lux */
    302     public static final float LIGHT_OVERCAST     = 10000.0f;
    303     /** luminance at sunrise in lux */
    304     public static final float LIGHT_SUNRISE      = 400.0f;
    305     /** luminance under a cloudy sky in lux */
    306     public static final float LIGHT_CLOUDY       = 100.0f;
    307     /** luminance at night with full moon in lux */
    308     public static final float LIGHT_FULLMOON     = 0.25f;
    309     /** luminance at night with no moon in lux*/
    310     public static final float LIGHT_NO_MOON      = 0.001f;
    311 
    312 
    313     /** get sensor data as fast as possible */
    314     public static final int SENSOR_DELAY_FASTEST = 0;
    315     /** rate suitable for games */
    316     public static final int SENSOR_DELAY_GAME = 1;
    317     /** rate suitable for the user interface  */
    318     public static final int SENSOR_DELAY_UI = 2;
    319     /** rate (default) suitable for screen orientation changes */
    320     public static final int SENSOR_DELAY_NORMAL = 3;
    321 
    322 
    323     /**
    324      * The values returned by this sensor cannot be trusted, calibration is
    325      * needed or the environment doesn't allow readings
    326      */
    327     public static final int SENSOR_STATUS_UNRELIABLE = 0;
    328 
    329     /**
    330      * This sensor is reporting data with low accuracy, calibration with the
    331      * environment is needed
    332      */
    333     public static final int SENSOR_STATUS_ACCURACY_LOW = 1;
    334 
    335     /**
    336      * This sensor is reporting data with an average level of accuracy,
    337      * calibration with the environment may improve the readings
    338      */
    339     public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2;
    340 
    341     /** This sensor is reporting data with maximum accuracy */
    342     public static final int SENSOR_STATUS_ACCURACY_HIGH = 3;
    343 
    344     /** see {@link #remapCoordinateSystem} */
    345     public static final int AXIS_X = 1;
    346     /** see {@link #remapCoordinateSystem} */
    347     public static final int AXIS_Y = 2;
    348     /** see {@link #remapCoordinateSystem} */
    349     public static final int AXIS_Z = 3;
    350     /** see {@link #remapCoordinateSystem} */
    351     public static final int AXIS_MINUS_X = AXIS_X | 0x80;
    352     /** see {@link #remapCoordinateSystem} */
    353     public static final int AXIS_MINUS_Y = AXIS_Y | 0x80;
    354     /** see {@link #remapCoordinateSystem} */
    355     public static final int AXIS_MINUS_Z = AXIS_Z | 0x80;
    356 
    357 
    358     /**
    359      * {@hide}
    360      */
    361     public SensorManager() {
    362     }
    363 
    364     /**
    365      * Gets the full list of sensors that are available.
    366      * @hide
    367      */
    368     protected abstract List<Sensor> getFullSensorList();
    369 
    370     /**
    371      * @return available sensors.
    372      * @deprecated This method is deprecated, use
    373      *             {@link SensorManager#getSensorList(int)} instead
    374      */
    375     @Deprecated
    376     public int getSensors() {
    377         return getLegacySensorManager().getSensors();
    378     }
    379 
    380     /**
    381      * Use this method to get the list of available sensors of a certain type.
    382      * Make multiple calls to get sensors of different types or use
    383      * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all the
    384      * sensors.
    385      *
    386      * @param type
    387      *        of sensors requested
    388      *
    389      * @return a list of sensors matching the asked type.
    390      *
    391      * @see #getDefaultSensor(int)
    392      * @see Sensor
    393      */
    394     public List<Sensor> getSensorList(int type) {
    395         // cache the returned lists the first time
    396         List<Sensor> list;
    397         final List<Sensor> fullList = getFullSensorList();
    398         synchronized (mSensorListByType) {
    399             list = mSensorListByType.get(type);
    400             if (list == null) {
    401                 if (type == Sensor.TYPE_ALL) {
    402                     list = fullList;
    403                 } else {
    404                     list = new ArrayList<Sensor>();
    405                     for (Sensor i : fullList) {
    406                         if (i.getType() == type)
    407                             list.add(i);
    408                     }
    409                 }
    410                 list = Collections.unmodifiableList(list);
    411                 mSensorListByType.append(type, list);
    412             }
    413         }
    414         return list;
    415     }
    416 
    417     /**
    418      * Use this method to get the default sensor for a given type. Note that the
    419      * returned sensor could be a composite sensor, and its data could be
    420      * averaged or filtered. If you need to access the raw sensors use
    421      * {@link SensorManager#getSensorList(int) getSensorList}.
    422      *
    423      * @param type
    424      *        of sensors requested
    425      *
    426      * @return the default sensors matching the asked type.
    427      *
    428      * @see #getSensorList(int)
    429      * @see Sensor
    430      */
    431     public Sensor getDefaultSensor(int type) {
    432         // TODO: need to be smarter, for now, just return the 1st sensor
    433         List<Sensor> l = getSensorList(type);
    434         return l.isEmpty() ? null : l.get(0);
    435     }
    436 
    437     /**
    438      * Registers a listener for given sensors.
    439      *
    440      * @deprecated This method is deprecated, use
    441      *             {@link SensorManager#registerListener(SensorEventListener, Sensor, int)}
    442      *             instead.
    443      *
    444      * @param listener
    445      *        sensor listener object
    446      *
    447      * @param sensors
    448      *        a bit masks of the sensors to register to
    449      *
    450      * @return <code>true</code> if the sensor is supported and successfully
    451      *         enabled
    452      */
    453     @Deprecated
    454     public boolean registerListener(SensorListener listener, int sensors) {
    455         return registerListener(listener, sensors, SENSOR_DELAY_NORMAL);
    456     }
    457 
    458     /**
    459      * Registers a SensorListener for given sensors.
    460      *
    461      * @deprecated This method is deprecated, use
    462      *             {@link SensorManager#registerListener(SensorEventListener, Sensor, int)}
    463      *             instead.
    464      *
    465      * @param listener
    466      *        sensor listener object
    467      *
    468      * @param sensors
    469      *        a bit masks of the sensors to register to
    470      *
    471      * @param rate
    472      *        rate of events. This is only a hint to the system. events may be
    473      *        received faster or slower than the specified rate. Usually events
    474      *        are received faster. The value must be one of
    475      *        {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    476      *        {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}.
    477      *
    478      * @return <code>true</code> if the sensor is supported and successfully
    479      *         enabled
    480      */
    481     @Deprecated
    482     public boolean registerListener(SensorListener listener, int sensors, int rate) {
    483         return getLegacySensorManager().registerListener(listener, sensors, rate);
    484     }
    485 
    486     /**
    487      * Unregisters a listener for all sensors.
    488      *
    489      * @deprecated This method is deprecated, use
    490      *             {@link SensorManager#unregisterListener(SensorEventListener)}
    491      *             instead.
    492      *
    493      * @param listener
    494      *        a SensorListener object
    495      */
    496     @Deprecated
    497     public void unregisterListener(SensorListener listener) {
    498         unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW);
    499     }
    500 
    501     /**
    502      * Unregisters a listener for the sensors with which it is registered.
    503      *
    504      * @deprecated This method is deprecated, use
    505      *             {@link SensorManager#unregisterListener(SensorEventListener, Sensor)}
    506      *             instead.
    507      *
    508      * @param listener
    509      *        a SensorListener object
    510      *
    511      * @param sensors
    512      *        a bit masks of the sensors to unregister from
    513      */
    514     @Deprecated
    515     public void unregisterListener(SensorListener listener, int sensors) {
    516         getLegacySensorManager().unregisterListener(listener, sensors);
    517     }
    518 
    519     /**
    520      * Unregisters a listener for the sensors with which it is registered.
    521      *
    522      * <p class="note"></p>
    523      * Note: Don't use this method with a one shot trigger sensor such as
    524      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
    525      * Use {@link #cancelTriggerSensor(TriggerEventListener, Sensor)} instead.
    526      * </p>
    527      *
    528      * @param listener
    529      *        a SensorEventListener object
    530      *
    531      * @param sensor
    532      *        the sensor to unregister from
    533      *
    534      * @see #unregisterListener(SensorEventListener)
    535      * @see #registerListener(SensorEventListener, Sensor, int)
    536      *
    537      * @throws IllegalArgumentException when sensor is a trigger sensor.
    538      */
    539     public void unregisterListener(SensorEventListener listener, Sensor sensor) {
    540         if (listener == null || sensor == null) {
    541             return;
    542         }
    543 
    544         unregisterListenerImpl(listener, sensor);
    545     }
    546 
    547     /**
    548      * Unregisters a listener for all sensors.
    549      *
    550      * @param listener
    551      *        a SensorListener object
    552      *
    553      * @see #unregisterListener(SensorEventListener, Sensor)
    554      * @see #registerListener(SensorEventListener, Sensor, int)
    555      *
    556      */
    557     public void unregisterListener(SensorEventListener listener) {
    558         if (listener == null) {
    559             return;
    560         }
    561 
    562         unregisterListenerImpl(listener, null);
    563     }
    564 
    565     /** @hide */
    566     protected abstract void unregisterListenerImpl(SensorEventListener listener, Sensor sensor);
    567 
    568     /**
    569      * Registers a {@link android.hardware.SensorEventListener
    570      * SensorEventListener} for the given sensor.
    571      *
    572      * <p class="note"></p>
    573      * Note: Don't use this method with a one shot trigger sensor such as
    574      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
    575      * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
    576      * </p>
    577      *
    578      * @param listener
    579      *        A {@link android.hardware.SensorEventListener SensorEventListener}
    580      *        object.
    581      *
    582      * @param sensor
    583      *        The {@link android.hardware.Sensor Sensor} to register to.
    584      *
    585      * @param rate
    586      *        The rate {@link android.hardware.SensorEvent sensor events} are
    587      *        delivered at. This is only a hint to the system. Events may be
    588      *        received faster or slower than the specified rate. Usually events
    589      *        are received faster. The value must be one of
    590      *        {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    591      *        {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}
    592      *        or, the desired delay between events in microseconds.
    593      *        Specifying the delay in microseconds only works from Android
    594      *        2.3 (API level 9) onwards. For earlier releases, you must use
    595      *        one of the {@code SENSOR_DELAY_*} constants.
    596      *
    597      * @return <code>true</code> if the sensor is supported and successfully
    598      *         enabled.
    599      *
    600      * @see #registerListener(SensorEventListener, Sensor, int, Handler)
    601      * @see #unregisterListener(SensorEventListener)
    602      * @see #unregisterListener(SensorEventListener, Sensor)
    603      *
    604      * @throws IllegalArgumentException when sensor is null or a trigger sensor
    605      */
    606     public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) {
    607         return registerListener(listener, sensor, rate, null);
    608     }
    609 
    610     /**
    611      * Registers a {@link android.hardware.SensorEventListener
    612      * SensorEventListener} for the given sensor.
    613      *
    614      * <p class="note"></p>
    615      * Note: Don't use this method with a one shot trigger sensor such as
    616      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
    617      * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
    618      * </p>
    619      *
    620      * @param listener
    621      *        A {@link android.hardware.SensorEventListener SensorEventListener}
    622      *        object.
    623      *
    624      * @param sensor
    625      *        The {@link android.hardware.Sensor Sensor} to register to.
    626      *
    627      * @param rate
    628      *        The rate {@link android.hardware.SensorEvent sensor events} are
    629      *        delivered at. This is only a hint to the system. Events may be
    630      *        received faster or slower than the specified rate. Usually events
    631      *        are received faster. The value must be one of
    632      *        {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    633      *        {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}.
    634      *        or, the desired delay between events in microseconds.
    635      *        Specifying the delay in microseconds only works from Android
    636      *        2.3 (API level 9) onwards. For earlier releases, you must use
    637      *        one of the {@code SENSOR_DELAY_*} constants.
    638      *
    639      * @param handler
    640      *        The {@link android.os.Handler Handler} the
    641      *        {@link android.hardware.SensorEvent sensor events} will be
    642      *        delivered to.
    643      *
    644      * @return true if the sensor is supported and successfully enabled.
    645      *
    646      * @see #registerListener(SensorEventListener, Sensor, int)
    647      * @see #unregisterListener(SensorEventListener)
    648      * @see #unregisterListener(SensorEventListener, Sensor)
    649      *
    650      * @throws IllegalArgumentException when sensor is null or a trigger sensor
    651      */
    652     public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate,
    653             Handler handler) {
    654         if (listener == null || sensor == null) {
    655             return false;
    656         }
    657 
    658         int delay = -1;
    659         switch (rate) {
    660             case SENSOR_DELAY_FASTEST:
    661                 delay = 0;
    662                 break;
    663             case SENSOR_DELAY_GAME:
    664                 delay = 20000;
    665                 break;
    666             case SENSOR_DELAY_UI:
    667                 delay = 66667;
    668                 break;
    669             case SENSOR_DELAY_NORMAL:
    670                 delay = 200000;
    671                 break;
    672             default:
    673                 delay = rate;
    674                 break;
    675         }
    676 
    677         return registerListenerImpl(listener, sensor, delay, handler);
    678     }
    679 
    680     /** @hide */
    681     protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
    682             int delay, Handler handler);
    683 
    684     /**
    685      * <p>
    686      * Computes the inclination matrix <b>I</b> as well as the rotation matrix
    687      * <b>R</b> transforming a vector from the device coordinate system to the
    688      * world's coordinate system which is defined as a direct orthonormal basis,
    689      * where:
    690      * </p>
    691      *
    692      * <ul>
    693      * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
    694      * the ground at the device's current location and roughly points East).</li>
    695      * <li>Y is tangential to the ground at the device's current location and
    696      * points towards the magnetic North Pole.</li>
    697      * <li>Z points towards the sky and is perpendicular to the ground.</li>
    698      * </ul>
    699      *
    700      * <p>
    701      * <center><img src="../../../images/axis_globe.png"
    702      * alt="World coordinate-system diagram." border="0" /></center>
    703      * </p>
    704      *
    705      * <p>
    706      * <hr>
    707      * <p>
    708      * By definition:
    709      * <p>
    710      * [0 0 g] = <b>R</b> * <b>gravity</b> (g = magnitude of gravity)
    711      * <p>
    712      * [0 m 0] = <b>I</b> * <b>R</b> * <b>geomagnetic</b> (m = magnitude of
    713      * geomagnetic field)
    714      * <p>
    715      * <b>R</b> is the identity matrix when the device is aligned with the
    716      * world's coordinate system, that is, when the device's X axis points
    717      * toward East, the Y axis points to the North Pole and the device is facing
    718      * the sky.
    719      *
    720      * <p>
    721      * <b>I</b> is a rotation matrix transforming the geomagnetic vector into
    722      * the same coordinate space as gravity (the world's coordinate space).
    723      * <b>I</b> is a simple rotation around the X axis. The inclination angle in
    724      * radians can be computed with {@link #getInclination}.
    725      * <hr>
    726      *
    727      * <p>
    728      * Each matrix is returned either as a 3x3 or 4x4 row-major matrix depending
    729      * on the length of the passed array:
    730      * <p>
    731      * <u>If the array length is 16:</u>
    732      *
    733      * <pre>
    734      *   /  M[ 0]   M[ 1]   M[ 2]   M[ 3]  \
    735      *   |  M[ 4]   M[ 5]   M[ 6]   M[ 7]  |
    736      *   |  M[ 8]   M[ 9]   M[10]   M[11]  |
    737      *   \  M[12]   M[13]   M[14]   M[15]  /
    738      *</pre>
    739      *
    740      * This matrix is ready to be used by OpenGL ES's
    741      * {@link javax.microedition.khronos.opengles.GL10#glLoadMatrixf(float[], int)
    742      * glLoadMatrixf(float[], int)}.
    743      * <p>
    744      * Note that because OpenGL matrices are column-major matrices you must
    745      * transpose the matrix before using it. However, since the matrix is a
    746      * rotation matrix, its transpose is also its inverse, conveniently, it is
    747      * often the inverse of the rotation that is needed for rendering; it can
    748      * therefore be used with OpenGL ES directly.
    749      * <p>
    750      * Also note that the returned matrices always have this form:
    751      *
    752      * <pre>
    753      *   /  M[ 0]   M[ 1]   M[ 2]   0  \
    754      *   |  M[ 4]   M[ 5]   M[ 6]   0  |
    755      *   |  M[ 8]   M[ 9]   M[10]   0  |
    756      *   \      0       0       0   1  /
    757      *</pre>
    758      *
    759      * <p>
    760      * <u>If the array length is 9:</u>
    761      *
    762      * <pre>
    763      *   /  M[ 0]   M[ 1]   M[ 2]  \
    764      *   |  M[ 3]   M[ 4]   M[ 5]  |
    765      *   \  M[ 6]   M[ 7]   M[ 8]  /
    766      *</pre>
    767      *
    768      * <hr>
    769      * <p>
    770      * The inverse of each matrix can be computed easily by taking its
    771      * transpose.
    772      *
    773      * <p>
    774      * The matrices returned by this function are meaningful only when the
    775      * device is not free-falling and it is not close to the magnetic north. If
    776      * the device is accelerating, or placed into a strong magnetic field, the
    777      * returned matrices may be inaccurate.
    778      *
    779      * @param R
    780      *        is an array of 9 floats holding the rotation matrix <b>R</b> when
    781      *        this function returns. R can be null.
    782      *        <p>
    783      *
    784      * @param I
    785      *        is an array of 9 floats holding the rotation matrix <b>I</b> when
    786      *        this function returns. I can be null.
    787      *        <p>
    788      *
    789      * @param gravity
    790      *        is an array of 3 floats containing the gravity vector expressed in
    791      *        the device's coordinate. You can simply use the
    792      *        {@link android.hardware.SensorEvent#values values} returned by a
    793      *        {@link android.hardware.SensorEvent SensorEvent} of a
    794      *        {@link android.hardware.Sensor Sensor} of type
    795      *        {@link android.hardware.Sensor#TYPE_ACCELEROMETER
    796      *        TYPE_ACCELEROMETER}.
    797      *        <p>
    798      *
    799      * @param geomagnetic
    800      *        is an array of 3 floats containing the geomagnetic vector
    801      *        expressed in the device's coordinate. You can simply use the
    802      *        {@link android.hardware.SensorEvent#values values} returned by a
    803      *        {@link android.hardware.SensorEvent SensorEvent} of a
    804      *        {@link android.hardware.Sensor Sensor} of type
    805      *        {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD
    806      *        TYPE_MAGNETIC_FIELD}.
    807      *
    808      * @return <code>true</code> on success, <code>false</code> on failure (for
    809      *         instance, if the device is in free fall). On failure the output
    810      *         matrices are not modified.
    811      *
    812      * @see #getInclination(float[])
    813      * @see #getOrientation(float[], float[])
    814      * @see #remapCoordinateSystem(float[], int, int, float[])
    815      */
    816 
    817     public static boolean getRotationMatrix(float[] R, float[] I,
    818             float[] gravity, float[] geomagnetic) {
    819         // TODO: move this to native code for efficiency
    820         float Ax = gravity[0];
    821         float Ay = gravity[1];
    822         float Az = gravity[2];
    823         final float Ex = geomagnetic[0];
    824         final float Ey = geomagnetic[1];
    825         final float Ez = geomagnetic[2];
    826         float Hx = Ey*Az - Ez*Ay;
    827         float Hy = Ez*Ax - Ex*Az;
    828         float Hz = Ex*Ay - Ey*Ax;
    829         final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
    830         if (normH < 0.1f) {
    831             // device is close to free fall (or in space?), or close to
    832             // magnetic north pole. Typical values are  > 100.
    833             return false;
    834         }
    835         final float invH = 1.0f / normH;
    836         Hx *= invH;
    837         Hy *= invH;
    838         Hz *= invH;
    839         final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az);
    840         Ax *= invA;
    841         Ay *= invA;
    842         Az *= invA;
    843         final float Mx = Ay*Hz - Az*Hy;
    844         final float My = Az*Hx - Ax*Hz;
    845         final float Mz = Ax*Hy - Ay*Hx;
    846         if (R != null) {
    847             if (R.length == 9) {
    848                 R[0] = Hx;     R[1] = Hy;     R[2] = Hz;
    849                 R[3] = Mx;     R[4] = My;     R[5] = Mz;
    850                 R[6] = Ax;     R[7] = Ay;     R[8] = Az;
    851             } else if (R.length == 16) {
    852                 R[0]  = Hx;    R[1]  = Hy;    R[2]  = Hz;   R[3]  = 0;
    853                 R[4]  = Mx;    R[5]  = My;    R[6]  = Mz;   R[7]  = 0;
    854                 R[8]  = Ax;    R[9]  = Ay;    R[10] = Az;   R[11] = 0;
    855                 R[12] = 0;     R[13] = 0;     R[14] = 0;    R[15] = 1;
    856             }
    857         }
    858         if (I != null) {
    859             // compute the inclination matrix by projecting the geomagnetic
    860             // vector onto the Z (gravity) and X (horizontal component
    861             // of geomagnetic vector) axes.
    862             final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez);
    863             final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE;
    864             final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE;
    865             if (I.length == 9) {
    866                 I[0] = 1;     I[1] = 0;     I[2] = 0;
    867                 I[3] = 0;     I[4] = c;     I[5] = s;
    868                 I[6] = 0;     I[7] =-s;     I[8] = c;
    869             } else if (I.length == 16) {
    870                 I[0] = 1;     I[1] = 0;     I[2] = 0;
    871                 I[4] = 0;     I[5] = c;     I[6] = s;
    872                 I[8] = 0;     I[9] =-s;     I[10]= c;
    873                 I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0;
    874                 I[15] = 1;
    875             }
    876         }
    877         return true;
    878     }
    879 
    880     /**
    881      * Computes the geomagnetic inclination angle in radians from the
    882      * inclination matrix <b>I</b> returned by {@link #getRotationMatrix}.
    883      *
    884      * @param I
    885      *        inclination matrix see {@link #getRotationMatrix}.
    886      *
    887      * @return The geomagnetic inclination angle in radians.
    888      *
    889      * @see #getRotationMatrix(float[], float[], float[], float[])
    890      * @see #getOrientation(float[], float[])
    891      * @see GeomagneticField
    892      *
    893      */
    894     public static float getInclination(float[] I) {
    895         if (I.length == 9) {
    896             return (float)Math.atan2(I[5], I[4]);
    897         } else {
    898             return (float)Math.atan2(I[6], I[5]);
    899         }
    900     }
    901 
    902     /**
    903      * <p>
    904      * Rotates the supplied rotation matrix so it is expressed in a different
    905      * coordinate system. This is typically used when an application needs to
    906      * compute the three orientation angles of the device (see
    907      * {@link #getOrientation}) in a different coordinate system.
    908      * </p>
    909      *
    910      * <p>
    911      * When the rotation matrix is used for drawing (for instance with OpenGL
    912      * ES), it usually <b>doesn't need</b> to be transformed by this function,
    913      * unless the screen is physically rotated, in which case you can use
    914      * {@link android.view.Display#getRotation() Display.getRotation()} to
    915      * retrieve the current rotation of the screen. Note that because the user
    916      * is generally free to rotate their screen, you often should consider the
    917      * rotation in deciding the parameters to use here.
    918      * </p>
    919      *
    920      * <p>
    921      * <u>Examples:</u>
    922      * <p>
    923      *
    924      * <ul>
    925      * <li>Using the camera (Y axis along the camera's axis) for an augmented
    926      * reality application where the rotation angles are needed:</li>
    927      *
    928      * <p>
    929      * <ul>
    930      * <code>remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);</code>
    931      * </ul>
    932      * </p>
    933      *
    934      * <li>Using the device as a mechanical compass when rotation is
    935      * {@link android.view.Surface#ROTATION_90 Surface.ROTATION_90}:</li>
    936      *
    937      * <p>
    938      * <ul>
    939      * <code>remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);</code>
    940      * </ul>
    941      * </p>
    942      *
    943      * Beware of the above example. This call is needed only to account for a
    944      * rotation from its natural orientation when calculating the rotation
    945      * angles (see {@link #getOrientation}). If the rotation matrix is also used
    946      * for rendering, it may not need to be transformed, for instance if your
    947      * {@link android.app.Activity Activity} is running in landscape mode.
    948      * </ul>
    949      *
    950      * <p>
    951      * Since the resulting coordinate system is orthonormal, only two axes need
    952      * to be specified.
    953      *
    954      * @param inR
    955      *        the rotation matrix to be transformed. Usually it is the matrix
    956      *        returned by {@link #getRotationMatrix}.
    957      *
    958      * @param X
    959      *        defines on which world axis and direction the X axis of the device
    960      *        is mapped.
    961      *
    962      * @param Y
    963      *        defines on which world axis and direction the Y axis of the device
    964      *        is mapped.
    965      *
    966      * @param outR
    967      *        the transformed rotation matrix. inR and outR can be the same
    968      *        array, but it is not recommended for performance reason.
    969      *
    970      * @return <code>true</code> on success. <code>false</code> if the input
    971      *         parameters are incorrect, for instance if X and Y define the same
    972      *         axis. Or if inR and outR don't have the same length.
    973      *
    974      * @see #getRotationMatrix(float[], float[], float[], float[])
    975      */
    976 
    977     public static boolean remapCoordinateSystem(float[] inR, int X, int Y,
    978             float[] outR)
    979     {
    980         if (inR == outR) {
    981             final float[] temp = mTempMatrix;
    982             synchronized(temp) {
    983                 // we don't expect to have a lot of contention
    984                 if (remapCoordinateSystemImpl(inR, X, Y, temp)) {
    985                     final int size = outR.length;
    986                     for (int i=0 ; i<size ; i++)
    987                         outR[i] = temp[i];
    988                     return true;
    989                 }
    990             }
    991         }
    992         return remapCoordinateSystemImpl(inR, X, Y, outR);
    993     }
    994 
    995     private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y,
    996             float[] outR)
    997     {
    998         /*
    999          * X and Y define a rotation matrix 'r':
   1000          *
   1001          *  (X==1)?((X&0x80)?-1:1):0    (X==2)?((X&0x80)?-1:1):0    (X==3)?((X&0x80)?-1:1):0
   1002          *  (Y==1)?((Y&0x80)?-1:1):0    (Y==2)?((Y&0x80)?-1:1):0    (Y==3)?((X&0x80)?-1:1):0
   1003          *                              r[0] ^ r[1]
   1004          *
   1005          * where the 3rd line is the vector product of the first 2 lines
   1006          *
   1007          */
   1008 
   1009         final int length = outR.length;
   1010         if (inR.length != length)
   1011             return false;   // invalid parameter
   1012         if ((X & 0x7C)!=0 || (Y & 0x7C)!=0)
   1013             return false;   // invalid parameter
   1014         if (((X & 0x3)==0) || ((Y & 0x3)==0))
   1015             return false;   // no axis specified
   1016         if ((X & 0x3) == (Y & 0x3))
   1017             return false;   // same axis specified
   1018 
   1019         // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y)
   1020         // this can be calculated by exclusive-or'ing X and Y; except for
   1021         // the sign inversion (+/-) which is calculated below.
   1022         int Z = X ^ Y;
   1023 
   1024         // extract the axis (remove the sign), offset in the range 0 to 2.
   1025         final int x = (X & 0x3)-1;
   1026         final int y = (Y & 0x3)-1;
   1027         final int z = (Z & 0x3)-1;
   1028 
   1029         // compute the sign of Z (whether it needs to be inverted)
   1030         final int axis_y = (z+1)%3;
   1031         final int axis_z = (z+2)%3;
   1032         if (((x^axis_y)|(y^axis_z)) != 0)
   1033             Z ^= 0x80;
   1034 
   1035         final boolean sx = (X>=0x80);
   1036         final boolean sy = (Y>=0x80);
   1037         final boolean sz = (Z>=0x80);
   1038 
   1039         // Perform R * r, in avoiding actual muls and adds.
   1040         final int rowLength = ((length==16)?4:3);
   1041         for (int j=0 ; j<3 ; j++) {
   1042             final int offset = j*rowLength;
   1043             for (int i=0 ; i<3 ; i++) {
   1044                 if (x==i)   outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0];
   1045                 if (y==i)   outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1];
   1046                 if (z==i)   outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2];
   1047             }
   1048         }
   1049         if (length == 16) {
   1050             outR[3] = outR[7] = outR[11] = outR[12] = outR[13] = outR[14] = 0;
   1051             outR[15] = 1;
   1052         }
   1053         return true;
   1054     }
   1055 
   1056     /**
   1057      * Computes the device's orientation based on the rotation matrix.
   1058      * <p>
   1059      * When it returns, the array values is filled with the result:
   1060      * <ul>
   1061      * <li>values[0]: <i>azimuth</i>, rotation around the Z axis.</li>
   1062      * <li>values[1]: <i>pitch</i>, rotation around the X axis.</li>
   1063      * <li>values[2]: <i>roll</i>, rotation around the Y axis.</li>
   1064      * </ul>
   1065      * <p>The reference coordinate-system used is different from the world
   1066      * coordinate-system defined for the rotation matrix:</p>
   1067      * <ul>
   1068      * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
   1069      * the ground at the device's current location and roughly points West).</li>
   1070      * <li>Y is tangential to the ground at the device's current location and
   1071      * points towards the magnetic North Pole.</li>
   1072      * <li>Z points towards the center of the Earth and is perpendicular to the ground.</li>
   1073      * </ul>
   1074      *
   1075      * <p>
   1076      * <center><img src="../../../images/axis_globe_inverted.png"
   1077      * alt="Inverted world coordinate-system diagram." border="0" /></center>
   1078      * </p>
   1079      * <p>
   1080      * All three angles above are in <b>radians</b> and <b>positive</b> in the
   1081      * <b>counter-clockwise</b> direction.
   1082      *
   1083      * @param R
   1084      *        rotation matrix see {@link #getRotationMatrix}.
   1085      *
   1086      * @param values
   1087      *        an array of 3 floats to hold the result.
   1088      *
   1089      * @return The array values passed as argument.
   1090      *
   1091      * @see #getRotationMatrix(float[], float[], float[], float[])
   1092      * @see GeomagneticField
   1093      */
   1094     public static float[] getOrientation(float[] R, float values[]) {
   1095         /*
   1096          * 4x4 (length=16) case:
   1097          *   /  R[ 0]   R[ 1]   R[ 2]   0  \
   1098          *   |  R[ 4]   R[ 5]   R[ 6]   0  |
   1099          *   |  R[ 8]   R[ 9]   R[10]   0  |
   1100          *   \      0       0       0   1  /
   1101          *
   1102          * 3x3 (length=9) case:
   1103          *   /  R[ 0]   R[ 1]   R[ 2]  \
   1104          *   |  R[ 3]   R[ 4]   R[ 5]  |
   1105          *   \  R[ 6]   R[ 7]   R[ 8]  /
   1106          *
   1107          */
   1108         if (R.length == 9) {
   1109             values[0] = (float)Math.atan2(R[1], R[4]);
   1110             values[1] = (float)Math.asin(-R[7]);
   1111             values[2] = (float)Math.atan2(-R[6], R[8]);
   1112         } else {
   1113             values[0] = (float)Math.atan2(R[1], R[5]);
   1114             values[1] = (float)Math.asin(-R[9]);
   1115             values[2] = (float)Math.atan2(-R[8], R[10]);
   1116         }
   1117         return values;
   1118     }
   1119 
   1120     /**
   1121      * Computes the Altitude in meters from the atmospheric pressure and the
   1122      * pressure at sea level.
   1123      * <p>
   1124      * Typically the atmospheric pressure is read from a
   1125      * {@link Sensor#TYPE_PRESSURE} sensor. The pressure at sea level must be
   1126      * known, usually it can be retrieved from airport databases in the
   1127      * vicinity. If unknown, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE}
   1128      * as an approximation, but absolute altitudes won't be accurate.
   1129      * </p>
   1130      * <p>
   1131      * To calculate altitude differences, you must calculate the difference
   1132      * between the altitudes at both points. If you don't know the altitude
   1133      * as sea level, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE} instead,
   1134      * which will give good results considering the range of pressure typically
   1135      * involved.
   1136      * </p>
   1137      * <p>
   1138      * <code><ul>
   1139      *  float altitude_difference =
   1140      *      getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point2)
   1141      *      - getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point1);
   1142      * </ul></code>
   1143      * </p>
   1144      *
   1145      * @param p0 pressure at sea level
   1146      * @param p atmospheric pressure
   1147      * @return Altitude in meters
   1148      */
   1149     public static float getAltitude(float p0, float p) {
   1150         final float coef = 1.0f / 5.255f;
   1151         return 44330.0f * (1.0f - (float)Math.pow(p/p0, coef));
   1152     }
   1153 
   1154     /** Helper function to compute the angle change between two rotation matrices.
   1155      *  Given a current rotation matrix (R) and a previous rotation matrix
   1156      *  (prevR) computes the rotation around the z,x, and y axes which
   1157      *  transforms prevR to R.
   1158      *  outputs a 3 element vector containing the z,x, and y angle
   1159      *  change at indexes 0, 1, and 2 respectively.
   1160      * <p> Each input matrix is either as a 3x3 or 4x4 row-major matrix
   1161      * depending on the length of the passed array:
   1162      * <p>If the array length is 9, then the array elements represent this matrix
   1163      * <pre>
   1164      *   /  R[ 0]   R[ 1]   R[ 2]   \
   1165      *   |  R[ 3]   R[ 4]   R[ 5]   |
   1166      *   \  R[ 6]   R[ 7]   R[ 8]   /
   1167      *</pre>
   1168      * <p>If the array length is 16, then the array elements represent this matrix
   1169      * <pre>
   1170      *   /  R[ 0]   R[ 1]   R[ 2]   R[ 3]  \
   1171      *   |  R[ 4]   R[ 5]   R[ 6]   R[ 7]  |
   1172      *   |  R[ 8]   R[ 9]   R[10]   R[11]  |
   1173      *   \  R[12]   R[13]   R[14]   R[15]  /
   1174      *</pre>
   1175      * @param R current rotation matrix
   1176      * @param prevR previous rotation matrix
   1177      * @param angleChange an an array of floats (z, x, and y) in which the angle change is stored
   1178      */
   1179 
   1180     public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) {
   1181         float rd1=0,rd4=0, rd6=0,rd7=0, rd8=0;
   1182         float ri0=0,ri1=0,ri2=0,ri3=0,ri4=0,ri5=0,ri6=0,ri7=0,ri8=0;
   1183         float pri0=0, pri1=0, pri2=0, pri3=0, pri4=0, pri5=0, pri6=0, pri7=0, pri8=0;
   1184 
   1185         if(R.length == 9) {
   1186             ri0 = R[0];
   1187             ri1 = R[1];
   1188             ri2 = R[2];
   1189             ri3 = R[3];
   1190             ri4 = R[4];
   1191             ri5 = R[5];
   1192             ri6 = R[6];
   1193             ri7 = R[7];
   1194             ri8 = R[8];
   1195         } else if(R.length == 16) {
   1196             ri0 = R[0];
   1197             ri1 = R[1];
   1198             ri2 = R[2];
   1199             ri3 = R[4];
   1200             ri4 = R[5];
   1201             ri5 = R[6];
   1202             ri6 = R[8];
   1203             ri7 = R[9];
   1204             ri8 = R[10];
   1205         }
   1206 
   1207         if(prevR.length == 9) {
   1208             pri0 = prevR[0];
   1209             pri1 = prevR[1];
   1210             pri2 = prevR[2];
   1211             pri3 = prevR[3];
   1212             pri4 = prevR[4];
   1213             pri5 = prevR[5];
   1214             pri6 = prevR[6];
   1215             pri7 = prevR[7];
   1216             pri8 = prevR[8];
   1217         } else if(prevR.length == 16) {
   1218             pri0 = prevR[0];
   1219             pri1 = prevR[1];
   1220             pri2 = prevR[2];
   1221             pri3 = prevR[4];
   1222             pri4 = prevR[5];
   1223             pri5 = prevR[6];
   1224             pri6 = prevR[8];
   1225             pri7 = prevR[9];
   1226             pri8 = prevR[10];
   1227         }
   1228 
   1229         // calculate the parts of the rotation difference matrix we need
   1230         // rd[i][j] = pri[0][i] * ri[0][j] + pri[1][i] * ri[1][j] + pri[2][i] * ri[2][j];
   1231 
   1232         rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7; //rd[0][1]
   1233         rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7; //rd[1][1]
   1234         rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6; //rd[2][0]
   1235         rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7; //rd[2][1]
   1236         rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8; //rd[2][2]
   1237 
   1238         angleChange[0] = (float)Math.atan2(rd1, rd4);
   1239         angleChange[1] = (float)Math.asin(-rd7);
   1240         angleChange[2] = (float)Math.atan2(-rd6, rd8);
   1241 
   1242     }
   1243 
   1244     /** Helper function to convert a rotation vector to a rotation matrix.
   1245      *  Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a
   1246      *  9  or 16 element rotation matrix in the array R.  R must have length 9 or 16.
   1247      *  If R.length == 9, the following matrix is returned:
   1248      * <pre>
   1249      *   /  R[ 0]   R[ 1]   R[ 2]   \
   1250      *   |  R[ 3]   R[ 4]   R[ 5]   |
   1251      *   \  R[ 6]   R[ 7]   R[ 8]   /
   1252      *</pre>
   1253      * If R.length == 16, the following matrix is returned:
   1254      * <pre>
   1255      *   /  R[ 0]   R[ 1]   R[ 2]   0  \
   1256      *   |  R[ 4]   R[ 5]   R[ 6]   0  |
   1257      *   |  R[ 8]   R[ 9]   R[10]   0  |
   1258      *   \  0       0       0       1  /
   1259      *</pre>
   1260      *  @param rotationVector the rotation vector to convert
   1261      *  @param R an array of floats in which to store the rotation matrix
   1262      */
   1263     public static void getRotationMatrixFromVector(float[] R, float[] rotationVector) {
   1264 
   1265         float q0;
   1266         float q1 = rotationVector[0];
   1267         float q2 = rotationVector[1];
   1268         float q3 = rotationVector[2];
   1269 
   1270         if (rotationVector.length == 4) {
   1271             q0 = rotationVector[3];
   1272         } else {
   1273             q0 = 1 - q1*q1 - q2*q2 - q3*q3;
   1274             q0 = (q0 > 0) ? (float)Math.sqrt(q0) : 0;
   1275         }
   1276 
   1277         float sq_q1 = 2 * q1 * q1;
   1278         float sq_q2 = 2 * q2 * q2;
   1279         float sq_q3 = 2 * q3 * q3;
   1280         float q1_q2 = 2 * q1 * q2;
   1281         float q3_q0 = 2 * q3 * q0;
   1282         float q1_q3 = 2 * q1 * q3;
   1283         float q2_q0 = 2 * q2 * q0;
   1284         float q2_q3 = 2 * q2 * q3;
   1285         float q1_q0 = 2 * q1 * q0;
   1286 
   1287         if(R.length == 9) {
   1288             R[0] = 1 - sq_q2 - sq_q3;
   1289             R[1] = q1_q2 - q3_q0;
   1290             R[2] = q1_q3 + q2_q0;
   1291 
   1292             R[3] = q1_q2 + q3_q0;
   1293             R[4] = 1 - sq_q1 - sq_q3;
   1294             R[5] = q2_q3 - q1_q0;
   1295 
   1296             R[6] = q1_q3 - q2_q0;
   1297             R[7] = q2_q3 + q1_q0;
   1298             R[8] = 1 - sq_q1 - sq_q2;
   1299         } else if (R.length == 16) {
   1300             R[0] = 1 - sq_q2 - sq_q3;
   1301             R[1] = q1_q2 - q3_q0;
   1302             R[2] = q1_q3 + q2_q0;
   1303             R[3] = 0.0f;
   1304 
   1305             R[4] = q1_q2 + q3_q0;
   1306             R[5] = 1 - sq_q1 - sq_q3;
   1307             R[6] = q2_q3 - q1_q0;
   1308             R[7] = 0.0f;
   1309 
   1310             R[8] = q1_q3 - q2_q0;
   1311             R[9] = q2_q3 + q1_q0;
   1312             R[10] = 1 - sq_q1 - sq_q2;
   1313             R[11] = 0.0f;
   1314 
   1315             R[12] = R[13] = R[14] = 0.0f;
   1316             R[15] = 1.0f;
   1317         }
   1318     }
   1319 
   1320     /** Helper function to convert a rotation vector to a normalized quaternion.
   1321      *  Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a normalized
   1322      *  quaternion in the array Q.  The quaternion is stored as [w, x, y, z]
   1323      *  @param rv the rotation vector to convert
   1324      *  @param Q an array of floats in which to store the computed quaternion
   1325      */
   1326     public static void getQuaternionFromVector(float[] Q, float[] rv) {
   1327         if (rv.length == 4) {
   1328             Q[0] = rv[3];
   1329         } else {
   1330             Q[0] = 1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2];
   1331             Q[0] = (Q[0] > 0) ? (float)Math.sqrt(Q[0]) : 0;
   1332         }
   1333         Q[1] = rv[0];
   1334         Q[2] = rv[1];
   1335         Q[3] = rv[2];
   1336     }
   1337 
   1338     /**
   1339      * Requests receiving trigger events for a trigger sensor.
   1340      *
   1341      * <p>
   1342      * When the sensor detects a trigger event condition, such as significant motion in
   1343      * the case of the {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the provided trigger listener
   1344      * will be invoked once and then its request to receive trigger events will be canceled.
   1345      * To continue receiving trigger events, the application must request to receive trigger
   1346      * events again.
   1347      * </p>
   1348      *
   1349      * @param listener The listener on which the
   1350      *        {@link TriggerEventListener#onTrigger(TriggerEvent)} will be delivered.
   1351      * @param sensor The sensor to be enabled.
   1352      *
   1353      * @return true if the sensor was successfully enabled.
   1354      *
   1355      * @throws IllegalArgumentException when sensor is null or not a trigger sensor.
   1356      */
   1357     public boolean requestTriggerSensor(TriggerEventListener listener, Sensor sensor) {
   1358         return requestTriggerSensorImpl(listener, sensor);
   1359     }
   1360 
   1361     /**
   1362      * @hide
   1363      */
   1364     protected abstract boolean requestTriggerSensorImpl(TriggerEventListener listener,
   1365             Sensor sensor);
   1366 
   1367     /**
   1368      * Cancels receiving trigger events for a trigger sensor.
   1369      *
   1370      * <p>
   1371      * Note that a Trigger sensor will be auto disabled if
   1372      * {@link TriggerEventListener#onTrigger(TriggerEvent)} has triggered.
   1373      * This method is provided in case the user wants to explicitly cancel the request
   1374      * to receive trigger events.
   1375      * </p>
   1376      *
   1377      * @param listener The listener on which the
   1378      *        {@link TriggerEventListener#onTrigger(TriggerEvent)}
   1379      *        is delivered.It should be the same as the one used
   1380      *        in {@link #requestTriggerSensor(TriggerEventListener, Sensor)}
   1381      * @param sensor The sensor for which the trigger request should be canceled.
   1382      *        If null, it cancels receiving trigger for all sensors associated
   1383      *        with the listener.
   1384      *
   1385      * @return true if successfully canceled.
   1386      *
   1387      * @throws IllegalArgumentException when sensor is a trigger sensor.
   1388      */
   1389     public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) {
   1390         return cancelTriggerSensorImpl(listener, sensor, true);
   1391     }
   1392 
   1393     /**
   1394      * @hide
   1395      */
   1396     protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener,
   1397             Sensor sensor, boolean disable);
   1398 
   1399 
   1400     private LegacySensorManager getLegacySensorManager() {
   1401         synchronized (mSensorListByType) {
   1402             if (mLegacySensorManager == null) {
   1403                 Log.i(TAG, "This application is using deprecated SensorManager API which will "
   1404                         + "be removed someday.  Please consider switching to the new API.");
   1405                 mLegacySensorManager = new LegacySensorManager(this);
   1406             }
   1407             return mLegacySensorManager;
   1408         }
   1409     }
   1410 }
   1411