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