aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Paik <spaik@google.com>2017-07-11 22:40:57 -0700
committerSteve Paik <spaik@google.com>2017-07-18 17:35:29 -0700
commit289ab99688d226518e47a7e47c9ffc20f221f0a6 (patch)
tree8cd22391570f031275eb94b85b10e1455f540175
parenta61a429da05cd913099b073bedc1d68d706beb44 (diff)
downloadCar-289ab99688d226518e47a7e47c9ffc20f221f0a6.tar.gz
Add SENSOR_TYPE_WHEEL_DISTANCE + friends
Bug: 62876582 Test: Embedded Kitchen Sink works with VHAL emulator Change-Id: I8b47e11850d5a8c4beab4b6fb579c6fc33cba5de
-rw-r--r--car-lib/api/current.txt10
-rw-r--r--car-lib/api/system-current.txt14
-rw-r--r--car-lib/src/android/car/Car.java4
-rw-r--r--car-lib/src/android/car/hardware/CarSensorEvent.java130
-rw-r--r--car-lib/src/android/car/hardware/CarSensorManager.java79
-rw-r--r--car-support-lib/api/current.txt9
-rw-r--r--car-support-lib/proguard-release.flags9
-rw-r--r--car-support-lib/src/android/support/car/Car.java6
-rw-r--r--car-support-lib/src/android/support/car/hardware/CarSensorEvent.java130
-rw-r--r--car-support-lib/src/android/support/car/hardware/CarSensorManager.java25
-rw-r--r--car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java2
-rw-r--r--car-support-lib/src/android/support/car/hardware/CarSensorsProxy.java10
-rw-r--r--service/AndroidManifest.xml6
-rw-r--r--service/res/values/strings.xml4
-rw-r--r--service/src/com/android/car/CarSensorEventFactory.java27
-rw-r--r--service/src/com/android/car/CarSensorService.java6
-rw-r--r--service/src/com/android/car/DayNightModePolicy.java2
-rw-r--r--service/src/com/android/car/DrivingStatePolicy.java3
-rw-r--r--service/src/com/android/car/hal/SensorHalService.java62
-rw-r--r--tests/EmbeddedKitchenSinkApp/AndroidManifest.xml1
-rw-r--r--tests/EmbeddedKitchenSinkApp/res/values/strings.xml5
-rw-r--r--tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java29
22 files changed, 512 insertions, 61 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 722d90040b..989b4cdd31 100644
--- a/car-lib/api/system-current.txt
+++ b/car-lib/api/system-current.txt
@@ -27,6 +27,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";
@@ -75,10 +76,10 @@ package android.car {
public final class CarProjectionManager {
method public void onCarDisconnected();
- method public void registerProjectionRunner(android.content.Intent) throws android.car.CarNotConnectedException;
method public void registerProjectionListener(android.car.CarProjectionManager.CarProjectionListener, int) throws android.car.CarNotConnectedException;
- method public void unregisterProjectionRunner(android.content.Intent);
+ method public void registerProjectionRunner(android.content.Intent) throws android.car.CarNotConnectedException;
method public void unregisterProjectionListener();
+ method public void unregisterProjectionRunner(android.content.Intent);
field public static final int PROJECTION_LONG_PRESS_VOICE_SEARCH = 2; // 0x2
field public static final int PROJECTION_VOICE_SEARCH = 1; // 0x1
}
@@ -446,8 +447,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;
}
@@ -470,6 +477,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
@@ -480,7 +488,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 6ed5d73d98..1e05b8229f 100644
--- a/car-lib/src/android/car/Car.java
+++ b/car-lib/src/android/car/Car.java
@@ -143,6 +143,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 89122655ad..4777c43ddb 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 4837decfe9..66ff16d608 100644
--- a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
@@ -163,7 +163,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>
@@ -174,6 +174,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);