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