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