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