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 because the sensor
    325       * had no contact with what it was measuring (for example, the heart rate
    326       * monitor is not in contact with the user).
    327       */
    328     public static final int SENSOR_STATUS_NO_CONTACT = -1;
    329 
    330     /**
    331      * The values returned by this sensor cannot be trusted, calibration is
    332      * needed or the environment doesn't allow readings
    333      */
    334     public static final int SENSOR_STATUS_UNRELIABLE = 0;
    335 
    336     /**
    337      * This sensor is reporting data with low accuracy, calibration with the
    338      * environment is needed
    339      */
    340     public static final int SENSOR_STATUS_ACCURACY_LOW = 1;
    341 
    342     /**
    343      * This sensor is reporting data with an average level of accuracy,
    344      * calibration with the environment may improve the readings
    345      */
    346     public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2;
    347 
    348     /** This sensor is reporting data with maximum accuracy */
    349     public static final int SENSOR_STATUS_ACCURACY_HIGH = 3;
    350 
    351     /** see {@link #remapCoordinateSystem} */
    352     public static final int AXIS_X = 1;
    353     /** see {@link #remapCoordinateSystem} */
    354     public static final int AXIS_Y = 2;
    355     /** see {@link #remapCoordinateSystem} */
    356     public static final int AXIS_Z = 3;
    357     /** see {@link #remapCoordinateSystem} */
    358     public static final int AXIS_MINUS_X = AXIS_X | 0x80;
    359     /** see {@link #remapCoordinateSystem} */
    360     public static final int AXIS_MINUS_Y = AXIS_Y | 0x80;
    361     /** see {@link #remapCoordinateSystem} */
    362     public static final int AXIS_MINUS_Z = AXIS_Z | 0x80;
    363 
    364 
    365     /**
    366      * {@hide}
    367      */
    368     public SensorManager() {
    369     }
    370 
    371     /**
    372      * Gets the full list of sensors that are available.
    373      * @hide
    374      */
    375     protected abstract List<Sensor> getFullSensorList();
    376 
    377     /**
    378      * @return available sensors.
    379      * @deprecated This method is deprecated, use
    380      *             {@link SensorManager#getSensorList(int)} instead
    381      */
    382     @Deprecated
    383     public int getSensors() {
    384         return getLegacySensorManager().getSensors();
    385     }
    386 
    387     /**
    388      * Use this method to get the list of available sensors of a certain type.
    389      * Make multiple calls to get sensors of different types or use
    390      * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all the
    391      * sensors.
    392      *
    393      * <p class="note">
    394      * NOTE: Both wake-up and non wake-up sensors matching the given type are
    395      * returned. Check {@link Sensor#isWakeUpSensor()} to know the wake-up properties
    396      * of the returned {@link Sensor}.
    397      * </p>
    398      *
    399      * @param type
    400      *        of sensors requested
    401      *
    402      * @return a list of sensors matching the asked type.
    403      *
    404      * @see #getDefaultSensor(int)
    405      * @see Sensor
    406      */
    407     public List<Sensor> getSensorList(int type) {
    408         // cache the returned lists the first time
    409         List<Sensor> list;
    410         final List<Sensor> fullList = getFullSensorList();
    411         synchronized (mSensorListByType) {
    412             list = mSensorListByType.get(type);
    413             if (list == null) {
    414                 if (type == Sensor.TYPE_ALL) {
    415                     list = fullList;
    416                 } else {
    417                     list = new ArrayList<Sensor>();
    418                     for (Sensor i : fullList) {
    419                         if (i.getType() == type)
    420                             list.add(i);
    421                     }
    422                 }
    423                 list = Collections.unmodifiableList(list);
    424                 mSensorListByType.append(type, list);
    425             }
    426         }
    427         return list;
    428     }
    429 
    430     /**
    431      * Use this method to get the default sensor for a given type. Note that the
    432      * returned sensor could be a composite sensor, and its data could be
    433      * averaged or filtered. If you need to access the raw sensors use
    434      * {@link SensorManager#getSensorList(int) getSensorList}.
    435      *
    436      * @param type
    437      *         of sensors requested
    438      *
    439      * @return the default sensor matching the requested type if one exists and the application
    440      *         has the necessary permissions, or null otherwise.
    441      *
    442      * @see #getSensorList(int)
    443      * @see Sensor
    444      */
    445     public Sensor getDefaultSensor(int type) {
    446         // TODO: need to be smarter, for now, just return the 1st sensor
    447         List<Sensor> l = getSensorList(type);
    448         boolean wakeUpSensor = false;
    449         // For the following sensor types, return a wake-up sensor. These types are by default
    450         // defined as wake-up sensors. For the rest of the SDK defined sensor types return a
    451         // non_wake-up version.
    452         if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION ||
    453                 type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE ||
    454                 type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE) {
    455             wakeUpSensor = true;
    456         }
    457 
    458         for (Sensor sensor : l) {
    459             if (sensor.isWakeUpSensor() == wakeUpSensor) return sensor;
    460         }
    461         return null;
    462     }
    463 
    464     /**
    465      * Return a Sensor with the given type and wakeUp properties. If multiple sensors of this
    466      * type exist, any one of them may be returned.
    467      * <p>
    468      * For example,
    469      * <ul>
    470      *     <li>getDefaultSensor({@link Sensor#TYPE_ACCELEROMETER}, true) returns a wake-up accelerometer
    471      *     sensor if it exists. </li>
    472      *     <li>getDefaultSensor({@link Sensor#TYPE_PROXIMITY}, false) returns a non wake-up proximity
    473      *     sensor if it exists. </li>
    474      *     <li>getDefaultSensor({@link Sensor#TYPE_PROXIMITY}, true) returns a wake-up proximity sensor
    475      *     which is the same as the Sensor returned by {@link #getDefaultSensor(int)}. </li>
    476      * </ul>
    477      * </p>
    478      * <p class="note">
    479      * Note: Sensors like {@link Sensor#TYPE_PROXIMITY} and {@link Sensor#TYPE_SIGNIFICANT_MOTION}
    480      * are declared as wake-up sensors by default.
    481      * </p>
    482      * @param type
    483      *        type of sensor requested
    484      * @param wakeUp
    485      *        flag to indicate whether the Sensor is a wake-up or non wake-up sensor.
    486      * @return the default sensor matching the requested type and wakeUp properties if one exists
    487      *         and the application has the necessary permissions, or null otherwise.
    488      * @see Sensor#isWakeUpSensor()
    489      */
    490     public Sensor getDefaultSensor(int type, boolean wakeUp) {
    491         List<Sensor> l = getSensorList(type);
    492         for (Sensor sensor : l) {
    493             if (sensor.isWakeUpSensor() == wakeUp)
    494                 return sensor;
    495         }
    496         return null;
    497     }
    498 
    499     /**
    500      * Registers a listener for given sensors.
    501      *
    502      * @deprecated This method is deprecated, use
    503      *             {@link SensorManager#registerListener(SensorEventListener, Sensor, int)}
    504      *             instead.
    505      *
    506      * @param listener
    507      *        sensor listener object
    508      *
    509      * @param sensors
    510      *        a bit masks of the sensors to register to
    511      *
    512      * @return <code>true</code> if the sensor is supported and successfully
    513      *         enabled
    514      */
    515     @Deprecated
    516     public boolean registerListener(SensorListener listener, int sensors) {
    517         return registerListener(listener, sensors, SENSOR_DELAY_NORMAL);
    518     }
    519 
    520     /**
    521      * Registers a SensorListener for given sensors.
    522      *
    523      * @deprecated This method is deprecated, use
    524      *             {@link SensorManager#registerListener(SensorEventListener, Sensor, int)}
    525      *             instead.
    526      *
    527      * @param listener
    528      *        sensor listener object
    529      *
    530      * @param sensors
    531      *        a bit masks of the sensors to register to
    532      *
    533      * @param rate
    534      *        rate of events. This is only a hint to the system. events may be
    535      *        received faster or slower than the specified rate. Usually events
    536      *        are received faster. The value must be one of
    537      *        {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    538      *        {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}.
    539      *
    540      * @return <code>true</code> if the sensor is supported and successfully
    541      *         enabled
    542      */
    543     @Deprecated
    544     public boolean registerListener(SensorListener listener, int sensors, int rate) {
    545         return getLegacySensorManager().registerListener(listener, sensors, rate);
    546     }
    547 
    548     /**
    549      * Unregisters a listener for all sensors.
    550      *
    551      * @deprecated This method is deprecated, use
    552      *             {@link SensorManager#unregisterListener(SensorEventListener)}
    553      *             instead.
    554      *
    555      * @param listener
    556      *        a SensorListener object
    557      */
    558     @Deprecated
    559     public void unregisterListener(SensorListener listener) {
    560         unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW);
    561     }
    562 
    563     /**
    564      * Unregisters a listener for the sensors with which it is registered.
    565      *
    566      * @deprecated This method is deprecated, use
    567      *             {@link SensorManager#unregisterListener(SensorEventListener, Sensor)}
    568      *             instead.
    569      *
    570      * @param listener
    571      *        a SensorListener object
    572      *
    573      * @param sensors
    574      *        a bit masks of the sensors to unregister from
    575      */
    576     @Deprecated
    577     public void unregisterListener(SensorListener listener, int sensors) {
    578         getLegacySensorManager().unregisterListener(listener, sensors);
    579     }
    580 
    581     /**
    582      * Unregisters a listener for the sensors with which it is registered.
    583      *
    584      * <p class="note"></p>
    585      * Note: Don't use this method with a one shot trigger sensor such as
    586      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
    587      * Use {@link #cancelTriggerSensor(TriggerEventListener, Sensor)} instead.
    588      * </p>
    589      *
    590      * @param listener
    591      *        a SensorEventListener object
    592      *
    593      * @param sensor
    594      *        the sensor to unregister from
    595      *
    596      * @see #unregisterListener(SensorEventListener)
    597      * @see #registerListener(SensorEventListener, Sensor, int)
    598      */
    599     public void unregisterListener(SensorEventListener listener, Sensor sensor) {
    600         if (listener == null || sensor == null) {
    601             return;
    602         }
    603 
    604         unregisterListenerImpl(listener, sensor);
    605     }
    606 
    607     /**
    608      * Unregisters a listener for all sensors.
    609      *
    610      * @param listener
    611      *        a SensorListener object
    612      *
    613      * @see #unregisterListener(SensorEventListener, Sensor)
    614      * @see #registerListener(SensorEventListener, Sensor, int)
    615      *
    616      */
    617     public void unregisterListener(SensorEventListener listener) {
    618         if (listener == null) {
    619             return;
    620         }
    621 
    622         unregisterListenerImpl(listener, null);
    623     }
    624 
    625     /** @hide */
    626     protected abstract void unregisterListenerImpl(SensorEventListener listener, Sensor sensor);
    627 
    628     /**
    629      * Registers a {@link android.hardware.SensorEventListener
    630      * SensorEventListener} for the given sensor.
    631      *
    632      * <p class="note"></p>
    633      * Note: Don't use this method with a one shot trigger sensor such as
    634      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
    635      * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
    636      * </p>
    637      *
    638      * @param listener
    639      *        A {@link android.hardware.SensorEventListener SensorEventListener}
    640      *        object.
    641      *
    642      * @param sensor
    643      *        The {@link android.hardware.Sensor Sensor} to register to.
    644      *
    645      * @param rateUs
    646      *        The rate {@link android.hardware.SensorEvent sensor events} are
    647      *        delivered at. This is only a hint to the system. Events may be
    648      *        received faster or slower than the specified rate. Usually events
    649      *        are received faster. The value must be one of
    650      *        {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    651      *        {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}
    652      *        or, the desired delay between events in microseconds.
    653      *        Specifying the delay in microseconds only works from Android
    654      *        2.3 (API level 9) onwards. For earlier releases, you must use
    655      *        one of the {@code SENSOR_DELAY_*} constants.
    656      *
    657      * @return <code>true</code> if the sensor is supported and successfully
    658      *         enabled.
    659      *
    660      * @see #registerListener(SensorEventListener, Sensor, int, Handler)
    661      * @see #unregisterListener(SensorEventListener)
    662      * @see #unregisterListener(SensorEventListener, Sensor)
    663      *
    664      */
    665     public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs) {
    666         return registerListener(listener, sensor, rateUs, null);
    667     }
    668 
    669     /**
    670      * Enables batch mode for a sensor with the given rate and maxBatchReportLatency. If the
    671      * underlying hardware does not support batch mode, this defaults to
    672      * {@link #registerListener(SensorEventListener, Sensor, int)} and other parameters are
    673      * ignored. In non-batch mode, all sensor events must be reported as soon as they are detected.
    674      * While in batch mode, sensor events do not need to be reported as soon as they are detected.
    675      * They can be temporarily stored in batches and reported in batches, as long as no event is
    676      * delayed by more than "maxBatchReportLatency" microseconds. That is, all events since the
    677      * previous batch are recorded and returned all at once. This allows to reduce the amount of
    678      * interrupts sent to the SoC, and allows the SoC to switch to a lower power state (Idle) while
    679      * the sensor is capturing and batching data.
    680      * <p>
    681      * Registering to a sensor in batch mode will not prevent the SoC from going to suspend mode. In
    682      * this case, the sensor will continue to gather events and store it in a hardware FIFO. If the
    683      * FIFO gets full before the AP wakes up again, some events will be lost, as the older events
    684      * get overwritten by new events in the hardware FIFO. This can be avoided by holding a wake
    685      * lock. If the application holds a wake lock, the SoC will not go to suspend mode, so no events
    686      * will be lost, as the events will be reported before the FIFO gets full.
    687      * </p>
    688      * <p>
    689      * Batching is always best effort. If a different application requests updates in continuous
    690      * mode, this application will also get events in continuous mode. Batch mode updates can be
    691      * unregistered by calling {@link #unregisterListener(SensorEventListener)}.
    692      * </p>
    693      * <p class="note">
    694      * </p>
    695      * Note: Don't use this method with a one shot trigger sensor such as
    696      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
    697      * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
    698      *
    699      * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
    700      *            that will receive the sensor events. If the application is interested in receiving
    701      *            flush complete notifications, it should register with
    702      *            {@link android.hardware.SensorEventListener SensorEventListener2} instead.
    703      * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
    704      * @param rateUs The desired delay between two consecutive events in microseconds. This is only
    705      *            a hint to the system. Events may be received faster or slower than the specified
    706      *            rate. Usually events are received faster. Can be one of
    707      *            {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    708      *            {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
    709      *            microseconds.
    710      * @param maxBatchReportLatencyUs An event in the batch can be delayed by at most
    711      *            maxBatchReportLatency microseconds. More events can be batched if this value is
    712      *            large. If this is set to zero, batch mode is disabled and events are delivered in
    713      *            continuous mode as soon as they are available which is equivalent to calling
    714      *            {@link #registerListener(SensorEventListener, Sensor, int)}.
    715      * @return <code>true</code> if batch mode is successfully enabled for this sensor,
    716      *         <code>false</code> otherwise.
    717      * @see #registerListener(SensorEventListener, Sensor, int)
    718      * @see #unregisterListener(SensorEventListener)
    719      * @see #flush(SensorEventListener)
    720      */
    721     public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
    722             int maxBatchReportLatencyUs) {
    723         int delay = getDelay(rateUs);
    724         return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs, 0);
    725     }
    726 
    727     /**
    728      * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
    729      * sensor. Events are delivered in continuous mode as soon as they are available. To reduce the
    730      * battery usage, use {@link #registerListener(SensorEventListener, Sensor, int, int)} which
    731      * enables batch mode for the sensor.
    732      *
    733      * <p class="note"></p>
    734      * Note: Don't use this method with a one shot trigger sensor such as
    735      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
    736      * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
    737      * </p>
    738      *
    739      * @param listener
    740      *        A {@link android.hardware.SensorEventListener SensorEventListener}
    741      *        object.
    742      *
    743      * @param sensor
    744      *        The {@link android.hardware.Sensor Sensor} to register to.
    745      *
    746      * @param rateUs
    747      *        The rate {@link android.hardware.SensorEvent sensor events} are
    748      *        delivered at. This is only a hint to the system. Events may be
    749      *        received faster or slower than the specified rate. Usually events
    750      *        are received faster. The value must be one of
    751      *        {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    752      *        {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}.
    753      *        or, the desired delay between events in microseconds.
    754      *        Specifying the delay in microseconds only works from Android
    755      *        2.3 (API level 9) onwards. For earlier releases, you must use
    756      *        one of the {@code SENSOR_DELAY_*} constants.
    757      *
    758      * @param handler
    759      *        The {@link android.os.Handler Handler} the
    760      *        {@link android.hardware.SensorEvent sensor events} will be
    761      *        delivered to.
    762      *
    763      * @return <code>true</code> if the sensor is supported and successfully enabled.
    764      *
    765      * @see #registerListener(SensorEventListener, Sensor, int)
    766      * @see #unregisterListener(SensorEventListener)
    767      * @see #unregisterListener(SensorEventListener, Sensor)
    768      */
    769     public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
    770             Handler handler) {
    771         int delay = getDelay(rateUs);
    772         return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
    773     }
    774 
    775     /**
    776      * Enables batch mode for a sensor with the given rate and maxBatchReportLatency.
    777      * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
    778      *            that will receive the sensor events. If the application is interested in receiving
    779      *            flush complete notifications, it should register with
    780      *            {@link android.hardware.SensorEventListener SensorEventListener2} instead.
    781      * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
    782      * @param rateUs The desired delay between two consecutive events in microseconds. This is only
    783      *            a hint to the system. Events may be received faster or slower than the specified
    784      *            rate. Usually events are received faster. Can be one of
    785      *            {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    786      *            {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
    787      *            microseconds.
    788      * @param maxBatchReportLatencyUs An event in the batch can be delayed by at most
    789      *            maxBatchReportLatency microseconds. More events can be batched if this value is
    790      *            large. If this is set to zero, batch mode is disabled and events are delivered in
    791      *            continuous mode as soon as they are available which is equivalent to calling
    792      *            {@link #registerListener(SensorEventListener, Sensor, int)}.
    793      * @param handler The {@link android.os.Handler Handler} the
    794      *        {@link android.hardware.SensorEvent sensor events} will be delivered to.
    795      *
    796      * @return <code>true</code> if batch mode is successfully enabled for this sensor,
    797      *         <code>false</code> otherwise.
    798      * @see #registerListener(SensorEventListener, Sensor, int, int)
    799      */
    800     public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
    801             int maxBatchReportLatencyUs, Handler handler) {
    802         int delayUs = getDelay(rateUs);
    803         return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs, 0);
    804     }
    805 
    806     /** @hide */
    807     protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
    808             int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags);
    809 
    810 
    811     /**
    812      * Flushes the batch FIFO of all the sensors registered for this listener. If there are events
    813      * in the FIFO of the sensor, they are returned as if the batch timeout in the FIFO of the
    814      * sensors had expired. Events are returned in the usual way through the SensorEventListener.
    815      * This call doesn't affect the batch timeout for this sensor. This call is asynchronous and
    816      * returns immediately.
    817      * {@link android.hardware.SensorEventListener2#onFlushCompleted onFlushCompleted} is called
    818      * after all the events in the batch at the time of calling this method have been delivered
    819      * successfully. If the hardware doesn't support flush, it still returns true and a trivial
    820      * flush complete event is sent after the current event for all the clients registered for this
    821      * sensor.
    822      *
    823      * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
    824      *        which was previously used in a registerListener call.
    825      * @return <code>true</code> if the flush is initiated successfully on all the sensors
    826      *         registered for this listener, false if no sensor is previously registered for this
    827      *         listener or flush on one of the sensors fails.
    828      * @see #registerListener(SensorEventListener, Sensor, int, int)
    829      * @throws IllegalArgumentException when listener is null.
    830      */
    831     public boolean flush(SensorEventListener listener) {
    832         return flushImpl(listener);
    833     }
    834 
    835     /** @hide */
    836     protected abstract boolean flushImpl(SensorEventListener listener);
    837 
    838     /**
    839      * <p>
    840      * Computes the inclination matrix <b>I</b> as well as the rotation matrix
    841      * <b>R</b> transforming a vector from the device coordinate system to the
    842      * world's coordinate system which is defined as a direct orthonormal basis,
    843      * where:
    844      * </p>
    845      *
    846      * <ul>
    847      * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
    848      * the ground at the device's current location and roughly points East).</li>
    849      * <li>Y is tangential to the ground at the device's current location and
    850      * points towards the magnetic North Pole.</li>
    851      * <li>Z points towards the sky and is perpendicular to the ground.</li>
    852      * </ul>
    853      *
    854      * <p>
    855      * <center><img src="../../../images/axis_globe.png"
    856      * alt="World coordinate-system diagram." border="0" /></center>
    857      * </p>
    858      *
    859      * <p>
    860      * <hr>
    861      * <p>
    862      * By definition:
    863      * <p>
    864      * [0 0 g] = <b>R</b> * <b>gravity</b> (g = magnitude of gravity)
    865      * <p>
    866      * [0 m 0] = <b>I</b> * <b>R</b> * <b>geomagnetic</b> (m = magnitude of
    867      * geomagnetic field)
    868      * <p>
    869      * <b>R</b> is the identity matrix when the device is aligned with the
    870      * world's coordinate system, that is, when the device's X axis points
    871      * toward East, the Y axis points to the North Pole and the device is facing
    872      * the sky.
    873      *
    874      * <p>
    875      * <b>I</b> is a rotation matrix transforming the geomagnetic vector into
    876      * the same coordinate space as gravity (the world's coordinate space).
    877      * <b>I</b> is a simple rotation around the X axis. The inclination angle in
    878      * radians can be computed with {@link #getInclination}.
    879      * <hr>
    880      *
    881      * <p>
    882      * Each matrix is returned either as a 3x3 or 4x4 row-major matrix depending
    883      * on the length of the passed array:
    884      * <p>
    885      * <u>If the array length is 16:</u>
    886      *
    887      * <pre>
    888      *   /  M[ 0]   M[ 1]   M[ 2]   M[ 3]  \
    889      *   |  M[ 4]   M[ 5]   M[ 6]   M[ 7]  |
    890      *   |  M[ 8]   M[ 9]   M[10]   M[11]  |
    891      *   \  M[12]   M[13]   M[14]   M[15]  /
    892      *</pre>
    893      *
    894      * This matrix is ready to be used by OpenGL ES's
    895      * {@link javax.microedition.khronos.opengles.GL10#glLoadMatrixf(float[], int)
    896      * glLoadMatrixf(float[], int)}.
    897      * <p>
    898      * Note that because OpenGL matrices are column-major matrices you must
    899      * transpose the matrix before using it. However, since the matrix is a
    900      * rotation matrix, its transpose is also its inverse, conveniently, it is
    901      * often the inverse of the rotation that is needed for rendering; it can
    902      * therefore be used with OpenGL ES directly.
    903      * <p>
    904      * Also note that the returned matrices always have this form:
    905      *
    906      * <pre>
    907      *   /  M[ 0]   M[ 1]   M[ 2]   0  \
    908      *   |  M[ 4]   M[ 5]   M[ 6]   0  |
    909      *   |  M[ 8]   M[ 9]   M[10]   0  |
    910      *   \      0       0       0   1  /
    911      *</pre>
    912      *
    913      * <p>
    914      * <u>If the array length is 9:</u>
    915      *
    916      * <pre>
    917      *   /  M[ 0]   M[ 1]   M[ 2]  \
    918      *   |  M[ 3]   M[ 4]   M[ 5]  |
    919      *   \  M[ 6]   M[ 7]   M[ 8]  /
    920      *</pre>
    921      *
    922      * <hr>
    923      * <p>
    924      * The inverse of each matrix can be computed easily by taking its
    925      * transpose.
    926      *
    927      * <p>
    928      * The matrices returned by this function are meaningful only when the
    929      * device is not free-falling and it is not close to the magnetic north. If
    930      * the device is accelerating, or placed into a strong magnetic field, the
    931      * returned matrices may be inaccurate.
    932      *
    933      * @param R
    934      *        is an array of 9 floats holding the rotation matrix <b>R</b> when
    935      *        this function returns. R can be null.
    936      *        <p>
    937      *
    938      * @param I
    939      *        is an array of 9 floats holding the rotation matrix <b>I</b> when
    940      *        this function returns. I can be null.
    941      *        <p>
    942      *
    943      * @param gravity
    944      *        is an array of 3 floats containing the gravity vector expressed in
    945      *        the device's coordinate. You can simply use the
    946      *        {@link android.hardware.SensorEvent#values values} returned by a
    947      *        {@link android.hardware.SensorEvent SensorEvent} of a
    948      *        {@link android.hardware.Sensor Sensor} of type
    949      *        {@link android.hardware.Sensor#TYPE_ACCELEROMETER
    950      *        TYPE_ACCELEROMETER}.
    951      *        <p>
    952      *
    953      * @param geomagnetic
    954      *        is an array of 3 floats containing the geomagnetic vector
    955      *        expressed in the device's coordinate. You can simply use the
    956      *        {@link android.hardware.SensorEvent#values values} returned by a
    957      *        {@link android.hardware.SensorEvent SensorEvent} of a
    958      *        {@link android.hardware.Sensor Sensor} of type
    959      *        {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD
    960      *        TYPE_MAGNETIC_FIELD}.
    961      *
    962      * @return <code>true</code> on success, <code>false</code> on failure (for
    963      *         instance, if the device is in free fall). On failure the output
    964      *         matrices are not modified.
    965      *
    966      * @see #getInclination(float[])
    967      * @see #getOrientation(float[], float[])
    968      * @see #remapCoordinateSystem(float[], int, int, float[])
    969      */
    970 
    971     public static boolean getRotationMatrix(float[] R, float[] I,
    972             float[] gravity, float[] geomagnetic) {
    973         // TODO: move this to native code for efficiency
    974         float Ax = gravity[0];
    975         float Ay = gravity[1];
    976         float Az = gravity[2];
    977         final float Ex = geomagnetic[0];
    978         final float Ey = geomagnetic[1];
    979         final float Ez = geomagnetic[2];
    980         float Hx = Ey*Az - Ez*Ay;
    981         float Hy = Ez*Ax - Ex*Az;
    982         float Hz = Ex*Ay - Ey*Ax;
    983         final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
    984         if (normH < 0.1f) {
    985             // device is close to free fall (or in space?), or close to
    986             // magnetic north pole. Typical values are  > 100.
    987             return false;
    988         }
    989         final float invH = 1.0f / normH;
    990         Hx *= invH;
    991         Hy *= invH;
    992         Hz *= invH;
    993         final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az);
    994         Ax *= invA;
    995         Ay *= invA;
    996         Az *= invA;
    997         final float Mx = Ay*Hz - Az*Hy;
    998         final float My = Az*Hx - Ax*Hz;
    999         final float Mz = Ax*Hy - Ay*Hx;
   1000         if (R != null) {
   1001             if (R.length == 9) {
   1002                 R[0] = Hx;     R[1] = Hy;     R[2] = Hz;
   1003                 R[3] = Mx;     R[4] = My;     R[5] = Mz;
   1004                 R[6] = Ax;     R[7] = Ay;     R[8] = Az;
   1005             } else if (R.length == 16) {
   1006                 R[0]  = Hx;    R[1]  = Hy;    R[2]  = Hz;   R[3]  = 0;
   1007                 R[4]  = Mx;    R[5]  = My;    R[6]  = Mz;   R[7]  = 0;
   1008                 R[8]  = Ax;    R[9]  = Ay;    R[10] = Az;   R[11] = 0;
   1009                 R[12] = 0;     R[13] = 0;     R[14] = 0;    R[15] = 1;
   1010             }
   1011         }
   1012         if (I != null) {
   1013             // compute the inclination matrix by projecting the geomagnetic
   1014             // vector onto the Z (gravity) and X (horizontal component
   1015             // of geomagnetic vector) axes.
   1016             final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez);
   1017             final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE;
   1018             final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE;
   1019             if (I.length == 9) {
   1020                 I[0] = 1;     I[1] = 0;     I[2] = 0;
   1021                 I[3] = 0;     I[4] = c;     I[5] = s;
   1022                 I[6] = 0;     I[7] =-s;     I[8] = c;
   1023             } else if (I.length == 16) {
   1024                 I[0] = 1;     I[1] = 0;     I[2] = 0;
   1025                 I[4] = 0;     I[5] = c;     I[6] = s;
   1026                 I[8] = 0;     I[9] =-s;     I[10]= c;
   1027                 I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0;
   1028                 I[15] = 1;
   1029             }
   1030         }
   1031         return true;
   1032     }
   1033 
   1034     /**
   1035      * Computes the geomagnetic inclination angle in radians from the
   1036      * inclination matrix <b>I</b> returned by {@link #getRotationMatrix}.
   1037      *
   1038      * @param I
   1039      *        inclination matrix see {@link #getRotationMatrix}.
   1040      *
   1041      * @return The geomagnetic inclination angle in radians.
   1042      *
   1043      * @see #getRotationMatrix(float[], float[], float[], float[])
   1044      * @see #getOrientation(float[], float[])
   1045      * @see GeomagneticField
   1046      *
   1047      */
   1048     public static float getInclination(float[] I) {
   1049         if (I.length == 9) {
   1050             return (float)Math.atan2(I[5], I[4]);
   1051         } else {
   1052             return (float)Math.atan2(I[6], I[5]);
   1053         }
   1054     }
   1055 
   1056     /**
   1057      * <p>
   1058      * Rotates the supplied rotation matrix so it is expressed in a different
   1059      * coordinate system. This is typically used when an application needs to
   1060      * compute the three orientation angles of the device (see
   1061      * {@link #getOrientation}) in a different coordinate system.
   1062      * </p>
   1063      *
   1064      * <p>
   1065      * When the rotation matrix is used for drawing (for instance with OpenGL
   1066      * ES), it usually <b>doesn't need</b> to be transformed by this function,
   1067      * unless the screen is physically rotated, in which case you can use
   1068      * {@link android.view.Display#getRotation() Display.getRotation()} to
   1069      * retrieve the current rotation of the screen. Note that because the user
   1070      * is generally free to rotate their screen, you often should consider the
   1071      * rotation in deciding the parameters to use here.
   1072      * </p>
   1073      *
   1074      * <p>
   1075      * <u>Examples:</u>
   1076      * <p>
   1077      *
   1078      * <ul>
   1079      * <li>Using the camera (Y axis along the camera's axis) for an augmented
   1080      * reality application where the rotation angles are needed:</li>
   1081      *
   1082      * <p>
   1083      * <ul>
   1084      * <code>remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);</code>
   1085      * </ul>
   1086      * </p>
   1087      *
   1088      * <li>Using the device as a mechanical compass when rotation is
   1089      * {@link android.view.Surface#ROTATION_90 Surface.ROTATION_90}:</li>
   1090      *
   1091      * <p>
   1092      * <ul>
   1093      * <code>remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);</code>
   1094      * </ul>
   1095      * </p>
   1096      *
   1097      * Beware of the above example. This call is needed only to account for a
   1098      * rotation from its natural orientation when calculating the rotation
   1099      * angles (see {@link #getOrientation}). If the rotation matrix is also used
   1100      * for rendering, it may not need to be transformed, for instance if your
   1101      * {@link android.app.Activity Activity} is running in landscape mode.
   1102      * </ul>
   1103      *
   1104      * <p>
   1105      * Since the resulting coordinate system is orthonormal, only two axes need
   1106      * to be specified.
   1107      *
   1108      * @param inR
   1109      *        the rotation matrix to be transformed. Usually it is the matrix
   1110      *        returned by {@link #getRotationMatrix}.
   1111      *
   1112      * @param X
   1113      *        defines on which world axis and direction the X axis of the device
   1114      *        is mapped.
   1115      *
   1116      * @param Y
   1117      *        defines on which world axis and direction the Y axis of the device
   1118      *        is mapped.
   1119      *
   1120      * @param outR
   1121      *        the transformed rotation matrix. inR and outR should not be the same
   1122      *        array.
   1123      *
   1124      * @return <code>true</code> on success. <code>false</code> if the input
   1125      *         parameters are incorrect, for instance if X and Y define the same
   1126      *         axis. Or if inR and outR don't have the same length.
   1127      *
   1128      * @see #getRotationMatrix(float[], float[], float[], float[])
   1129      */
   1130 
   1131     public static boolean remapCoordinateSystem(float[] inR, int X, int Y,
   1132             float[] outR)
   1133     {
   1134         if (inR == outR) {
   1135             final float[] temp = mTempMatrix;
   1136             synchronized(temp) {
   1137                 // we don't expect to have a lot of contention
   1138                 if (remapCoordinateSystemImpl(inR, X, Y, temp)) {
   1139                     final int size = outR.length;
   1140                     for (int i=0 ; i<size ; i++)
   1141                         outR[i] = temp[i];
   1142                     return true;
   1143                 }
   1144             }
   1145         }
   1146         return remapCoordinateSystemImpl(inR, X, Y, outR);
   1147     }
   1148 
   1149     private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y,
   1150             float[] outR)
   1151     {
   1152         /*
   1153          * X and Y define a rotation matrix 'r':
   1154          *
   1155          *  (X==1)?((X&0x80)?-1:1):0    (X==2)?((X&0x80)?-1:1):0    (X==3)?((X&0x80)?-1:1):0
   1156          *  (Y==1)?((Y&0x80)?-1:1):0    (Y==2)?((Y&0x80)?-1:1):0    (Y==3)?((X&0x80)?-1:1):0
   1157          *                              r[0] ^ r[1]
   1158          *
   1159          * where the 3rd line is the vector product of the first 2 lines
   1160          *
   1161          */
   1162 
   1163         final int length = outR.length;
   1164         if (inR.length != length)
   1165             return false;   // invalid parameter
   1166         if ((X & 0x7C)!=0 || (Y & 0x7C)!=0)
   1167             return false;   // invalid parameter
   1168         if (((X & 0x3)==0) || ((Y & 0x3)==0))
   1169             return false;   // no axis specified
   1170         if ((X & 0x3) == (Y & 0x3))
   1171             return false;   // same axis specified
   1172 
   1173         // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y)
   1174         // this can be calculated by exclusive-or'ing X and Y; except for
   1175         // the sign inversion (+/-) which is calculated below.
   1176         int Z = X ^ Y;
   1177 
   1178         // extract the axis (remove the sign), offset in the range 0 to 2.
   1179         final int x = (X & 0x3)-1;
   1180         final int y = (Y & 0x3)-1;
   1181         final int z = (Z & 0x3)-1;
   1182 
   1183         // compute the sign of Z (whether it needs to be inverted)
   1184         final int axis_y = (z+1)%3;
   1185         final int axis_z = (z+2)%3;
   1186         if (((x^axis_y)|(y^axis_z)) != 0)
   1187             Z ^= 0x80;
   1188 
   1189         final boolean sx = (X>=0x80);
   1190         final boolean sy = (Y>=0x80);
   1191         final boolean sz = (Z>=0x80);
   1192 
   1193         // Perform R * r, in avoiding actual muls and adds.
   1194         final int rowLength = ((length==16)?4:3);
   1195         for (int j=0 ; j<3 ; j++) {
   1196             final int offset = j*rowLength;
   1197             for (int i=0 ; i<3 ; i++) {
   1198                 if (x==i)   outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0];
   1199                 if (y==i)   outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1];
   1200                 if (z==i)   outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2];
   1201             }
   1202         }
   1203         if (length == 16) {
   1204             outR[3] = outR[7] = outR[11] = outR[12] = outR[13] = outR[14] = 0;
   1205             outR[15] = 1;
   1206         }
   1207         return true;
   1208     }
   1209 
   1210     /**
   1211      * Computes the device's orientation based on the rotation matrix.
   1212      * <p>
   1213      * When it returns, the array values is filled with the result:
   1214      * <ul>
   1215      * <li>values[0]: <i>azimuth</i>, rotation around the Z axis.</li>
   1216      * <li>values[1]: <i>pitch</i>, rotation around the X axis.</li>
   1217      * <li>values[2]: <i>roll</i>, rotation around the Y axis.</li>
   1218      * </ul>
   1219      * <p>The reference coordinate-system used is different from the world
   1220      * coordinate-system defined for the rotation matrix:</p>
   1221      * <ul>
   1222      * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
   1223      * the ground at the device's current location and roughly points West).</li>
   1224      * <li>Y is tangential to the ground at the device's current location and
   1225      * points towards the magnetic North Pole.</li>
   1226      * <li>Z points towards the center of the Earth and is perpendicular to the ground.</li>
   1227      * </ul>
   1228      *
   1229      * <p>
   1230      * <center><img src="../../../images/axis_globe_inverted.png"
   1231      * alt="Inverted world coordinate-system diagram." border="0" /></center>
   1232      * </p>
   1233      * <p>
   1234      * All three angles above are in <b>radians</b> and <b>positive</b> in the
   1235      * <b>counter-clockwise</b> direction.
   1236      *
   1237      * @param R
   1238      *        rotation matrix see {@link #getRotationMatrix}.
   1239      *
   1240      * @param values
   1241      *        an array of 3 floats to hold the result.
   1242      *
   1243      * @return The array values passed as argument.
   1244      *
   1245      * @see #getRotationMatrix(float[], float[], float[], float[])
   1246      * @see GeomagneticField
   1247      */
   1248     public static float[] getOrientation(float[] R, float values[]) {
   1249         /*
   1250          * 4x4 (length=16) case:
   1251          *   /  R[ 0]   R[ 1]   R[ 2]   0  \
   1252          *   |  R[ 4]   R[ 5]   R[ 6]   0  |
   1253          *   |  R[ 8]   R[ 9]   R[10]   0  |
   1254          *   \      0       0       0   1  /
   1255          *
   1256          * 3x3 (length=9) case:
   1257          *   /  R[ 0]   R[ 1]   R[ 2]  \
   1258          *   |  R[ 3]   R[ 4]   R[ 5]  |
   1259          *   \  R[ 6]   R[ 7]   R[ 8]  /
   1260          *
   1261          */
   1262         if (R.length == 9) {
   1263             values[0] = (float)Math.atan2(R[1], R[4]);
   1264             values[1] = (float)Math.asin(-R[7]);
   1265             values[2] = (float)Math.atan2(-R[6], R[8]);
   1266         } else {
   1267             values[0] = (float)Math.atan2(R[1], R[5]);
   1268             values[1] = (float)Math.asin(-R[9]);
   1269             values[2] = (float)Math.atan2(-R[8], R[10]);
   1270         }
   1271         return values;
   1272     }
   1273 
   1274     /**
   1275      * Computes the Altitude in meters from the atmospheric pressure and the
   1276      * pressure at sea level.
   1277      * <p>
   1278      * Typically the atmospheric pressure is read from a
   1279      * {@link Sensor#TYPE_PRESSURE} sensor. The pressure at sea level must be
   1280      * known, usually it can be retrieved from airport databases in the
   1281      * vicinity. If unknown, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE}
   1282      * as an approximation, but absolute altitudes won't be accurate.
   1283      * </p>
   1284      * <p>
   1285      * To calculate altitude differences, you must calculate the difference
   1286      * between the altitudes at both points. If you don't know the altitude
   1287      * as sea level, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE} instead,
   1288      * which will give good results considering the range of pressure typically
   1289      * involved.
   1290      * </p>
   1291      * <p>
   1292      * <code><ul>
   1293      *  float altitude_difference =
   1294      *      getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point2)
   1295      *      - getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point1);
   1296      * </ul></code>
   1297      * </p>
   1298      *
   1299      * @param p0 pressure at sea level
   1300      * @param p atmospheric pressure
   1301      * @return Altitude in meters
   1302      */
   1303     public static float getAltitude(float p0, float p) {
   1304         final float coef = 1.0f / 5.255f;
   1305         return 44330.0f * (1.0f - (float)Math.pow(p/p0, coef));
   1306     }
   1307 
   1308     /** Helper function to compute the angle change between two rotation matrices.
   1309      *  Given a current rotation matrix (R) and a previous rotation matrix
   1310      *  (prevR) computes the rotation around the z,x, and y axes which
   1311      *  transforms prevR to R.
   1312      *  outputs a 3 element vector containing the z,x, and y angle
   1313      *  change at indexes 0, 1, and 2 respectively.
   1314      * <p> Each input matrix is either as a 3x3 or 4x4 row-major matrix
   1315      * depending on the length of the passed array:
   1316      * <p>If the array length is 9, then the array elements represent this matrix
   1317      * <pre>
   1318      *   /  R[ 0]   R[ 1]   R[ 2]   \
   1319      *   |  R[ 3]   R[ 4]   R[ 5]   |
   1320      *   \  R[ 6]   R[ 7]   R[ 8]   /
   1321      *</pre>
   1322      * <p>If the array length is 16, then the array elements represent this matrix
   1323      * <pre>
   1324      *   /  R[ 0]   R[ 1]   R[ 2]   R[ 3]  \
   1325      *   |  R[ 4]   R[ 5]   R[ 6]   R[ 7]  |
   1326      *   |  R[ 8]   R[ 9]   R[10]   R[11]  |
   1327      *   \  R[12]   R[13]   R[14]   R[15]  /
   1328      *</pre>
   1329      * @param R current rotation matrix
   1330      * @param prevR previous rotation matrix
   1331      * @param angleChange an an array of floats (z, x, and y) in which the angle change is stored
   1332      */
   1333 
   1334     public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) {
   1335         float rd1=0,rd4=0, rd6=0,rd7=0, rd8=0;
   1336         float ri0=0,ri1=0,ri2=0,ri3=0,ri4=0,ri5=0,ri6=0,ri7=0,ri8=0;
   1337         float pri0=0, pri1=0, pri2=0, pri3=0, pri4=0, pri5=0, pri6=0, pri7=0, pri8=0;
   1338 
   1339         if(R.length == 9) {
   1340             ri0 = R[0];
   1341             ri1 = R[1];
   1342             ri2 = R[2];
   1343             ri3 = R[3];
   1344             ri4 = R[4];
   1345             ri5 = R[5];
   1346             ri6 = R[6];
   1347             ri7 = R[7];
   1348             ri8 = R[8];
   1349         } else if(R.length == 16) {
   1350             ri0 = R[0];
   1351             ri1 = R[1];
   1352             ri2 = R[2];
   1353             ri3 = R[4];
   1354             ri4 = R[5];
   1355             ri5 = R[6];
   1356             ri6 = R[8];
   1357             ri7 = R[9];
   1358             ri8 = R[10];
   1359         }
   1360 
   1361         if(prevR.length == 9) {
   1362             pri0 = prevR[0];
   1363             pri1 = prevR[1];
   1364             pri2 = prevR[2];
   1365             pri3 = prevR[3];
   1366             pri4 = prevR[4];
   1367             pri5 = prevR[5];
   1368             pri6 = prevR[6];
   1369             pri7 = prevR[7];
   1370             pri8 = prevR[8];
   1371         } else if(prevR.length == 16) {
   1372             pri0 = prevR[0];
   1373             pri1 = prevR[1];
   1374             pri2 = prevR[2];
   1375             pri3 = prevR[4];
   1376             pri4 = prevR[5];
   1377             pri5 = prevR[6];
   1378             pri6 = prevR[8];
   1379             pri7 = prevR[9];
   1380             pri8 = prevR[10];
   1381         }
   1382 
   1383         // calculate the parts of the rotation difference matrix we need
   1384         // rd[i][j] = pri[0][i] * ri[0][j] + pri[1][i] * ri[1][j] + pri[2][i] * ri[2][j];
   1385 
   1386         rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7; //rd[0][1]
   1387         rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7; //rd[1][1]
   1388         rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6; //rd[2][0]
   1389         rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7; //rd[2][1]
   1390         rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8; //rd[2][2]
   1391 
   1392         angleChange[0] = (float)Math.atan2(rd1, rd4);
   1393         angleChange[1] = (float)Math.asin(-rd7);
   1394         angleChange[2] = (float)Math.atan2(-rd6, rd8);
   1395 
   1396     }
   1397 
   1398     /** Helper function to convert a rotation vector to a rotation matrix.
   1399      *  Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a
   1400      *  9  or 16 element rotation matrix in the array R.  R must have length 9 or 16.
   1401      *  If R.length == 9, the following matrix is returned:
   1402      * <pre>
   1403      *   /  R[ 0]   R[ 1]   R[ 2]   \
   1404      *   |  R[ 3]   R[ 4]   R[ 5]   |
   1405      *   \  R[ 6]   R[ 7]   R[ 8]   /
   1406      *</pre>
   1407      * If R.length == 16, the following matrix is returned:
   1408      * <pre>
   1409      *   /  R[ 0]   R[ 1]   R[ 2]   0  \
   1410      *   |  R[ 4]   R[ 5]   R[ 6]   0  |
   1411      *   |  R[ 8]   R[ 9]   R[10]   0  |
   1412      *   \  0       0       0       1  /
   1413      *</pre>
   1414      *  @param rotationVector the rotation vector to convert
   1415      *  @param R an array of floats in which to store the rotation matrix
   1416      */
   1417     public static void getRotationMatrixFromVector(float[] R, float[] rotationVector) {
   1418 
   1419         float q0;
   1420         float q1 = rotationVector[0];
   1421         float q2 = rotationVector[1];
   1422         float q3 = rotationVector[2];
   1423 
   1424         if (rotationVector.length >= 4) {
   1425             q0 = rotationVector[3];
   1426         } else {
   1427             q0 = 1 - q1*q1 - q2*q2 - q3*q3;
   1428             q0 = (q0 > 0) ? (float)Math.sqrt(q0) : 0;
   1429         }
   1430 
   1431         float sq_q1 = 2 * q1 * q1;
   1432         float sq_q2 = 2 * q2 * q2;
   1433         float sq_q3 = 2 * q3 * q3;
   1434         float q1_q2 = 2 * q1 * q2;
   1435         float q3_q0 = 2 * q3 * q0;
   1436         float q1_q3 = 2 * q1 * q3;
   1437         float q2_q0 = 2 * q2 * q0;
   1438         float q2_q3 = 2 * q2 * q3;
   1439         float q1_q0 = 2 * q1 * q0;
   1440 
   1441         if(R.length == 9) {
   1442             R[0] = 1 - sq_q2 - sq_q3;
   1443             R[1] = q1_q2 - q3_q0;
   1444             R[2] = q1_q3 + q2_q0;
   1445 
   1446             R[3] = q1_q2 + q3_q0;
   1447             R[4] = 1 - sq_q1 - sq_q3;
   1448             R[5] = q2_q3 - q1_q0;
   1449 
   1450             R[6] = q1_q3 - q2_q0;
   1451             R[7] = q2_q3 + q1_q0;
   1452             R[8] = 1 - sq_q1 - sq_q2;
   1453         } else if (R.length == 16) {
   1454             R[0] = 1 - sq_q2 - sq_q3;
   1455             R[1] = q1_q2 - q3_q0;
   1456             R[2] = q1_q3 + q2_q0;
   1457             R[3] = 0.0f;
   1458 
   1459             R[4] = q1_q2 + q3_q0;
   1460             R[5] = 1 - sq_q1 - sq_q3;
   1461             R[6] = q2_q3 - q1_q0;
   1462             R[7] = 0.0f;
   1463 
   1464             R[8] = q1_q3 - q2_q0;
   1465             R[9] = q2_q3 + q1_q0;
   1466             R[10] = 1 - sq_q1 - sq_q2;
   1467             R[11] = 0.0f;
   1468 
   1469             R[12] = R[13] = R[14] = 0.0f;
   1470             R[15] = 1.0f;
   1471         }
   1472     }
   1473 
   1474     /** Helper function to convert a rotation vector to a normalized quaternion.
   1475      *  Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a normalized
   1476      *  quaternion in the array Q.  The quaternion is stored as [w, x, y, z]
   1477      *  @param rv the rotation vector to convert
   1478      *  @param Q an array of floats in which to store the computed quaternion
   1479      */
   1480     public static void getQuaternionFromVector(float[] Q, float[] rv) {
   1481         if (rv.length >= 4) {
   1482             Q[0] = rv[3];
   1483         } else {
   1484             Q[0] = 1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2];
   1485             Q[0] = (Q[0] > 0) ? (float)Math.sqrt(Q[0]) : 0;
   1486         }
   1487         Q[1] = rv[0];
   1488         Q[2] = rv[1];
   1489         Q[3] = rv[2];
   1490     }
   1491 
   1492     /**
   1493      * Requests receiving trigger events for a trigger sensor.
   1494      *
   1495      * <p>
   1496      * When the sensor detects a trigger event condition, such as significant motion in
   1497      * the case of the {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the provided trigger listener
   1498      * will be invoked once and then its request to receive trigger events will be canceled.
   1499      * To continue receiving trigger events, the application must request to receive trigger
   1500      * events again.
   1501      * </p>
   1502      *
   1503      * @param listener The listener on which the
   1504      *        {@link TriggerEventListener#onTrigger(TriggerEvent)} will be delivered.
   1505      * @param sensor The sensor to be enabled.
   1506      *
   1507      * @return true if the sensor was successfully enabled.
   1508      *
   1509      * @throws IllegalArgumentException when sensor is null or not a trigger sensor.
   1510      */
   1511     public boolean requestTriggerSensor(TriggerEventListener listener, Sensor sensor) {
   1512         return requestTriggerSensorImpl(listener, sensor);
   1513     }
   1514 
   1515     /**
   1516      * @hide
   1517      */
   1518     protected abstract boolean requestTriggerSensorImpl(TriggerEventListener listener,
   1519             Sensor sensor);
   1520 
   1521     /**
   1522      * Cancels receiving trigger events for a trigger sensor.
   1523      *
   1524      * <p>
   1525      * Note that a Trigger sensor will be auto disabled if
   1526      * {@link TriggerEventListener#onTrigger(TriggerEvent)} has triggered.
   1527      * This method is provided in case the user wants to explicitly cancel the request
   1528      * to receive trigger events.
   1529      * </p>
   1530      *
   1531      * @param listener The listener on which the
   1532      *        {@link TriggerEventListener#onTrigger(TriggerEvent)}
   1533      *        is delivered.It should be the same as the one used
   1534      *        in {@link #requestTriggerSensor(TriggerEventListener, Sensor)}
   1535      * @param sensor The sensor for which the trigger request should be canceled.
   1536      *        If null, it cancels receiving trigger for all sensors associated
   1537      *        with the listener.
   1538      *
   1539      * @return true if successfully canceled.
   1540      *
   1541      * @throws IllegalArgumentException when sensor is a trigger sensor.
   1542      */
   1543     public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) {
   1544         return cancelTriggerSensorImpl(listener, sensor, true);
   1545     }
   1546 
   1547     /**
   1548      * @hide
   1549      */
   1550     protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener,
   1551             Sensor sensor, boolean disable);
   1552 
   1553 
   1554     private LegacySensorManager getLegacySensorManager() {
   1555         synchronized (mSensorListByType) {
   1556             if (mLegacySensorManager == null) {
   1557                 Log.i(TAG, "This application is using deprecated SensorManager API which will "
   1558                         + "be removed someday.  Please consider switching to the new API.");
   1559                 mLegacySensorManager = new LegacySensorManager(this);
   1560             }
   1561             return mLegacySensorManager;
   1562         }
   1563     }
   1564 
   1565     private static int getDelay(int rate) {
   1566         int delay = -1;
   1567         switch (rate) {
   1568             case SENSOR_DELAY_FASTEST:
   1569                 delay = 0;
   1570                 break;
   1571             case SENSOR_DELAY_GAME:
   1572                 delay = 20000;
   1573                 break;
   1574             case SENSOR_DELAY_UI:
   1575                 delay = 66667;
   1576                 break;
   1577             case SENSOR_DELAY_NORMAL:
   1578                 delay = 200000;
   1579                 break;
   1580             default:
   1581                 delay = rate;
   1582                 break;
   1583         }
   1584         return delay;
   1585     }
   1586 }
   1587