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