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