Merge "Add test case for checking the timestamp by areaId" into rvc-dev
diff --git a/car-lib/src/android/car/hardware/property/CarPropertyManager.java b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
index 3f7cafa..5c5cebb 100644
--- a/car-lib/src/android/car/hardware/property/CarPropertyManager.java
+++ b/car-lib/src/android/car/hardware/property/CarPropertyManager.java
@@ -819,7 +819,9 @@
long updateTime = event.getCarPropertyValue().getTimestamp();
int areaId = event.getCarPropertyValue().getAreaId();
if (!needUpdateForAreaId(areaId, updateTime)) {
- Log.w(TAG, "dropping old property data");
+ if (DBG) {
+ Log.w(TAG, "Dropping a stale event: " + event.toString());
+ }
return;
}
List<CarPropertyEventCallback> listeners;
diff --git a/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java b/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
index 9966046..80c0df9 100644
--- a/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarPropertyManagerTest.java
@@ -55,6 +55,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Test for {@link android.car.hardware.property.CarPropertyManager}
@@ -83,7 +84,12 @@
private static final Object[] EXPECTED_VALUE_1 = {"android", 1, 1L};
private static final Object[] EXPECTED_VALUE_2 = {"android", true, 3, 1.1f, 2f};
- private static final int CUSTOM_GLOBAL_MIXED_PROP_ID_1 =
+ private static final int CUSTOM_SEAT_INT_PROP_1 =
+ 0x1201 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.INT32 | VehicleArea.SEAT;
+ private static final int CUSTOM_SEAT_INT_PROP_2 =
+ 0x1202 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.INT32 | VehicleArea.SEAT;
+
+ private static final int CUSTOM_SEAT_MIXED_PROP_ID_1 =
0x1101 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.MIXED | VehicleArea.SEAT;
private static final int CUSTOM_GLOBAL_MIXED_PROP_ID_2 =
0x1102 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.MIXED | VehicleArea.GLOBAL;
@@ -110,7 +116,6 @@
| VehicleAreaSeat.ROW_2_RIGHT;
private static final float INIT_TEMP_VALUE = 16f;
private static final float CHANGED_TEMP_VALUE = 20f;
-
private CarPropertyManager mManager;
@Rule public TestName mTestName = new TestName();
@@ -134,10 +139,9 @@
@Test
public void testMixedPropertyConfigs() {
List<CarPropertyConfig> configs = mManager.getPropertyList();
-
for (CarPropertyConfig cfg : configs) {
switch (cfg.getPropertyId()) {
- case CUSTOM_GLOBAL_MIXED_PROP_ID_1:
+ case CUSTOM_SEAT_MIXED_PROP_ID_1:
Assert.assertArrayEquals(CONFIG_ARRAY_1.toArray(),
cfg.getConfigArray().toArray());
break;
@@ -151,6 +155,8 @@
case PROP_CAUSE_STATUS_CODE_TRY_AGAIN:
case PROP_CAUSE_STATUS_CODE_NOT_AVAILABLE:
case PROP_CAUSE_STATUS_CODE_INVALID_ARG:
+ case CUSTOM_SEAT_INT_PROP_1:
+ case CUSTOM_SEAT_INT_PROP_2:
break;
default:
Assert.fail("Unexpected CarPropertyConfig: " + cfg.toString());
@@ -160,10 +166,10 @@
@Test
public void testGetMixTypeProperty() {
- mManager.setProperty(Object[].class, CUSTOM_GLOBAL_MIXED_PROP_ID_1,
+ mManager.setProperty(Object[].class, CUSTOM_SEAT_MIXED_PROP_ID_1,
0, EXPECTED_VALUE_1);
CarPropertyValue<Object[]> result = mManager.getProperty(
- CUSTOM_GLOBAL_MIXED_PROP_ID_1, 0);
+ CUSTOM_SEAT_MIXED_PROP_ID_1, 0);
Assert.assertArrayEquals(EXPECTED_VALUE_1, result.getValue());
mManager.setProperty(Object[].class, CUSTOM_GLOBAL_MIXED_PROP_ID_2,
@@ -175,15 +181,15 @@
@Test
public void testGetPropertyConfig() {
- CarPropertyConfig config = mManager.getCarPropertyConfig(CUSTOM_GLOBAL_MIXED_PROP_ID_1);
- Assert.assertEquals(CUSTOM_GLOBAL_MIXED_PROP_ID_1, config.getPropertyId());
+ CarPropertyConfig config = mManager.getCarPropertyConfig(CUSTOM_SEAT_MIXED_PROP_ID_1);
+ Assert.assertEquals(CUSTOM_SEAT_MIXED_PROP_ID_1, config.getPropertyId());
// return null if can not find the propertyConfig for the property.
Assert.assertNull(mManager.getCarPropertyConfig(FAKE_PROPERTY_ID));
}
@Test
public void testGetAreaId() {
- int result = mManager.getAreaId(CUSTOM_GLOBAL_MIXED_PROP_ID_1, VehicleAreaSeat.ROW_1_LEFT);
+ int result = mManager.getAreaId(CUSTOM_SEAT_MIXED_PROP_ID_1, VehicleAreaSeat.ROW_1_LEFT);
Assert.assertEquals(DRIVER_SIDE_AREA_ID, result);
//test for the GLOBAL property
@@ -193,7 +199,7 @@
//test exception
try {
- int areaId = mManager.getAreaId(CUSTOM_GLOBAL_MIXED_PROP_ID_1,
+ int areaId = mManager.getAreaId(CUSTOM_SEAT_MIXED_PROP_ID_1,
VehicleAreaSeat.ROW_3_CENTER);
Assert.fail("Unexpected areaId: " + areaId);
} catch (IllegalArgumentException e) {
@@ -258,7 +264,6 @@
Assert.assertFalse(callback1.mReceivedErrorEventWithErrorCode);
Assert.assertFalse(callback1.mReceivedErrorEventWithOutErrorCode);
}
-
@Test
public void testSetterExceptionsInQ() {
Truth.assertThat(getContext().getApplicationInfo().targetSdkVersion)
@@ -330,26 +335,91 @@
.isEqualTo(Build.VERSION_CODES.R);
assertThrows(PropertyAccessDeniedSecurityException.class,
- ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_ACCESS_DENIED,
+ () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_ACCESS_DENIED,
VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
assertThrows(IllegalArgumentException.class,
- ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_INVALID_ARG,
+ () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_INVALID_ARG,
VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
assertThrows(PropertyNotAvailableAndRetryException.class,
- ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_TRY_AGAIN,
+ () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_TRY_AGAIN,
VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
assertThrows(PropertyNotAvailableException.class,
- ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_NOT_AVAILABLE,
+ () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_NOT_AVAILABLE,
VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
assertThrows(CarInternalErrorException.class,
- ()->mManager.getProperty(PROP_CAUSE_STATUS_CODE_INTERNAL_ERROR,
+ () -> mManager.getProperty(PROP_CAUSE_STATUS_CODE_INTERNAL_ERROR,
VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL));
}
+ @Test
+ public void testOnChangeEventWithSameAreaId() {
+ // init
+ mManager.setProperty(Integer.class,
+ CUSTOM_SEAT_INT_PROP_1, DRIVER_SIDE_AREA_ID, 1);
+ TestSequenceCallback callback = new TestSequenceCallback();
+ mManager.registerCallback(callback, CUSTOM_SEAT_INT_PROP_1, 0);
+
+ VehiclePropValue firstFakeValueDriveSide = new VehiclePropValue();
+ firstFakeValueDriveSide.prop = CUSTOM_SEAT_INT_PROP_1;
+ firstFakeValueDriveSide.areaId = DRIVER_SIDE_AREA_ID;
+ firstFakeValueDriveSide.value.int32Values.add(2);
+ firstFakeValueDriveSide.timestamp = SystemClock.elapsedRealtimeNanos();
+ VehiclePropValue secFakeValueDriveSide = new VehiclePropValue();
+ secFakeValueDriveSide.prop = CUSTOM_SEAT_INT_PROP_1;
+ secFakeValueDriveSide.areaId = DRIVER_SIDE_AREA_ID;
+ secFakeValueDriveSide.value.int32Values.add(3); // 0 in HAL indicate false;
+ secFakeValueDriveSide.timestamp = SystemClock.elapsedRealtimeNanos();
+ SystemClock.sleep(100);
+ callback.reset(); // clean up the old events
+
+ // inject the new event first
+ getMockedVehicleHal().injectEvent(secFakeValueDriveSide);
+ // inject the old event
+ getMockedVehicleHal().injectEvent(firstFakeValueDriveSide);
+ SystemClock.sleep(100); // waiting for events
+ // Client should only get the new event
+ Assert.assertEquals(3,
+ (int) callback.getLastCarPropertyValue(CUSTOM_SEAT_INT_PROP_1).getValue());
+ Assert.assertEquals(1, callback.getEventCounter());
+
+ }
+
+ @Test
+ public void testOnChangeEventWithDifferentAreaId() {
+ // init
+ mManager.setProperty(Integer.class,
+ CUSTOM_SEAT_INT_PROP_2, DRIVER_SIDE_AREA_ID, 1);
+ TestSequenceCallback callback = new TestSequenceCallback();
+ mManager.registerCallback(callback, CUSTOM_SEAT_INT_PROP_2, 0);
+
+ VehiclePropValue fakeValueDriveSide = new VehiclePropValue();
+ fakeValueDriveSide.prop = CUSTOM_SEAT_INT_PROP_2;
+ fakeValueDriveSide.areaId = DRIVER_SIDE_AREA_ID;
+ fakeValueDriveSide.value.int32Values.add(4);
+ fakeValueDriveSide.timestamp = SystemClock.elapsedRealtimeNanos();
+
+ VehiclePropValue fakeValuePsgSide = new VehiclePropValue();
+ fakeValuePsgSide.prop = CUSTOM_SEAT_INT_PROP_2;
+ fakeValuePsgSide.areaId = PASSENGER_SIDE_AREA_ID;
+ fakeValuePsgSide.value.int32Values.add(5);
+ fakeValuePsgSide.timestamp = SystemClock.elapsedRealtimeNanos();
+ SystemClock.sleep(100);
+ callback.reset();
+ // inject passenger event before driver event
+ getMockedVehicleHal().injectEvent(fakeValuePsgSide);
+ getMockedVehicleHal().injectEvent(fakeValueDriveSide);
+ SystemClock.sleep(100);
+
+ // both events should be received by listener
+ Assert.assertEquals(4,
+ (int) callback.getLastCarPropertyValue(CUSTOM_SEAT_INT_PROP_2).getValue());
+ Assert.assertEquals(2, callback.getEventCounter());
+ }
+
@Override
protected synchronized void configureMockedHal() {
PropertyHandler handler = new PropertyHandler();
- addProperty(CUSTOM_GLOBAL_MIXED_PROP_ID_1, handler).setConfigArray(CONFIG_ARRAY_1)
+ addProperty(CUSTOM_SEAT_MIXED_PROP_ID_1, handler).setConfigArray(CONFIG_ARRAY_1)
.addAreaConfig(DRIVER_SIDE_AREA_ID).addAreaConfig(PASSENGER_SIDE_AREA_ID);
addProperty(CUSTOM_GLOBAL_MIXED_PROP_ID_2, handler).setConfigArray(CONFIG_ARRAY_2);
@@ -359,12 +429,16 @@
addProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, tempValue)
.addAreaConfig(DRIVER_SIDE_AREA_ID).addAreaConfig(PASSENGER_SIDE_AREA_ID);
- // Adds properties for testing exceptions.
addProperty(PROP_CAUSE_STATUS_CODE_ACCESS_DENIED, handler);
addProperty(PROP_CAUSE_STATUS_CODE_TRY_AGAIN, handler);
addProperty(PROP_CAUSE_STATUS_CODE_INTERNAL_ERROR, handler);
addProperty(PROP_CAUSE_STATUS_CODE_INVALID_ARG, handler);
addProperty(PROP_CAUSE_STATUS_CODE_NOT_AVAILABLE, handler);
+
+ addProperty(CUSTOM_SEAT_INT_PROP_1, handler).addAreaConfig(DRIVER_SIDE_AREA_ID)
+ .addAreaConfig(PASSENGER_SIDE_AREA_ID);
+ addProperty(CUSTOM_SEAT_INT_PROP_2, handler).addAreaConfig(DRIVER_SIDE_AREA_ID)
+ .addAreaConfig(PASSENGER_SIDE_AREA_ID);
}
private class PropertyHandler implements VehicleHalPropertyHandler {
@@ -435,6 +509,7 @@
private boolean mReceivedErrorEventWithErrorCode = false;
private boolean mReceivedErrorEventWithOutErrorCode = false;
private int mErrorCode;
+
@Override
public void onChangeEvent(CarPropertyValue value) {
Log.d(CALLBACK_TAG, "onChangeEvent: " + value);
@@ -454,4 +529,36 @@
+ "errorCode: " + errorCode);
}
}
+
+ private class TestSequenceCallback implements CarPropertyManager.CarPropertyEventCallback {
+
+ private ConcurrentHashMap<Integer, CarPropertyValue> mRecorder = new ConcurrentHashMap<>();
+ private int mCounter = 0;
+
+ @Override
+ public void onChangeEvent(CarPropertyValue value) {
+ Log.e(TAG, "onChanged get a event " + value);
+ mRecorder.put(value.getPropertyId(), value);
+ mCounter++;
+ }
+
+ @Override
+ public void onErrorEvent(int properId, int zone) {
+ Log.e(TAG, "TestSequenceCallback get an onErrorEvent");
+ }
+
+ public CarPropertyValue getLastCarPropertyValue(int propId) {
+ return mRecorder.get(propId);
+ }
+
+ public int getEventCounter() {
+ return mCounter;
+ }
+
+ public void reset() {
+ mRecorder.clear();
+ mCounter = 0;
+ }
+ }
+
}