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