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