diff options
9 files changed, 122 insertions, 12 deletions
diff --git a/service/src/com/android/car/CarPropertyServiceBase.java b/service/src/com/android/car/CarPropertyServiceBase.java index 7864e6aff5..02ab7c95cb 100644 --- a/service/src/com/android/car/CarPropertyServiceBase.java +++ b/service/src/com/android/car/CarPropertyServiceBase.java @@ -192,12 +192,19 @@ public class CarPropertyServiceBase extends ICarProperty.Stub mHal.setProperty(prop); } + private ICarPropertyEventListener[] getListeners() { + synchronized (mLock) { + int size = mListenersMap.values().size(); + return mListenersMap.values().toArray(new ICarPropertyEventListener[size]); + } + } + // Implement PropertyHalListener interface @Override public void onPropertyChange(CarPropertyEvent event) { - for (ICarPropertyEventListener l : mListenersMap.values()) { + for (ICarPropertyEventListener listener : getListeners()) { try { - l.onEvent(event); + listener.onEvent(event); } catch (RemoteException ex) { // If we could not send a record, its likely the connection snapped. Let the binder // death handle the situation. @@ -207,7 +214,20 @@ public class CarPropertyServiceBase extends ICarProperty.Stub } @Override - public void onError(int zone, int property) { - // TODO bug:32068464 + public void onPropertySetError(int property, int area) { + for (ICarPropertyEventListener listener : getListeners()) { + try { + listener.onEvent(createErrorEvent(property, area)); + } catch (RemoteException ex) { + // If we could not send a record, its likely the connection snapped. Let the binder + // death handle the situation. + Log.e(mTag, "onEvent calling failed: " + ex); + } + } + } + + private static CarPropertyEvent createErrorEvent(int property, int area) { + return new CarPropertyEvent(CarPropertyEvent.PROPERTY_EVENT_ERROR, + new CarPropertyValue<>(property, area, null)); } } diff --git a/service/src/com/android/car/hal/HalClient.java b/service/src/com/android/car/hal/HalClient.java index d0c9954e49..cf1ca0f7bf 100644 --- a/service/src/com/android/car/hal/HalClient.java +++ b/service/src/com/android/car/hal/HalClient.java @@ -27,7 +27,6 @@ import android.hardware.vehicle.V2_0.SubscribeOptions; import android.hardware.vehicle.V2_0.VehiclePropConfig; import android.hardware.vehicle.V2_0.VehiclePropValue; import android.os.Handler; -import android.os.IHwBinder; import android.os.Looper; import android.os.Message; import android.util.Log; diff --git a/service/src/com/android/car/hal/HalServiceBase.java b/service/src/com/android/car/hal/HalServiceBase.java index 30115ae30a..364f834c61 100644 --- a/service/src/com/android/car/hal/HalServiceBase.java +++ b/service/src/com/android/car/hal/HalServiceBase.java @@ -62,5 +62,7 @@ public abstract class HalServiceBase { public abstract void handleHalEvents(List<VehiclePropValue> values); + public void handlePropertySetError(int property, int area) {} + public abstract void dump(PrintWriter writer); } diff --git a/service/src/com/android/car/hal/PropertyHalServiceBase.java b/service/src/com/android/car/hal/PropertyHalServiceBase.java index 28dd4c60bf..cd75599d2c 100644 --- a/service/src/com/android/car/hal/PropertyHalServiceBase.java +++ b/service/src/com/android/car/hal/PropertyHalServiceBase.java @@ -58,7 +58,7 @@ public abstract class PropertyHalServiceBase extends HalServiceBase { public interface PropertyHalListener { void onPropertyChange(CarPropertyEvent event); - void onError(int zone, int property); + void onPropertySetError(int property, int area); } protected PropertyHalServiceBase(VehicleHal vehicleHal, String tag, boolean dbg) { @@ -172,7 +172,7 @@ public abstract class PropertyHalServiceBase extends HalServiceBase { @Override public void handleHalEvents(List<VehiclePropValue> values) { PropertyHalListener listener; - synchronized (this) { + synchronized (mLock) { listener = mListener; } if (listener != null) { @@ -199,6 +199,17 @@ public abstract class PropertyHalServiceBase extends HalServiceBase { } @Override + public void handlePropertySetError(int property, int area) { + PropertyHalListener listener; + synchronized (mLock) { + listener = mListener; + } + if (listener != null) { + listener.onPropertySetError(property, area); + } + } + + @Override public void dump(PrintWriter writer) { writer.println(mTag); writer.println(" Properties available:"); diff --git a/service/src/com/android/car/hal/VehicleHal.java b/service/src/com/android/car/hal/VehicleHal.java index 182583d296..7e3dea449b 100644 --- a/service/src/com/android/car/hal/VehicleHal.java +++ b/service/src/com/android/car/hal/VehicleHal.java @@ -27,6 +27,7 @@ import android.hardware.vehicle.V2_0.IVehicleCallback; import android.hardware.vehicle.V2_0.VehicleAreaConfig; import android.hardware.vehicle.V2_0.VehiclePropConfig; import android.hardware.vehicle.V2_0.VehiclePropValue; +import android.hardware.vehicle.V2_0.VehicleProperty; import android.hardware.vehicle.V2_0.VehiclePropertyAccess; import android.hardware.vehicle.V2_0.VehiclePropertyChangeMode; import android.os.HandlerThread; @@ -389,7 +390,12 @@ public class VehicleHal extends IVehicleCallback.Stub { public void onPropertySetError(int errorCode, int propId, int areaId) { Log.e(CarLog.TAG_HAL, String.format("onPropertySetError, errorCode: %d, prop: 0x%x, " + "area: 0x%x", errorCode, propId, areaId)); - // TODO propagate per property error to HAL services and handle global error, bug:32068464 + if (propId != VehicleProperty.INVALID) { + HalServiceBase service = mPropertyHandlers.get(propId); + if (service != null) { + service.handlePropertySetError(propId, areaId); + } + } } public void dump(PrintWriter writer) { @@ -403,7 +409,6 @@ public class VehicleHal extends IVehicleCallback.Stub { configList = new ArrayList<>(mAllProperties.values()); } - writer.println("**All properties**"); for (VehiclePropConfig config : configList) { StringBuilder builder = new StringBuilder() diff --git a/tests/carservice_test/AndroidManifest.xml b/tests/carservice_test/AndroidManifest.xml index d7c7bdf9ce..bf48e88da9 100644 --- a/tests/carservice_test/AndroidManifest.xml +++ b/tests/carservice_test/AndroidManifest.xml @@ -15,7 +15,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.car.carservicetest" + package="com.android.car.test" android:sharedUserId="android.uid.system" > <uses-permission android:name="android.Manifest.permission.MODIFY_AUDIO_ROUTING" /> @@ -24,7 +24,7 @@ <uses-permission android:name="android.car.permission.CONTROL_APP_BLOCKING" /> <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" /> <instrumentation android:name="android.test.InstrumentationTestRunner" - android:targetPackage="com.android.car.carservicetest" + android:targetPackage="com.android.car.test" android:label="Tests for Car APIs"/> <application android:label="CarServiceTest"> diff --git a/tests/carservice_test/src/com/android/car/test/CarCabinManagerTest.java b/tests/carservice_test/src/com/android/car/test/CarCabinManagerTest.java index 7024250041..a3694365ca 100644 --- a/tests/carservice_test/src/com/android/car/test/CarCabinManagerTest.java +++ b/tests/carservice_test/src/com/android/car/test/CarCabinManagerTest.java @@ -20,6 +20,7 @@ import android.car.Car; import android.car.hardware.CarPropertyValue; import android.car.hardware.cabin.CarCabinManager; import android.car.hardware.cabin.CarCabinManager.CarCabinEventCallback; +import android.car.hardware.cabin.CarCabinManager.PropertyId; import android.hardware.vehicle.V2_0.VehicleAreaDoor; import android.hardware.vehicle.V2_0.VehicleAreaWindow; import android.hardware.vehicle.V2_0.VehiclePropValue; @@ -27,11 +28,13 @@ import android.hardware.vehicle.V2_0.VehicleProperty; import android.os.SystemClock; import android.test.suitebuilder.annotation.MediumTest; import android.util.Log; +import android.util.MutableInt; import com.android.car.vehiclehal.VehiclePropValueBuilder; import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; import java.util.HashMap; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -93,6 +96,36 @@ public class CarCabinManagerTest extends MockedCarTestBase { assertEquals(25, windowPos); } + public void testError() throws Exception { + final int PROP = VehicleProperty.DOOR_LOCK; + final int AREA = VehicleAreaWindow.ROW_1_LEFT; + final int ERR_CODE = 42; + + CountDownLatch errorLatch = new CountDownLatch(1); + MutableInt propertyIdReceived = new MutableInt(0); + MutableInt areaIdReceived = new MutableInt(0); + + mCarCabinManager.registerCallback(new CarCabinEventCallback() { + @Override + public void onChangeEvent(CarPropertyValue value) { + + } + + @Override + public void onErrorEvent(@PropertyId int propertyId, int area) { + propertyIdReceived.value = propertyId; + areaIdReceived.value = area; + errorLatch.countDown(); + } + }); + + getMockedVehicleHal().injectError(ERR_CODE, PROP, AREA); + assertTrue(errorLatch.await(DEFAULT_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + assertEquals(PROP, propertyIdReceived.value); + assertEquals(AREA, areaIdReceived.value); + } + + // Test an event public void testEvent() throws Exception { mCarCabinManager.registerCallback(new EventListener()); diff --git a/tests/carservice_test/src/com/android/car/test/CarHvacManagerTest.java b/tests/carservice_test/src/com/android/car/test/CarHvacManagerTest.java index 8510e4cf7c..26225ef76b 100644 --- a/tests/carservice_test/src/com/android/car/test/CarHvacManagerTest.java +++ b/tests/carservice_test/src/com/android/car/test/CarHvacManagerTest.java @@ -20,6 +20,7 @@ import android.car.Car; import android.car.hardware.CarPropertyValue; import android.car.hardware.hvac.CarHvacManager; import android.car.hardware.hvac.CarHvacManager.CarHvacEventCallback; +import android.car.hardware.hvac.CarHvacManager.PropertyId; import android.hardware.vehicle.V2_0.VehicleAreaWindow; import android.hardware.vehicle.V2_0.VehicleAreaZone; import android.hardware.vehicle.V2_0.VehiclePropValue; @@ -29,11 +30,13 @@ import android.hardware.vehicle.V2_0.VehiclePropertyChangeMode; import android.os.SystemClock; import android.test.suitebuilder.annotation.MediumTest; import android.util.Log; +import android.util.MutableInt; import com.android.car.vehiclehal.VehiclePropValueBuilder; import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; import java.util.HashMap; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -117,6 +120,35 @@ public class CarHvacManagerTest extends MockedCarTestBase { assertEquals(65.5, temp, 0); } + public void testError() throws Exception { + final int PROP = VehicleProperty.HVAC_DEFROSTER; + final int AREA = VehicleAreaWindow.FRONT_WINDSHIELD; + final int ERR_CODE = 42; + + CountDownLatch errorLatch = new CountDownLatch(1); + MutableInt propertyIdReceived = new MutableInt(0); + MutableInt areaIdReceived = new MutableInt(0); + + mCarHvacManager.registerCallback(new CarHvacEventCallback() { + @Override + public void onChangeEvent(CarPropertyValue value) { + + } + + @Override + public void onErrorEvent(@PropertyId int propertyId, int area) { + propertyIdReceived.value = propertyId; + areaIdReceived.value = area; + errorLatch.countDown(); + } + }); + + getMockedVehicleHal().injectError(ERR_CODE, PROP, AREA); + assertTrue(errorLatch.await(DEFAULT_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + assertEquals(PROP, propertyIdReceived.value); + assertEquals(AREA, areaIdReceived.value); + } + // Test an event public void testEvent() throws Exception { mCarHvacManager.registerCallback(new EventListener()); diff --git a/vehicle-hal-support-lib/src/com/android/car/vehiclehal/test/MockedVehicleHal.java b/vehicle-hal-support-lib/src/com/android/car/vehiclehal/test/MockedVehicleHal.java index 2d73a104b6..03822085db 100644 --- a/vehicle-hal-support-lib/src/com/android/car/vehiclehal/test/MockedVehicleHal.java +++ b/vehicle-hal-support-lib/src/com/android/car/vehiclehal/test/MockedVehicleHal.java @@ -28,7 +28,6 @@ import android.hardware.vehicle.V2_0.SubscribeOptions; import android.hardware.vehicle.V2_0.VehiclePropConfig; import android.hardware.vehicle.V2_0.VehiclePropValue; import android.hardware.vehicle.V2_0.VehiclePropertyAccess; -import android.os.IHwBinder; import com.google.android.collect.Lists; @@ -83,6 +82,15 @@ public class MockedVehicleHal extends IVehicle.Stub { } } + public synchronized void injectError(int errorCode, int propertyId, int areaId) { + List<IVehicleCallback> callbacks = mSubscribers.get(propertyId); + assertNotNull("Injecting error failed for property: " + propertyId + ". No listeners found", + callbacks); + for (IVehicleCallback callback : callbacks) { + callback.onPropertySetError(errorCode, propertyId, areaId); + } + } + @Override public synchronized ArrayList<VehiclePropConfig> getAllPropConfigs() { return new ArrayList<>(mConfigs.values()); |