• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.hardware;
18 
19 import android.annotation.SystemApi;
20 import android.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 are as follows:
1360      * <ul>
1361      * <li>values[0]: <i>Azimuth</i>, angle of rotation about the -z axis.
1362      *                This value represents the angle between the device's y
1363      *                axis and the magnetic north pole. When facing north, this
1364      *                angle is 0, when facing south, this angle is &pi;.
1365      *                Likewise, when facing east, this angle is &pi;/2, and
1366      *                when facing west, this angle is -&pi;/2. The range of
1367      *                values is -&pi; to &pi;.</li>
1368      * <li>values[1]: <i>Pitch</i>, angle of rotation about the x axis.
1369      *                This value represents the angle between a plane parallel
1370      *                to the device's screen and a plane parallel to the ground.
1371      *                Assuming that the bottom edge of the device faces the
1372      *                user and that the screen is face-up, tilting the top edge
1373      *                of the device toward the ground creates a positive pitch
1374      *                angle. The range of values is -&pi; to &pi;.</li>
1375      * <li>values[2]: <i>Roll</i>, angle of rotation about the y axis. This
1376      *                value represents the angle between a plane perpendicular
1377      *                to the device's screen and a plane perpendicular to the
1378      *                ground. Assuming that the bottom edge of the device faces
1379      *                the user and that the screen is face-up, tilting the left
1380      *                edge of the device toward the ground creates a positive
1381      *                roll angle. The range of values is -&pi;/2 to &pi;/2.</li>
1382      * </ul>
1383      * <p>
1384      * Applying these three rotations in the azimuth, pitch, roll order
1385      * transforms an identity matrix to the rotation matrix passed into this
1386      * method. Also, note that all three orientation angles are expressed in
1387      * <b>radians</b>.
1388      *
1389      * @param R
1390      *        rotation matrix see {@link #getRotationMatrix}.
1391      *
1392      * @param values
1393      *        an array of 3 floats to hold the result.
1394      *
1395      * @return The array values passed as argument.
1396      *
1397      * @see #getRotationMatrix(float[], float[], float[], float[])
1398      * @see GeomagneticField
1399      */
getOrientation(float[] R, float values[])1400     public static float[] getOrientation(float[] R, float values[]) {
1401         /*
1402          * 4x4 (length=16) case:
1403          *   /  R[ 0]   R[ 1]   R[ 2]   0  \
1404          *   |  R[ 4]   R[ 5]   R[ 6]   0  |
1405          *   |  R[ 8]   R[ 9]   R[10]   0  |
1406          *   \      0       0       0   1  /
1407          *
1408          * 3x3 (length=9) case:
1409          *   /  R[ 0]   R[ 1]   R[ 2]  \
1410          *   |  R[ 3]   R[ 4]   R[ 5]  |
1411          *   \  R[ 6]   R[ 7]   R[ 8]  /
1412          *
1413          */
1414         if (R.length == 9) {
1415             values[0] = (float)Math.atan2(R[1], R[4]);
1416             values[1] = (float)Math.asin(-R[7]);
1417             values[2] = (float)Math.atan2(-R[6], R[8]);
1418         } else {
1419             values[0] = (float)Math.atan2(R[1], R[5]);
1420             values[1] = (float)Math.asin(-R[9]);
1421             values[2] = (float)Math.atan2(-R[8], R[10]);
1422         }
1423 
1424         return values;
1425     }
1426 
1427     /**
1428      * Computes the Altitude in meters from the atmospheric pressure and the
1429      * pressure at sea level.
1430      * <p>
1431      * Typically the atmospheric pressure is read from a
1432      * {@link Sensor#TYPE_PRESSURE} sensor. The pressure at sea level must be
1433      * known, usually it can be retrieved from airport databases in the
1434      * vicinity. If unknown, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE}
1435      * as an approximation, but absolute altitudes won't be accurate.
1436      * </p>
1437      * <p>
1438      * To calculate altitude differences, you must calculate the difference
1439      * between the altitudes at both points. If you don't know the altitude
1440      * as sea level, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE} instead,
1441      * which will give good results considering the range of pressure typically
1442      * involved.
1443      * </p>
1444      * <p>
1445      * <code><ul>
1446      *  float altitude_difference =
1447      *      getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point2)
1448      *      - getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point1);
1449      * </ul></code>
1450      * </p>
1451      *
1452      * @param p0 pressure at sea level
1453      * @param p atmospheric pressure
1454      * @return Altitude in meters
1455      */
getAltitude(float p0, float p)1456     public static float getAltitude(float p0, float p) {
1457         final float coef = 1.0f / 5.255f;
1458         return 44330.0f * (1.0f - (float)Math.pow(p/p0, coef));
1459     }
1460 
1461     /** Helper function to compute the angle change between two rotation matrices.
1462      *  Given a current rotation matrix (R) and a previous rotation matrix
1463      *  (prevR) computes the intrinsic rotation around the z, x, and y axes which
1464      *  transforms prevR to R.
1465      *  outputs a 3 element vector containing the z, x, and y angle
1466      *  change at indexes 0, 1, and 2 respectively.
1467      * <p> Each input matrix is either as a 3x3 or 4x4 row-major matrix
1468      * depending on the length of the passed array:
1469      * <p>If the array length is 9, then the array elements represent this matrix
1470      * <pre>
1471      *   /  R[ 0]   R[ 1]   R[ 2]   \
1472      *   |  R[ 3]   R[ 4]   R[ 5]   |
1473      *   \  R[ 6]   R[ 7]   R[ 8]   /
1474      *</pre>
1475      * <p>If the array length is 16, then the array elements represent this matrix
1476      * <pre>
1477      *   /  R[ 0]   R[ 1]   R[ 2]   R[ 3]  \
1478      *   |  R[ 4]   R[ 5]   R[ 6]   R[ 7]  |
1479      *   |  R[ 8]   R[ 9]   R[10]   R[11]  |
1480      *   \  R[12]   R[13]   R[14]   R[15]  /
1481      *</pre>
1482      *
1483      * See {@link #getOrientation} for more detailed definition of the output.
1484      *
1485      * @param R current rotation matrix
1486      * @param prevR previous rotation matrix
1487      * @param angleChange an an array of floats (z, x, and y) in which the angle change
1488      *        (in radians) is stored
1489      */
1490 
getAngleChange( float[] angleChange, float[] R, float[] prevR)1491     public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) {
1492         float rd1=0,rd4=0, rd6=0,rd7=0, rd8=0;
1493         float ri0=0,ri1=0,ri2=0,ri3=0,ri4=0,ri5=0,ri6=0,ri7=0,ri8=0;
1494         float pri0=0, pri1=0, pri2=0, pri3=0, pri4=0, pri5=0, pri6=0, pri7=0, pri8=0;
1495 
1496         if(R.length == 9) {
1497             ri0 = R[0];
1498             ri1 = R[1];
1499             ri2 = R[2];
1500             ri3 = R[3];
1501             ri4 = R[4];
1502             ri5 = R[5];
1503             ri6 = R[6];
1504             ri7 = R[7];
1505             ri8 = R[8];
1506         } else if(R.length == 16) {
1507             ri0 = R[0];
1508             ri1 = R[1];
1509             ri2 = R[2];
1510             ri3 = R[4];
1511             ri4 = R[5];
1512             ri5 = R[6];
1513             ri6 = R[8];
1514             ri7 = R[9];
1515             ri8 = R[10];
1516         }
1517 
1518         if(prevR.length == 9) {
1519             pri0 = prevR[0];
1520             pri1 = prevR[1];
1521             pri2 = prevR[2];
1522             pri3 = prevR[3];
1523             pri4 = prevR[4];
1524             pri5 = prevR[5];
1525             pri6 = prevR[6];
1526             pri7 = prevR[7];
1527             pri8 = prevR[8];
1528         } else if(prevR.length == 16) {
1529             pri0 = prevR[0];
1530             pri1 = prevR[1];
1531             pri2 = prevR[2];
1532             pri3 = prevR[4];
1533             pri4 = prevR[5];
1534             pri5 = prevR[6];
1535             pri6 = prevR[8];
1536             pri7 = prevR[9];
1537             pri8 = prevR[10];
1538         }
1539 
1540         // calculate the parts of the rotation difference matrix we need
1541         // rd[i][j] = pri[0][i] * ri[0][j] + pri[1][i] * ri[1][j] + pri[2][i] * ri[2][j];
1542 
1543         rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7; //rd[0][1]
1544         rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7; //rd[1][1]
1545         rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6; //rd[2][0]
1546         rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7; //rd[2][1]
1547         rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8; //rd[2][2]
1548 
1549         angleChange[0] = (float)Math.atan2(rd1, rd4);
1550         angleChange[1] = (float)Math.asin(-rd7);
1551         angleChange[2] = (float)Math.atan2(-rd6, rd8);
1552 
1553     }
1554 
1555     /** Helper function to convert a rotation vector to a rotation matrix.
1556      *  Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a
1557      *  9  or 16 element rotation matrix in the array R.  R must have length 9 or 16.
1558      *  If R.length == 9, the following matrix is returned:
1559      * <pre>
1560      *   /  R[ 0]   R[ 1]   R[ 2]   \
1561      *   |  R[ 3]   R[ 4]   R[ 5]   |
1562      *   \  R[ 6]   R[ 7]   R[ 8]   /
1563      *</pre>
1564      * If R.length == 16, the following matrix is returned:
1565      * <pre>
1566      *   /  R[ 0]   R[ 1]   R[ 2]   0  \
1567      *   |  R[ 4]   R[ 5]   R[ 6]   0  |
1568      *   |  R[ 8]   R[ 9]   R[10]   0  |
1569      *   \  0       0       0       1  /
1570      *</pre>
1571      *  @param rotationVector the rotation vector to convert
1572      *  @param R an array of floats in which to store the rotation matrix
1573      */
getRotationMatrixFromVector(float[] R, float[] rotationVector)1574     public static void getRotationMatrixFromVector(float[] R, float[] rotationVector) {
1575 
1576         float q0;
1577         float q1 = rotationVector[0];
1578         float q2 = rotationVector[1];
1579         float q3 = rotationVector[2];
1580 
1581         if (rotationVector.length >= 4) {
1582             q0 = rotationVector[3];
1583         } else {
1584             q0 = 1 - q1*q1 - q2*q2 - q3*q3;
1585             q0 = (q0 > 0) ? (float)Math.sqrt(q0) : 0;
1586         }
1587 
1588         float sq_q1 = 2 * q1 * q1;
1589         float sq_q2 = 2 * q2 * q2;
1590         float sq_q3 = 2 * q3 * q3;
1591         float q1_q2 = 2 * q1 * q2;
1592         float q3_q0 = 2 * q3 * q0;
1593         float q1_q3 = 2 * q1 * q3;
1594         float q2_q0 = 2 * q2 * q0;
1595         float q2_q3 = 2 * q2 * q3;
1596         float q1_q0 = 2 * q1 * q0;
1597 
1598         if(R.length == 9) {
1599             R[0] = 1 - sq_q2 - sq_q3;
1600             R[1] = q1_q2 - q3_q0;
1601             R[2] = q1_q3 + q2_q0;
1602 
1603             R[3] = q1_q2 + q3_q0;
1604             R[4] = 1 - sq_q1 - sq_q3;
1605             R[5] = q2_q3 - q1_q0;
1606 
1607             R[6] = q1_q3 - q2_q0;
1608             R[7] = q2_q3 + q1_q0;
1609             R[8] = 1 - sq_q1 - sq_q2;
1610         } else if (R.length == 16) {
1611             R[0] = 1 - sq_q2 - sq_q3;
1612             R[1] = q1_q2 - q3_q0;
1613             R[2] = q1_q3 + q2_q0;
1614             R[3] = 0.0f;
1615 
1616             R[4] = q1_q2 + q3_q0;
1617             R[5] = 1 - sq_q1 - sq_q3;
1618             R[6] = q2_q3 - q1_q0;
1619             R[7] = 0.0f;
1620 
1621             R[8] = q1_q3 - q2_q0;
1622             R[9] = q2_q3 + q1_q0;
1623             R[10] = 1 - sq_q1 - sq_q2;
1624             R[11] = 0.0f;
1625 
1626             R[12] = R[13] = R[14] = 0.0f;
1627             R[15] = 1.0f;
1628         }
1629     }
1630 
1631     /** Helper function to convert a rotation vector to a normalized quaternion.
1632      *  Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a normalized
1633      *  quaternion in the array Q.  The quaternion is stored as [w, x, y, z]
1634      *  @param rv the rotation vector to convert
1635      *  @param Q an array of floats in which to store the computed quaternion
1636      */
getQuaternionFromVector(float[] Q, float[] rv)1637     public static void getQuaternionFromVector(float[] Q, float[] rv) {
1638         if (rv.length >= 4) {
1639             Q[0] = rv[3];
1640         } else {
1641             Q[0] = 1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2];
1642             Q[0] = (Q[0] > 0) ? (float)Math.sqrt(Q[0]) : 0;
1643         }
1644         Q[1] = rv[0];
1645         Q[2] = rv[1];
1646         Q[3] = rv[2];
1647     }
1648 
1649     /**
1650      * Requests receiving trigger events for a trigger sensor.
1651      *
1652      * <p>
1653      * When the sensor detects a trigger event condition, such as significant motion in
1654      * the case of the {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the provided trigger listener
1655      * will be invoked once and then its request to receive trigger events will be canceled.
1656      * To continue receiving trigger events, the application must request to receive trigger
1657      * events again.
1658      * </p>
1659      *
1660      * @param listener The listener on which the
1661      *        {@link TriggerEventListener#onTrigger(TriggerEvent)} will be delivered.
1662      * @param sensor The sensor to be enabled.
1663      *
1664      * @return true if the sensor was successfully enabled.
1665      *
1666      * @throws IllegalArgumentException when sensor is null or not a trigger sensor.
1667      */
requestTriggerSensor(TriggerEventListener listener, Sensor sensor)1668     public boolean requestTriggerSensor(TriggerEventListener listener, Sensor sensor) {
1669         return requestTriggerSensorImpl(listener, sensor);
1670     }
1671 
1672     /**
1673      * @hide
1674      */
requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor)1675     protected abstract boolean requestTriggerSensorImpl(TriggerEventListener listener,
1676             Sensor sensor);
1677 
1678     /**
1679      * Cancels receiving trigger events for a trigger sensor.
1680      *
1681      * <p>
1682      * Note that a Trigger sensor will be auto disabled if
1683      * {@link TriggerEventListener#onTrigger(TriggerEvent)} has triggered.
1684      * This method is provided in case the user wants to explicitly cancel the request
1685      * to receive trigger events.
1686      * </p>
1687      *
1688      * @param listener The listener on which the
1689      *        {@link TriggerEventListener#onTrigger(TriggerEvent)}
1690      *        is delivered.It should be the same as the one used
1691      *        in {@link #requestTriggerSensor(TriggerEventListener, Sensor)}
1692      * @param sensor The sensor for which the trigger request should be canceled.
1693      *        If null, it cancels receiving trigger for all sensors associated
1694      *        with the listener.
1695      *
1696      * @return true if successfully canceled.
1697      *
1698      * @throws IllegalArgumentException when sensor is a trigger sensor.
1699      */
cancelTriggerSensor(TriggerEventListener listener, Sensor sensor)1700     public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) {
1701         return cancelTriggerSensorImpl(listener, sensor, true);
1702     }
1703 
1704     /**
1705      * @hide
1706      */
cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, boolean disable)1707     protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener,
1708             Sensor sensor, boolean disable);
1709 
1710 
1711     /**
1712      * For testing purposes only. Not for third party applications.
1713      *
1714      * Initialize data injection mode and create a client for data injection. SensorService should
1715      * already be operating in DATA_INJECTION mode for this call succeed. To set SensorService into
1716      * DATA_INJECTION mode "adb shell dumpsys sensorservice data_injection" needs to be called
1717      * through adb. Typically this is done using a host side test.  This mode is expected to be used
1718      * only for testing purposes. If the HAL is set to data injection mode, it will ignore the input
1719      * from physical sensors and read sensor data that is injected from the test application. This
1720      * mode is used for testing vendor implementations for various algorithms like Rotation Vector,
1721      * Significant Motion, Step Counter etc. Not all HALs support DATA_INJECTION. This method will
1722      * fail in those cases. Once this method succeeds, the test can call
1723      * {@link injectSensorData(Sensor, float[], int, long)} to inject sensor data into the HAL.
1724      *
1725      * @param enable True to initialize a client in DATA_INJECTION mode.
1726      *               False to clean up the native resources.
1727      *
1728      * @return true if the HAL supports data injection and false
1729      *         otherwise.
1730      * @hide
1731      */
1732     @SystemApi
initDataInjection(boolean enable)1733     public boolean initDataInjection(boolean enable) {
1734           return initDataInjectionImpl(enable);
1735     }
1736 
1737     /**
1738      * @hide
1739      */
initDataInjectionImpl(boolean enable)1740     protected abstract boolean initDataInjectionImpl(boolean enable);
1741 
1742     /**
1743      * For testing purposes only. Not for third party applications.
1744      *
1745      * This method is used to inject raw sensor data into the HAL.  Call {@link
1746      * initDataInjection(boolean)} before this method to set the HAL in data injection mode. This
1747      * method should be called only if a previous call to initDataInjection has been successful and
1748      * the HAL and SensorService are already opreating in data injection mode.
1749      *
1750      * @param sensor The sensor to inject.
1751      * @param values Sensor values to inject. The length of this
1752      *               array must be exactly equal to the number of
1753      *               values reported by the sensor type.
1754      * @param accuracy Accuracy of the sensor.
1755      * @param timestamp Sensor timestamp associated with the event.
1756      *
1757      * @return boolean True if the data injection succeeds, false
1758      *         otherwise.
1759      * @throws IllegalArgumentException when the sensor is null,
1760      *         data injection is not supported by the sensor, values
1761      *         are null, incorrect number of values for the sensor,
1762      *         sensor accuracy is incorrect or timestamps are
1763      *         invalid.
1764      * @hide
1765      */
1766     @SystemApi
injectSensorData(Sensor sensor, float[] values, int accuracy, long timestamp)1767     public boolean injectSensorData(Sensor sensor, float[] values, int accuracy,
1768                 long timestamp) {
1769         if (sensor == null) {
1770             throw new IllegalArgumentException("sensor cannot be null");
1771         }
1772         if (!sensor.isDataInjectionSupported()) {
1773             throw new IllegalArgumentException("sensor does not support data injection");
1774         }
1775         if (values == null) {
1776             throw new IllegalArgumentException("sensor data cannot be null");
1777         }
1778         int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.M);
1779         if (values.length != expectedNumValues) {
1780             throw new  IllegalArgumentException ("Wrong number of values for sensor " +
1781                     sensor.getName() + " actual=" + values.length + " expected=" +
1782                                                   expectedNumValues);
1783         }
1784         if (accuracy < SENSOR_STATUS_NO_CONTACT || accuracy > SENSOR_STATUS_ACCURACY_HIGH) {
1785             throw new IllegalArgumentException("Invalid sensor accuracy");
1786         }
1787         if (timestamp <= 0) {
1788             throw new IllegalArgumentException("Negative or zero sensor timestamp");
1789         }
1790         return injectSensorDataImpl(sensor, values, accuracy, timestamp);
1791     }
1792 
1793     /**
1794      * @hide
1795      */
injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, long timestamp)1796     protected abstract boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy,
1797                 long timestamp);
1798 
getLegacySensorManager()1799     private LegacySensorManager getLegacySensorManager() {
1800         synchronized (mSensorListByType) {
1801             if (mLegacySensorManager == null) {
1802                 Log.i(TAG, "This application is using deprecated SensorManager API which will "
1803                         + "be removed someday.  Please consider switching to the new API.");
1804                 mLegacySensorManager = new LegacySensorManager(this);
1805             }
1806             return mLegacySensorManager;
1807         }
1808     }
1809 
getDelay(int rate)1810     private static int getDelay(int rate) {
1811         int delay = -1;
1812         switch (rate) {
1813             case SENSOR_DELAY_FASTEST:
1814                 delay = 0;
1815                 break;
1816             case SENSOR_DELAY_GAME:
1817                 delay = 20000;
1818                 break;
1819             case SENSOR_DELAY_UI:
1820                 delay = 66667;
1821                 break;
1822             case SENSOR_DELAY_NORMAL:
1823                 delay = 200000;
1824                 break;
1825             default:
1826                 delay = rate;
1827                 break;
1828         }
1829         return delay;
1830     }
1831 }
1832