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