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