1 /* 2 * Copyright (C) 2015 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.support.car.hardware; 18 19 import android.location.GpsSatellite; 20 import android.location.Location; 21 import android.os.SystemClock; 22 import android.support.annotation.RestrictTo; 23 24 import static android.support.annotation.RestrictTo.Scope.GROUP_ID; 25 26 /** 27 * A CarSensorEvent object corresponds to a single sensor event coming from the car. Sensor 28 * data is stored in a sensor type-specific format in the object's float and byte arrays. 29 * </p> 30 * To aid in unmarshalling the object's data arrays, this class provides static nested classes and 31 * conversion methods (such as {@link DrivingStatusData} and {@link #getDrivingStatusData}). 32 * Additionally, calling a conversion method on a CarSensorEvent object with an inappropriate type 33 * results in an {@code UnsupportedOperationException} being thrown. 34 */ 35 public class CarSensorEvent { 36 37 38 /** 39 * Status for {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}: No restrictions. 40 */ 41 public static final int DRIVE_STATUS_UNRESTRICTED = 0; 42 /** 43 * Status for {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}: No video playback allowed. 44 * See {@link #getDrivingStatusData()}. 45 */ 46 public static final int DRIVE_STATUS_NO_VIDEO = 0x1; 47 /** 48 * Status for {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}: No keyboard or rotary 49 * controller input allowed. See {@link #getDrivingStatusData()}. 50 */ 51 public static final int DRIVE_STATUS_NO_KEYBOARD_INPUT = 0x2; 52 /** 53 * Status for {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}: No voice input allowed. 54 * See {@link #getDrivingStatusData()}. 55 */ 56 public static final int DRIVE_STATUS_NO_VOICE_INPUT = 0x4; 57 /** 58 * Status for {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}: No setup/configuration 59 * allowed. See {@link #getDrivingStatusData()}. 60 */ 61 public static final int DRIVE_STATUS_NO_CONFIG = 0x8; 62 /** 63 * Status for {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}: Limit displayed message 64 * length. See {@link #getDrivingStatusData()}. 65 */ 66 public static final int DRIVE_STATUS_LIMIT_MESSAGE_LEN = 0x10; 67 /** 68 * Status for {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}: All driving restrictions 69 * enabled. See {@link #getDrivingStatusData()}. 70 */ 71 public static final int DRIVE_STATUS_FULLY_RESTRICTED = DRIVE_STATUS_NO_VIDEO | 72 DRIVE_STATUS_NO_KEYBOARD_INPUT | DRIVE_STATUS_NO_VOICE_INPUT | DRIVE_STATUS_NO_CONFIG | 73 DRIVE_STATUS_LIMIT_MESSAGE_LEN; 74 /** 75 * Indices for {@link CarSensorManager#SENSOR_TYPE_COMPASS} in floatValues. 76 * Angles are in degrees. Can be NaN if not available. See {@link #getCompassData()}. 77 */ 78 public static final int INDEX_COMPASS_BEARING = 0; 79 /** 80 * Indices for {@link CarSensorManager#SENSOR_TYPE_COMPASS} in floatValues. 81 * Angles are in degrees. Can be NaN if not available. See {@link #getCompassData()}. 82 */ 83 public static final int INDEX_COMPASS_PITCH = 1; 84 /** 85 * Indices for {@link CarSensorManager#SENSOR_TYPE_COMPASS} in floatValues. 86 * Angles are in degrees. Can be NaN if not available. See {@link #getCompassData()}. 87 */ 88 public static final int INDEX_COMPASS_ROLL = 2; 89 90 91 /** 92 * Index for {@link CarSensorManager#SENSOR_TYPE_WHEEL_TICK_DISTANCE} in longValues. 93 */ 94 public static final int INDEX_WHEEL_DISTANCE_RESET_COUNT = 0; 95 public static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1; 96 public static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2; 97 public static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3; 98 public static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4; 99 100 private static final long MILLI_IN_NANOS = 1000000L; 101 102 /** Sensor type for this event, such as {@link CarSensorManager#SENSOR_TYPE_COMPASS}. */ 103 public final int sensorType; 104 105 /** 106 * When this data was acquired in car or received from car. It is the elapsed time of data 107 * reception from the car in nanoseconds since system boot. 108 */ 109 public final long timestamp; 110 /** 111 * Array holding float type of sensor data. If the sensor has single value, only floatValues[0] 112 * should be used. */ 113 public final float[] floatValues; 114 /** Array holding int type of sensor data. */ 115 public final int[] intValues; 116 /** array holding long int type of sensor data */ 117 public final long[] longValues; 118 119 private static final float[] EMPTY_FLOAT_ARRAY = {}; 120 private static final int[] EMPTY_INT_ARRAY = {}; 121 private static final long[] EMPTY_LONG_ARRAY = {}; 122 123 /** 124 * Constructs a {@link CarSensorEvent} from integer values. Handled by 125 * CarSensorManager implementations. App developers need not worry about constructing these 126 * objects. 127 * @hide 128 */ 129 @RestrictTo(GROUP_ID) 130 public CarSensorEvent(int sensorType, long timestamp, int floatValueSize, int intValueSize, 131 int longValueSize) { 132 this.sensorType = sensorType; 133 this.timestamp = timestamp; 134 floatValues = new float[floatValueSize]; 135 intValues = new int[intValueSize]; 136 longValues = new long[longValueSize]; 137 } 138 139 /** 140 * Constructor 141 * @param sensorType one of the {@link CarSensorManager}'s SENSOR_TYPE_* constants 142 * @param timestamp time since system start in nanoseconds 143 * @param floatValues {@code null} will be converted to an empty array 144 * @param intValues {@code null} will be converted to an empty array 145 * @param longValues {@code null} will be converted to an empty array 146 * @hide 147 */ 148 @RestrictTo(GROUP_ID) 149 public CarSensorEvent(int sensorType, long timestamp, float[] floatValues, int[] intValues, 150 long[] longValues) { 151 this.sensorType = sensorType; 152 this.timestamp = timestamp; 153 this.floatValues = (floatValues == null) ? EMPTY_FLOAT_ARRAY : floatValues; 154 this.intValues = (intValues == null) ? EMPTY_INT_ARRAY : intValues; 155 this.longValues = (longValues == null) ? EMPTY_LONG_ARRAY : longValues; 156 } 157 158 /** 159 * Constructor 160 * @param sensorType one of the {@link CarSensorManager}'s SENSOR_TYPE_* constants 161 * @param timestamp time since system start in nanoseconds 162 * @param floatValues {@code null} will be converted to an empty array 163 * @param byteValues bytes will be converted into the intValues array. {@code null} will be 164 * converted to an empty array. 165 * @param longValues {@code null} will be converted to an empty array 166 * @hide 167 */ 168 @RestrictTo(GROUP_ID) 169 public CarSensorEvent(int sensorType, long timestamp, float[] floatValues, byte[] byteValues, 170 long[] longValues) { 171 this.sensorType = sensorType; 172 this.timestamp = timestamp; 173 this.floatValues = (floatValues == null) ? EMPTY_FLOAT_ARRAY : floatValues; 174 if (byteValues == null) { 175 this.intValues = EMPTY_INT_ARRAY; 176 } else { 177 this.intValues = new int[byteValues.length]; 178 for (int i = 0; i < byteValues.length; i++) { 179 this.intValues[i] = byteValues[i]; 180 } 181 } 182 this.longValues = (longValues == null) ? EMPTY_LONG_ARRAY : longValues; 183 } 184 185 private void checkType(int type) { 186 if (sensorType == type) { 187 return; 188 } 189 throw new UnsupportedOperationException(String.format( 190 "Invalid sensor type: expected %d, got %d", type, sensorType)); 191 } 192 193 /** 194 * Holds data about the car's compass readings. See {@link #getCompassData()}. 195 */ 196 public static class CompassData { 197 /** The time in nanoseconds since system boot. */ 198 public final long timestamp; 199 /** The bearing in degrees. If unsupported by the car, this value is NaN. */ 200 public final float bearing; 201 /** 202 * The pitch in degrees. Nose down is positive. If unsupported by the car, this value is 203 * NaN. 204 */ 205 public final float pitch; 206 /** 207 * The roll in degrees. Right door down is positive. If unsupported by the car, this value 208 * is NaN. 209 */ 210 public final float roll; 211 212 /** @hide */ 213 @RestrictTo(GROUP_ID) 214 public CompassData(long timestamp, float bearing, float pitch, float roll) { 215 this.timestamp = timestamp; 216 this.bearing = bearing; 217 this.pitch = pitch; 218 this.roll = roll; 219 } 220 } 221 222 /** 223 * Convenience method for obtaining a {@link CompassData} object from a CarSensorEvent object 224 * with type {@link CarSensorManager#SENSOR_TYPE_COMPASS}. 225 * 226 * @return A CompassData object corresponding to the data contained in the CarSensorEvent. 227 */ 228 public CompassData getCompassData() { 229 checkType(CarSensorManager.SENSOR_TYPE_COMPASS); 230 return new CompassData(0, floatValues[INDEX_COMPASS_BEARING], 231 floatValues[INDEX_COMPASS_PITCH], floatValues[INDEX_COMPASS_ROLL]); 232 } 233 234 /** 235 * Indicates the state of the parking brake (engaged or not). See 236 * {@link #getParkingBrakeData()}. 237 */ 238 public static class ParkingBrakeData { 239 /** The time in nanoseconds since system boot. */ 240 public final long timestamp; 241 /** Returns {@code true} if the parking brake is engaged. */ 242 public final boolean isEngaged; 243 244 /** @hide */ 245 @RestrictTo(GROUP_ID) 246 public ParkingBrakeData(long timestamp, boolean isEngaged) { 247 this.timestamp = timestamp; 248 this.isEngaged = isEngaged; 249 } 250 } 251 252 /** 253 * Convenience method for obtaining a {@link ParkingBrakeData} object from a CarSensorEvent 254 * object with type {@link CarSensorManager#SENSOR_TYPE_PARKING_BRAKE}. See 255 * {@link #getParkingBrakeData()}. 256 * 257 * @return A ParkingBreakData object corresponding to the data contained in the CarSensorEvent. 258 */ 259 public ParkingBrakeData getParkingBrakeData() { 260 checkType(CarSensorManager.SENSOR_TYPE_PARKING_BRAKE); 261 return new ParkingBrakeData(timestamp, (intValues[0] == 1)); 262 } 263 264 /** 265 * Indicates if the system is in night mode (a state in which the screen is 266 * darkened or displays a darker color palette). See {@link #getNightData()}. 267 */ 268 public static class NightData { 269 /** The time in nanoseconds since system boot. */ 270 public final long timestamp; 271 /** Returns {@code true} if the system is in night mode. */ 272 public final boolean isNightMode; 273 274 /** @hide */ 275 @RestrictTo(GROUP_ID) 276 public NightData(long timestamp, boolean isNightMode) { 277 this.timestamp = timestamp; 278 this.isNightMode = isNightMode; 279 } 280 } 281 282 /** 283 * Convenience method for obtaining a {@link NightData} object from a CarSensorEvent object 284 * with type {@link CarSensorManager#SENSOR_TYPE_NIGHT}. 285 * 286 * @return A NightData object corresponding to the data contained in the CarSensorEvent. 287 */ 288 public NightData getNightData() { 289 checkType(CarSensorManager.SENSOR_TYPE_NIGHT); 290 return new NightData(timestamp, (intValues[0] == 1)); 291 } 292 293 /** 294 * Indicates the restrictions in effect based on the status of the vehicle. See 295 * {@link #getDrivingStatusData()}. 296 */ 297 public static class DrivingStatusData { 298 /** 299 * The time in nanoseconds since system boot. 300 */ 301 public final long timestamp; 302 /** 303 * A bitmask with the following field values: {@link #DRIVE_STATUS_NO_VIDEO}, 304 * {@link #DRIVE_STATUS_NO_KEYBOARD_INPUT}, {@link #DRIVE_STATUS_NO_VOICE_INPUT}, 305 * {@link #DRIVE_STATUS_NO_CONFIG}, {@link #DRIVE_STATUS_LIMIT_MESSAGE_LEN}. You may read 306 * this or use the convenience methods. 307 */ 308 public final int status; 309 310 /** @hide */ 311 @RestrictTo(GROUP_ID) 312 public DrivingStatusData(long timestamp, int status) { 313 this.timestamp = timestamp; 314 this.status = status; 315 } 316 317 /** 318 * @return Returns {@code true} if the keyboard is not allowed at this time. 319 */ 320 public boolean isKeyboardRestricted() { 321 return DRIVE_STATUS_NO_KEYBOARD_INPUT == (status & DRIVE_STATUS_NO_KEYBOARD_INPUT); 322 } 323 324 /** 325 * @return Returns {@code true} if voice commands are not allowed at this time. 326 */ 327 public boolean isVoiceRestricted() { 328 return DRIVE_STATUS_NO_VOICE_INPUT == (status & DRIVE_STATUS_NO_VOICE_INPUT); 329 } 330 331 /** 332 * @return Returns {@code true} if video is not allowed at this time. 333 */ 334 public boolean isVideoRestricted() { 335 return DRIVE_STATUS_NO_VIDEO == (status & DRIVE_STATUS_NO_VIDEO); 336 } 337 338 /** 339 * @return Returns {@code true} if configuration should not be performed at this time. 340 */ 341 public boolean isConfigurationRestricted() { 342 return DRIVE_STATUS_NO_CONFIG == (status & DRIVE_STATUS_NO_CONFIG); 343 } 344 345 /** 346 * @return Returns {@code true} if message length should be limited at this time. 347 */ 348 public boolean isMessageLengthRestricted() { 349 return DRIVE_STATUS_LIMIT_MESSAGE_LEN == (status & DRIVE_STATUS_LIMIT_MESSAGE_LEN); 350 } 351 352 /** 353 * @return Returns {@code true} if all restrictions are in place at this time. 354 */ 355 public boolean isFullyRestricted() { 356 return DRIVE_STATUS_FULLY_RESTRICTED == (status & DRIVE_STATUS_FULLY_RESTRICTED); 357 } 358 } 359 360 /** 361 * Convenience method for obtaining a {@link DrivingStatusData} object from a CarSensorEvent 362 * object with type {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}. 363 * 364 * @return A DrivingStatusData object corresponding to the data contained in the 365 * CarSensorEvent. 366 */ 367 public DrivingStatusData getDrivingStatusData() { 368 checkType(CarSensorManager.SENSOR_TYPE_DRIVING_STATUS); 369 return new DrivingStatusData(timestamp, intValues[0]); 370 } 371 372 373 /*things that are currently hidden*/ 374 375 376 /** 377 * Index in {@link #floatValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of 378 * sensor. This value is fuel level in percentile. 379 * @hide 380 */ 381 public static final int INDEX_FUEL_LEVEL_IN_PERCENTILE = 0; 382 /** 383 * Index in {@link #floatValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of 384 * sensor. This value is fuel level in coverable distance. The unit is Km. 385 * @hide 386 */ 387 public static final int INDEX_FUEL_LEVEL_IN_DISTANCE = 1; 388 /** 389 * Index in {@link #intValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of 390 * sensor. This value is set to 1 if fuel low level warning is on. 391 * @hide 392 */ 393 public static final int INDEX_FUEL_LOW_WARNING = 0; 394 395 /** 396 * GEAR_* represents meaning of intValues[0] for {@link CarSensorManager#SENSOR_TYPE_GEAR} 397 * sensor type. 398 * GEAR_NEUTRAL means transmission gear is in neutral state, and the car may be moving. 399 * @hide 400 */ 401 public static final int GEAR_NEUTRAL = 0; 402 /** 403 * intValues[0] from 1 to 99 represents transmission gear number for moving forward. 404 * GEAR_FIRST is for gear number 1. 405 * @hide 406 */ 407 public static final int GEAR_FIRST = 1; 408 /** Gear number 2. @hide */ 409 public static final int GEAR_SECOND = 2; 410 /** Gear number 3. @hide */ 411 public static final int GEAR_THIRD = 3; 412 /** Gear number 4. @hide */ 413 public static final int GEAR_FOURTH = 4; 414 /** Gear number 5. @hide */ 415 public static final int GEAR_FIFTH = 5; 416 /** Gear number 6. @hide */ 417 public static final int GEAR_SIXTH = 6; 418 /** Gear number 7. @hide */ 419 public static final int GEAR_SEVENTH = 7; 420 /** Gear number 8. @hide */ 421 public static final int GEAR_EIGHTH = 8; 422 /** Gear number 9. @hide */ 423 public static final int GEAR_NINTH = 9; 424 /** Gear number 10. @hide */ 425 public static final int GEAR_TENTH = 10; 426 /** 427 * This is for transmission without specific gear number for moving forward like CVT. It tells 428 * that car is in a transmission state to move it forward. 429 * @hide 430 */ 431 public static final int GEAR_DRIVE = 100; 432 /** Gear in parking state @hide */ 433 public static final int GEAR_PARK = 101; 434 /** Gear in reverse @hide */ 435 public static final int GEAR_REVERSE = 102; 436 437 /** 438 * Indices for {@link CarSensorManager#SENSOR_TYPE_GYROSCOPE} in floatValues. 439 * Rotation speed is in rad/s. Any component can be NaN if it is not available. 440 */ 441 /**@hide*/ 442 public static final int INDEX_GYROSCOPE_X = 0; 443 /**@hide*/ 444 public static final int INDEX_GYROSCOPE_Y = 1; 445 /**@hide*/ 446 public static final int INDEX_GYROSCOPE_Z = 2; 447 448 /** 449 * Indices for {@link CarSensorManager#SENSOR_TYPE_GPS_SATELLITE}. 450 * Both byte values and float values are used. 451 * Two first bytes encode number of satellites in-use/in-view (or 0xFF if unavailable). 452 * Then optionally with INDEX_GPS_SATELLITE_ARRAY_BYTE_OFFSET offset and interval 453 * INDEX_GPS_SATELLITE_ARRAY_BYTE_INTERVAL between elements are encoded boolean flags of 454 * whether particular satellite from in-view participate in in-use subset. 455 * Float values with INDEX_GPS_SATELLITE_ARRAY_FLOAT_OFFSET offset and interval 456 * INDEX_GPS_SATELLITE_ARRAY_FLOAT_INTERVAL between elements can optionally contain 457 * per-satellite values of signal strength and other values or NaN if unavailable. 458 */ 459 /**@hide*/ 460 public static final int INDEX_GPS_SATELLITE_NUMBER_IN_USE = 0; 461 /**@hide*/ 462 public static final int INDEX_GPS_SATELLITE_NUMBER_IN_VIEW = 1; 463 /**@hide*/ 464 public static final int INDEX_GPS_SATELLITE_ARRAY_INT_OFFSET = 2; 465 /**@hide*/ 466 public static final int INDEX_GPS_SATELLITE_ARRAY_INT_INTERVAL = 1; 467 /**@hide*/ 468 public static final int INDEX_GPS_SATELLITE_ARRAY_FLOAT_OFFSET = 0; 469 /**@hide*/ 470 public static final int INDEX_GPS_SATELLITE_ARRAY_FLOAT_INTERVAL = 4; 471 /**@hide*/ 472 public static final int INDEX_GPS_SATELLITE_PRN_OFFSET = 0; 473 /**@hide*/ 474 public static final int INDEX_GPS_SATELLITE_SNR_OFFSET = 1; 475 /**@hide*/ 476 public static final int INDEX_GPS_SATELLITE_AZIMUTH_OFFSET = 2; 477 /**@hide*/ 478 public static final int INDEX_GPS_SATELLITE_ELEVATION_OFFSET = 3; 479 480 481 /** 482 * Index for {@link CarSensorManager#SENSOR_TYPE_LOCATION} in floatValues. 483 * Each bit intValues[0] represents whether the corresponding data is present. 484 */ 485 /**@hide*/ 486 public static final int INDEX_LOCATION_LATITUDE = 0; 487 /**@hide*/ 488 public static final int INDEX_LOCATION_LONGITUDE = 1; 489 /**@hide*/ 490 public static final int INDEX_LOCATION_ACCURACY = 2; 491 /**@hide*/ 492 public static final int INDEX_LOCATION_ALTITUDE = 3; 493 /**@hide*/ 494 public static final int INDEX_LOCATION_SPEED = 4; 495 /**@hide*/ 496 public static final int INDEX_LOCATION_BEARING = 5; 497 /**@hide*/ 498 public static final int INDEX_LOCATION_MAX = INDEX_LOCATION_BEARING; 499 /**@hide*/ 500 public static final int INDEX_LOCATION_LATITUDE_INTS = 1; 501 /**@hide*/ 502 public static final int INDEX_LOCATION_LONGITUDE_INTS = 2; 503 504 505 /** 506 * Index for {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT} in floatValues. 507 * Temperature in Celsius degrees. 508 * @hide 509 */ 510 public static final int INDEX_ENVIRONMENT_TEMPERATURE = 0; 511 /** 512 * Index for {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT} in floatValues. 513 * Pressure in kPa. 514 * @hide 515 */ 516 public static final int INDEX_ENVIRONMENT_PRESSURE = 1; 517 518 519 /** 520 * Indices for {@link CarSensorManager#SENSOR_TYPE_ACCELEROMETER} in floatValues. 521 * Acceleration (gravity) is in m/s^2. Any component can be NaN if it is not available. 522 */ 523 /**@hide*/ 524 public static final int INDEX_ACCELEROMETER_X = 0; 525 /**@hide*/ 526 public static final int INDEX_ACCELEROMETER_Y = 1; 527 /**@hide*/ 528 public static final int INDEX_ACCELEROMETER_Z = 2; 529 530 /** @hide */ 531 public static class EnvironmentData { 532 /** The time in nanoseconds since system boot. */ 533 public final long timestamp; 534 /** If unsupported by the car, this value is NaN. */ 535 public final float temperature; 536 /** If unsupported by the car, this value is NaN. */ 537 public final float pressure; 538 539 /** @hide */ 540 @RestrictTo(GROUP_ID) 541 public EnvironmentData(long timestamp, float temperature, float pressure) { 542 this.timestamp = timestamp; 543 this.temperature = temperature; 544 this.pressure = pressure; 545 } 546 } 547 548 /** 549 * Convenience method for obtaining an {@link EnvironmentData} object from a CarSensorEvent 550 * object with type {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT}. 551 * 552 * @return an EnvironmentData object corresponding to the data contained in the CarSensorEvent. 553 * @hide 554 */ 555 public EnvironmentData getEnvironmentData() { 556 checkType(CarSensorManager.SENSOR_TYPE_ENVIRONMENT); 557 558 float temperature = floatValues[INDEX_ENVIRONMENT_TEMPERATURE]; 559 float pressure = floatValues[INDEX_ENVIRONMENT_PRESSURE]; 560 return new EnvironmentData(timestamp, temperature, pressure); 561 } 562 563 /** @hide */ 564 public static class GearData { 565 /** The time in nanoseconds since system boot. */ 566 public final long timestamp; 567 public final int gear; 568 569 /** @hide */ 570 @RestrictTo(GROUP_ID) 571 public GearData(long timestamp, int gear) { 572 this.timestamp = timestamp; 573 this.gear = gear; 574 } 575 } 576 577 /** 578 * Convenience method for obtaining a {@link GearData} object from a CarSensorEvent 579 * object with type {@link CarSensorManager#SENSOR_TYPE_GEAR}. 580 * 581 * @return a GearData object corresponding to the data contained in the CarSensorEvent. 582 * @hide 583 */ 584 public GearData getGearData() { 585 checkType(CarSensorManager.SENSOR_TYPE_GEAR); 586 return new GearData(timestamp, intValues[0]); 587 } 588 589 /** @hide */ 590 public static class FuelLevelData { 591 /** The time in nanoseconds since system boot. */ 592 public final long timestamp; 593 /** Fuel level in %. If unsupported by the car, this value is -1. */ 594 public final int level; 595 /** Fuel as possible range in Km. If unsupported by the car, this value is -1. */ 596 public final float range; 597 /** If unsupported by the car, this value is false. */ 598 public final boolean lowFuelWarning; 599 600 /** @hide */ 601 @RestrictTo(GROUP_ID) 602 public FuelLevelData(long timestamp, int level, float range, boolean lowFuelWarning) { 603 this.timestamp = timestamp; 604 this.level = level; 605 this.range = range; 606 this.lowFuelWarning = lowFuelWarning; 607 } 608 } 609 610 /** 611 * Convenience method for obtaining a {@link FuelLevelData} object from a CarSensorEvent object 612 * with type {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL}. 613 * 614 * @return A FuelLevel object corresponding to the data contained in the CarSensorEvent. 615 * @hide 616 */ 617 public FuelLevelData getFuelLevelData() { 618 checkType(CarSensorManager.SENSOR_TYPE_FUEL_LEVEL); 619 int level = -1; 620 float range = -1; 621 if (floatValues != null) { 622 if (floatValues[INDEX_FUEL_LEVEL_IN_PERCENTILE] >= 0) { 623 level = (int) floatValues[INDEX_FUEL_LEVEL_IN_PERCENTILE]; 624 } 625 626 if (floatValues[INDEX_FUEL_LEVEL_IN_DISTANCE] >= 0) { 627 range = floatValues[INDEX_FUEL_LEVEL_IN_DISTANCE]; 628 } 629 } 630 boolean lowFuelWarning = (intValues[0] == 1); 631 return new FuelLevelData(timestamp, level, range, lowFuelWarning); 632 } 633 634 /** @hide */ 635 public static class OdometerData { 636 /** The time in nanoseconds since system boot. */ 637 public final long timestamp; 638 public final float kms; 639 640 /** @hide */ 641 @RestrictTo(GROUP_ID) 642 public OdometerData(long timestamp, float kms) { 643 this.timestamp = timestamp; 644 this.kms = kms; 645 } 646 } 647 648 /** 649 * Convenience method for obtaining an {@link OdometerData} object from a CarSensorEvent 650 * object with type {@link CarSensorManager#SENSOR_TYPE_ODOMETER}. 651 * 652 * @return an OdometerData object corresponding to the data contained in the CarSensorEvent. 653 * @hide 654 */ 655 public OdometerData getOdometerData() { 656 checkType(CarSensorManager.SENSOR_TYPE_ODOMETER); 657 return new OdometerData(timestamp, floatValues[0]); 658 } 659 660 /** @hide */ 661 public static class RpmData { 662 /** The time in nanoseconds since system boot. */ 663 public final long timestamp; 664 public final float rpm; 665 666 /** @hide */ 667 @RestrictTo(GROUP_ID) 668 public RpmData(long timestamp, float rpm) { 669 this.timestamp = timestamp; 670 this.rpm = rpm; 671 } 672 } 673 674 /** 675 * Convenience method for obtaining a {@link RpmData} object from a CarSensorEvent object with 676 * type {@link CarSensorManager#SENSOR_TYPE_RPM}. 677 * 678 * @return An RpmData object corresponding to the data contained in the CarSensorEvent. 679 * @hide 680 */ 681 public RpmData getRpmData() { 682 checkType(CarSensorManager.SENSOR_TYPE_RPM); 683 return new RpmData(timestamp, floatValues[0]); 684 } 685 686 /** @hide */ 687 public static class CarSpeedData { 688 /** The time in nanoseconds since system boot. */ 689 public final long timestamp; 690 public final float carSpeed; 691 692 /** @hide */ 693 @RestrictTo(GROUP_ID) 694 public CarSpeedData(long timestamp, float carSpeed) { 695 this.timestamp = timestamp; 696 this.carSpeed = carSpeed; 697 } 698 } 699 700 /** 701 * Convenience method for obtaining a {@link CarSpeedData} object from a CarSensorEvent 702 * object with type {@link CarSensorManager#SENSOR_TYPE_CAR_SPEED}. 703 * 704 * @return a CarSpeedData object corresponding to the data contained in the CarSensorEvent. 705 * @hide 706 */ 707 public CarSpeedData getCarSpeedData() { 708 checkType(CarSensorManager.SENSOR_TYPE_CAR_SPEED); 709 return new CarSpeedData(timestamp, floatValues[0]); 710 } 711 712 /** 713 * Convenience method for obtaining a {@link Location} object from a CarSensorEvent 714 * object with type {@link CarSensorManager#SENSOR_TYPE_LOCATION}. 715 * 716 * @param location an optional output parameter which, if non-null, will be used by this method 717 * instead of a newly created object. 718 * @return a Location object corresponding to the data contained in the CarSensorEvent. 719 * @hide 720 */ 721 public Location getLocation(Location location) { 722 checkType(CarSensorManager.SENSOR_TYPE_LOCATION); 723 if (location == null) { 724 location = new Location("Car-GPS"); 725 } 726 // intValues[0]: bit flags for the presence of other values following. 727 int presense = intValues[0]; 728 if ((presense & (0x1 << INDEX_LOCATION_LATITUDE)) != 0) { 729 int latE7 = intValues[INDEX_LOCATION_LATITUDE_INTS]; 730 location.setLatitude(latE7 * 1e-7); 731 } 732 if ((presense & (0x1 << INDEX_LOCATION_LONGITUDE)) != 0) { 733 int longE7 = intValues[INDEX_LOCATION_LONGITUDE_INTS]; 734 location.setLongitude(longE7 * 1e-7); 735 } 736 if ((presense & (0x1 << INDEX_LOCATION_ACCURACY)) != 0) { 737 location.setAccuracy(floatValues[INDEX_LOCATION_ACCURACY]); 738 } 739 if ((presense & (0x1 << INDEX_LOCATION_ALTITUDE)) != 0) { 740 location.setAltitude(floatValues[INDEX_LOCATION_ALTITUDE]); 741 } 742 if ((presense & (0x1 << INDEX_LOCATION_SPEED)) != 0) { 743 location.setSpeed(floatValues[INDEX_LOCATION_SPEED]); 744 } 745 if ((presense & (0x1 << INDEX_LOCATION_BEARING)) != 0) { 746 location.setBearing(floatValues[INDEX_LOCATION_BEARING]); 747 } 748 location.setElapsedRealtimeNanos(timestamp); 749 // There is a risk of scheduler delaying 2nd elapsedRealtimeNs value. 750 // But will not try to fix it assuming that is acceptable as UTC time's accuracy is not 751 // guaranteed in Location data. 752 long currentTimeMs = System.currentTimeMillis(); 753 long elapsedRealtimeNs = SystemClock.elapsedRealtimeNanos(); 754 location.setTime( 755 currentTimeMs - (elapsedRealtimeNs - timestamp) / MILLI_IN_NANOS); 756 return location; 757 } 758 759 /** @hide */ 760 public static class AccelerometerData { 761 /** The time in nanoseconds since system boot. */ 762 public final long timestamp; 763 /** If unsupported by the car, this value is NaN. */ 764 public final float x; 765 /** If unsupported by the car, this value is NaN. */ 766 public final float y; 767 /** If unsupported by the car, this value is NaN. */ 768 public final float z; 769 770 /** @hide */ 771 @RestrictTo(GROUP_ID) 772 public AccelerometerData(long timestamp, float x, float y, float z) { 773 this.timestamp = timestamp; 774 this.x = x; 775 this.y = y; 776 this.z = z; 777 } 778 } 779 780 /** 781 * Convenience method for obtaining an {@link AccelerometerData} object from a CarSensorEvent 782 * object with type {@link CarSensorManager#SENSOR_TYPE_ACCELEROMETER}. 783 * 784 * @return An AccelerometerData object corresponding to the data contained in the 785 * CarSensorEvent. 786 * @hide 787 */ 788 public AccelerometerData getAccelerometerData() { 789 checkType(CarSensorManager.SENSOR_TYPE_ACCELEROMETER); 790 float x = floatValues[INDEX_ACCELEROMETER_X]; 791 float y = floatValues[INDEX_ACCELEROMETER_Y]; 792 float z = floatValues[INDEX_ACCELEROMETER_Z]; 793 return new AccelerometerData(timestamp, x, y, z); 794 } 795 796 /** @hide */ 797 public static class GyroscopeData { 798 /** The time in nanoseconds since system boot. */ 799 public final long timestamp; 800 /** If unsupported by the car, this value is NaN. */ 801 public final float x; 802 /** If unsupported by the car, this value is NaN. */ 803 public final float y; 804 /** If unsupported by the car, this value is NaN. */ 805 public final float z; 806 807 /** @hide */ 808 @RestrictTo(GROUP_ID) 809 public GyroscopeData(long timestamp, float x, float y, float z) { 810 this.timestamp = timestamp; 811 this.x = x; 812 this.y = y; 813 this.z = z; 814 } 815 } 816 817 /** 818 * Convenience method for obtaining a {@link GyroscopeData} object from a CarSensorEvent object 819 * with type {@link CarSensorManager#SENSOR_TYPE_GYROSCOPE}. 820 * 821 * @return A GyroscopeData object corresponding to the data contained in the CarSensorEvent. 822 * @hide 823 */ 824 public GyroscopeData getGyroscopeData() { 825 checkType(CarSensorManager.SENSOR_TYPE_GYROSCOPE); 826 float x = floatValues[INDEX_GYROSCOPE_X]; 827 float y = floatValues[INDEX_GYROSCOPE_Y]; 828 float z = floatValues[INDEX_GYROSCOPE_Z]; 829 return new GyroscopeData(timestamp, x, y, z); 830 } 831 832 // android.location.GpsSatellite doesn't have a public constructor, so that can't be used. 833 /** 834 * Class that contains GPS satellite status. For more info on meaning of these fields refer 835 * to the documentation to the {@link GpsSatellite} class. 836 * @hide 837 */ 838 public static class GpsSatelliteData { 839 /** The time in nanoseconds since system boot. */ 840 public final long timestamp; 841 /** 842 * Number of satellites used in GPS fix or -1 of unavailable. 843 */ 844 public final int numberInUse; 845 /** 846 * Number of satellites in view or -1 of unavailable. 847 */ 848 public final int numberInView; 849 /** 850 * Per-satellite flag if this satellite was used for GPS fix. 851 * Can be null if per-satellite data is unavailable. 852 */ 853 public final boolean[] usedInFix; 854 /** 855 * Per-satellite pseudo-random id. 856 * Can be null if per-satellite data is unavailable. 857 */ 858 public final int[] prn; 859 /** 860 * Per-satellite signal to noise ratio. 861 * Can be null if per-satellite data is unavailable. 862 */ 863 public final float[] snr; 864 /** 865 * Per-satellite azimuth. 866 * Can be null if per-satellite data is unavailable. 867 */ 868 public final float[] azimuth; 869 /** 870 * Per-satellite elevation. 871 * Can be null if per-satellite data is unavailable. 872 */ 873 public final float[] elevation; 874 875 /** @hide */ 876 @RestrictTo(GROUP_ID) 877 public GpsSatelliteData(long timestamp, int numberInUse, int numberInView, 878 boolean[] usedInFix, int[] prn, float[] snr, float[] azimuth, float[] elevation) { 879 this.timestamp = timestamp; 880 this.numberInUse = numberInUse; 881 this.numberInView = numberInView; 882 this.usedInFix = usedInFix; 883 this.prn = prn; 884 this.snr = snr; 885 this.azimuth = azimuth; 886 this.elevation = elevation; 887 } 888 } 889 890 private final int intOffset = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_INT_OFFSET; 891 private final int intInterval = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_INT_INTERVAL; 892 private final int floatOffset = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_FLOAT_OFFSET; 893 private final int floatInterval = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_FLOAT_INTERVAL; 894 895 /** 896 * Convenience method for obtaining a {@link GpsSatelliteData} object from a CarSensorEvent 897 * object with type {@link CarSensorManager#SENSOR_TYPE_GPS_SATELLITE} with optional 898 * per-satellite info. 899 * 900 * @param withPerSatellite whether to include per-satellite data. 901 * @return a GpsSatelliteData object corresponding to the data contained in the CarSensorEvent. 902 * @hide 903 */ 904 public GpsSatelliteData getGpsSatelliteData(boolean withPerSatellite) { 905 checkType(CarSensorManager.SENSOR_TYPE_GPS_SATELLITE); 906 907 //init all vars 908 int numberInUse = intValues[CarSensorEvent.INDEX_GPS_SATELLITE_NUMBER_IN_USE]; 909 int numberInView = intValues[CarSensorEvent.INDEX_GPS_SATELLITE_NUMBER_IN_VIEW]; 910 boolean[] usedInFix = null; 911 int[] prn = null; 912 float[] snr = null; 913 float[] azimuth = null; 914 float[] elevation = null; 915 916 if (withPerSatellite && numberInView >= 0) { 917 final int numberOfSats = (floatValues.length - floatOffset) / floatInterval; 918 usedInFix = new boolean[numberOfSats]; 919 prn = new int[numberOfSats]; 920 snr = new float[numberOfSats]; 921 azimuth = new float[numberOfSats]; 922 elevation = new float[numberOfSats]; 923 924 for (int i = 0; i < numberOfSats; ++i) { 925 int iInt = intOffset + intInterval * i; 926 int iFloat = floatOffset + floatInterval * i; 927 usedInFix[i] = intValues[iInt] != 0; 928 prn[i] = Math.round( 929 floatValues[iFloat + CarSensorEvent.INDEX_GPS_SATELLITE_PRN_OFFSET]); 930 snr[i] = 931 floatValues[iFloat + CarSensorEvent.INDEX_GPS_SATELLITE_SNR_OFFSET]; 932 azimuth[i] = floatValues[iFloat 933 + CarSensorEvent.INDEX_GPS_SATELLITE_AZIMUTH_OFFSET]; 934 elevation[i] = floatValues[iFloat 935 + CarSensorEvent.INDEX_GPS_SATELLITE_ELEVATION_OFFSET]; 936 } 937 } 938 return new GpsSatelliteData(timestamp, numberInUse, numberInView, usedInFix, prn, snr, 939 azimuth, elevation); 940 } 941 942 /** @hide */ 943 public static class CarWheelTickDistanceData { 944 public final long timestamp; 945 public final long sensorResetCount; 946 public final long frontLeftWheelDistanceMm; 947 public final long frontRightWheelDistanceMm; 948 public final long rearRightWheelDistanceMm; 949 public final long rearLeftWheelDistanceMm; 950 951 /** @hide */ 952 @RestrictTo(GROUP_ID) 953 public CarWheelTickDistanceData(long timestamp, long sensorResetCount, 954 long frontLeftWheelDistanceMm, long frontRightWheelDistanceMm, 955 long rearRightWheelDistanceMm, long rearLeftWheelDistanceMm) { 956 this.timestamp = timestamp; 957 this.sensorResetCount = sensorResetCount; 958 this.frontLeftWheelDistanceMm = frontLeftWheelDistanceMm; 959 this.frontRightWheelDistanceMm = frontRightWheelDistanceMm; 960 this.rearRightWheelDistanceMm = rearRightWheelDistanceMm; 961 this.rearLeftWheelDistanceMm = rearLeftWheelDistanceMm; 962 } 963 } 964 965 /** 966 * Convenience method for obtaining a {@link CarWheelTickDistanceData} object from a 967 * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_WHEEL_TICK_DISTANCE}. 968 * 969 * @return CarWheelTickDistanceData object corresponding to data contained in the CarSensorEvent 970 * @hide 971 */ 972 public CarWheelTickDistanceData getCarWheelTickDistanceData() { 973 checkType(CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE); 974 long sensorResetCount = longValues[INDEX_WHEEL_DISTANCE_RESET_COUNT]; 975 long frontLeftWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_FRONT_LEFT]; 976 long frontRightWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_FRONT_RIGHT]; 977 long rearRightWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_REAR_RIGHT]; 978 long rearLeftWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_REAR_LEFT]; 979 return new CarWheelTickDistanceData(timestamp, sensorResetCount, frontLeftWheelDistanceMm, 980 frontRightWheelDistanceMm, rearRightWheelDistanceMm, rearLeftWheelDistanceMm); 981 } 982 983 /** @hide */ 984 public static class CarAbsActiveData { 985 public final long timestamp; 986 public final boolean absIsActive; 987 988 /** @hide */ 989 @RestrictTo(GROUP_ID) 990 public CarAbsActiveData(long timestamp, boolean absIsActive) { 991 this.timestamp = timestamp; 992 this.absIsActive = absIsActive; 993 }; 994 } 995 996 /** 997 * Convenience method for obtaining a {@link CarAbsActiveData} object from a CarSensorEvent 998 * object with type {@link CarSensorManager#SENSOR_TYPE_ABS_ACTIVE}. 999 * 1000 * @param data an optional output parameter which, if non-null, will be used by this method 1001 * instead of a newly created object. 1002 * @return a CarAbsActiveData object corresponding to data contained in the CarSensorEvent. 1003 * @hide 1004 */ 1005 public CarAbsActiveData getCarAbsActiveData() { 1006 checkType(CarSensorManager.SENSOR_TYPE_ABS_ACTIVE); 1007 boolean absIsActive = intValues[0] == 1; 1008 return new CarAbsActiveData(timestamp, absIsActive); 1009 } 1010 1011 /** @hide */ 1012 public static class CarTractionControlActiveData { 1013 public final long timestamp; 1014 public final boolean tractionControlIsActive; 1015 1016 /** @hide */ 1017 @RestrictTo(GROUP_ID) 1018 public CarTractionControlActiveData(long timestamp, boolean tractionControlIsActive) { 1019 this.timestamp = timestamp; 1020 this.tractionControlIsActive = tractionControlIsActive; 1021 }; 1022 } 1023 1024 /** 1025 * Convenience method for obtaining a {@link CarTractionControlActiveData} object from a 1026 * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_TRACTION_CONTROL_ACTIVE}. 1027 * 1028 * @param data an optional output parameter which, if non-null, will be used by this method 1029 * instead of a newly created object. 1030 * @return a CarTractionControlActiveData object corresponding to data contained in the 1031 * CarSensorEvent. 1032 * @hide 1033 */ 1034 public CarTractionControlActiveData getCarTractionControlActiveData() { 1035 checkType(CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE); 1036 boolean tractionControlIsActive = intValues[0] == 1; 1037 return new CarTractionControlActiveData(timestamp, tractionControlIsActive); 1038 } 1039 1040 /** @hide */ 1041 @Override 1042 public String toString() { 1043 StringBuilder sb = new StringBuilder(); 1044 sb.append(getClass().getName() + "["); 1045 sb.append("type:" + Integer.toHexString(sensorType)); 1046 if (floatValues != null && floatValues.length > 0) { 1047 sb.append(" float values:"); 1048 for (float v: floatValues) { 1049 sb.append(" " + v); 1050 } 1051 } 1052 if (intValues != null && intValues.length > 0) { 1053 sb.append(" int values:"); 1054 for (int v: intValues) { 1055 sb.append(" " + v); 1056 } 1057 } 1058 if (longValues != null && longValues.length > 0) { 1059 sb.append(" long values:"); 1060 for (long v: longValues) { 1061 sb.append(" " + v); 1062 } 1063 } 1064 sb.append("]"); 1065 return sb.toString(); 1066 } 1067 } 1068