diff options
author | Steve Paik <spaik@google.com> | 2017-07-19 20:17:54 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-07-19 20:17:54 +0000 |
commit | 60f0a4492a6b598e09f0d1400361b5b6b895c337 (patch) | |
tree | 86561b70831d33c8379b754712e7c34954643857 | |
parent | 2b59e8caac5578595d65876e3f0aff34a4d56ac4 (diff) | |
parent | 289ab99688d226518e47a7e47c9ffc20f221f0a6 (diff) | |
download | Car-60f0a4492a6b598e09f0d1400361b5b6b895c337.tar.gz |
Merge "Add SENSOR_TYPE_WHEEL_DISTANCE + friends"
22 files changed, 510 insertions, 59 deletions
diff --git a/car-lib/api/current.txt b/car-lib/api/current.txt index fb94b19ead..a461995fb9 100644 --- a/car-lib/api/current.txt +++ b/car-lib/api/current.txt @@ -18,6 +18,7 @@ package android.car { field public static final java.lang.String PERMISSION_FUEL = "android.car.permission.CAR_FUEL"; field public static final java.lang.String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE"; field public static final java.lang.String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; + field public static final java.lang.String PERMISSION_VEHICLE_DYNAMICS_STATE = "android.car.permission.VEHICLE_DYNAMICS_STATE"; field public static final java.lang.String SENSOR_SERVICE = "sensor"; field public static final int VERSION = 2; // 0x2 } @@ -213,8 +214,14 @@ package android.car.hardware { field public static final int INDEX_FUEL_LEVEL_IN_DISTANCE = 1; // 0x1 field public static final int INDEX_FUEL_LEVEL_IN_PERCENTILE = 0; // 0x0 field public static final int INDEX_FUEL_LOW_WARNING = 0; // 0x0 + field public static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1; // 0x1 + field public static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2; // 0x2 + field public static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4; // 0x4 + field public static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3; // 0x3 + field public static final int INDEX_WHEEL_DISTANCE_RESET_COUNT = 0; // 0x0 field public final float[] floatValues; field public final int[] intValues; + field public final long[] longValues; field public int sensorType; field public long timestamp; } @@ -237,6 +244,7 @@ package android.car.hardware { field public static final int SENSOR_RATE_FASTEST = 0; // 0x0 field public static final int SENSOR_RATE_NORMAL = 3; // 0x3 field public static final int SENSOR_RATE_UI = 2; // 0x2 + field public static final int SENSOR_TYPE_ABS_ACTIVE = 24; // 0x18 field public static final int SENSOR_TYPE_CAR_SPEED = 2; // 0x2 field public static final int SENSOR_TYPE_DRIVING_STATUS = 11; // 0xb field public static final int SENSOR_TYPE_ENVIRONMENT = 12; // 0xc @@ -247,7 +255,9 @@ package android.car.hardware { field public static final int SENSOR_TYPE_ODOMETER = 4; // 0x4 field public static final int SENSOR_TYPE_PARKING_BRAKE = 6; // 0x6 field public static final int SENSOR_TYPE_RPM = 3; // 0x3 + field public static final int SENSOR_TYPE_TRACTION_CONTROL_ACTIVE = 25; // 0x19 field public static final int SENSOR_TYPE_VENDOR_EXTENSION_END = 1879048191; // 0x6fffffff + field public static final int SENSOR_TYPE_WHEEL_TICK_DISTANCE = 23; // 0x17 } public static abstract interface CarSensorManager.OnSensorChangedListener { diff --git a/car-lib/api/system-current.txt b/car-lib/api/system-current.txt index 88f0576d29..889af9f33b 100644 --- a/car-lib/api/system-current.txt +++ b/car-lib/api/system-current.txt @@ -30,6 +30,7 @@ package android.car { field public static final java.lang.String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE"; field public static final deprecated java.lang.String PERMISSION_MOCK_VEHICLE_HAL = "android.car.permission.CAR_MOCK_VEHICLE_HAL"; field public static final java.lang.String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; + field public static final java.lang.String PERMISSION_VEHICLE_DYNAMICS_STATE = "android.car.permission.VEHICLE_DYNAMICS_STATE"; field public static final java.lang.String PERMISSION_VENDOR_EXTENSION = "android.car.permission.CAR_VENDOR_EXTENSION"; field public static final java.lang.String PROJECTION_SERVICE = "projection"; field public static final java.lang.String RADIO_SERVICE = "radio"; @@ -725,8 +726,14 @@ package android.car.hardware { field public static final int INDEX_FUEL_LEVEL_IN_DISTANCE = 1; // 0x1 field public static final int INDEX_FUEL_LEVEL_IN_PERCENTILE = 0; // 0x0 field public static final int INDEX_FUEL_LOW_WARNING = 0; // 0x0 + field public static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1; // 0x1 + field public static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2; // 0x2 + field public static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4; // 0x4 + field public static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3; // 0x3 + field public static final int INDEX_WHEEL_DISTANCE_RESET_COUNT = 0; // 0x0 field public final float[] floatValues; field public final int[] intValues; + field public final long[] longValues; field public int sensorType; field public long timestamp; } @@ -749,6 +756,7 @@ package android.car.hardware { field public static final int SENSOR_RATE_FASTEST = 0; // 0x0 field public static final int SENSOR_RATE_NORMAL = 3; // 0x3 field public static final int SENSOR_RATE_UI = 2; // 0x2 + field public static final int SENSOR_TYPE_ABS_ACTIVE = 24; // 0x18 field public static final int SENSOR_TYPE_CAR_SPEED = 2; // 0x2 field public static final int SENSOR_TYPE_DRIVING_STATUS = 11; // 0xb field public static final int SENSOR_TYPE_ENVIRONMENT = 12; // 0xc @@ -759,7 +767,9 @@ package android.car.hardware { field public static final int SENSOR_TYPE_ODOMETER = 4; // 0x4 field public static final int SENSOR_TYPE_PARKING_BRAKE = 6; // 0x6 field public static final int SENSOR_TYPE_RPM = 3; // 0x3 + field public static final int SENSOR_TYPE_TRACTION_CONTROL_ACTIVE = 25; // 0x19 field public static final int SENSOR_TYPE_VENDOR_EXTENSION_END = 1879048191; // 0x6fffffff + field public static final int SENSOR_TYPE_WHEEL_TICK_DISTANCE = 23; // 0x17 } public static abstract interface CarSensorManager.OnSensorChangedListener { diff --git a/car-lib/src/android/car/Car.java b/car-lib/src/android/car/Car.java index ac2b4cac0b..7440df1315 100644 --- a/car-lib/src/android/car/Car.java +++ b/car-lib/src/android/car/Car.java @@ -144,6 +144,10 @@ public final class Car { /** Permission necessary to access car's speed. */ public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; + /** Permission necessary to access car's dynamics state. */ + public static final String PERMISSION_VEHICLE_DYNAMICS_STATE = + "android.car.permission.VEHICLE_DYNAMICS_STATE"; + /** * Permission necessary to change car audio volume through {@link CarAudioManager}. */ diff --git a/car-lib/src/android/car/hardware/CarSensorEvent.java b/car-lib/src/android/car/hardware/CarSensorEvent.java index 680b9ab762..52f363d980 100644 --- a/car-lib/src/android/car/hardware/CarSensorEvent.java +++ b/car-lib/src/android/car/hardware/CarSensorEvent.java @@ -137,6 +137,17 @@ public class CarSensorEvent implements Parcelable { * Pressure in kPa. */ public static final int INDEX_ENVIRONMENT_PRESSURE = 1; + /** + * Index for {@link CarSensorManager#SENSOR_TYPE_WHEEL_TICK_DISTANCE} in longValues. RESET_COUNT + * is incremented whenever the HAL detects that a sensor reset has occurred. It represents to + * the upper layer that the WHEEL_DISTANCE values will not be contiguous with other values + * reported with a different RESET_COUNT. + */ + public static final int INDEX_WHEEL_DISTANCE_RESET_COUNT = 0; + public static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1; + public static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2; + public static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3; + public static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4; private static final long MILLI_IN_NANOS = 1000000L; @@ -144,8 +155,8 @@ public class CarSensorEvent implements Parcelable { public int sensorType; /** - * When this data was acquired in car or received from car. It is elapsed real-time of data - * reception from car in nanoseconds since system boot. + * When this data was received from car. It is elapsed real-time of data reception from car in + * nanoseconds since system boot. */ public long timestamp; /** @@ -154,6 +165,8 @@ public class CarSensorEvent implements Parcelable { public final float[] floatValues; /** array holding int type of sensor data */ public final int[] intValues; + /** array holding long int type of sensor data */ + public final long[] longValues; /** @hide */ public CarSensorEvent(Parcel in) { @@ -166,6 +179,9 @@ public class CarSensorEvent implements Parcelable { intValues = new int[len]; in.readIntArray(intValues); // version 1 up to here + len = in.readInt(); + longValues = new long[len]; + in.readLongArray(longValues); } @Override @@ -181,6 +197,8 @@ public class CarSensorEvent implements Parcelable { dest.writeFloatArray(floatValues); dest.writeInt(intValues.length); dest.writeIntArray(intValues); + dest.writeInt(longValues.length); + dest.writeLongArray(longValues); } public static final Parcelable.Creator<CarSensorEvent> CREATOR @@ -195,19 +213,23 @@ public class CarSensorEvent implements Parcelable { }; /** @hide */ - public CarSensorEvent(int sensorType, long timestamp, int floatValueSize, int intValueSize) { + public CarSensorEvent(int sensorType, long timestamp, int floatValueSize, int intValueSize, + int longValueSize) { this.sensorType = sensorType; this.timestamp = timestamp; floatValues = new float[floatValueSize]; intValues = new int[intValueSize]; + longValues = new long[longValueSize]; } /** @hide */ - CarSensorEvent(int sensorType, long timestamp, float[] floatValues, int[] intValues) { + CarSensorEvent(int sensorType, long timestamp, float[] floatValues, int[] intValues, + long[] longValues) { this.sensorType = sensorType; this.timestamp = timestamp; this.floatValues = floatValues; this.intValues = intValues; + this.longValues = longValues; } private void checkType(int type) { @@ -493,6 +515,100 @@ public class CarSensorEvent implements Parcelable { } /** @hide */ + public static class CarWheelTickDistanceData { + public long timestamp; + public long sensorResetCount; + public long frontLeftWheelDistanceMm; + public long frontRightWheelDistanceMm; + public long rearRightWheelDistanceMm; + public long rearLeftWheelDistanceMm; + + /** @hide */ + private CarWheelTickDistanceData() {}; + } + + /** + * Convenience method for obtaining a {@link CarWheelTickDistanceData} object from a + * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_WHEEL_TICK_DISTANCE}. + * + * @param data an optional output parameter which, if non-null, will be used by this method + * instead of a newly created object. + * @return CarWheelTickDistanceData object corresponding to data contained in the CarSensorEvent + * @hide + */ + public CarWheelTickDistanceData getCarWheelTickDistanceData(CarWheelTickDistanceData data) { + checkType(CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE); + if (data == null) { + data = new CarWheelTickDistanceData(); + } + data.timestamp = timestamp; + data.sensorResetCount = longValues[INDEX_WHEEL_DISTANCE_RESET_COUNT]; + data.frontLeftWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_FRONT_LEFT]; + data.frontRightWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_FRONT_RIGHT]; + data.rearRightWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_REAR_RIGHT]; + data.rearLeftWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_REAR_LEFT]; + return data; + } + + /** @hide */ + public static class CarAbsActiveData { + public long timestamp; + public boolean absIsActive; + + /** @hide */ + private CarAbsActiveData() {}; + } + + /** + * Convenience method for obtaining a {@link CarAbsActiveData} object from a CarSensorEvent + * object with type {@link CarSensorManager#SENSOR_TYPE_ABS_ACTIVE}. + * + * @param data an optional output parameter which, if non-null, will be used by this method + * instead of a newly created object. + * @return a CarAbsActiveData object corresponding to data contained in the CarSensorEvent. + * @hide + */ + public CarAbsActiveData getCarAbsActiveData(CarAbsActiveData data) { + checkType(CarSensorManager.SENSOR_TYPE_ABS_ACTIVE); + if (data == null) { + data = new CarAbsActiveData(); + } + data.timestamp = timestamp; + data.absIsActive = intValues[0] == 1; + return data; + } + + /** @hide */ + public static class CarTractionControlActiveData { + public long timestamp; + public boolean tractionControlIsActive; + + /** @hide */ + private CarTractionControlActiveData() {}; + } + + /** + * Convenience method for obtaining a {@link CarTractionControlActiveData} object from a + * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_TRACTION_CONTROL_ACTIVE}. + * + * @param data an optional output parameter which, if non-null, will be used by this method + * instead of a newly created object. + * @return a CarTractionControlActiveData object corresponding to data contained in the + * CarSensorEvent. + * @hide + */ + public CarTractionControlActiveData getCarTractionControlActiveData( + CarTractionControlActiveData data) { + checkType(CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE); + if (data == null) { + data = new CarTractionControlActiveData(); + } + data.timestamp = timestamp; + data.tractionControlIsActive = intValues[0] == 1; + return data; + } + + /** @hide */ @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -510,6 +626,12 @@ public class CarSensorEvent implements Parcelable { sb.append(" " + v); } } + if (longValues != null && longValues.length > 0) { + sb.append(" long values:"); + for (long v: longValues) { + sb.append(" " + v); + } + } sb.append("]"); return sb.toString(); } diff --git a/car-lib/src/android/car/hardware/CarSensorManager.java b/car-lib/src/android/car/hardware/CarSensorManager.java index 4fbc2cd619..796da7f978 100644 --- a/car-lib/src/android/car/hardware/CarSensorManager.java +++ b/car-lib/src/android/car/hardware/CarSensorManager.java @@ -48,22 +48,22 @@ import java.util.function.Consumer; */ public final class CarSensorManager implements CarManagerBase { /** @hide */ - public static final int SENSOR_TYPE_RESERVED1 = 1; + public static final int SENSOR_TYPE_RESERVED1 = 1; /** * This sensor represents vehicle speed in m/s. * Sensor data in {@link CarSensorEvent} is a float which will be >= 0. * This requires {@link Car#PERMISSION_SPEED} permission. */ - public static final int SENSOR_TYPE_CAR_SPEED = 2; + public static final int SENSOR_TYPE_CAR_SPEED = 2; /** * Represents engine RPM of the car. Sensor data in {@link CarSensorEvent} is a float. */ - public static final int SENSOR_TYPE_RPM = 3; + public static final int SENSOR_TYPE_RPM = 3; /** * Total travel distance of the car in Kilometer. Sensor data is a float. * This requires {@link Car#PERMISSION_MILEAGE} permission. */ - public static final int SENSOR_TYPE_ODOMETER = 4; + public static final int SENSOR_TYPE_ODOMETER = 4; /** * Indicates fuel level of the car. * In {@link CarSensorEvent}, floatValues[{@link CarSensorEvent#INDEX_FUEL_LEVEL_IN_PERCENTILE}] @@ -74,67 +74,84 @@ public final class CarSensorManager implements CarManagerBase { * condition. * This requires {@link Car#PERMISSION_FUEL} permission. */ - public static final int SENSOR_TYPE_FUEL_LEVEL = 5; + public static final int SENSOR_TYPE_FUEL_LEVEL = 5; /** * Represents the current status of parking brake. Sensor data in {@link CarSensorEvent} is an * intValues[0]. Value of 1 represents parking brake applied while 0 means the other way * around. For this sensor, rate in {@link #registerListener(OnSensorChangedListener, int, int)} * will be ignored and all changes will be notified. */ - public static final int SENSOR_TYPE_PARKING_BRAKE = 6; + public static final int SENSOR_TYPE_PARKING_BRAKE = 6; /** * This represents the current position of transmission gear. Sensor data in * {@link CarSensorEvent} is an intValues[0]. For the meaning of the value, check * {@link CarSensorEvent#GEAR_NEUTRAL} and other GEAR_*. */ - public static final int SENSOR_TYPE_GEAR = 7; + public static final int SENSOR_TYPE_GEAR = 7; /** @hide */ - public static final int SENSOR_TYPE_RESERVED8 = 8; + public static final int SENSOR_TYPE_RESERVED8 = 8; /** * Day/night sensor. Sensor data is intValues[0]. */ - public static final int SENSOR_TYPE_NIGHT = 9; + public static final int SENSOR_TYPE_NIGHT = 9; /** @hide */ - public static final int SENSOR_TYPE_RESERVED10 = 10; + public static final int SENSOR_TYPE_RESERVED10 = 10; /** * Represents the current driving status of car. Different user interaction should be used * depending on the current driving status. Driving status is intValues[0]. */ - public static final int SENSOR_TYPE_DRIVING_STATUS = 11; + public static final int SENSOR_TYPE_DRIVING_STATUS = 11; /** * Environment like temperature and pressure. */ - public static final int SENSOR_TYPE_ENVIRONMENT = 12; + public static final int SENSOR_TYPE_ENVIRONMENT = 12; /** @hide */ - public static final int SENSOR_TYPE_RESERVED13 = 13; + public static final int SENSOR_TYPE_RESERVED13 = 13; /** @hide */ - public static final int SENSOR_TYPE_RESERVED14 = 14; + public static final int SENSOR_TYPE_RESERVED14 = 14; /** @hide */ - public static final int SENSOR_TYPE_RESERVED15 = 15; + public static final int SENSOR_TYPE_RESERVED15 = 15; /** @hide */ - public static final int SENSOR_TYPE_RESERVED16 = 16; + public static final int SENSOR_TYPE_RESERVED16 = 16; /** @hide */ - public static final int SENSOR_TYPE_RESERVED17 = 17; + public static final int SENSOR_TYPE_RESERVED17 = 17; /** @hide */ - public static final int SENSOR_TYPE_RESERVED18 = 18; + public static final int SENSOR_TYPE_RESERVED18 = 18; /** @hide */ - public static final int SENSOR_TYPE_RESERVED19 = 19; + public static final int SENSOR_TYPE_RESERVED19 = 19; /** @hide */ - public static final int SENSOR_TYPE_RESERVED20 = 20; + public static final int SENSOR_TYPE_RESERVED20 = 20; /** @hide */ - public static final int SENSOR_TYPE_RESERVED21 = 21; - + public static final int SENSOR_TYPE_RESERVED21 = 21; /** * Represents ignition state. The value should be one of the constants that starts with * IGNITION_STATE_* in {@link CarSensorEvent}. */ - public static final int SENSOR_TYPE_IGNITION_STATE = 22; + public static final int SENSOR_TYPE_IGNITION_STATE = 22; + /** + * Represents wheel distance in millimeters. Some cars may not have individual sensors on each + * wheel. If a value is not available, Long.MAX_VALUE will be reported. The wheel distance + * accumulates over time. It increments on forward movement, and decrements on reverse. Wheel + * distance shall be reset to zero each time a vehicle is started by the user. + * This requires {@link Car#PERMISSION_SPEED} permission. + */ + public static final int SENSOR_TYPE_WHEEL_TICK_DISTANCE = 23; + /** + * Set to true when ABS is active. This sensor is event driven. + * This requires {@link Car#PERMISSION_VEHICLE_DYNAMICS_STATE} permission. + */ + public static final int SENSOR_TYPE_ABS_ACTIVE = 24; + /** + * Set to true when traction control is active. This sensor is event driven. + * This requires {@link Car#PERMISSION_VEHICLE_DYNAMICS_STATE} permission. + */ + public static final int SENSOR_TYPE_TRACTION_CONTROL_ACTIVE = 25; /** * Sensor type bigger than this is invalid. Always update this after adding a new sensor. * @hide */ - private static final int SENSOR_TYPE_MAX = SENSOR_TYPE_IGNITION_STATE; + private static final int SENSOR_TYPE_MAX = SENSOR_TYPE_TRACTION_CONTROL_ACTIVE; /** * Sensors defined in this range [{@link #SENSOR_TYPE_VENDOR_EXTENSION_START}, @@ -162,6 +179,9 @@ public final class CarSensorManager implements CarManagerBase { SENSOR_TYPE_DRIVING_STATUS, SENSOR_TYPE_ENVIRONMENT, SENSOR_TYPE_IGNITION_STATE, + SENSOR_TYPE_WHEEL_TICK_DISTANCE, + SENSOR_TYPE_ABS_ACTIVE, + SENSOR_TYPE_TRACTION_CONTROL_ACTIVE, }) @Retention(RetentionPolicy.SOURCE) public @interface SensorType {} @@ -291,9 +311,11 @@ public final class CarSensorManager implements CarManagerBase { * If the same listener is registered again for the same sensor, it will be either ignored or * updated depending on the rate. * <p> - * Requires {@link Car#PERMISSION_SPEED} for {@link #SENSOR_TYPE_CAR_SPEED}, - * {@link Car#PERMISSION_MILEAGE} for {@link #SENSOR_TYPE_ODOMETER}, - * or {@link Car#PERMISSION_FUEL} for {@link #SENSOR_TYPE_FUEL_LEVEL}. + * Requires {@link Car#PERMISSION_SPEED} for {@link #SENSOR_TYPE_CAR_SPEED} and + * {@link #SENSOR_TYPE_WHEEL_TICK_DISTANCE}, {@link Car#PERMISSION_MILEAGE} for + * {@link #SENSOR_TYPE_ODOMETER}, {@link Car#PERMISSION_FUEL} for + * {@link #SENSOR_TYPE_FUEL_LEVEL}, or {@link Car#PERMISSION_VEHICLE_DYNAMICS_STATE} for + * {@link #SENSOR_TYPE_ABS_ACTIVE} and {@link #SENSOR_TYPE_TRACTION_CONTROL_ACTIVE} * * @param listener * @param sensorType sensor type to subscribe. @@ -310,7 +332,8 @@ public final class CarSensorManager implements CarManagerBase { * @throws SecurityException if missing the appropriate permission */ @RequiresPermission(anyOf={Manifest.permission.ACCESS_FINE_LOCATION, Car.PERMISSION_SPEED, - Car.PERMISSION_MILEAGE, Car.PERMISSION_FUEL}, conditional=true) + Car.PERMISSION_MILEAGE, Car.PERMISSION_FUEL, Car.PERMISSION_VEHICLE_DYNAMICS_STATE}, + conditional=true) public boolean registerListener(OnSensorChangedListener listener, @SensorType int sensorType, @SensorRate int rate) throws CarNotConnectedException, IllegalArgumentException { assertSensorType(sensorType); diff --git a/car-support-lib/api/current.txt b/car-support-lib/api/current.txt index 86f9850309..3d9c32bc86 100644 --- a/car-support-lib/api/current.txt +++ b/car-support-lib/api/current.txt @@ -100,8 +100,14 @@ package android.support.car.hardware { field public static final int INDEX_COMPASS_BEARING = 0; // 0x0 field public static final int INDEX_COMPASS_PITCH = 1; // 0x1 field public static final int INDEX_COMPASS_ROLL = 2; // 0x2 + field public static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1; // 0x1 + field public static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2; // 0x2 + field public static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4; // 0x4 + field public static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3; // 0x3 + field public static final int INDEX_WHEEL_DISTANCE_RESET_COUNT = 0; // 0x0 field public final float[] floatValues; field public final int[] intValues; + field public final long[] longValues; field public final int sensorType; field public final long timestamp; } @@ -144,10 +150,13 @@ package android.support.car.hardware { method public abstract void removeListener(android.support.car.hardware.CarSensorManager.OnSensorChangedListener, int); field public static final int SENSOR_RATE_FASTEST = 0; // 0x0 field public static final int SENSOR_RATE_NORMAL = 3; // 0x3 + field public static final int SENSOR_TYPE_ABS_ACTIVE = 24; // 0x18 field public static final int SENSOR_TYPE_COMPASS = 1; // 0x1 field public static final int SENSOR_TYPE_DRIVING_STATUS = 11; // 0xb field public static final int SENSOR_TYPE_NIGHT = 9; // 0x9 field public static final int SENSOR_TYPE_PARKING_BRAKE = 6; // 0x6 + field public static final int SENSOR_TYPE_TRACTION_CONTROL_ACTIVE = 25; // 0x19 + field public static final int SENSOR_TYPE_WHEEL_TICK_DISTANCE = 23; // 0x17 } public static abstract interface CarSensorManager.OnSensorChangedListener { diff --git a/car-support-lib/proguard-release.flags b/car-support-lib/proguard-release.flags index daccb0dc52..6ec8b3c969 100644 --- a/car-support-lib/proguard-release.flags +++ b/car-support-lib/proguard-release.flags @@ -5227,8 +5227,14 @@ public static int INDEX_COMPASS_BEARING; public static int INDEX_COMPASS_PITCH; public static int INDEX_COMPASS_ROLL; + public static int INDEX_WHEEL_DISTANCE_FRONT_LEFT; + public static int INDEX_WHEEL_DISTANCE_FRONT_RIGHT; + public static int INDEX_WHEEL_DISTANCE_REAR_LEFT; + public static int INDEX_WHEEL_DISTANCE_REAR_RIGHT; + public static int INDEX_WHEEL_DISTANCE_RESET_COUNT; public float[] floatValues; public int[] intValues; + public long[] longValues; public int sensorType; public long timestamp; } @@ -5286,10 +5292,13 @@ public static int SENSOR_RATE_FASTEST; public static int SENSOR_RATE_NORMAL; + public static int SENSOR_TYPE_ABS_ACTIVE; public static int SENSOR_TYPE_COMPASS; public static int SENSOR_TYPE_DRIVING_STATUS; public static int SENSOR_TYPE_NIGHT; public static int SENSOR_TYPE_PARKING_BRAKE; + public static int SENSOR_TYPE_TRACTION_CONTROL_ACTIVE; + public static int SENSOR_TYPE_WHEEL_TICK_DISTANCE; } -keep class android.support.car.hardware.CarSensorManager$OnSensorChangedListener { diff --git a/car-support-lib/src/android/support/car/Car.java b/car-support-lib/src/android/support/car/Car.java index c47b6508d8..a374d87cac 100644 --- a/car-support-lib/src/android/support/car/Car.java +++ b/car-support-lib/src/android/support/car/Car.java @@ -178,6 +178,12 @@ public class Car { */ public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; /** + * Permission necessary to access car dynamics state. + * @hide + */ + public static final String PERMISSION_VEHICLE_DYNAMICS_STATE = + "android.car.permission.VEHICLE_DYNAMICS_STATE"; + /** * Permission necessary to access a car-specific communication channel. */ public static final String PERMISSION_VENDOR_EXTENSION = diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorEvent.java b/car-support-lib/src/android/support/car/hardware/CarSensorEvent.java index 215cddf9ce..f7b4dba22b 100644 --- a/car-support-lib/src/android/support/car/hardware/CarSensorEvent.java +++ b/car-support-lib/src/android/support/car/hardware/CarSensorEvent.java @@ -88,6 +88,15 @@ public class CarSensorEvent { public static final int INDEX_COMPASS_ROLL = 2; + /** + * Index for {@link CarSensorManager#SENSOR_TYPE_WHEEL_TICK_DISTANCE} in longValues. + */ + public static final int INDEX_WHEEL_DISTANCE_RESET_COUNT = 0; + public static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1; + public static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2; + public static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3; + public static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4; + private static final long MILLI_IN_NANOS = 1000000L; /** Sensor type for this event, such as {@link CarSensorManager#SENSOR_TYPE_COMPASS}. */ @@ -104,9 +113,12 @@ public class CarSensorEvent { public final float[] floatValues; /** Array holding int type of sensor data. */ public final int[] intValues; + /** array holding long int type of sensor data */ + public final long[] longValues; private static final float[] EMPTY_FLOAT_ARRAY = {}; private static final int[] EMPTY_INT_ARRAY = {}; + private static final long[] EMPTY_LONG_ARRAY = {}; /** * Constructs a {@link CarSensorEvent} from integer values. Handled by @@ -115,11 +127,13 @@ public class CarSensorEvent { * @hide */ @RestrictTo(GROUP_ID) - public CarSensorEvent(int sensorType, long timestamp, int floatValueSize, int intValueSize) { + public CarSensorEvent(int sensorType, long timestamp, int floatValueSize, int intValueSize, + int longValueSize) { this.sensorType = sensorType; this.timestamp = timestamp; floatValues = new float[floatValueSize]; intValues = new int[intValueSize]; + longValues = new long[longValueSize]; } /** @@ -128,14 +142,17 @@ public class CarSensorEvent { * @param timestamp time since system start in nanoseconds * @param floatValues {@code null} will be converted to an empty array * @param intValues {@code null} will be converted to an empty array + * @param longValues {@code null} will be converted to an empty array * @hide */ @RestrictTo(GROUP_ID) - public CarSensorEvent(int sensorType, long timestamp, float[] floatValues, int[] intValues) { + public CarSensorEvent(int sensorType, long timestamp, float[] floatValues, int[] intValues, + long[] longValues) { this.sensorType = sensorType; this.timestamp = timestamp; this.floatValues = (floatValues == null) ? EMPTY_FLOAT_ARRAY : floatValues; this.intValues = (intValues == null) ? EMPTY_INT_ARRAY : intValues; + this.longValues = (longValues == null) ? EMPTY_LONG_ARRAY : longValues; } /** @@ -145,10 +162,12 @@ public class CarSensorEvent { * @param floatValues {@code null} will be converted to an empty array * @param byteValues bytes will be converted into the intValues array. {@code null} will be * converted to an empty array. + * @param longValues {@code null} will be converted to an empty array * @hide */ @RestrictTo(GROUP_ID) - public CarSensorEvent(int sensorType, long timestamp, float[] floatValues, byte[] byteValues) { + public CarSensorEvent(int sensorType, long timestamp, float[] floatValues, byte[] byteValues, + long[] longValues) { this.sensorType = sensorType; this.timestamp = timestamp; this.floatValues = (floatValues == null) ? EMPTY_FLOAT_ARRAY : floatValues; @@ -160,6 +179,7 @@ public class CarSensorEvent { this.intValues[i] = byteValues[i]; } } + this.longValues = (longValues == null) ? EMPTY_LONG_ARRAY : longValues; } private void checkType(int type) { @@ -920,6 +940,104 @@ public class CarSensorEvent { } /** @hide */ + public static class CarWheelTickDistanceData { + public final long timestamp; + public final long sensorResetCount; + public final long frontLeftWheelDistanceMm; + public final long frontRightWheelDistanceMm; + public final long rearRightWheelDistanceMm; + public final long rearLeftWheelDistanceMm; + + /** @hide */ + @RestrictTo(GROUP_ID) + public CarWheelTickDistanceData(long timestamp, long sensorResetCount, + long frontLeftWheelDistanceMm, long frontRightWheelDistanceMm, + long rearRightWheelDistanceMm, long rearLeftWheelDistanceMm) { + this.timestamp = timestamp; + this.sensorResetCount = sensorResetCount; + this.frontLeftWheelDistanceMm = frontLeftWheelDistanceMm; + this.frontRightWheelDistanceMm = frontRightWheelDistanceMm; + this.rearRightWheelDistanceMm = rearRightWheelDistanceMm; + this.rearLeftWheelDistanceMm = rearLeftWheelDistanceMm; + } + } + + /** + * Convenience method for obtaining a {@link CarWheelTickDistanceData} object from a + * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_WHEEL_TICK_DISTANCE}. + * + * @return CarWheelTickDistanceData object corresponding to data contained in the CarSensorEvent + * @hide + */ + public CarWheelTickDistanceData getCarWheelTickDistanceData() { + checkType(CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE); + long sensorResetCount = longValues[INDEX_WHEEL_DISTANCE_RESET_COUNT]; + long frontLeftWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_FRONT_LEFT]; + long frontRightWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_FRONT_RIGHT]; + long rearRightWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_REAR_RIGHT]; + long rearLeftWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_REAR_LEFT]; + return new CarWheelTickDistanceData(timestamp, sensorResetCount, frontLeftWheelDistanceMm, + frontRightWheelDistanceMm, rearRightWheelDistanceMm, rearLeftWheelDistanceMm); + } + + /** @hide */ + public static class CarAbsActiveData { + public final long timestamp; + public final boolean absIsActive; + + /** @hide */ + @RestrictTo(GROUP_ID) + public CarAbsActiveData(long timestamp, boolean absIsActive) { + this.timestamp = timestamp; + this.absIsActive = absIsActive; + }; + } + + /** + * Convenience method for obtaining a {@link CarAbsActiveData} object from a CarSensorEvent + * object with type {@link CarSensorManager#SENSOR_TYPE_ABS_ACTIVE}. + * + * @param data an optional output parameter which, if non-null, will be used by this method + * instead of a newly created object. + * @return a CarAbsActiveData object corresponding to data contained in the CarSensorEvent. + * @hide + */ + public CarAbsActiveData getCarAbsActiveData() { + checkType(CarSensorManager.SENSOR_TYPE_ABS_ACTIVE); + boolean absIsActive = intValues[0] == 1; + return new CarAbsActiveData(timestamp, absIsActive); + } + + /** @hide */ + public static class CarTractionControlActiveData { + public final long timestamp; + public final boolean tractionControlIsActive; + + /** @hide */ + @RestrictTo(GROUP_ID) + public CarTractionControlActiveData(long timestamp, boolean tractionControlIsActive) { + this.timestamp = timestamp; + this.tractionControlIsActive = tractionControlIsActive; + }; + } + + /** + * Convenience method for obtaining a {@link CarTractionControlActiveData} object from a + * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_TRACTION_CONTROL_ACTIVE}. + * + * @param data an optional output parameter which, if non-null, will be used by this method + * instead of a newly created object. + * @return a CarTractionControlActiveData object corresponding to data contained in the + * CarSensorEvent. + * @hide + */ + public CarTractionControlActiveData getCarTractionControlActiveData() { + checkType(CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE); + boolean tractionControlIsActive = intValues[0] == 1; + return new CarTractionControlActiveData(timestamp, tractionControlIsActive); + } + + /** @hide */ @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -937,6 +1055,12 @@ public class CarSensorEvent { sb.append(" " + v); } } + if (longValues != null && longValues.length > 0) { + sb.append(" long values:"); + for (long v: longValues) { + sb.append(" " + v); + } + } sb.append("]"); return sb.toString(); } diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorManager.java b/car-support-lib/src/android/support/car/hardware/CarSensorManager.java index adc976ce22..f705a9f4e3 100644 --- a/car-support-lib/src/android/support/car/hardware/CarSensorManager.java +++ b/car-support-lib/src/android/support/car/hardware/CarSensorManager.java @@ -124,6 +124,23 @@ public abstract class CarSensorManager implements CarManagerBase { public static final int SENSOR_TYPE_RESERVED21 = 21; /** @hide */ public static final int SENSOR_TYPE_RESERVED22 = 22; + /** + * Represents wheel distance in millimeters. Some cars may not have individual sensors on each + * wheel. If a value is not available, -1 will be reported. The wheel distance accumulates + * over time. + * Requires {@link Car#PERMISSION_MILEAGE} permission. + */ + public static final int SENSOR_TYPE_WHEEL_TICK_DISTANCE = 23; + /** + * Set to true when ABS is active. This sensor is event driven. + * Requires {@link Car#PERMISSION_VEHICLE_DYNAMICS_STATE} permission. + */ + public static final int SENSOR_TYPE_ABS_ACTIVE = 24; + /** + * Set to true when traction control is active. This sensor is event driven. + * Requires {@link Car#PERMISSION_VEHICLE_DYNAMICS_STATE} permission. + */ + public static final int SENSOR_TYPE_TRACTION_CONTROL_ACTIVE = 25; /** * Sensors defined in this range [{@link #SENSOR_TYPE_VENDOR_EXTENSION_START}, @@ -155,7 +172,10 @@ public abstract class CarSensorManager implements CarManagerBase { SENSOR_TYPE_ENVIRONMENT, SENSOR_TYPE_ACCELEROMETER, SENSOR_TYPE_GPS_SATELLITE, - SENSOR_TYPE_GYROSCOPE + SENSOR_TYPE_GYROSCOPE, + SENSOR_TYPE_WHEEL_TICK_DISTANCE, + SENSOR_TYPE_ABS_ACTIVE, + SENSOR_TYPE_TRACTION_CONTROL_ACTIVE }) @Retention(RetentionPolicy.SOURCE) public @interface SensorType {} @@ -230,7 +250,8 @@ public abstract class CarSensorManager implements CarManagerBase { * @throws SecurityException if missing the appropriate permission. */ @RequiresPermission(anyOf={Manifest.permission.ACCESS_FINE_LOCATION, Car.PERMISSION_SPEED, - Car.PERMISSION_MILEAGE, Car.PERMISSION_FUEL}, conditional=true) + Car.PERMISSION_MILEAGE, Car.PERMISSION_FUEL, Car.PERMISSION_VEHICLE_DYNAMICS_STATE}, + conditional=true) public abstract boolean addListener(OnSensorChangedListener listener, @SensorType int sensorType, @SensorRate int rate) throws CarNotConnectedException, IllegalArgumentException; diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java b/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java index 2692267b09..5fa207cc9f 100644 --- a/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java +++ b/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java @@ -173,7 +173,7 @@ public class CarSensorManagerEmbedded extends CarSensorManager { return null; } return new CarSensorEvent(event.sensorType, event.timestamp, event.floatValues, - event.intValues); + event.intValues, event.longValues); } private static class OnSensorChangedListenerProxy diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorsProxy.java b/car-support-lib/src/android/support/car/hardware/CarSensorsProxy.java index a0eb482d8e..e110d0792f 100644 --- a/car-support-lib/src/android/support/car/hardware/CarSensorsProxy.java +++ b/car-support-lib/src/android/support/car/hardware/CarSensorsProxy.java @@ -322,7 +322,7 @@ class CarSensorsProxy { case CarSensorManager.SENSOR_TYPE_COMPASS: if (mLastMagneticFieldDataTime != 0 && mLastAccelerometerDataTime != 0) { event = new CarSensorEvent(sensorType, Math.max(mLastMagneticFieldDataTime, - mLastAccelerometerDataTime), 3, 0); + mLastAccelerometerDataTime), 3, 0, 0); SensorManager.getRotationMatrix(mR, mI, mLastAccelerometerData, mLastMagneticFieldData); SensorManager.getOrientation(mR, mOrientation); @@ -336,13 +336,13 @@ class CarSensorsProxy { break; case CarSensorManager.SENSOR_TYPE_LOCATION: if (mLastLocationTime != 0) { - event = new CarSensorEvent(sensorType, mLastLocationTime, 6, 3); + event = new CarSensorEvent(sensorType, mLastLocationTime, 6, 3, 0); populateLocationCarSensorEvent(event, mLastLocation); } break; case CarSensorManager.SENSOR_TYPE_ACCELEROMETER: if (mLastAccelerometerDataTime != 0) { - event = new CarSensorEvent(sensorType, mLastAccelerometerDataTime, 3, 0); + event = new CarSensorEvent(sensorType, mLastAccelerometerDataTime, 3, 0, 0); event.floatValues[CarSensorEvent.INDEX_ACCELEROMETER_X] = mLastAccelerometerData[0]; event.floatValues[CarSensorEvent.INDEX_ACCELEROMETER_Y] = @@ -358,7 +358,7 @@ class CarSensorsProxy { break; case CarSensorManager.SENSOR_TYPE_GYROSCOPE: if (mLastGyroscopeDataTime != 0) { - event = new CarSensorEvent(sensorType, mLastGyroscopeDataTime, 3, 0); + event = new CarSensorEvent(sensorType, mLastGyroscopeDataTime, 3, 0, 0); event.floatValues[CarSensorEvent.INDEX_GYROSCOPE_X] = mLastGyroscopeData[0]; event.floatValues[CarSensorEvent.INDEX_GYROSCOPE_Y] = mLastGyroscopeData[1]; event.floatValues[CarSensorEvent.INDEX_GYROSCOPE_Z] = mLastGyroscopeData[2]; @@ -430,7 +430,7 @@ class CarSensorsProxy { int intValuesSize = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_INT_INTERVAL * numberInView + CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_INT_OFFSET; event = new CarSensorEvent(CarSensorManager.SENSOR_TYPE_GPS_SATELLITE, mLastGpsStatusTime, - floatValuesSize, intValuesSize); + floatValuesSize, intValuesSize, 0); event.intValues[CarSensorEvent.INDEX_GPS_SATELLITE_NUMBER_IN_USE] = numberInUse; event.intValues[CarSensorEvent.INDEX_GPS_SATELLITE_NUMBER_IN_VIEW] = numberInView; int i = 0; diff --git a/service/AndroidManifest.xml b/service/AndroidManifest.xml index 175a8bb091..5fa6072af2 100644 --- a/service/AndroidManifest.xml +++ b/service/AndroidManifest.xml @@ -61,6 +61,12 @@ android:label="@string/car_permission_label_speed" android:description="@string/car_permission_desc_speed" /> <permission + android:name="android.car.permission.VEHICLE_DYNAMICS_STATE" + android:permissionGroup="android.permission-group.CAR_INFORMATION" + android:protectionLevel="dangerous" + android:label="@string/car_permission_label_vehicle_dynamics_state" + android:description="@string/car_permission_desc_vehicle_dynamics_state" /> + <permission android:name="android.car.permission.CAR_VENDOR_EXTENSION" android:protectionLevel="system|signature" android:label="@string/car_permission_label_vendor_extension" diff --git a/service/res/values/strings.xml b/service/res/values/strings.xml index 1cd53ca1d8..e17b53367d 100644 --- a/service/res/values/strings.xml +++ b/service/res/values/strings.xml @@ -44,6 +44,10 @@ <string name="car_permission_label_speed">Car speed</string> <!-- Permission text: can access your car's speed [CHAR LIMIT=NONE] --> <string name="car_permission_desc_speed">Access your car\'s speed.</string> + <!-- Permission text: can access your car's dynamics state [CHAR LIMIT=NONE] --> + <string name="car_permission_label_vehicle_dynamics_state">Vehicle dynamics state</string> + <!-- Permission text: can access your car's dynamic state [CHAR LIMIT=NONE] --> + <string name="car_permission_desc_vehicle_dynamics_state">Access your car\'s dynamics state</string> <!-- Permission text: apps can access car-manufacturer specific data [CHAR LIMIT=NONE] --> <string name="car_permission_label_vendor_extension">Car vendor channel</string> <!-- Permission text: apps can access car-manufacturer specific data [CHAR LIMIT=NONE] --> diff --git a/service/src/com/android/car/CarSensorEventFactory.java b/service/src/com/android/car/CarSensorEventFactory.java index fbae0edfe1..6497e16be9 100644 --- a/service/src/com/android/car/CarSensorEventFactory.java +++ b/service/src/com/android/car/CarSensorEventFactory.java @@ -17,29 +17,50 @@ package com.android.car; import android.car.hardware.CarSensorEvent; +import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; //TODO add memory pool and recycling public class CarSensorEventFactory { public static CarSensorEvent createBooleanEvent(int sensorType, long timestamp, boolean value) { - CarSensorEvent event = new CarSensorEvent(sensorType, timestamp, 0, 1); + CarSensorEvent event = new CarSensorEvent(sensorType, timestamp, 0, 1, 0); event.intValues[0] = value ? 1 : 0; return event; } public static CarSensorEvent createIntEvent(int sensorType, long timestamp, int value) { - CarSensorEvent event = new CarSensorEvent(sensorType, timestamp, 0, 1); + CarSensorEvent event = new CarSensorEvent(sensorType, timestamp, 0, 1, 0); event.intValues[0] = value; return event; } public static CarSensorEvent createFloatEvent(int sensorType, long timestamp, float value) { - CarSensorEvent event = new CarSensorEvent(sensorType, timestamp, 1, 0); + CarSensorEvent event = new CarSensorEvent(sensorType, timestamp, 1, 0, 0); event.floatValues[0] = value; return event; } + public static CarSensorEvent createComplexEvent(int sensorType, long timestamp, + VehiclePropValue v) { + int numFloats = v.value.floatValues.size(); + int numInts = v.value.int32Values.size(); + int numLongs = v.value.int64Values.size(); + CarSensorEvent event = new CarSensorEvent(sensorType, timestamp, numFloats, numInts, + numLongs); + // Copy arraylist elements into final arrays + for (int i=0; i<numFloats; i++) { + event.floatValues[i] = v.value.floatValues.get(i); + } + for (int i=0; i<numInts; i++) { + event.intValues[i] = v.value.int32Values.get(i); + } + for (int i=0; i<numLongs; i++) { + event.longValues[i] = v.value.int64Values.get(i); + } + return event; + } + public static void returnToPool(CarSensorEvent event) { //TODO } diff --git a/service/src/com/android/car/CarSensorService.java b/service/src/com/android/car/CarSensorService.java index ffb13ca946..44a33b4bae 100644 --- a/service/src/com/android/car/CarSensorService.java +++ b/service/src/com/android/car/CarSensorService.java @@ -420,6 +420,7 @@ public class CarSensorService extends ICarSensor.Stub switch (sensorType) { case CarSensorManager.SENSOR_TYPE_CAR_SPEED: case CarSensorManager.SENSOR_TYPE_RPM: + case CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE: return true; case CarSensorManager.SENSOR_TYPE_ODOMETER: case CarSensorManager.SENSOR_TYPE_FUEL_LEVEL: @@ -454,6 +455,7 @@ public class CarSensorService extends ICarSensor.Stub String permission = null; switch (sensorType) { case CarSensorManager.SENSOR_TYPE_CAR_SPEED: + case CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE: permission = Car.PERMISSION_SPEED; break; case CarSensorManager.SENSOR_TYPE_ODOMETER: @@ -462,6 +464,10 @@ public class CarSensorService extends ICarSensor.Stub case CarSensorManager.SENSOR_TYPE_FUEL_LEVEL: permission = Car.PERMISSION_FUEL; break; + case CarSensorManager.SENSOR_TYPE_ABS_ACTIVE: + case CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE: + permission = Car.PERMISSION_VEHICLE_DYNAMICS_STATE; + break; default: break; } diff --git a/service/src/com/android/car/DayNightModePolicy.java b/service/src/com/android/car/DayNightModePolicy.java index dae9a141f8..48072ebc8b 100644 --- a/service/src/com/android/car/DayNightModePolicy.java +++ b/service/src/com/android/car/DayNightModePolicy.java @@ -86,7 +86,7 @@ public class DayNightModePolicy extends CarSensorService.LogicalSensor { private static CarSensorEvent createEvent(boolean isNight, long timestamp) { CarSensorEvent event = new CarSensorEvent(CarSensorManager.SENSOR_TYPE_NIGHT, - timestamp, 0, 1); + timestamp, 0, 1, 0); event.intValues[0] = isNight ? 1 : 0; return event; } diff --git a/service/src/com/android/car/DrivingStatePolicy.java b/service/src/com/android/car/DrivingStatePolicy.java index ce81209b0e..37bbbc09fe 100644 --- a/service/src/com/android/car/DrivingStatePolicy.java +++ b/service/src/com/android/car/DrivingStatePolicy.java @@ -204,7 +204,8 @@ public class DrivingStatePolicy extends CarSensorService.LogicalSensor { CarSensorManager.SENSOR_TYPE_DRIVING_STATUS, timestamp, 0 /* float values */, - 1 /* int values */); + 1 /* int values */, + 0 /* long values */); event.intValues[0] = drivingState; return event; } diff --git a/service/src/com/android/car/hal/SensorHalService.java b/service/src/com/android/car/hal/SensorHalService.java index a4fd77d2e4..2b84fc4ecf 100644 --- a/service/src/com/android/car/hal/SensorHalService.java +++ b/service/src/com/android/car/hal/SensorHalService.java @@ -25,7 +25,7 @@ import android.hardware.automotive.vehicle.V2_0.VehicleGear; import android.hardware.automotive.vehicle.V2_0.VehicleIgnitionState; import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig; import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; -import android.hardware.automotive.vehicle.V2_0.VehicleProperty; +import android.hardware.automotive.vehicle.V2_1.VehicleProperty; import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode; import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType; @@ -66,7 +66,12 @@ public class SensorHalService extends SensorHalServiceBase { CarSensorManager.SENSOR_TYPE_PARKING_BRAKE, VehicleProperty.PARKING_BRAKE_ON, CarSensorManager.SENSOR_TYPE_DRIVING_STATUS, VehicleProperty.DRIVING_STATUS, CarSensorManager.SENSOR_TYPE_FUEL_LEVEL, VehicleProperty.FUEL_LEVEL_LOW, - CarSensorManager.SENSOR_TYPE_IGNITION_STATE, VehicleProperty.IGNITION_STATE); + CarSensorManager.SENSOR_TYPE_IGNITION_STATE, VehicleProperty.IGNITION_STATE, + CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE, VehicleProperty.WHEEL_TICK, + CarSensorManager.SENSOR_TYPE_ABS_ACTIVE, VehicleProperty.ABS_ACTIVE, + CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE, + VehicleProperty.TRACTION_CONTROL_ACTIVE + ); private final static SparseIntArray mMgrGearToHalMap = initSparseIntArray( VehicleGear.GEAR_NEUTRAL, CarSensorEvent.GEAR_NEUTRAL, @@ -93,6 +98,24 @@ public class SensorHalService extends SensorHalServiceBase { private SensorListener mSensorListener; + private int[] mMicrometersPerWheelTick = {0, 0, 0, 0}; + + @Override + public void init() { + // Populate internal values if available + VehiclePropConfig config = mSensorToPropConfig.get( + CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE); + if (config == null) { + Log.e(TAG, "init: unable to get property config for SENSOR_TYPE_WHEEL_TICK_DISTANCE"); + } else { + for (int i=0; i<4; i++) { + // ConfigArray starts with Wheels enum at idx 0 + mMicrometersPerWheelTick[i] = config.configArray.get(i+1); + } + } + super.init(); + } + public SensorHalService(VehicleHal hal) { super(hal); } @@ -156,27 +179,45 @@ public class SensorHalService extends SensorHalServiceBase { if (sensorType == SENSOR_TYPE_INVALID) { throw new RuntimeException("no sensor defined for property 0x" + toHexString(property)); } - + // Handle the valid sensor int dataType = property & VehiclePropertyType.MASK; - CarSensorEvent event = null; switch (dataType) { case VehiclePropertyType.BOOLEAN: event = CarSensorEventFactory.createBooleanEvent(sensorType, v.timestamp, - v.value.int32Values.get(0) == 1); + v.value.int32Values.get(0) == 1); + break; + case VehiclePropertyType.COMPLEX: + event = CarSensorEventFactory.createComplexEvent(sensorType, v.timestamp, v); break; case VehiclePropertyType.INT32: Integer mgrVal = mapHalEnumValueToMgr(property, v.value.int32Values.get(0)); event = mgrVal == null ? null - : CarSensorEventFactory.createIntEvent(sensorType, v.timestamp, mgrVal); + : CarSensorEventFactory.createIntEvent(sensorType, v.timestamp, mgrVal); break; - case VehiclePropertyType.FLOAT: { + case VehiclePropertyType.FLOAT: event = CarSensorEventFactory.createFloatEvent(sensorType, v.timestamp, - v.value.floatValues.get(0)); + v.value.floatValues.get(0)); break; - } default: Log.w(TAG, "createCarSensorEvent: unsupported type: 0x" + toHexString(dataType)); + break; + } + // Perform property specific actions + switch (property) { + case VehicleProperty.WHEEL_TICK: + // Apply the um/tick scaling factor, then divide by 1000 to generate mm + for (int i = 0; i < 4; i++) { + // ResetCounts is at longValues[0] + if (event.longValues[i + CarSensorEvent.INDEX_WHEEL_DISTANCE_FRONT_LEFT] != + Long.MAX_VALUE) { + event.longValues[i + CarSensorEvent.INDEX_WHEEL_DISTANCE_FRONT_LEFT] *= + mMicrometersPerWheelTick[i]; + event.longValues[i + CarSensorEvent.INDEX_WHEEL_DISTANCE_FRONT_LEFT] /= + 1000; + } + } + break; } if (DBG_EVENTS) Log.i(TAG, "Sensor event created: " + event); return event; @@ -225,6 +266,9 @@ public class SensorHalService extends SensorHalServiceBase { for (int i = 0; i < mSensorToPropConfig.size(); i++) { writer.println(mSensorToPropConfig.valueAt(i).toString()); } + for (int i = 0; i < mMicrometersPerWheelTick.length; i++) { + writer.println("mMicrometersPerWheelTick[" + i + "] = " + mMicrometersPerWheelTick[i]); + } } private static SparseIntArray initSparseIntArray(int... keyValuePairs) { diff --git a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml index 4d29276ee3..dc10d2b824 100644 --- a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml +++ b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml @@ -31,6 +31,7 @@ <uses-permission android:name="android.car.permission.CAR_CAMERA" /> <uses-permission android:name="android.car.permission.CAR_NAVIGATION_MANAGER"/> <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME"/> + <uses-permission android:name="android.car.permission.VEHICLE_DYNAMICS_STATE"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.MANAGE_USB" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> diff --git a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml index dc4231909b..72e08fa1eb 100644 --- a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml +++ b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml @@ -169,7 +169,7 @@ <string name="sensor_night">Night[%1$s]: isNight=%2$s</string> <string name="sensor_gear">Gear[%1$s]: gear=%2$s</string> <string name="sensor_parking_brake">Parking brake[%1$s]: isEngaged=%2$s</string> - <string name="sensor_fuel_level">Fuel level[%1$s]: lebel=%2$s, range=%3$s, lowFuelWarning=%4$s</string> + <string name="sensor_fuel_level">Fuel level[%1$s]: level=%2$s, range=%3$s, lowFuelWarning=%4$s</string> <string name="sensor_odometer">Odometer[%1$s]: kms=%2$s</string> <string name="sensor_rpm">RPM[%1$s]: rpm=%2$s</string> <string name="sensor_speed">Speed[%1$s]: speed=%2$s</string> @@ -180,6 +180,9 @@ <string name="sensor_location">Location[%1$s]: lat=%2$s, lon=%3$s, accuracy=%4$s, altitude=%5$s, speed=%6$s, bearing=%7$s</string> <string name="sensor_gps">GPS Satellites[%1$s]: inView: %2$s, inUse: %3$s. %4$s</string> <string name="sensor_single_gps_satellite">(%1$s): usedInFix: %2$s, prn: %3$s, snr: %4$s, azimuth: %5$s, elevation: %6$s</string> + <string name="sensor_wheel_ticks">Wheel Distance[%1$s]: reset=%2$s, FL=%3$s, FR=%4$s, RL=%5$s, RR=%6$s</string> + <string name="sensor_abs_is_active">ABS[%1$s]: isActive=%2$s</string> + <string name="sensor_traction_control_is_active">Traction Control[%1$s]: isActive=%2$s</string> <string name="volume_test">Volume Test</string> <string name="volume_up_logical">Vol +</string> diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java index 3c3f57df08..082a3f0a6b 100644 --- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java +++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java @@ -58,7 +58,8 @@ public class SensorsTestFragment extends Fragment { Manifest.permission.ACCESS_COARSE_LOCATION, Car.PERMISSION_MILEAGE, Car.PERMISSION_FUEL, - Car.PERMISSION_SPEED + Car.PERMISSION_SPEED, + Car.PERMISSION_VEHICLE_DYNAMICS_STATE }; private final CarSensorManager.OnSensorChangedListener mOnSensorChangedListener = @@ -271,6 +272,32 @@ public class SensorsTestFragment extends Fragment { case CarSensorManager.SENSOR_TYPE_GYROSCOPE: summary.add(getGyroscopeString(event)); break; + case CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE: + if(event != null) { + CarSensorEvent.CarWheelTickDistanceData d = + event.getCarWheelTickDistanceData(); + summary.add(getContext().getString(R.string.sensor_wheel_ticks, + getTimestamp(event), d.sensorResetCount, d.frontLeftWheelDistanceMm, + d.frontRightWheelDistanceMm, d.rearLeftWheelDistanceMm, + d.rearRightWheelDistanceMm)); + } else { + summary.add(getContext().getString(R.string.sensor_wheel_ticks, + getTimestamp(event), mNaString, mNaString, mNaString, mNaString, + mNaString)); + } + break; + case CarSensorManager.SENSOR_TYPE_ABS_ACTIVE: + summary.add(getContext().getString(R.string.sensor_abs_is_active, + getTimestamp(event), event == null ? mNaString : + event.getCarAbsActiveData().absIsActive)); + break; + + case CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE: + summary.add( + getContext().getString(R.string.sensor_traction_control_is_active, + getTimestamp(event), event == null ? mNaString : + event.getCarTractionControlActiveData().tractionControlIsActive)); + break; default: // Should never happen. Log.w(TAG, "Unrecognized event type: " + i); |