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.annotation.SystemApi;
     20 import android.os.Build;
     21 import android.os.Handler;
     22 import android.util.Log;
     23 import android.util.SparseArray;
     24 
     25 import java.util.ArrayList;
     26 import java.util.Collections;
     27 import java.util.List;
     28 
     29 /**
     30  * <p>
     31  * SensorManager lets you access the device's {@link android.hardware.Sensor
     32  * sensors}. Get an instance of this class by calling
     33  * {@link android.content.Context#getSystemService(java.lang.String)
     34  * Context.getSystemService()} with the argument
     35  * {@link android.content.Context#SENSOR_SERVICE}.
     36  * </p>
     37  * <p>
     38  * Always make sure to disable sensors you don't need, especially when your
     39  * activity is paused. Failing to do so can drain the battery in just a few
     40  * hours. Note that the system will <i>not</i> disable sensors automatically when
     41  * the screen turns off.
     42  * </p>
     43  * <p class="note">
     44  * Note: Don't use this mechanism with a Trigger Sensor, have a look
     45  * at {@link TriggerEventListener}. {@link Sensor#TYPE_SIGNIFICANT_MOTION}
     46  * is an example of a trigger sensor.
     47  * </p>
     48  * <pre class="prettyprint">
     49  * public class SensorActivity extends Activity implements SensorEventListener {
     50  *     private final SensorManager mSensorManager;
     51  *     private final Sensor mAccelerometer;
     52  *
     53  *     public SensorActivity() {
     54  *         mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
     55  *         mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
     56  *     }
     57  *
     58  *     protected void onResume() {
     59  *         super.onResume();
     60  *         mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
     61  *     }
     62  *
     63  *     protected void onPause() {
     64  *         super.onPause();
     65  *         mSensorManager.unregisterListener(this);
     66  *     }
     67  *
     68  *     public void onAccuracyChanged(Sensor sensor, int accuracy) {
     69  *     }
     70  *
     71  *     public void onSensorChanged(SensorEvent event) {
     72  *     }
     73  * }
     74  * </pre>
     75  *
     76  * @see SensorEventListener
     77  * @see SensorEvent
     78  * @see Sensor
     79  *
     80  */
     81 public abstract class SensorManager {
     82     /** @hide */
     83     protected static final String TAG = "SensorManager";
     84 
     85     private static final float[] mTempMatrix = new float[16];
     86 
     87     // Cached lists of sensors by type.  Guarded by mSensorListByType.
     88     private final SparseArray<List<Sensor>> mSensorListByType =
     89             new SparseArray<List<Sensor>>();
     90 
     91     // Legacy sensor manager implementation.  Guarded by mSensorListByType during initialization.
     92     private LegacySensorManager mLegacySensorManager;
     93 
     94     /* NOTE: sensor IDs must be a power of 2 */
     95 
     96     /**
     97      * A constant describing an orientation sensor. See
     98      * {@link android.hardware.SensorListener SensorListener} for more details.
     99      *
    100      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    101      */
    102     @Deprecated
    103     public static final int SENSOR_ORIENTATION = 1 << 0;
    104 
    105     /**
    106      * A constant describing an accelerometer. See
    107      * {@link android.hardware.SensorListener SensorListener} for more details.
    108      *
    109      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    110      */
    111     @Deprecated
    112     public static final int SENSOR_ACCELEROMETER = 1 << 1;
    113 
    114     /**
    115      * A constant describing a temperature sensor See
    116      * {@link android.hardware.SensorListener SensorListener} for more details.
    117      *
    118      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    119      */
    120     @Deprecated
    121     public static final int SENSOR_TEMPERATURE = 1 << 2;
    122 
    123     /**
    124      * A constant describing a magnetic sensor See
    125      * {@link android.hardware.SensorListener SensorListener} for more details.
    126      *
    127      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    128      */
    129     @Deprecated
    130     public static final int SENSOR_MAGNETIC_FIELD = 1 << 3;
    131 
    132     /**
    133      * A constant describing an ambient light sensor See
    134      * {@link android.hardware.SensorListener SensorListener} for more details.
    135      *
    136      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    137      */
    138     @Deprecated
    139     public static final int SENSOR_LIGHT = 1 << 4;
    140 
    141     /**
    142      * A constant describing a proximity sensor See
    143      * {@link android.hardware.SensorListener SensorListener} for more details.
    144      *
    145      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    146      */
    147     @Deprecated
    148     public static final int SENSOR_PROXIMITY = 1 << 5;
    149 
    150     /**
    151      * A constant describing a Tricorder See
    152      * {@link android.hardware.SensorListener SensorListener} for more details.
    153      *
    154      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    155      */
    156     @Deprecated
    157     public static final int SENSOR_TRICORDER = 1 << 6;
    158 
    159     /**
    160      * A constant describing an orientation sensor. See
    161      * {@link android.hardware.SensorListener SensorListener} for more details.
    162      *
    163      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    164      */
    165     @Deprecated
    166     public static final int SENSOR_ORIENTATION_RAW = 1 << 7;
    167 
    168     /**
    169      * A constant that includes all sensors
    170      *
    171      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    172      */
    173     @Deprecated
    174     public static final int SENSOR_ALL = 0x7F;
    175 
    176     /**
    177      * Smallest sensor ID
    178      *
    179      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    180      */
    181     @Deprecated
    182     public static final int SENSOR_MIN = SENSOR_ORIENTATION;
    183 
    184     /**
    185      * Largest sensor ID
    186      *
    187      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    188      */
    189     @Deprecated
    190     public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1);
    191 
    192 
    193     /**
    194      * Index of the X value in the array returned by
    195      * {@link android.hardware.SensorListener#onSensorChanged}
    196      *
    197      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    198      */
    199     @Deprecated
    200     public static final int DATA_X = 0;
    201 
    202     /**
    203      * Index of the Y value in the array returned by
    204      * {@link android.hardware.SensorListener#onSensorChanged}
    205      *
    206      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    207      */
    208     @Deprecated
    209     public static final int DATA_Y = 1;
    210 
    211     /**
    212      * Index of the Z value in the array returned by
    213      * {@link android.hardware.SensorListener#onSensorChanged}
    214      *
    215      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    216      */
    217     @Deprecated
    218     public static final int DATA_Z = 2;
    219 
    220     /**
    221      * Offset to the untransformed values in the array returned by
    222      * {@link android.hardware.SensorListener#onSensorChanged}
    223      *
    224      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    225      */
    226     @Deprecated
    227     public static final int RAW_DATA_INDEX = 3;
    228 
    229     /**
    230      * Index of the untransformed X value in the array returned by
    231      * {@link android.hardware.SensorListener#onSensorChanged}
    232      *
    233      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    234      */
    235     @Deprecated
    236     public static final int RAW_DATA_X = 3;
    237 
    238     /**
    239      * Index of the untransformed Y value in the array returned by
    240      * {@link android.hardware.SensorListener#onSensorChanged}
    241      *
    242      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    243      */
    244     @Deprecated
    245     public static final int RAW_DATA_Y = 4;
    246 
    247     /**
    248      * Index of the untransformed Z value in the array returned by
    249      * {@link android.hardware.SensorListener#onSensorChanged}
    250      *
    251      * @deprecated use {@link android.hardware.Sensor Sensor} instead.
    252      */
    253     @Deprecated
    254     public static final int RAW_DATA_Z = 5;
    255 
    256     /** Standard gravity (g) on Earth. This value is equivalent to 1G */
    257     public static final float STANDARD_GRAVITY = 9.80665f;
    258 
    259     /** Sun's gravity in SI units (m/s^2) */
    260     public static final float GRAVITY_SUN             = 275.0f;
    261     /** Mercury's gravity in SI units (m/s^2) */
    262     public static final float GRAVITY_MERCURY         = 3.70f;
    263     /** Venus' gravity in SI units (m/s^2) */
    264     public static final float GRAVITY_VENUS           = 8.87f;
    265     /** Earth's gravity in SI units (m/s^2) */
    266     public static final float GRAVITY_EARTH           = 9.80665f;
    267     /** The Moon's gravity in SI units (m/s^2) */
    268     public static final float GRAVITY_MOON            = 1.6f;
    269     /** Mars' gravity in SI units (m/s^2) */
    270     public static final float GRAVITY_MARS            = 3.71f;
    271     /** Jupiter's gravity in SI units (m/s^2) */
    272     public static final float GRAVITY_JUPITER         = 23.12f;
    273     /** Saturn's gravity in SI units (m/s^2) */
    274     public static final float GRAVITY_SATURN          = 8.96f;
    275     /** Uranus' gravity in SI units (m/s^2) */
    276     public static final float GRAVITY_URANUS          = 8.69f;
    277     /** Neptune's gravity in SI units (m/s^2) */
    278     public static final float GRAVITY_NEPTUNE         = 11.0f;
    279     /** Pluto's gravity in SI units (m/s^2) */
    280     public static final float GRAVITY_PLUTO           = 0.6f;
    281     /** Gravity (estimate) on the first Death Star in Empire units (m/s^2) */
    282     public static final float GRAVITY_DEATH_STAR_I    = 0.000000353036145f;
    283     /** Gravity on the island */
    284     public static final float GRAVITY_THE_ISLAND      = 4.815162342f;
    285 
    286 
    287     /** Maximum magnetic field on Earth's surface */
    288     public static final float MAGNETIC_FIELD_EARTH_MAX = 60.0f;
    289     /** Minimum magnetic field on Earth's surface */
    290     public static final float MAGNETIC_FIELD_EARTH_MIN = 30.0f;
    291 
    292 
    293     /** Standard atmosphere, or average sea-level pressure in hPa (millibar) */
    294     public static final float PRESSURE_STANDARD_ATMOSPHERE = 1013.25f;
    295 
    296 
    297     /** Maximum luminance of sunlight in lux */
    298     public static final float LIGHT_SUNLIGHT_MAX = 120000.0f;
    299     /** luminance of sunlight in lux */
    300     public static final float LIGHT_SUNLIGHT     = 110000.0f;
    301     /** luminance in shade in lux */
    302     public static final float LIGHT_SHADE        = 20000.0f;
    303     /** luminance under an overcast sky in lux */
    304     public static final float LIGHT_OVERCAST     = 10000.0f;
    305     /** luminance at sunrise in lux */
    306     public static final float LIGHT_SUNRISE      = 400.0f;
    307     /** luminance under a cloudy sky in lux */
    308     public static final float LIGHT_CLOUDY       = 100.0f;
    309     /** luminance at night with full moon in lux */
    310     public static final float LIGHT_FULLMOON     = 0.25f;
    311     /** luminance at night with no moon in lux*/
    312     public static final float LIGHT_NO_MOON      = 0.001f;
    313 
    314 
    315     /** get sensor data as fast as possible */
    316     public static final int SENSOR_DELAY_FASTEST = 0;
    317     /** rate suitable for games */
    318     public static final int SENSOR_DELAY_GAME = 1;
    319     /** rate suitable for the user interface  */
    320     public static final int SENSOR_DELAY_UI = 2;
    321     /** rate (default) suitable for screen orientation changes */
    322     public static final int SENSOR_DELAY_NORMAL = 3;
    323 
    324 
    325     /**
    326       * The values returned by this sensor cannot be trusted because the sensor
    327       * had no contact with what it was measuring (for example, the heart rate
    328       * monitor is not in contact with the user).
    329       */
    330     public static final int SENSOR_STATUS_NO_CONTACT = -1;
    331 
    332     /**
    333      * The values returned by this sensor cannot be trusted, calibration is
    334      * needed or the environment doesn't allow readings
    335      */
    336     public static final int SENSOR_STATUS_UNRELIABLE = 0;
    337 
    338     /**
    339      * This sensor is reporting data with low accuracy, calibration with the
    340      * environment is needed
    341      */
    342     public static final int SENSOR_STATUS_ACCURACY_LOW = 1;
    343 
    344     /**
    345      * This sensor is reporting data with an average level of accuracy,
    346      * calibration with the environment may improve the readings
    347      */
    348     public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2;
    349 
    350     /** This sensor is reporting data with maximum accuracy */
    351     public static final int SENSOR_STATUS_ACCURACY_HIGH = 3;
    352 
    353     /** see {@link #remapCoordinateSystem} */
    354     public static final int AXIS_X = 1;
    355     /** see {@link #remapCoordinateSystem} */
    356     public static final int AXIS_Y = 2;
    357     /** see {@link #remapCoordinateSystem} */
    358     public static final int AXIS_Z = 3;
    359     /** see {@link #remapCoordinateSystem} */
    360     public static final int AXIS_MINUS_X = AXIS_X | 0x80;
    361     /** see {@link #remapCoordinateSystem} */
    362     public static final int AXIS_MINUS_Y = AXIS_Y | 0x80;
    363     /** see {@link #remapCoordinateSystem} */
    364     public static final int AXIS_MINUS_Z = AXIS_Z | 0x80;
    365 
    366 
    367     /**
    368      * {@hide}
    369      */
    370     public SensorManager() {
    371     }
    372 
    373     /**
    374      * Gets the full list of sensors that are available.
    375      * @hide
    376      */
    377     protected abstract List<Sensor> getFullSensorList();
    378 
    379     /**
    380      * Gets the full list of dynamic sensors that are available.
    381      * @hide
    382      */
    383     protected abstract List<Sensor> getFullDynamicSensorList();
    384 
    385     /**
    386      * @return available sensors.
    387      * @deprecated This method is deprecated, use
    388      *             {@link SensorManager#getSensorList(int)} instead
    389      */
    390     @Deprecated
    391     public int getSensors() {
    392         return getLegacySensorManager().getSensors();
    393     }
    394 
    395     /**
    396      * Use this method to get the list of available sensors of a certain type.
    397      * Make multiple calls to get sensors of different types or use
    398      * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all the
    399      * sensors.
    400      *
    401      * <p class="note">
    402      * NOTE: Both wake-up and non wake-up sensors matching the given type are
    403      * returned. Check {@link Sensor#isWakeUpSensor()} to know the wake-up properties
    404      * of the returned {@link Sensor}.
    405      * </p>
    406      *
    407      * @param type
    408      *        of sensors requested
    409      *
    410      * @return a list of sensors matching the asked type.
    411      *
    412      * @see #getDefaultSensor(int)
    413      * @see Sensor
    414      */
    415     public List<Sensor> getSensorList(int type) {
    416         // cache the returned lists the first time
    417         List<Sensor> list;
    418         final List<Sensor> fullList = getFullSensorList();
    419         synchronized (mSensorListByType) {
    420             list = mSensorListByType.get(type);
    421             if (list == null) {
    422                 if (type == Sensor.TYPE_ALL) {
    423                     list = fullList;
    424                 } else {
    425                     list = new ArrayList<Sensor>();
    426                     for (Sensor i : fullList) {
    427                         if (i.getType() == type)
    428                             list.add(i);
    429                     }
    430                 }
    431                 list = Collections.unmodifiableList(list);
    432                 mSensorListByType.append(type, list);
    433             }
    434         }
    435         return list;
    436     }
    437 
    438     /**
    439      * Use this method to get a list of available dynamic sensors of a certain type.
    440      * Make multiple calls to get sensors of different types or use
    441      * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all dynamic sensors.
    442      *
    443      * <p class="note">
    444      * NOTE: Both wake-up and non wake-up sensors matching the given type are
    445      * returned. Check {@link Sensor#isWakeUpSensor()} to know the wake-up properties
    446      * of the returned {@link Sensor}.
    447      * </p>
    448      *
    449      * @param type of sensors requested
    450      *
    451      * @return a list of dynamic sensors matching the requested type.
    452      *
    453      * @see Sensor
    454      */
    455     public List<Sensor> getDynamicSensorList(int type) {
    456         // cache the returned lists the first time
    457         final List<Sensor> fullList = getFullDynamicSensorList();
    458         if (type == Sensor.TYPE_ALL) {
    459             return Collections.unmodifiableList(fullList);
    460         } else {
    461             List<Sensor> list = new ArrayList();
    462             for (Sensor i : fullList) {
    463                 if (i.getType() == type)
    464                     list.add(i);
    465             }
    466             return Collections.unmodifiableList(list);
    467         }
    468     }
    469 
    470     /**
    471      * Use this method to get the default sensor for a given type. Note that the
    472      * returned sensor could be a composite sensor, and its data could be
    473      * averaged or filtered. If you need to access the raw sensors use
    474      * {@link SensorManager#getSensorList(int) getSensorList}.
    475      *
    476      * @param type
    477      *         of sensors requested
    478      *
    479      * @return the default sensor matching the requested type if one exists and the application
    480      *         has the necessary permissions, or null otherwise.
    481      *
    482      * @see #getSensorList(int)
    483      * @see Sensor
    484      */
    485     public Sensor getDefaultSensor(int type) {
    486         // TODO: need to be smarter, for now, just return the 1st sensor
    487         List<Sensor> l = getSensorList(type);
    488         boolean wakeUpSensor = false;
    489         // For the following sensor types, return a wake-up sensor. These types are by default
    490         // defined as wake-up sensors. For the rest of the SDK defined sensor types return a
    491         // non_wake-up version.
    492         if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION ||
    493                 type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE ||
    494                 type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE ||
    495                 type == Sensor.TYPE_WRIST_TILT_GESTURE) {
    496             wakeUpSensor = true;
    497         }
    498 
    499         for (Sensor sensor : l) {
    500             if (sensor.isWakeUpSensor() == wakeUpSensor) return sensor;
    501         }
    502         return null;
    503     }
    504 
    505     /**
    506      * Return a Sensor with the given type and wakeUp properties. If multiple sensors of this
    507      * type exist, any one of them may be returned.
    508      * <p>
    509      * For example,
    510      * <ul>
    511      *     <li>getDefaultSensor({@link Sensor#TYPE_ACCELEROMETER}, true) returns a wake-up accelerometer
    512      *     sensor if it exists. </li>
    513      *     <li>getDefaultSensor({@link Sensor#TYPE_PROXIMITY}, false) returns a non wake-up proximity
    514      *     sensor if it exists. </li>
    515      *     <li>getDefaultSensor({@link Sensor#TYPE_PROXIMITY}, true) returns a wake-up proximity sensor
    516      *     which is the same as the Sensor returned by {@link #getDefaultSensor(int)}. </li>
    517      * </ul>
    518      * </p>
    519      * <p class="note">
    520      * Note: Sensors like {@link Sensor#TYPE_PROXIMITY} and {@link Sensor#TYPE_SIGNIFICANT_MOTION}
    521      * are declared as wake-up sensors by default.
    522      * </p>
    523      * @param type
    524      *        type of sensor requested
    525      * @param wakeUp
    526      *        flag to indicate whether the Sensor is a wake-up or non wake-up sensor.
    527      * @return the default sensor matching the requested type and wakeUp properties if one exists
    528      *         and the application has the necessary permissions, or null otherwise.
    529      * @see Sensor#isWakeUpSensor()
    530      */
    531     public Sensor getDefaultSensor(int type, boolean wakeUp) {
    532         List<Sensor> l = getSensorList(type);
    533         for (Sensor sensor : l) {
    534             if (sensor.isWakeUpSensor() == wakeUp)
    535                 return sensor;
    536         }
    537         return null;
    538     }
    539 
    540     /**
    541      * Registers a listener for given sensors.
    542      *
    543      * @deprecated This method is deprecated, use
    544      *             {@link SensorManager#registerListener(SensorEventListener, Sensor, int)}
    545      *             instead.
    546      *
    547      * @param listener
    548      *        sensor listener object
    549      *
    550      * @param sensors
    551      *        a bit masks of the sensors to register to
    552      *
    553      * @return <code>true</code> if the sensor is supported and successfully
    554      *         enabled
    555      */
    556     @Deprecated
    557     public boolean registerListener(SensorListener listener, int sensors) {
    558         return registerListener(listener, sensors, SENSOR_DELAY_NORMAL);
    559     }
    560 
    561     /**
    562      * Registers a SensorListener for given sensors.
    563      *
    564      * @deprecated This method is deprecated, use
    565      *             {@link SensorManager#registerListener(SensorEventListener, Sensor, int)}
    566      *             instead.
    567      *
    568      * @param listener
    569      *        sensor listener object
    570      *
    571      * @param sensors
    572      *        a bit masks of the sensors to register to
    573      *
    574      * @param rate
    575      *        rate of events. This is only a hint to the system. events may be
    576      *        received faster or slower than the specified rate. Usually events
    577      *        are received faster. The value must be one of
    578      *        {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    579      *        {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}.
    580      *
    581      * @return <code>true</code> if the sensor is supported and successfully
    582      *         enabled
    583      */
    584     @Deprecated
    585     public boolean registerListener(SensorListener listener, int sensors, int rate) {
    586         return getLegacySensorManager().registerListener(listener, sensors, rate);
    587     }
    588 
    589     /**
    590      * Unregisters a listener for all sensors.
    591      *
    592      * @deprecated This method is deprecated, use
    593      *             {@link SensorManager#unregisterListener(SensorEventListener)}
    594      *             instead.
    595      *
    596      * @param listener
    597      *        a SensorListener object
    598      */
    599     @Deprecated
    600     public void unregisterListener(SensorListener listener) {
    601         unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW);
    602     }
    603 
    604     /**
    605      * Unregisters a listener for the sensors with which it is registered.
    606      *
    607      * @deprecated This method is deprecated, use
    608      *             {@link SensorManager#unregisterListener(SensorEventListener, Sensor)}
    609      *             instead.
    610      *
    611      * @param listener
    612      *        a SensorListener object
    613      *
    614      * @param sensors
    615      *        a bit masks of the sensors to unregister from
    616      */
    617     @Deprecated
    618     public void unregisterListener(SensorListener listener, int sensors) {
    619         getLegacySensorManager().unregisterListener(listener, sensors);
    620     }
    621 
    622     /**
    623      * Unregisters a listener for the sensors with which it is registered.
    624      *
    625      * <p class="note"></p>
    626      * Note: Don't use this method with a one shot trigger sensor such as
    627      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
    628      * Use {@link #cancelTriggerSensor(TriggerEventListener, Sensor)} instead.
    629      * </p>
    630      *
    631      * @param listener
    632      *        a SensorEventListener object
    633      *
    634      * @param sensor
    635      *        the sensor to unregister from
    636      *
    637      * @see #unregisterListener(SensorEventListener)
    638      * @see #registerListener(SensorEventListener, Sensor, int)
    639      */
    640     public void unregisterListener(SensorEventListener listener, Sensor sensor) {
    641         if (listener == null || sensor == null) {
    642             return;
    643         }
    644 
    645         unregisterListenerImpl(listener, sensor);
    646     }
    647 
    648     /**
    649      * Unregisters a listener for all sensors.
    650      *
    651      * @param listener
    652      *        a SensorListener object
    653      *
    654      * @see #unregisterListener(SensorEventListener, Sensor)
    655      * @see #registerListener(SensorEventListener, Sensor, int)
    656      *
    657      */
    658     public void unregisterListener(SensorEventListener listener) {
    659         if (listener == null) {
    660             return;
    661         }
    662 
    663         unregisterListenerImpl(listener, null);
    664     }
    665 
    666     /** @hide */
    667     protected abstract void unregisterListenerImpl(SensorEventListener listener, Sensor sensor);
    668 
    669     /**
    670      * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
    671      * sensor at the given sampling frequency.
    672      * <p>
    673      * The events will be delivered to the provided {@code SensorEventListener} as soon as they are
    674      * available. To reduce the power consumption, applications can use
    675      * {@link #registerListener(SensorEventListener, Sensor, int, int)} instead and specify a
    676      * positive non-zero maximum reporting latency.
    677      * </p>
    678      * <p>
    679      * In the case of non-wake-up sensors, the events are only delivered while the Application
    680      * Processor (AP) is not in suspend mode. See {@link Sensor#isWakeUpSensor()} for more details.
    681      * To ensure delivery of events from non-wake-up sensors even when the screen is OFF, the
    682      * application registering to the sensor must hold a partial wake-lock to keep the AP awake,
    683      * otherwise some events might be lost while the AP is asleep. Note that although events might
    684      * be lost while the AP is asleep, the sensor will still consume power if it is not explicitly
    685      * deactivated by the application. Applications must unregister their {@code
    686      * SensorEventListener}s in their activity's {@code onPause()} method to avoid consuming power
    687      * while the device is inactive.  See {@link #registerListener(SensorEventListener, Sensor, int,
    688      * int)} for more details on hardware FIFO (queueing) capabilities and when some sensor events
    689      * might be lost.
    690      * </p>
    691      * <p>
    692      * In the case of wake-up sensors, each event generated by the sensor will cause the AP to
    693      * wake-up, ensuring that each event can be delivered. Because of this, registering to a wake-up
    694      * sensor has very significant power implications. Call {@link Sensor#isWakeUpSensor()} to check
    695      * whether a sensor is a wake-up sensor. See
    696      * {@link #registerListener(SensorEventListener, Sensor, int, int)} for information on how to
    697      * reduce the power impact of registering to wake-up sensors.
    698      * </p>
    699      * <p class="note">
    700      * Note: Don't use this method with one-shot trigger sensors such as
    701      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
    702      * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. Use
    703      * {@link Sensor#getReportingMode()} to obtain the reporting mode of a given sensor.
    704      * </p>
    705      *
    706      * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object.
    707      * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
    708      * @param samplingPeriodUs The rate {@link android.hardware.SensorEvent sensor events} are
    709      *            delivered at. This is only a hint to the system. Events may be received faster or
    710      *            slower than the specified rate. Usually events are received faster. The value must
    711      *            be one of {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    712      *            {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST} or, the desired delay
    713      *            between events in microseconds. Specifying the delay in microseconds only works
    714      *            from Android 2.3 (API level 9) onwards. For earlier releases, you must use one of
    715      *            the {@code SENSOR_DELAY_*} constants.
    716      * @return <code>true</code> if the sensor is supported and successfully enabled.
    717      * @see #registerListener(SensorEventListener, Sensor, int, Handler)
    718      * @see #unregisterListener(SensorEventListener)
    719      * @see #unregisterListener(SensorEventListener, Sensor)
    720      */
    721     public boolean registerListener(SensorEventListener listener, Sensor sensor,
    722             int samplingPeriodUs) {
    723         return registerListener(listener, sensor, samplingPeriodUs, null);
    724     }
    725 
    726     /**
    727      * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
    728      * sensor at the given sampling frequency and the given maximum reporting latency.
    729      * <p>
    730      * This function is similar to {@link #registerListener(SensorEventListener, Sensor, int)} but
    731      * it allows events to stay temporarily in the hardware FIFO (queue) before being delivered. The
    732      * events can be stored in the hardware FIFO up to {@code maxReportLatencyUs} microseconds. Once
    733      * one of the events in the FIFO needs to be reported, all of the events in the FIFO are
    734      * reported sequentially. This means that some events will be reported before the maximum
    735      * reporting latency has elapsed.
    736      * </p><p>
    737      * When {@code maxReportLatencyUs} is 0, the call is equivalent to a call to
    738      * {@link #registerListener(SensorEventListener, Sensor, int)}, as it requires the events to be
    739      * delivered as soon as possible.
    740      * </p><p>
    741      * When {@code sensor.maxFifoEventCount()} is 0, the sensor does not use a FIFO, so the call
    742      * will also be equivalent to {@link #registerListener(SensorEventListener, Sensor, int)}.
    743      * </p><p>
    744      * Setting {@code maxReportLatencyUs} to a positive value allows to reduce the number of
    745      * interrupts the AP (Application Processor) receives, hence reducing power consumption, as the
    746      * AP can switch to a lower power state while the sensor is capturing the data. This is
    747      * especially important when registering to wake-up sensors, for which each interrupt causes the
    748      * AP to wake up if it was in suspend mode. See {@link Sensor#isWakeUpSensor()} for more
    749      * information on wake-up sensors.
    750      * </p>
    751      * <p class="note">
    752      * </p>
    753      * Note: Don't use this method with one-shot trigger sensors such as
    754      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
    755      * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
    756      *
    757      * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
    758      *            that will receive the sensor events. If the application is interested in receiving
    759      *            flush complete notifications, it should register with
    760      *            {@link android.hardware.SensorEventListener SensorEventListener2} instead.
    761      * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
    762      * @param samplingPeriodUs The desired delay between two consecutive events in microseconds.
    763      *            This is only a hint to the system. Events may be received faster or slower than
    764      *            the specified rate. Usually events are received faster. Can be one of
    765      *            {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    766      *            {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
    767      *            microseconds.
    768      * @param maxReportLatencyUs Maximum time in microseconds that events can be delayed before
    769      *            being reported to the application. A large value allows reducing the power
    770      *            consumption associated with the sensor. If maxReportLatencyUs is set to zero,
    771      *            events are delivered as soon as they are available, which is equivalent to calling
    772      *            {@link #registerListener(SensorEventListener, Sensor, int)}.
    773      * @return <code>true</code> if the sensor is supported and successfully enabled.
    774      * @see #registerListener(SensorEventListener, Sensor, int)
    775      * @see #unregisterListener(SensorEventListener)
    776      * @see #flush(SensorEventListener)
    777      */
    778     public boolean registerListener(SensorEventListener listener, Sensor sensor,
    779             int samplingPeriodUs, int maxReportLatencyUs) {
    780         int delay = getDelay(samplingPeriodUs);
    781         return registerListenerImpl(listener, sensor, delay, null, maxReportLatencyUs, 0);
    782     }
    783 
    784     /**
    785      * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
    786      * sensor. Events are delivered in continuous mode as soon as they are available. To reduce the
    787      * power consumption, applications can use
    788      * {@link #registerListener(SensorEventListener, Sensor, int, int)} instead and specify a
    789      * positive non-zero maximum reporting latency.
    790      * <p class="note">
    791      * </p>
    792      * Note: Don't use this method with a one shot trigger sensor such as
    793      * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
    794      * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
    795      *
    796      * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object.
    797      * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
    798      * @param samplingPeriodUs The rate {@link android.hardware.SensorEvent sensor events} are
    799      *            delivered at. This is only a hint to the system. Events may be received faster or
    800      *            slower than the specified rate. Usually events are received faster. The value must
    801      *            be one of {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    802      *            {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST} or, the desired
    803      *            delay between events in microseconds. Specifying the delay in microseconds only
    804      *            works from Android 2.3 (API level 9) onwards. For earlier releases, you must use
    805      *            one of the {@code SENSOR_DELAY_*} constants.
    806      * @param handler The {@link android.os.Handler Handler} the {@link android.hardware.SensorEvent
    807      *            sensor events} will be delivered to.
    808      * @return <code>true</code> if the sensor is supported and successfully enabled.
    809      * @see #registerListener(SensorEventListener, Sensor, int)
    810      * @see #unregisterListener(SensorEventListener)
    811      * @see #unregisterListener(SensorEventListener, Sensor)
    812      */
    813     public boolean registerListener(SensorEventListener listener, Sensor sensor,
    814             int samplingPeriodUs, Handler handler) {
    815         int delay = getDelay(samplingPeriodUs);
    816         return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
    817     }
    818 
    819     /**
    820      * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
    821      * sensor at the given sampling frequency and the given maximum reporting latency.
    822      *
    823      * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
    824      *            that will receive the sensor events. If the application is interested in receiving
    825      *            flush complete notifications, it should register with
    826      *            {@link android.hardware.SensorEventListener SensorEventListener2} instead.
    827      * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
    828      * @param samplingPeriodUs The desired delay between two consecutive events in microseconds.
    829      *            This is only a hint to the system. Events may be received faster or slower than
    830      *            the specified rate. Usually events are received faster. Can be one of
    831      *            {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
    832      *            {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
    833      *            microseconds.
    834      * @param maxReportLatencyUs Maximum time in microseconds that events can be delayed before
    835      *            being reported to the application. A large value allows reducing the power
    836      *            consumption associated with the sensor. If maxReportLatencyUs is set to zero,
    837      *            events are delivered as soon as they are available, which is equivalent to calling
    838      *            {@link #registerListener(SensorEventListener, Sensor, int)}.
    839      * @param handler The {@link android.os.Handler Handler} the {@link android.hardware.SensorEvent
    840      *            sensor events} will be delivered to.
    841      * @return <code>true</code> if the sensor is supported and successfully enabled.
    842      * @see #registerListener(SensorEventListener, Sensor, int, int)
    843      */
    844     public boolean registerListener(SensorEventListener listener, Sensor sensor, int samplingPeriodUs,
    845             int maxReportLatencyUs, Handler handler) {
    846         int delayUs = getDelay(samplingPeriodUs);
    847         return registerListenerImpl(listener, sensor, delayUs, handler, maxReportLatencyUs, 0);
    848     }
    849 
    850     /** @hide */
    851     protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
    852             int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags);
    853 
    854 
    855     /**
    856      * Flushes the FIFO of all the sensors registered for this listener. If there are events
    857      * in the FIFO of the sensor, they are returned as if the maxReportLantecy of the FIFO has
    858      * expired. Events are returned in the usual way through the SensorEventListener.
    859      * This call doesn't affect the maxReportLantecy for this sensor. This call is asynchronous and
    860      * returns immediately.
    861      * {@link android.hardware.SensorEventListener2#onFlushCompleted onFlushCompleted} is called
    862      * after all the events in the batch at the time of calling this method have been delivered
    863      * successfully. If the hardware doesn't support flush, it still returns true and a trivial
    864      * flush complete event is sent after the current event for all the clients registered for this
    865      * sensor.
    866      *
    867      * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
    868      *        which was previously used in a registerListener call.
    869      * @return <code>true</code> if the flush is initiated successfully on all the sensors
    870      *         registered for this listener, false if no sensor is previously registered for this
    871      *         listener or flush on one of the sensors fails.
    872      * @see #registerListener(SensorEventListener, Sensor, int, int)
    873      * @throws IllegalArgumentException when listener is null.
    874      */
    875     public boolean flush(SensorEventListener listener) {
    876         return flushImpl(listener);
    877     }
    878 
    879     /** @hide */
    880     protected abstract boolean flushImpl(SensorEventListener listener);
    881 
    882 
    883     /**
    884      * Used for receiving notifications from the SensorManager when dynamic sensors are connected or
    885      * disconnected.
    886      */
    887     public static abstract class DynamicSensorCallback {
    888         /**
    889          * Called when there is a dynamic sensor being connected to the system.
    890          *
    891          * @param sensor the newly connected sensor. See {@link android.hardware.Sensor Sensor}.
    892          */
    893         public void onDynamicSensorConnected(Sensor sensor) {}
    894 
    895         /**
    896          * Called when there is a dynamic sensor being disconnected from the system.
    897          *
    898          * @param sensor the disconnected sensor. See {@link android.hardware.Sensor Sensor}.
    899          */
    900         public void onDynamicSensorDisconnected(Sensor sensor) {}
    901     }
    902 
    903 
    904     /**
    905      * Add a {@link android.hardware.SensorManager.DynamicSensorCallback
    906      * DynamicSensorCallback} to receive dynamic sensor connection callbacks. Repeat
    907      * registration with the already registered callback object will have no additional effect.
    908      *
    909      * @param callback An object that implements the
    910      *        {@link android.hardware.SensorManager.DynamicSensorCallback
    911      *        DynamicSensorCallback}
    912      *        interface for receiving callbacks.
    913      * @see #addDynamicSensorCallback(DynamicSensorCallback, Handler)
    914      *
    915      * @throws IllegalArgumentException when callback is null.
    916      */
    917     public void registerDynamicSensorCallback(DynamicSensorCallback callback) {
    918         registerDynamicSensorCallback(callback, null);
    919     }
    920 
    921     /**
    922      * Add a {@link android.hardware.SensorManager.DynamicSensorCallback
    923      * DynamicSensorCallback} to receive dynamic sensor connection callbacks. Repeat
    924      * registration with the already registered callback object will have no additional effect.
    925      *
    926      * @param callback An object that implements the
    927      *        {@link android.hardware.SensorManager.DynamicSensorCallback
    928      *        DynamicSensorCallback} interface for receiving callbacks.
    929      * @param handler The {@link android.os.Handler Handler} the {@link
    930      *        android.hardware.SensorManager.DynamicSensorCallback
    931      *        sensor connection events} will be delivered to.
    932      *
    933      * @throws IllegalArgumentException when callback is null.
    934      */
    935     public void registerDynamicSensorCallback(
    936             DynamicSensorCallback callback, Handler handler) {
    937         registerDynamicSensorCallbackImpl(callback, handler);
    938     }
    939 
    940     /**
    941      * Remove a {@link android.hardware.SensorManager.DynamicSensorCallback
    942      * DynamicSensorCallback} to stop sending dynamic sensor connection events to that
    943      * callback.
    944      *
    945      * @param callback An object that implements the
    946      *        {@link android.hardware.SensorManager.DynamicSensorCallback
    947      *        DynamicSensorCallback}
    948      *        interface for receiving callbacks.
    949      */
    950     public void unregisterDynamicSensorCallback(DynamicSensorCallback callback) {
    951         unregisterDynamicSensorCallbackImpl(callback);
    952     }
    953 
    954     /**
    955      * Tell if dynamic sensor discovery feature is supported by system.
    956      *
    957      * @return <code>true</code> if dynamic sensor discovery is supported, <code>false</code>
    958      * otherwise.
    959      */
    960     public boolean isDynamicSensorDiscoverySupported() {
    961         List<Sensor> sensors = getSensorList(Sensor.TYPE_DYNAMIC_SENSOR_META);
    962         return sensors.size() > 0;
    963     }
    964 
    965     /** @hide */
    966     protected abstract void registerDynamicSensorCallbackImpl(
    967             DynamicSensorCallback callback, Handler handler);
    968 
    969     /** @hide */
    970     protected abstract void unregisterDynamicSensorCallbackImpl(
    971             DynamicSensorCallback callback);
    972 
    973     /**
    974      * <p>
    975      * Computes the inclination matrix <b>I</b> as well as the rotation matrix
    976      * <b>R</b> transforming a vector from the device coordinate system to the
    977      * world's coordinate system which is defined as a direct orthonormal basis,
    978      * where:
    979      * </p>
    980      *
    981      * <ul>
    982      * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
    983      * the ground at the device's current location and roughly points East).</li>
    984      * <li>Y is tangential to the ground at the device's current location and
    985      * points towards the magnetic North Pole.</li>
    986      * <li>Z points towards the sky and is perpendicular to the ground.</li>
    987      * </ul>
    988      *
    989      * <p>
    990      * <center><img src="../../../images/axis_globe.png"
    991      * alt="World coordinate-system diagram." border="0" /></center>
    992      * </p>
    993      *
    994      * <p>
    995      * <hr>
    996      * <p>
    997      * By definition:
    998      * <p>
    999      * [0 0 g] = <b>R</b> * <b>gravity</b> (g = magnitude of gravity)
   1000      * <p>
   1001      * [0 m 0] = <b>I</b> * <b>R</b> * <b>geomagnetic</b> (m = magnitude of
   1002      * geomagnetic field)
   1003      * <p>
   1004      * <b>R</b> is the identity matrix when the device is aligned with the
   1005      * world's coordinate system, that is, when the device's X axis points
   1006      * toward East, the Y axis points to the North Pole and the device is facing
   1007      * the sky.
   1008      *
   1009      * <p>
   1010      * <b>I</b> is a rotation matrix transforming the geomagnetic vector into
   1011      * the same coordinate space as gravity (the world's coordinate space).
   1012      * <b>I</b> is a simple rotation around the X axis. The inclination angle in
   1013      * radians can be computed with {@link #getInclination}.
   1014      * <hr>
   1015      *
   1016      * <p>
   1017      * Each matrix is returned either as a 3x3 or 4x4 row-major matrix depending
   1018      * on the length of the passed array:
   1019      * <p>
   1020      * <u>If the array length is 16:</u>
   1021      *
   1022      * <pre>
   1023      *   /  M[ 0]   M[ 1]   M[ 2]   M[ 3]  \
   1024      *   |  M[ 4]   M[ 5]   M[ 6]   M[ 7]  |
   1025      *   |  M[ 8]   M[ 9]   M[10]   M[11]  |
   1026      *   \  M[12]   M[13]   M[14]   M[15]  /
   1027      *</pre>
   1028      *
   1029      * This matrix is ready to be used by OpenGL ES's
   1030      * {@link javax.microedition.khronos.opengles.GL10#glLoadMatrixf(float[], int)
   1031      * glLoadMatrixf(float[], int)}.
   1032      * <p>
   1033      * Note that because OpenGL matrices are column-major matrices you must
   1034      * transpose the matrix before using it. However, since the matrix is a
   1035      * rotation matrix, its transpose is also its inverse, conveniently, it is
   1036      * often the inverse of the rotation that is needed for rendering; it can
   1037      * therefore be used with OpenGL ES directly.
   1038      * <p>
   1039      * Also note that the returned matrices always have this form:
   1040      *
   1041      * <pre>
   1042      *   /  M[ 0]   M[ 1]   M[ 2]   0  \
   1043      *   |  M[ 4]   M[ 5]   M[ 6]   0  |
   1044      *   |  M[ 8]   M[ 9]   M[10]   0  |
   1045      *   \      0       0       0   1  /
   1046      *</pre>
   1047      *
   1048      * <p>
   1049      * <u>If the array length is 9:</u>
   1050      *
   1051      * <pre>
   1052      *   /  M[ 0]   M[ 1]   M[ 2]  \
   1053      *   |  M[ 3]   M[ 4]   M[ 5]  |
   1054      *   \  M[ 6]   M[ 7]   M[ 8]  /
   1055      *</pre>
   1056      *
   1057      * <hr>
   1058      * <p>
   1059      * The inverse of each matrix can be computed easily by taking its
   1060      * transpose.
   1061      *
   1062      * <p>
   1063      * The matrices returned by this function are meaningful only when the
   1064      * device is not free-falling and it is not close to the magnetic north. If
   1065      * the device is accelerating, or placed into a strong magnetic field, the
   1066      * returned matrices may be inaccurate.
   1067      *
   1068      * @param R
   1069      *        is an array of 9 floats holding the rotation matrix <b>R</b> when
   1070      *        this function returns. R can be null.
   1071      *        <p>
   1072      *
   1073      * @param I
   1074      *        is an array of 9 floats holding the rotation matrix <b>I</b> when
   1075      *        this function returns. I can be null.
   1076      *        <p>
   1077      *
   1078      * @param gravity
   1079      *        is an array of 3 floats containing the gravity vector expressed in
   1080      *        the device's coordinate. You can simply use the
   1081      *        {@link android.hardware.SensorEvent#values values} returned by a
   1082      *        {@link android.hardware.SensorEvent SensorEvent} of a
   1083      *        {@link android.hardware.Sensor Sensor} of type
   1084      *        {@link android.hardware.Sensor#TYPE_ACCELEROMETER
   1085      *        TYPE_ACCELEROMETER}.
   1086      *        <p>
   1087      *
   1088      * @param geomagnetic
   1089      *        is an array of 3 floats containing the geomagnetic vector
   1090      *        expressed in the device's coordinate. You can simply use the
   1091      *        {@link android.hardware.SensorEvent#values values} returned by a
   1092      *        {@link android.hardware.SensorEvent SensorEvent} of a
   1093      *        {@link android.hardware.Sensor Sensor} of type
   1094      *        {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD
   1095      *        TYPE_MAGNETIC_FIELD}.
   1096      *
   1097      * @return <code>true</code> on success, <code>false</code> on failure (for
   1098      *         instance, if the device is in free fall). Free fall is defined as
   1099      *         condition when the magnitude of the gravity is less than 1/10 of
   1100      *         the nominal value. On failure the output matrices are not modified.
   1101      *
   1102      * @see #getInclination(float[])
   1103      * @see #getOrientation(float[], float[])
   1104      * @see #remapCoordinateSystem(float[], int, int, float[])
   1105      */
   1106 
   1107     public static boolean getRotationMatrix(float[] R, float[] I,
   1108             float[] gravity, float[] geomagnetic) {
   1109         // TODO: move this to native code for efficiency
   1110         float Ax = gravity[0];
   1111         float Ay = gravity[1];
   1112         float Az = gravity[2];
   1113 
   1114         final float normsqA = (Ax*Ax + Ay*Ay + Az*Az);
   1115         final float g = 9.81f;
   1116         final float freeFallGravitySquared = 0.01f * g * g;
   1117         if (normsqA < freeFallGravitySquared) {
   1118             // gravity less than 10% of normal value
   1119             return false;
   1120         }
   1121 
   1122         final float Ex = geomagnetic[0];
   1123         final float Ey = geomagnetic[1];
   1124         final float Ez = geomagnetic[2];
   1125         float Hx = Ey*Az - Ez*Ay;
   1126         float Hy = Ez*Ax - Ex*Az;
   1127         float Hz = Ex*Ay - Ey*Ax;
   1128         final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
   1129 
   1130         if (normH < 0.1f) {
   1131             // device is close to free fall (or in space?), or close to
   1132             // magnetic north pole. Typical values are  > 100.
   1133             return false;
   1134         }
   1135         final float invH = 1.0f / normH;
   1136         Hx *= invH;
   1137         Hy *= invH;
   1138         Hz *= invH;
   1139         final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az);
   1140         Ax *= invA;
   1141         Ay *= invA;
   1142         Az *= invA;
   1143         final float Mx = Ay*Hz - Az*Hy;
   1144         final float My = Az*Hx - Ax*Hz;
   1145         final float Mz = Ax*Hy - Ay*Hx;
   1146         if (R != null) {
   1147             if (R.length == 9) {
   1148                 R[0] = Hx;     R[1] = Hy;     R[2] = Hz;
   1149                 R[3] = Mx;     R[4] = My;     R[5] = Mz;
   1150                 R[6] = Ax;     R[7] = Ay;     R[8] = Az;
   1151             } else if (R.length == 16) {
   1152                 R[0]  = Hx;    R[1]  = Hy;    R[2]  = Hz;   R[3]  = 0;
   1153                 R[4]  = Mx;    R[5]  = My;    R[6]  = Mz;   R[7]  = 0;
   1154                 R[8]  = Ax;    R[9]  = Ay;    R[10] = Az;   R[11] = 0;
   1155                 R[12] = 0;     R[13] = 0;     R[14] = 0;    R[15] = 1;
   1156             }
   1157         }
   1158         if (I != null) {
   1159             // compute the inclination matrix by projecting the geomagnetic
   1160             // vector onto the Z (gravity) and X (horizontal component
   1161             // of geomagnetic vector) axes.
   1162             final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez);
   1163             final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE;
   1164             final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE;
   1165             if (I.length == 9) {
   1166                 I[0] = 1;     I[1] = 0;     I[2] = 0;
   1167                 I[3] = 0;     I[4] = c;     I[5] = s;
   1168                 I[6] = 0;     I[7] =-s;     I[8] = c;
   1169             } else if (I.length == 16) {
   1170                 I[0] = 1;     I[1] = 0;     I[2] = 0;
   1171                 I[4] = 0;     I[5] = c;     I[6] = s;
   1172                 I[8] = 0;     I[9] =-s;     I[10]= c;
   1173                 I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0;
   1174                 I[15] = 1;
   1175             }
   1176         }
   1177         return true;
   1178     }
   1179 
   1180     /**
   1181      * Computes the geomagnetic inclination angle in radians from the
   1182      * inclination matrix <b>I</b> returned by {@link #getRotationMatrix}.
   1183      *
   1184      * @param I
   1185      *        inclination matrix see {@link #getRotationMatrix}.
   1186      *
   1187      * @return The geomagnetic inclination angle in radians.
   1188      *
   1189      * @see #getRotationMatrix(float[], float[], float[], float[])
   1190      * @see #getOrientation(float[], float[])
   1191      * @see GeomagneticField
   1192      *
   1193      */
   1194     public static float getInclination(float[] I) {
   1195         if (I.length == 9) {
   1196             return (float)Math.atan2(I[5], I[4]);
   1197         } else {
   1198             return (float)Math.atan2(I[6], I[5]);
   1199         }
   1200     }
   1201 
   1202     /**
   1203      * <p>
   1204      * Rotates the supplied rotation matrix so it is expressed in a different
   1205      * coordinate system. This is typically used when an application needs to
   1206      * compute the three orientation angles of the device (see
   1207      * {@link #getOrientation}) in a different coordinate system.
   1208      * </p>
   1209      *
   1210      * <p>
   1211      * When the rotation matrix is used for drawing (for instance with OpenGL
   1212      * ES), it usually <b>doesn't need</b> to be transformed by this function,
   1213      * unless the screen is physically rotated, in which case you can use
   1214      * {@link android.view.Display#getRotation() Display.getRotation()} to
   1215      * retrieve the current rotation of the screen. Note that because the user
   1216      * is generally free to rotate their screen, you often should consider the
   1217      * rotation in deciding the parameters to use here.
   1218      * </p>
   1219      *
   1220      * <p>
   1221      * <u>Examples:</u>
   1222      * <p>
   1223      *
   1224      * <ul>
   1225      * <li>Using the camera (Y axis along the camera's axis) for an augmented
   1226      * reality application where the rotation angles are needed:</li>
   1227      *
   1228      * <p>
   1229      * <ul>
   1230      * <code>remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);</code>
   1231      * </ul>
   1232      * </p>
   1233      *
   1234      * <li>Using the device as a mechanical compass when rotation is
   1235      * {@link android.view.Surface#ROTATION_90 Surface.ROTATION_90}:</li>
   1236      *
   1237      * <p>
   1238      * <ul>
   1239      * <code>remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);</code>
   1240      * </ul>
   1241      * </p>
   1242      *
   1243      * Beware of the above example. This call is needed only to account for a
   1244      * rotation from its natural orientation when calculating the rotation
   1245      * angles (see {@link #getOrientation}). If the rotation matrix is also used
   1246      * for rendering, it may not need to be transformed, for instance if your
   1247      * {@link android.app.Activity Activity} is running in landscape mode.
   1248      * </ul>
   1249      *
   1250      * <p>
   1251      * Since the resulting coordinate system is orthonormal, only two axes need
   1252      * to be specified.
   1253      *
   1254      * @param inR
   1255      *        the rotation matrix to be transformed. Usually it is the matrix
   1256      *        returned by {@link #getRotationMatrix}.
   1257      *
   1258      * @param X
   1259      *        defines the axis of the new cooridinate system that coincide with the X axis of the
   1260      *        original coordinate system.
   1261      *
   1262      * @param Y
   1263      *        defines the axis of the new cooridinate system that coincide with the Y axis of the
   1264      *        original coordinate system.
   1265      *
   1266      * @param outR
   1267      *        the transformed rotation matrix. inR and outR should not be the same
   1268      *        array.
   1269      *
   1270      * @return <code>true</code> on success. <code>false</code> if the input
   1271      *         parameters are incorrect, for instance if X and Y define the same
   1272      *         axis. Or if inR and outR don't have the same length.
   1273      *
   1274      * @see #getRotationMatrix(float[], float[], float[], float[])
   1275      */
   1276 
   1277     public static boolean remapCoordinateSystem(float[] inR, int X, int Y,
   1278             float[] outR)
   1279     {
   1280         if (inR == outR) {
   1281             final float[] temp = mTempMatrix;
   1282             synchronized(temp) {
   1283                 // we don't expect to have a lot of contention
   1284                 if (remapCoordinateSystemImpl(inR, X, Y, temp)) {
   1285                     final int size = outR.length;
   1286                     for (int i=0 ; i<size ; i++)
   1287                         outR[i] = temp[i];
   1288                     return true;
   1289                 }
   1290             }
   1291         }
   1292         return remapCoordinateSystemImpl(inR, X, Y, outR);
   1293     }
   1294 
   1295     private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y,
   1296             float[] outR)
   1297     {
   1298         /*
   1299          * X and Y define a rotation matrix 'r':
   1300          *
   1301          *  (X==1)?((X&0x80)?-1:1):0    (X==2)?((X&0x80)?-1:1):0    (X==3)?((X&0x80)?-1:1):0
   1302          *  (Y==1)?((Y&0x80)?-1:1):0    (Y==2)?((Y&0x80)?-1:1):0    (Y==3)?((X&0x80)?-1:1):0
   1303          *                              r[0] ^ r[1]
   1304          *
   1305          * where the 3rd line is the vector product of the first 2 lines
   1306          *
   1307          */
   1308 
   1309         final int length = outR.length;
   1310         if (inR.length != length)
   1311             return false;   // invalid parameter
   1312         if ((X & 0x7C)!=0 || (Y & 0x7C)!=0)
   1313             return false;   // invalid parameter
   1314         if (((X & 0x3)==0) || ((Y & 0x3)==0))
   1315             return false;   // no axis specified
   1316         if ((X & 0x3) == (Y & 0x3))
   1317             return false;   // same axis specified
   1318 
   1319         // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y)
   1320         // this can be calculated by exclusive-or'ing X and Y; except for
   1321         // the sign inversion (+/-) which is calculated below.
   1322         int Z = X ^ Y;
   1323 
   1324         // extract the axis (remove the sign), offset in the range 0 to 2.
   1325         final int x = (X & 0x3)-1;
   1326         final int y = (Y & 0x3)-1;
   1327         final int z = (Z & 0x3)-1;
   1328 
   1329         // compute the sign of Z (whether it needs to be inverted)
   1330         final int axis_y = (z+1)%3;
   1331         final int axis_z = (z+2)%3;
   1332         if (((x^axis_y)|(y^axis_z)) != 0)
   1333             Z ^= 0x80;
   1334 
   1335         final boolean sx = (X>=0x80);
   1336         final boolean sy = (Y>=0x80);
   1337         final boolean sz = (Z>=0x80);
   1338 
   1339         // Perform R * r, in avoiding actual muls and adds.
   1340         final int rowLength = ((length==16)?4:3);
   1341         for (int j=0 ; j<3 ; j++) {
   1342             final int offset = j*rowLength;
   1343             for (int i=0 ; i<3 ; i++) {
   1344                 if (x==i)   outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0];
   1345                 if (y==i)   outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1];
   1346                 if (z==i)   outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2];
   1347             }
   1348         }
   1349         if (length == 16) {
   1350             outR[3] = outR[7] = outR[11] = outR[12] = outR[13] = outR[14] = 0;
   1351             outR[15] = 1;
   1352         }
   1353         return true;
   1354     }
   1355 
   1356     /**
   1357      * Computes the device's orientation based on the rotation matrix.
   1358      * <p>
   1359      * When it returns, the array values are as follows:
   1360      * <ul>
   1361      * <li>values[0]: <i>Azimuth</i>, angle of rotation about the -z axis.
   1362      *                This value represents the angle between the device's y
   1363      *                axis and the magnetic north pole. When facing north, this
   1364      *                angle is 0, when facing south, this angle is &pi;.
   1365      *                Likewise, when facing east, this angle is &pi;/2, and
   1366      *                when facing west, this angle is -&pi;/2. The range of
   1367      *                values is -&pi; to &pi;.</li>
   1368      * <li>values[1]: <i>Pitch</i>, angle of rotation about the x axis.
   1369      *                This value represents the angle between a plane parallel
   1370      *                to the device's screen and a plane parallel to the ground.
   1371      *                Assuming that the bottom edge of the device faces the
   1372      *                user and that the screen is face-up, tilting the top edge
   1373      *                of the device toward the ground creates a positive pitch
   1374      *                angle. The range of values is -&pi; to &pi;.</li>
   1375      * <li>values[2]: <i>Roll</i>, angle of rotation about the y axis. This
   1376      *                value represents the angle between a plane perpendicular
   1377      *                to the device's screen and a plane perpendicular to the
   1378      *                ground. Assuming that the bottom edge of the device faces
   1379      *                the user and that the screen is face-up, tilting the left
   1380      *                edge of the device toward the ground creates a positive
   1381      *                roll angle. The range of values is -&pi;/2 to &pi;/2.</li>
   1382      * </ul>
   1383      * <p>
   1384      * Applying these three rotations in the azimuth, pitch, roll order
   1385      * transforms an identity matrix to the rotation matrix passed into this
   1386      * method. Also, note that all three orientation angles are expressed in
   1387      * <b>radians</b>.
   1388      *
   1389      * @param R
   1390      *        rotation matrix see {@link #getRotationMatrix}.
   1391      *
   1392      * @param values
   1393      *        an array of 3 floats to hold the result.
   1394      *
   1395      * @return The array values passed as argument.
   1396      *
   1397      * @see #getRotationMatrix(float[], float[], float[], float[])
   1398      * @see GeomagneticField
   1399      */
   1400     public static float[] getOrientation(float[] R, float values[]) {
   1401         /*
   1402          * 4x4 (length=16) case:
   1403          *   /  R[ 0]   R[ 1]   R[ 2]   0  \
   1404          *   |  R[ 4]   R[ 5]   R[ 6]   0  |
   1405          *   |  R[ 8]   R[ 9]   R[10]   0  |
   1406          *   \      0       0       0   1  /
   1407          *
   1408          * 3x3 (length=9) case:
   1409          *   /  R[ 0]   R[ 1]   R[ 2]  \
   1410          *   |  R[ 3]   R[ 4]   R[ 5]  |
   1411          *   \  R[ 6]   R[ 7]   R[ 8]  /
   1412          *
   1413          */
   1414         if (R.length == 9) {
   1415             values[0] = (float)Math.atan2(R[1], R[4]);
   1416             values[1] = (float)Math.asin(-R[7]);
   1417             values[2] = (float)Math.atan2(-R[6], R[8]);
   1418         } else {
   1419             values[0] = (float)Math.atan2(R[1], R[5]);
   1420             values[1] = (float)Math.asin(-R[9]);
   1421             values[2] = (float)Math.atan2(-R[8], R[10]);
   1422         }
   1423 
   1424         return values;
   1425     }
   1426 
   1427     /**
   1428      * Computes the Altitude in meters from the atmospheric pressure and the
   1429      * pressure at sea level.
   1430      * <p>
   1431      * Typically the atmospheric pressure is read from a
   1432      * {@link Sensor#TYPE_PRESSURE} sensor. The pressure at sea level must be
   1433      * known, usually it can be retrieved from airport databases in the
   1434      * vicinity. If unknown, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE}
   1435      * as an approximation, but absolute altitudes won't be accurate.
   1436      * </p>
   1437      * <p>
   1438      * To calculate altitude differences, you must calculate the difference
   1439      * between the altitudes at both points. If you don't know the altitude
   1440      * as sea level, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE} instead,
   1441      * which will give good results considering the range of pressure typically
   1442      * involved.
   1443      * </p>
   1444      * <p>
   1445      * <code><ul>
   1446      *  float altitude_difference =
   1447      *      getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point2)
   1448      *      - getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point1);
   1449      * </ul></code>
   1450      * </p>
   1451      *
   1452      * @param p0 pressure at sea level
   1453      * @param p atmospheric pressure
   1454      * @return Altitude in meters
   1455      */
   1456     public static float getAltitude(float p0, float p) {
   1457         final float coef = 1.0f / 5.255f;
   1458         return 44330.0f * (1.0f - (float)Math.pow(p/p0, coef));
   1459     }
   1460 
   1461     /** Helper function to compute the angle change between two rotation matrices.
   1462      *  Given a current rotation matrix (R) and a previous rotation matrix
   1463      *  (prevR) computes the intrinsic rotation around the z, x, and y axes which
   1464      *  transforms prevR to R.
   1465      *  outputs a 3 element vector containing the z, x, and y angle
   1466      *  change at indexes 0, 1, and 2 respectively.
   1467      * <p> Each input matrix is either as a 3x3 or 4x4 row-major matrix
   1468      * depending on the length of the passed array:
   1469      * <p>If the array length is 9, then the array elements represent this matrix
   1470      * <pre>
   1471      *   /  R[ 0]   R[ 1]   R[ 2]   \
   1472      *   |  R[ 3]   R[ 4]   R[ 5]   |
   1473      *   \  R[ 6]   R[ 7]   R[ 8]   /
   1474      *</pre>
   1475      * <p>If the array length is 16, then the array elements represent this matrix
   1476      * <pre>
   1477      *   /  R[ 0]   R[ 1]   R[ 2]   R[ 3]  \
   1478      *   |  R[ 4]   R[ 5]   R[ 6]   R[ 7]  |
   1479      *   |  R[ 8]   R[ 9]   R[10]   R[11]  |
   1480      *   \  R[12]   R[13]   R[14]   R[15]  /
   1481      *</pre>
   1482      *
   1483      * See {@link #getOrientation} for more detailed definition of the output.
   1484      *
   1485      * @param R current rotation matrix
   1486      * @param prevR previous rotation matrix
   1487      * @param angleChange an an array of floats (z, x, and y) in which the angle change
   1488      *        (in radians) is stored
   1489      */
   1490 
   1491     public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) {
   1492         float rd1=0,rd4=0, rd6=0,rd7=0, rd8=0;
   1493         float ri0=0,ri1=0,ri2=0,ri3=0,ri4=0,ri5=0,ri6=0,ri7=0,ri8=0;
   1494         float pri0=0, pri1=0, pri2=0, pri3=0, pri4=0, pri5=0, pri6=0, pri7=0, pri8=0;
   1495 
   1496         if(R.length == 9) {
   1497             ri0 = R[0];
   1498             ri1 = R[1];
   1499             ri2 = R[2];
   1500             ri3 = R[3];
   1501             ri4 = R[4];
   1502             ri5 = R[5];
   1503             ri6 = R[6];
   1504             ri7 = R[7];
   1505             ri8 = R[8];
   1506         } else if(R.length == 16) {
   1507             ri0 = R[0];
   1508             ri1 = R[1];
   1509             ri2 = R[2];
   1510             ri3 = R[4];
   1511             ri4 = R[5];
   1512             ri5 = R[6];
   1513             ri6 = R[8];
   1514             ri7 = R[9];
   1515             ri8 = R[10];
   1516         }
   1517 
   1518         if(prevR.length == 9) {
   1519             pri0 = prevR[0];
   1520             pri1 = prevR[1];
   1521             pri2 = prevR[2];
   1522             pri3 = prevR[3];
   1523             pri4 = prevR[4];
   1524             pri5 = prevR[5];
   1525             pri6 = prevR[6];
   1526             pri7 = prevR[7];
   1527             pri8 = prevR[8];
   1528         } else if(prevR.length == 16) {
   1529             pri0 = prevR[0];
   1530             pri1 = prevR[1];
   1531             pri2 = prevR[2];
   1532             pri3 = prevR[4];
   1533             pri4 = prevR[5];
   1534             pri5 = prevR[6];
   1535             pri6 = prevR[8];
   1536             pri7 = prevR[9];
   1537             pri8 = prevR[10];
   1538         }
   1539 
   1540         // calculate the parts of the rotation difference matrix we need
   1541         // rd[i][j] = pri[0][i] * ri[0][j] + pri[1][i] * ri[1][j] + pri[2][i] * ri[2][j];
   1542 
   1543         rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7; //rd[0][1]
   1544         rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7; //rd[1][1]
   1545         rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6; //rd[2][0]
   1546         rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7; //rd[2][1]
   1547         rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8; //rd[2][2]
   1548 
   1549         angleChange[0] = (float)Math.atan2(rd1, rd4);
   1550         angleChange[1] = (float)Math.asin(-rd7);
   1551         angleChange[2] = (float)Math.atan2(-rd6, rd8);
   1552 
   1553     }
   1554 
   1555     /** Helper function to convert a rotation vector to a rotation matrix.
   1556      *  Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a
   1557      *  9  or 16 element rotation matrix in the array R.  R must have length 9 or 16.
   1558      *  If R.length == 9, the following matrix is returned:
   1559      * <pre>
   1560      *   /  R[ 0]   R[ 1]   R[ 2]   \
   1561      *   |  R[ 3]   R[ 4]   R[ 5]   |
   1562      *   \  R[ 6]   R[ 7]   R[ 8]   /
   1563      *</pre>
   1564      * If R.length == 16, the following matrix is returned:
   1565      * <pre>
   1566      *   /  R[ 0]   R[ 1]   R[ 2]   0  \
   1567      *   |  R[ 4]   R[ 5]   R[ 6]   0  |
   1568      *   |  R[ 8]   R[ 9]   R[10]   0  |
   1569      *   \  0       0       0       1  /
   1570      *</pre>
   1571      *  @param rotationVector the rotation vector to convert
   1572      *  @param R an array of floats in which to store the rotation matrix
   1573      */
   1574     public static void getRotationMatrixFromVector(float[] R, float[] rotationVector) {
   1575 
   1576         float q0;
   1577         float q1 = rotationVector[0];
   1578         float q2 = rotationVector[1];
   1579         float q3 = rotationVector[2];
   1580 
   1581         if (rotationVector.length >= 4) {
   1582             q0 = rotationVector[3];
   1583         } else {
   1584             q0 = 1 - q1*q1 - q2*q2 - q3*q3;
   1585             q0 = (q0 > 0) ? (float)Math.sqrt(q0) : 0;
   1586         }
   1587 
   1588         float sq_q1 = 2 * q1 * q1;
   1589         float sq_q2 = 2 * q2 * q2;
   1590         float sq_q3 = 2 * q3 * q3;
   1591         float q1_q2 = 2 * q1 * q2;
   1592         float q3_q0 = 2 * q3 * q0;
   1593         float q1_q3 = 2 * q1 * q3;
   1594         float q2_q0 = 2 * q2 * q0;
   1595         float q2_q3 = 2 * q2 * q3;
   1596         float q1_q0 = 2 * q1 * q0;
   1597 
   1598         if(R.length == 9) {
   1599             R[0] = 1 - sq_q2 - sq_q3;
   1600             R[1] = q1_q2 - q3_q0;
   1601             R[2] = q1_q3 + q2_q0;
   1602 
   1603             R[3] = q1_q2 + q3_q0;
   1604             R[4] = 1 - sq_q1 - sq_q3;
   1605             R[5] = q2_q3 - q1_q0;
   1606 
   1607             R[6] = q1_q3 - q2_q0;
   1608             R[7] = q2_q3 + q1_q0;
   1609             R[8] = 1 - sq_q1 - sq_q2;
   1610         } else if (R.length == 16) {
   1611             R[0] = 1 - sq_q2 - sq_q3;
   1612             R[1] = q1_q2 - q3_q0;
   1613             R[2] = q1_q3 + q2_q0;
   1614             R[3] = 0.0f;
   1615 
   1616             R[4] = q1_q2 + q3_q0;
   1617             R[5] = 1 - sq_q1 - sq_q3;
   1618             R[6] = q2_q3 - q1_q0;
   1619             R[7] = 0.0f;
   1620 
   1621             R[8] = q1_q3 - q2_q0;
   1622             R[9] = q2_q3 + q1_q0;
   1623             R[10] = 1 - sq_q1 - sq_q2;
   1624             R[11] = 0.0f;
   1625 
   1626             R[12] = R[13] = R[14] = 0.0f;
   1627             R[15] = 1.0f;
   1628         }
   1629     }
   1630 
   1631     /** Helper function to convert a rotation vector to a normalized quaternion.
   1632      *  Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a normalized
   1633      *  quaternion in the array Q.  The quaternion is stored as [w, x, y, z]
   1634      *  @param rv the rotation vector to convert
   1635      *  @param Q an array of floats in which to store the computed quaternion
   1636      */
   1637     public static void getQuaternionFromVector(float[] Q, float[] rv) {
   1638         if (rv.length >= 4) {
   1639             Q[0] = rv[3];
   1640         } else {
   1641             Q[0] = 1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2];
   1642             Q[0] = (Q[0] > 0) ? (float)Math.sqrt(Q[0]) : 0;
   1643         }
   1644         Q[1] = rv[0];
   1645         Q[2] = rv[1];
   1646         Q[3] = rv[2];
   1647     }
   1648 
   1649     /**
   1650      * Requests receiving trigger events for a trigger sensor.
   1651      *
   1652      * <p>
   1653      * When the sensor detects a trigger event condition, such as significant motion in
   1654      * the case of the {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the provided trigger listener
   1655      * will be invoked once and then its request to receive trigger events will be canceled.
   1656      * To continue receiving trigger events, the application must request to receive trigger
   1657      * events again.
   1658      * </p>
   1659      *
   1660      * @param listener The listener on which the
   1661      *        {@link TriggerEventListener#onTrigger(TriggerEvent)} will be delivered.
   1662      * @param sensor The sensor to be enabled.
   1663      *
   1664      * @return true if the sensor was successfully enabled.
   1665      *
   1666      * @throws IllegalArgumentException when sensor is null or not a trigger sensor.
   1667      */
   1668     public boolean requestTriggerSensor(TriggerEventListener listener, Sensor sensor) {
   1669         return requestTriggerSensorImpl(listener, sensor);
   1670     }
   1671 
   1672     /**
   1673      * @hide
   1674      */
   1675     protected abstract boolean requestTriggerSensorImpl(TriggerEventListener listener,
   1676             Sensor sensor);
   1677 
   1678     /**
   1679      * Cancels receiving trigger events for a trigger sensor.
   1680      *
   1681      * <p>
   1682      * Note that a Trigger sensor will be auto disabled if
   1683      * {@link TriggerEventListener#onTrigger(TriggerEvent)} has triggered.
   1684      * This method is provided in case the user wants to explicitly cancel the request
   1685      * to receive trigger events.
   1686      * </p>
   1687      *
   1688      * @param listener The listener on which the
   1689      *        {@link TriggerEventListener#onTrigger(TriggerEvent)}
   1690      *        is delivered.It should be the same as the one used
   1691      *        in {@link #requestTriggerSensor(TriggerEventListener, Sensor)}
   1692      * @param sensor The sensor for which the trigger request should be canceled.
   1693      *        If null, it cancels receiving trigger for all sensors associated
   1694      *        with the listener.
   1695      *
   1696      * @return true if successfully canceled.
   1697      *
   1698      * @throws IllegalArgumentException when sensor is a trigger sensor.
   1699      */
   1700     public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) {
   1701         return cancelTriggerSensorImpl(listener, sensor, true);
   1702     }
   1703 
   1704     /**
   1705      * @hide
   1706      */
   1707     protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener,
   1708             Sensor sensor, boolean disable);
   1709 
   1710 
   1711     /**
   1712      * For testing purposes only. Not for third party applications.
   1713      *
   1714      * Initialize data injection mode and create a client for data injection. SensorService should
   1715      * already be operating in DATA_INJECTION mode for this call succeed. To set SensorService into
   1716      * DATA_INJECTION mode "adb shell dumpsys sensorservice data_injection" needs to be called
   1717      * through adb. Typically this is done using a host side test.  This mode is expected to be used
   1718      * only for testing purposes. If the HAL is set to data injection mode, it will ignore the input
   1719      * from physical sensors and read sensor data that is injected from the test application. This
   1720      * mode is used for testing vendor implementations for various algorithms like Rotation Vector,
   1721      * Significant Motion, Step Counter etc. Not all HALs support DATA_INJECTION. This method will
   1722      * fail in those cases. Once this method succeeds, the test can call
   1723      * {@link injectSensorData(Sensor, float[], int, long)} to inject sensor data into the HAL.
   1724      *
   1725      * @param enable True to initialize a client in DATA_INJECTION mode.
   1726      *               False to clean up the native resources.
   1727      *
   1728      * @return true if the HAL supports data injection and false
   1729      *         otherwise.
   1730      * @hide
   1731      */
   1732     @SystemApi
   1733     public boolean initDataInjection(boolean enable) {
   1734           return initDataInjectionImpl(enable);
   1735     }
   1736 
   1737     /**
   1738      * @hide
   1739      */
   1740     protected abstract boolean initDataInjectionImpl(boolean enable);
   1741 
   1742     /**
   1743      * For testing purposes only. Not for third party applications.
   1744      *
   1745      * This method is used to inject raw sensor data into the HAL.  Call {@link
   1746      * initDataInjection(boolean)} before this method to set the HAL in data injection mode. This
   1747      * method should be called only if a previous call to initDataInjection has been successful and
   1748      * the HAL and SensorService are already opreating in data injection mode.
   1749      *
   1750      * @param sensor The sensor to inject.
   1751      * @param values Sensor values to inject. The length of this
   1752      *               array must be exactly equal to the number of
   1753      *               values reported by the sensor type.
   1754      * @param accuracy Accuracy of the sensor.
   1755      * @param timestamp Sensor timestamp associated with the event.
   1756      *
   1757      * @return boolean True if the data injection succeeds, false
   1758      *         otherwise.
   1759      * @throws IllegalArgumentException when the sensor is null,
   1760      *         data injection is not supported by the sensor, values
   1761      *         are null, incorrect number of values for the sensor,
   1762      *         sensor accuracy is incorrect or timestamps are
   1763      *         invalid.
   1764      * @hide
   1765      */
   1766     @SystemApi
   1767     public boolean injectSensorData(Sensor sensor, float[] values, int accuracy,
   1768                 long timestamp) {
   1769         if (sensor == null) {
   1770             throw new IllegalArgumentException("sensor cannot be null");
   1771         }
   1772         if (!sensor.isDataInjectionSupported()) {
   1773             throw new IllegalArgumentException("sensor does not support data injection");
   1774         }
   1775         if (values == null) {
   1776             throw new IllegalArgumentException("sensor data cannot be null");
   1777         }
   1778         int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.M);
   1779         if (values.length != expectedNumValues) {
   1780             throw new  IllegalArgumentException ("Wrong number of values for sensor " +
   1781                     sensor.getName() + " actual=" + values.length + " expected=" +
   1782                                                   expectedNumValues);
   1783         }
   1784         if (accuracy < SENSOR_STATUS_NO_CONTACT || accuracy > SENSOR_STATUS_ACCURACY_HIGH) {
   1785             throw new IllegalArgumentException("Invalid sensor accuracy");
   1786         }
   1787         if (timestamp <= 0) {
   1788             throw new IllegalArgumentException("Negative or zero sensor timestamp");
   1789         }
   1790         return injectSensorDataImpl(sensor, values, accuracy, timestamp);
   1791     }
   1792 
   1793     /**
   1794      * @hide
   1795      */
   1796     protected abstract boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy,
   1797                 long timestamp);
   1798 
   1799     private LegacySensorManager getLegacySensorManager() {
   1800         synchronized (mSensorListByType) {
   1801             if (mLegacySensorManager == null) {
   1802                 Log.i(TAG, "This application is using deprecated SensorManager API which will "
   1803                         + "be removed someday.  Please consider switching to the new API.");
   1804                 mLegacySensorManager = new LegacySensorManager(this);
   1805             }
   1806             return mLegacySensorManager;
   1807         }
   1808     }
   1809 
   1810     private static int getDelay(int rate) {
   1811         int delay = -1;
   1812         switch (rate) {
   1813             case SENSOR_DELAY_FASTEST:
   1814                 delay = 0;
   1815                 break;
   1816             case SENSOR_DELAY_GAME:
   1817                 delay = 20000;
   1818                 break;
   1819             case SENSOR_DELAY_UI:
   1820                 delay = 66667;
   1821                 break;
   1822             case SENSOR_DELAY_NORMAL:
   1823                 delay = 200000;
   1824                 break;
   1825             default:
   1826                 delay = rate;
   1827                 break;
   1828         }
   1829         return delay;
   1830     }
   1831 }
   1832