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.NonNull;
20 import android.compat.annotation.UnsupportedAppUsage;
21 
22 /**
23  * This class represents a {@link android.hardware.Sensor Sensor} event and
24  * holds information such as the sensor's type, the time-stamp, accuracy and of
25  * course the sensor's {@link SensorEvent#values data}.
26  *
27  * <p>
28  * <u>Definition of the coordinate system used by the SensorEvent API.</u>
29  * </p>
30  *
31  * <p>
32  * The coordinate-system is defined relative to the screen of the phone in its
33  * default orientation. The axes are not swapped when the device's screen
34  * orientation changes.
35  * </p>
36  *
37  * <p>
38  * The X axis is horizontal and points to the right, the Y axis is vertical and
39  * points up and the Z axis points towards the outside of the front face of the
40  * screen. In this system, coordinates behind the screen have negative Z values.
41  * </p>
42  *
43  * <p>
44  * <center><img src="../../../images/axis_device.png"
45  * alt="Sensors coordinate-system diagram." border="0" /></center>
46  * </p>
47  *
48  * <p>
49  * <b>Note:</b> This coordinate system is different from the one used in the
50  * Android 2D APIs where the origin is in the top-left corner.
51  * </p>
52  *
53  * @see SensorManager
54  * @see SensorEvent
55  * @see Sensor
56  *
57  */
58 
59 public class SensorEvent {
60     /**
61      * <p>
62      * The length and contents of the {@link #values values} array depends on
63      * which {@link android.hardware.Sensor sensor} type is being monitored (see
64      * also {@link SensorEvent} for a definition of the coordinate system used).
65      * </p>
66      *
67      * <h4>{@link android.hardware.Sensor#TYPE_ACCELEROMETER
68      * Sensor.TYPE_ACCELEROMETER}:</h4> All values are in SI units (m/s^2)
69      *
70      * <ul>
71      * <li> values[0]: Acceleration minus Gx on the x-axis </li>
72      * <li> values[1]: Acceleration minus Gy on the y-axis </li>
73      * <li> values[2]: Acceleration minus Gz on the z-axis </li>
74      * </ul>
75      *
76      * <p>
77      * A sensor of this type measures the acceleration applied to the device
78      * (<b>Ad</b>). Conceptually, it does so by measuring forces applied to the
79      * sensor itself (<b>Fs</b>) using the relation:
80      * </p>
81      *
82      * <b><center>Ad = - &#8721;Fs / mass</center></b>
83      *
84      * <p>
85      * In particular, the force of gravity is always influencing the measured
86      * acceleration:
87      * </p>
88      *
89      * <b><center>Ad = -g - &#8721;F / mass</center></b>
90      *
91      * <p>
92      * For this reason, when the device is sitting on a table (and obviously not
93      * accelerating), the accelerometer reads a magnitude of <b>g</b> = 9.81
94      * m/s^2
95      * </p>
96      *
97      * <p>
98      * Similarly, when the device is in free-fall and therefore dangerously
99      * accelerating towards to ground at 9.81 m/s^2, its accelerometer reads a
100      * magnitude of 0 m/s^2.
101      * </p>
102      *
103      * <p>
104      * It should be apparent that in order to measure the real acceleration of
105      * the device, the contribution of the force of gravity must be eliminated.
106      * This can be achieved by applying a <i>high-pass</i> filter. Conversely, a
107      * <i>low-pass</i> filter can be used to isolate the force of gravity.
108      * </p>
109      *
110      * <pre class="prettyprint">
111      *
112      *     public void onSensorChanged(SensorEvent event)
113      *     {
114      *          // alpha is calculated as t / (t + dT)
115      *          // with t, the low-pass filter's time-constant
116      *          // and dT, the event delivery rate
117      *
118      *          final float alpha = 0.8;
119      *
120      *          gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
121      *          gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
122      *          gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
123      *
124      *          linear_acceleration[0] = event.values[0] - gravity[0];
125      *          linear_acceleration[1] = event.values[1] - gravity[1];
126      *          linear_acceleration[2] = event.values[2] - gravity[2];
127      *     }
128      * </pre>
129      *
130      * <p>
131      * <u>Examples</u>:
132      * <ul>
133      * <li>When the device lies flat on a table and is pushed on its left side
134      * toward the right, the x acceleration value is positive.</li>
135      *
136      * <li>When the device lies flat on a table, the acceleration value is
137      * +9.81, which correspond to the acceleration of the device (0 m/s^2) minus
138      * the force of gravity (-9.81 m/s^2).</li>
139      *
140      * <li>When the device lies flat on a table and is pushed toward the sky
141      * with an acceleration of A m/s^2, the acceleration value is equal to
142      * A+9.81 which correspond to the acceleration of the device (+A m/s^2)
143      * minus the force of gravity (-9.81 m/s^2).</li>
144      * </ul>
145      *
146      *
147      * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD
148      * Sensor.TYPE_MAGNETIC_FIELD}:</h4>
149      * All values are in micro-Tesla (uT) and measure the ambient magnetic field
150      * in the X, Y and Z axis.
151      *
152      * <h4>{@link android.hardware.Sensor#TYPE_GYROSCOPE Sensor.TYPE_GYROSCOPE}:
153      * </h4> All values are in radians/second and measure the rate of rotation
154      * around the device's local X, Y and Z axis. The coordinate system is the
155      * same as is used for the acceleration sensor. Rotation is positive in the
156      * counter-clockwise direction. That is, an observer looking from some
157      * positive location on the x, y or z axis at a device positioned on the
158      * origin would report positive rotation if the device appeared to be
159      * rotating counter clockwise. Note that this is the standard mathematical
160      * definition of positive rotation and does not agree with the definition of
161      * roll given earlier.
162      * <ul>
163      * <li> values[0]: Angular speed around the x-axis </li>
164      * <li> values[1]: Angular speed around the y-axis </li>
165      * <li> values[2]: Angular speed around the z-axis </li>
166      * </ul>
167      * <p>
168      * Typically the output of the gyroscope is integrated over time to
169      * calculate a rotation describing the change of angles over the time step,
170      * for example:
171      * </p>
172      *
173      * <pre class="prettyprint">
174      *     private static final float NS2S = 1.0f / 1000000000.0f;
175      *     private final float[] deltaRotationVector = new float[4]();
176      *     private float timestamp;
177      *
178      *     public void onSensorChanged(SensorEvent event) {
179      *          // This time step's delta rotation to be multiplied by the current rotation
180      *          // after computing it from the gyro sample data.
181      *          if (timestamp != 0) {
182      *              final float dT = (event.timestamp - timestamp) * NS2S;
183      *              // Axis of the rotation sample, not normalized yet.
184      *              float axisX = event.values[0];
185      *              float axisY = event.values[1];
186      *              float axisZ = event.values[2];
187      *
188      *              // Calculate the angular speed of the sample
189      *              float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
190      *
191      *              // Normalize the rotation vector if it's big enough to get the axis
192      *              if (omegaMagnitude > EPSILON) {
193      *                  axisX /= omegaMagnitude;
194      *                  axisY /= omegaMagnitude;
195      *                  axisZ /= omegaMagnitude;
196      *              }
197      *
198      *              // Integrate around this axis with the angular speed by the time step
199      *              // in order to get a delta rotation from this sample over the time step
200      *              // We will convert this axis-angle representation of the delta rotation
201      *              // into a quaternion before turning it into the rotation matrix.
202      *              float thetaOverTwo = omegaMagnitude * dT / 2.0f;
203      *              float sinThetaOverTwo = sin(thetaOverTwo);
204      *              float cosThetaOverTwo = cos(thetaOverTwo);
205      *              deltaRotationVector[0] = sinThetaOverTwo * axisX;
206      *              deltaRotationVector[1] = sinThetaOverTwo * axisY;
207      *              deltaRotationVector[2] = sinThetaOverTwo * axisZ;
208      *              deltaRotationVector[3] = cosThetaOverTwo;
209      *          }
210      *          timestamp = event.timestamp;
211      *          float[] deltaRotationMatrix = new float[9];
212      *          SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
213      *          // User code should concatenate the delta rotation we computed with the current
214      *          // rotation in order to get the updated rotation.
215      *          // rotationCurrent = rotationCurrent * deltaRotationMatrix;
216      *     }
217      * </pre>
218      * <p>
219      * In practice, the gyroscope noise and offset will introduce some errors
220      * which need to be compensated for. This is usually done using the
221      * information from other sensors, but is beyond the scope of this document.
222      * </p>
223      * <h4>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:</h4>
224      * <ul>
225      * <li>values[0]: Ambient light level in SI lux units </li>
226      * </ul>
227      *
228      * <h4>{@link android.hardware.Sensor#TYPE_PRESSURE Sensor.TYPE_PRESSURE}:</h4>
229      * <ul>
230      * <li>values[0]: Atmospheric pressure in hPa (millibar) </li>
231      * </ul>
232      *
233      * <h4>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}:
234      * </h4>
235      *
236      * <ul>
237      * <li>values[0]: Proximity sensor distance measured in centimeters </li>
238      * </ul>
239      *
240      * <p>
241      * <b>Note:</b> Some proximity sensors only support a binary <i>near</i> or
242      * <i>far</i> measurement. In this case, the sensor should report its
243      * {@link android.hardware.Sensor#getMaximumRange() maximum range} value in
244      * the <i>far</i> state and a lesser value in the <i>near</i> state.
245      * </p>
246      *
247      *  <h4>{@link android.hardware.Sensor#TYPE_GRAVITY Sensor.TYPE_GRAVITY}:</h4>
248      *  <p>A three dimensional vector indicating the direction and magnitude of gravity.  Units
249      *  are m/s^2. The coordinate system is the same as is used by the acceleration sensor.</p>
250      *  <p><b>Note:</b> When the device is at rest, the output of the gravity sensor should be
251      *  identical to that of the accelerometer.</p>
252      *
253      *  <h4>
254      *  {@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION Sensor.TYPE_LINEAR_ACCELERATION}:
255      *  </h4> A three dimensional vector indicating acceleration along each device axis, not
256      *  including gravity. All values have units of m/s^2.  The coordinate system is the same as is
257      *  used by the acceleration sensor.
258      *  <p>The output of the accelerometer, gravity and  linear-acceleration sensors must obey the
259      *  following relation:</p>
260      *  <p><ul>acceleration = gravity + linear-acceleration</ul></p>
261      *
262      *  <h4>{@link android.hardware.Sensor#TYPE_ROTATION_VECTOR Sensor.TYPE_ROTATION_VECTOR}:</h4>
263      *  <p>The rotation vector represents the orientation of the device as a combination of an
264      *  <i>angle</i> and an <i>axis</i>, in which the device has rotated through an angle &#952
265      *  around an axis &lt;x, y, z>.</p>
266      *  <p>The three elements of the rotation vector are
267      *  &lt;x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>, such that the magnitude of the rotation
268      *  vector is equal to sin(&#952/2), and the direction of the rotation vector is equal to the
269      *  direction of the axis of rotation.</p>
270      *  </p>The three elements of the rotation vector are equal to
271      *  the last three components of a <b>unit</b> quaternion
272      *  &lt;cos(&#952/2), x*sin(&#952/2), y*sin(&#952/2), z*sin(&#952/2)>.</p>
273      *  <p>Elements of the rotation vector are unitless.
274      *  The x,y, and z axis are defined in the same way as the acceleration
275      *  sensor.</p>
276      *  The reference coordinate system is defined as a direct orthonormal basis,
277      *  where:
278      * </p>
279      *
280      * <ul>
281      * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
282      * the ground at the device's current location and roughly points East).</li>
283      * <li>Y is tangential to the ground at the device's current location and
284      * points towards magnetic north.</li>
285      * <li>Z points towards the sky and is perpendicular to the ground.</li>
286      * </ul>
287      *
288      * <p>
289      * <center><img src="../../../images/axis_globe.png"
290      * alt="World coordinate-system diagram." border="0" /></center>
291      * </p>
292      *
293      * <ul>
294      * <li> values[0]: x*sin(&#952/2) </li>
295      * <li> values[1]: y*sin(&#952/2) </li>
296      * <li> values[2]: z*sin(&#952/2) </li>
297      * <li> values[3]: cos(&#952/2) </li>
298      * <li> values[4]: estimated heading Accuracy (in radians) (-1 if unavailable)</li>
299      * </ul>
300      * <p> values[3], originally optional, will always be present from SDK Level 18 onwards.
301      * values[4] is a new value that has been added in SDK Level 18.
302      * </p>
303      *
304      * <h4>{@link android.hardware.Sensor#TYPE_ORIENTATION
305      * Sensor.TYPE_ORIENTATION}:</h4> All values are angles in degrees.
306      *
307      * <ul>
308      * <li> values[0]: Azimuth, angle between the magnetic north direction and the
309      * y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South,
310      * 270=West
311      * </p>
312      *
313      * <p>
314      * values[1]: Pitch, rotation around x-axis (-180 to 180), with positive
315      * values when the z-axis moves <b>toward</b> the y-axis.
316      * </p>
317      *
318      * <p>
319      * values[2]: Roll, rotation around the y-axis (-90 to 90)
320      * increasing as the device moves clockwise.
321      * </p>
322      * </ul>
323      *
324      * <p>
325      * <b>Note:</b> This definition is different from <b>yaw, pitch and roll</b>
326      * used in aviation where the X axis is along the long side of the plane
327      * (tail to nose).
328      * </p>
329      *
330      * <p>
331      * <b>Note:</b> This sensor type exists for legacy reasons, please use
332      * {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR
333      * rotation vector sensor type} and
334      * {@link android.hardware.SensorManager#getRotationMatrix
335      * getRotationMatrix()} in conjunction with
336      * {@link android.hardware.SensorManager#remapCoordinateSystem
337      * remapCoordinateSystem()} and
338      * {@link android.hardware.SensorManager#getOrientation getOrientation()} to
339      * compute these values instead.
340      * </p>
341      *
342      * <p>
343      * <b>Important note:</b> For historical reasons the roll angle is positive
344      * in the clockwise direction (mathematically speaking, it should be
345      * positive in the counter-clockwise direction).
346      * </p>
347      *
348      * <h4>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY
349      * Sensor.TYPE_RELATIVE_HUMIDITY}:</h4>
350      * <ul>
351      * <li> values[0]: Relative ambient air humidity in percent </li>
352      * </ul>
353      * <p>
354      * When relative ambient air humidity and ambient temperature are
355      * measured, the dew point and absolute humidity can be calculated.
356      * </p>
357      * <u>Dew Point</u>
358      * <p>
359      * The dew point is the temperature to which a given parcel of air must be
360      * cooled, at constant barometric pressure, for water vapor to condense
361      * into water.
362      * </p>
363      * <center><pre>
364      *                    ln(RH/100%) + m&#183;t/(T<sub>n</sub>+t)
365      * t<sub>d</sub>(t,RH) = T<sub>n</sub> &#183; ------------------------------
366      *                 m - [ln(RH/100%) + m&#183;t/(T<sub>n</sub>+t)]
367      * </pre></center>
368      * <dl>
369      * <dt>t<sub>d</sub></dt> <dd>dew point temperature in &deg;C</dd>
370      * <dt>t</dt>             <dd>actual temperature in &deg;C</dd>
371      * <dt>RH</dt>            <dd>actual relative humidity in %</dd>
372      * <dt>m</dt>             <dd>17.62</dd>
373      * <dt>T<sub>n</sub></dt> <dd>243.12 &deg;C</dd>
374      * </dl>
375      * <p>for example:</p>
376      * <pre class="prettyprint">
377      * h = Math.log(rh / 100.0) + (17.62 * t) / (243.12 + t);
378      * td = 243.12 * h / (17.62 - h);
379      * </pre>
380      * <u>Absolute Humidity</u>
381      * <p>
382      * The absolute humidity is the mass of water vapor in a particular volume
383      * of dry air. The unit is g/m<sup>3</sup>.
384      * </p>
385      * <center><pre>
386      *                    RH/100%&#183;A&#183;exp(m&#183;t/(T<sub>n</sub>+t))
387      * d<sub>v</sub>(t,RH) = 216.7 &#183; -------------------------
388      *                           273.15 + t
389      * </pre></center>
390      * <dl>
391      * <dt>d<sub>v</sub></dt> <dd>absolute humidity in g/m<sup>3</sup></dd>
392      * <dt>t</dt>             <dd>actual temperature in &deg;C</dd>
393      * <dt>RH</dt>            <dd>actual relative humidity in %</dd>
394      * <dt>m</dt>             <dd>17.62</dd>
395      * <dt>T<sub>n</sub></dt> <dd>243.12 &deg;C</dd>
396      * <dt>A</dt>             <dd>6.112 hPa</dd>
397      * </dl>
398      * <p>for example:</p>
399      * <pre class="prettyprint">
400      * dv = 216.7 *
401      * (rh / 100.0 * 6.112 * Math.exp(17.62 * t / (243.12 + t)) / (273.15 + t));
402      * </pre>
403      *
404      * <h4>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE Sensor.TYPE_AMBIENT_TEMPERATURE}:
405      * </h4>
406      *
407      * <ul>
408      * <li> values[0]: ambient (room) temperature in degree Celsius.</li>
409      * </ul>
410      *
411      *
412      * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED
413      * Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED}:</h4>
414      * Similar to {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD},
415      * but the hard iron calibration is reported separately instead of being included
416      * in the measurement. Factory calibration and temperature compensation will still
417      * be applied to the "uncalibrated" measurement. Assumptions that the magnetic field
418      * is due to the Earth's poles is avoided.
419      * <p>
420      * The values array is shown below:
421      * <ul>
422      * <li> values[0] = x_uncalib </li>
423      * <li> values[1] = y_uncalib </li>
424      * <li> values[2] = z_uncalib </li>
425      * <li> values[3] = x_bias </li>
426      * <li> values[4] = y_bias </li>
427      * <li> values[5] = z_bias </li>
428      * </ul>
429      * </p>
430      * <p>
431      * x_uncalib, y_uncalib, z_uncalib are the measured magnetic field in X, Y, Z axes.
432      * Soft iron and temperature calibrations are applied. But the hard iron
433      * calibration is not applied. The values are in micro-Tesla (uT).
434      * </p>
435      * <p>
436      * x_bias, y_bias, z_bias give the iron bias estimated in X, Y, Z axes.
437      * Each field is a component of the estimated hard iron calibration.
438      * The values are in micro-Tesla (uT).
439      * </p>
440      * <p> Hard iron - These distortions arise due to the magnetized iron, steel or permanent
441      * magnets on the device.
442      * Soft iron - These distortions arise due to the interaction with the earth's magnetic
443      * field.
444      * </p>
445      * <h4> {@link android.hardware.Sensor#TYPE_GAME_ROTATION_VECTOR
446      * Sensor.TYPE_GAME_ROTATION_VECTOR}:</h4>
447      * Identical to {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR} except that it
448      * doesn't use the geomagnetic field. Therefore the Y axis doesn't
449      * point north, but instead to some other reference, that reference is
450      * allowed to drift by the same order of magnitude as the gyroscope
451      * drift around the Z axis.
452      * <p>
453      * In the ideal case, a phone rotated and returning to the same real-world
454      * orientation will report the same game rotation vector
455      * (without using the earth's geomagnetic field). However, the orientation
456      * may drift somewhat over time. See {@link android.hardware.Sensor#TYPE_ROTATION_VECTOR}
457      * for a detailed description of the values. This sensor will not have
458      * the estimated heading accuracy value.
459      * </p>
460      *
461      * <h4> {@link android.hardware.Sensor#TYPE_GYROSCOPE_UNCALIBRATED
462      * Sensor.TYPE_GYROSCOPE_UNCALIBRATED}:</h4>
463      * All values are in radians/second and measure the rate of rotation
464      * around the X, Y and Z axis. An estimation of the drift on each axis is
465      * reported as well.
466      * <p>
467      * No gyro-drift compensation is performed. Factory calibration and temperature
468      * compensation is still applied to the rate of rotation (angular speeds).
469      * </p>
470      * <p>
471      * The coordinate system is the same as is used for the
472      * {@link android.hardware.Sensor#TYPE_ACCELEROMETER}
473      * Rotation is positive in the counter-clockwise direction (right-hand rule).
474      * That is, an observer looking from some positive location on the x, y or z axis
475      * at a device positioned on the origin would report positive rotation if the device
476      * appeared to be rotating counter clockwise.
477      * The range would at least be 17.45 rad/s (ie: ~1000 deg/s).
478      * <ul>
479      * <li> values[0] : angular speed (w/o drift compensation) around the X axis in rad/s </li>
480      * <li> values[1] : angular speed (w/o drift compensation) around the Y axis in rad/s </li>
481      * <li> values[2] : angular speed (w/o drift compensation) around the Z axis in rad/s </li>
482      * <li> values[3] : estimated drift around X axis in rad/s </li>
483      * <li> values[4] : estimated drift around Y axis in rad/s </li>
484      * <li> values[5] : estimated drift around Z axis in rad/s </li>
485      * </ul>
486      * </p>
487      * <p><b>Pro Tip:</b> Always use the length of the values array while performing operations
488      * on it. In earlier versions, this used to be always 3 which has changed now. </p>
489      *
490      *   <h4>{@link android.hardware.Sensor#TYPE_POSE_6DOF
491      * Sensor.TYPE_POSE_6DOF}:</h4>
492      *
493      * A TYPE_POSE_6DOF event consists of a rotation expressed as a quaternion and a translation
494      * expressed in SI units. The event also contains a delta rotation and translation that show
495      * how the device?s pose has changed since the previous sequence numbered pose.
496      * The event uses the cannonical Android Sensor axes.
497      *
498      *
499      * <ul>
500      * <li> values[0]: x*sin(&#952/2) </li>
501      * <li> values[1]: y*sin(&#952/2) </li>
502      * <li> values[2]: z*sin(&#952/2) </li>
503      * <li> values[3]: cos(&#952/2)   </li>
504      *
505      *
506      * <li> values[4]: Translation along x axis from an arbitrary origin. </li>
507      * <li> values[5]: Translation along y axis from an arbitrary origin. </li>
508      * <li> values[6]: Translation along z axis from an arbitrary origin. </li>
509      *
510      * <li> values[7]:  Delta quaternion rotation x*sin(&#952/2) </li>
511      * <li> values[8]:  Delta quaternion rotation y*sin(&#952/2) </li>
512      * <li> values[9]:  Delta quaternion rotation z*sin(&#952/2) </li>
513      * <li> values[10]: Delta quaternion rotation cos(&#952/2) </li>
514      *
515      * <li> values[11]: Delta translation along x axis. </li>
516      * <li> values[12]: Delta translation along y axis. </li>
517      * <li> values[13]: Delta translation along z axis. </li>
518      *
519      * <li> values[14]: Sequence number </li>
520      *
521      * </ul>
522      *
523      *   <h4>{@link android.hardware.Sensor#TYPE_STATIONARY_DETECT
524      * Sensor.TYPE_STATIONARY_DETECT}:</h4>
525      *
526      * A TYPE_STATIONARY_DETECT event is produced if the device has been
527      * stationary for at least 5 seconds with a maximal latency of 5
528      * additional seconds. ie: it may take up anywhere from 5 to 10 seconds
529      * afte the device has been at rest to trigger this event.
530      *
531      * The only allowed value is 1.0.
532      *
533      * <ul>
534      *  <li> values[0]: 1.0 </li>
535      * </ul>
536      *
537      *   <h4>{@link android.hardware.Sensor#TYPE_MOTION_DETECT
538      * Sensor.TYPE_MOTION_DETECT}:</h4>
539      *
540      * A TYPE_MOTION_DETECT event is produced if the device has been in
541      * motion  for at least 5 seconds with a maximal latency of 5
542      * additional seconds. ie: it may take up anywhere from 5 to 10 seconds
543      * afte the device has been at rest to trigger this event.
544      *
545      * The only allowed value is 1.0.
546      *
547      * <ul>
548      *  <li> values[0]: 1.0 </li>
549      * </ul>
550      *
551      *   <h4>{@link android.hardware.Sensor#TYPE_HEART_BEAT
552      * Sensor.TYPE_HEART_BEAT}:</h4>
553      *
554      * A sensor of this type returns an event everytime a heart beat peak is
555      * detected.
556      *
557      * Peak here ideally corresponds to the positive peak in the QRS complex of
558      * an ECG signal.
559      *
560      * <ul>
561      *  <li> values[0]: confidence</li>
562      * </ul>
563      *
564      * <p>
565      * A confidence value of 0.0 indicates complete uncertainty - that a peak
566      * is as likely to be at the indicated timestamp as anywhere else.
567      * A confidence value of 1.0 indicates complete certainly - that a peak is
568      * completely unlikely to be anywhere else on the QRS complex.
569      * </p>
570      *
571      * <h4>{@link android.hardware.Sensor#TYPE_LOW_LATENCY_OFFBODY_DETECT
572      * Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT}:</h4>
573      *
574      * <p>
575      * A sensor of this type returns an event every time the device transitions
576      * from off-body to on-body and from on-body to off-body (e.g. a wearable
577      * device being removed from the wrist would trigger an event indicating an
578      * off-body transition). The event returned will contain a single value to
579      * indicate off-body state:
580      * </p>
581      *
582      * <ul>
583      *  <li> values[0]: off-body state</li>
584      * </ul>
585      *
586      * <p>
587      *     Valid values for off-body state:
588      * <ul>
589      *  <li> 1.0 (device is on-body)</li>
590      *  <li> 0.0 (device is off-body)</li>
591      * </ul>
592      * </p>
593      *
594      * <p>
595      * When a sensor of this type is activated, it must deliver the initial
596      * on-body or off-body event representing the current device state within
597      * 5 seconds of activating the sensor.
598      * </p>
599      *
600      * <p>
601      * This sensor must be able to detect and report an on-body to off-body
602      * transition within 1 second of the device being removed from the body,
603      * and must be able to detect and report an off-body to on-body transition
604      * within 5 seconds of the device being put back onto the body.
605      * </p>
606      *
607      * <h4>{@link android.hardware.Sensor#TYPE_ACCELEROMETER_UNCALIBRATED
608      * Sensor.TYPE_ACCELEROMETER_UNCALIBRATED}:</h4> All values are in SI
609      * units (m/s^2)
610      *
611      * Similar to {@link android.hardware.Sensor#TYPE_ACCELEROMETER},
612      * Factory calibration and temperature compensation will still be applied
613      * to the "uncalibrated" measurement.
614      *
615      * <p>
616      * The values array is shown below:
617      * <ul>
618      * <li> values[0] = x_uncalib without bias compensation </li>
619      * <li> values[1] = y_uncalib without bias compensation </li>
620      * <li> values[2] = z_uncalib without bias compensation </li>
621      * <li> values[3] = estimated x_bias </li>
622      * <li> values[4] = estimated y_bias </li>
623      * <li> values[5] = estimated z_bias </li>
624      * </ul>
625      * </p>
626      * <p>
627      * x_uncalib, y_uncalib, z_uncalib are the measured acceleration in X, Y, Z
628      * axes similar to the  {@link android.hardware.Sensor#TYPE_ACCELEROMETER},
629      * without any bias correction (factory bias compensation and any
630      * temperature compensation is allowed).
631      * x_bias, y_bias, z_bias are the estimated biases.
632      * </p>
633      *
634      * <h4>{@link android.hardware.Sensor#TYPE_HINGE_ANGLE Sensor.TYPE_HINGE_ANGLE}:</h4>
635      *
636      * A sensor of this type measures the angle, in degrees, between two integral parts of the
637      * device. Movement of a hinge measured by this sensor type is expected to alter the ways in
638      * which the user may interact with the device, for example by unfolding or revealing a display.
639      *
640      * <ul>
641      *  <li> values[0]: Measured hinge angle between 0 and 360 degrees inclusive</li>
642      * </ul>
643      *
644      * @see GeomagneticField
645      */
646     public final float[] values;
647 
648     /**
649      * The sensor that generated this event. See
650      * {@link android.hardware.SensorManager SensorManager} for details.
651      */
652     public Sensor sensor;
653 
654     /**
655      * The accuracy of this event. See {@link android.hardware.SensorManager
656      * SensorManager} for details.
657      */
658     public int accuracy;
659 
660     /**
661      * The time in nanoseconds at which the event happened. For a given sensor,
662      * each new sensor event should be monotonically increasing using the same
663      * time base as {@link android.os.SystemClock#elapsedRealtimeNanos()}.
664      */
665     public long timestamp;
666 
667     @UnsupportedAppUsage
SensorEvent(int valueSize)668     SensorEvent(int valueSize) {
669         values = new float[valueSize];
670     }
671 
672     /**
673      * Construct a sensor event object by sensor object, accuracy, timestamp and values.
674      * This is only used for constructing an input device sensor event object.
675      * @hide
676      */
SensorEvent(@onNull Sensor sensor, int accuracy, long timestamp, float[] values)677     public SensorEvent(@NonNull Sensor sensor, int accuracy, long timestamp, float[] values) {
678         this.sensor = sensor;
679         this.accuracy = accuracy;
680         this.timestamp = timestamp;
681         this.values = values;
682     }
683 }
684