blob: 945d5544341426c0f60bd8d2cca8f1c541b4fcc0 [file] [log] [blame]
Kaif057bd42019-07-26 16:49:33 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.car;
18
19import android.car.Car;
Kaida0ce5e2019-10-16 13:42:17 -070020import android.car.VehicleAreaType;
Kai6e75d492020-02-20 16:11:40 -080021import android.car.VehiclePropertyIds;
Kaif057bd42019-07-26 16:49:33 -070022import android.car.hardware.CarPropertyConfig;
23import android.car.hardware.CarPropertyValue;
24import android.car.hardware.property.CarPropertyManager;
25import android.hardware.automotive.vehicle.V2_0.VehicleArea;
Kaida0ce5e2019-10-16 13:42:17 -070026import android.hardware.automotive.vehicle.V2_0.VehicleAreaSeat;
Kaif057bd42019-07-26 16:49:33 -070027import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
28import android.hardware.automotive.vehicle.V2_0.VehiclePropertyGroup;
29import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType;
Kai6e75d492020-02-20 16:11:40 -080030import android.os.SystemClock;
Kaif057bd42019-07-26 16:49:33 -070031import android.util.Log;
32
33import androidx.test.ext.junit.runners.AndroidJUnit4;
34import androidx.test.filters.MediumTest;
35
36import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
37
38import org.junit.Assert;
39import org.junit.Test;
40import org.junit.runner.RunWith;
41
42import java.util.Arrays;
43import java.util.HashMap;
44import java.util.List;
45
46/**
47 * Test for {@link android.car.hardware.property.CarPropertyManager}
48 */
49@RunWith(AndroidJUnit4.class)
50@MediumTest
51public class CarPropertyManagerTest extends MockedCarTestBase {
52
53 private static final String TAG = CarPropertyManagerTest.class.getSimpleName();
54
55 /**
56 * configArray[0], 1 indicates the property has a String value
57 * configArray[1], 1 indicates the property has a Boolean value .
58 * configArray[2], 1 indicates the property has a Integer value
59 * configArray[3], the number indicates the size of Integer[] in the property.
60 * configArray[4], 1 indicates the property has a Long value .
61 * configArray[5], the number indicates the size of Long[] in the property.
62 * configArray[6], 1 indicates the property has a Float value .
63 * configArray[7], the number indicates the size of Float[] in the property.
64 * configArray[8], the number indicates the size of byte[] in the property.
65 */
66 private static final java.util.Collection<Integer> CONFIG_ARRAY_1 =
67 Arrays.asList(1, 0, 1, 0, 1, 0, 0, 0, 0);
68 private static final java.util.Collection<Integer> CONFIG_ARRAY_2 =
69 Arrays.asList(1, 1, 1, 0, 0, 0, 0, 2, 0);
70 private static final Object[] EXPECTED_VALUE_1 = {"android", 1, 1L};
71 private static final Object[] EXPECTED_VALUE_2 = {"android", true, 3, 1.1f, 2f};
72
73 private static final int CUSTOM_GLOBAL_MIXED_PROP_ID_1 =
Kaida0ce5e2019-10-16 13:42:17 -070074 0x1101 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.MIXED | VehicleArea.SEAT;
Kaif057bd42019-07-26 16:49:33 -070075 private static final int CUSTOM_GLOBAL_MIXED_PROP_ID_2 =
76 0x1102 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.MIXED | VehicleArea.GLOBAL;
Kaida0ce5e2019-10-16 13:42:17 -070077 // Use FAKE_PROPERTY_ID to test api return null or throw exception.
78 private static final int FAKE_PROPERTY_ID = 0x111;
79
80 private static final int DRIVER_SIDE_AREA_ID = VehicleAreaSeat.ROW_1_LEFT
81 | VehicleAreaSeat.ROW_2_LEFT;
82 private static final int PASSENGER_SIDE_AREA_ID = VehicleAreaSeat.ROW_1_RIGHT
83 | VehicleAreaSeat.ROW_2_CENTER
84 | VehicleAreaSeat.ROW_2_RIGHT;
Kai6e75d492020-02-20 16:11:40 -080085 private static final float INIT_TEMP_VALUE = 16f;
86 private static final float CHANGED_TEMP_VALUE = 20f;
Kaif057bd42019-07-26 16:49:33 -070087
88 private CarPropertyManager mManager;
89
90 @Override
91 public void setUp() throws Exception {
92 super.setUp();
93 mManager = (CarPropertyManager) getCar().getCarManager(Car.PROPERTY_SERVICE);
94 Assert.assertNotNull(mManager);
95 }
96
97 @Test
98 public void testMixedPropertyConfigs() {
99 List<CarPropertyConfig> configs = mManager.getPropertyList();
Kai6e75d492020-02-20 16:11:40 -0800100 Assert.assertEquals(3, configs.size());
Kaif057bd42019-07-26 16:49:33 -0700101
102 for (CarPropertyConfig cfg : configs) {
103 switch (cfg.getPropertyId()) {
104 case CUSTOM_GLOBAL_MIXED_PROP_ID_1:
105 Assert.assertArrayEquals(CONFIG_ARRAY_1.toArray(),
106 cfg.getConfigArray().toArray());
107 break;
108 case CUSTOM_GLOBAL_MIXED_PROP_ID_2:
109 Assert.assertArrayEquals(CONFIG_ARRAY_2.toArray(),
110 cfg.getConfigArray().toArray());
111 break;
Kai6e75d492020-02-20 16:11:40 -0800112 case VehiclePropertyIds.HVAC_TEMPERATURE_SET:
113 break;
Kaif057bd42019-07-26 16:49:33 -0700114 default:
115 Assert.fail("Unexpected CarPropertyConfig: " + cfg.toString());
116 }
117 }
118 }
119
120 @Test
121 public void testGetMixTypeProperty() {
122 mManager.setProperty(Object[].class, CUSTOM_GLOBAL_MIXED_PROP_ID_1,
123 0, EXPECTED_VALUE_1);
124 CarPropertyValue<Object[]> result = mManager.getProperty(
125 CUSTOM_GLOBAL_MIXED_PROP_ID_1, 0);
126 Assert.assertArrayEquals(EXPECTED_VALUE_1, result.getValue());
127
128 mManager.setProperty(Object[].class, CUSTOM_GLOBAL_MIXED_PROP_ID_2,
129 0, EXPECTED_VALUE_2);
130 result = mManager.getProperty(
131 CUSTOM_GLOBAL_MIXED_PROP_ID_2, 0);
132 Assert.assertArrayEquals(EXPECTED_VALUE_2, result.getValue());
133 }
134
Kaida0ce5e2019-10-16 13:42:17 -0700135 @Test
136 public void testGetPropertyConfig() {
137 CarPropertyConfig config = mManager.getCarPropertyConfig(CUSTOM_GLOBAL_MIXED_PROP_ID_1);
138 Assert.assertEquals(CUSTOM_GLOBAL_MIXED_PROP_ID_1, config.getPropertyId());
139 // return null if can not find the propertyConfig for the property.
140 Assert.assertNull(mManager.getCarPropertyConfig(FAKE_PROPERTY_ID));
141 }
142
143 @Test
144 public void testGetAreaId() {
145 int result = mManager.getAreaId(CUSTOM_GLOBAL_MIXED_PROP_ID_1, VehicleAreaSeat.ROW_1_LEFT);
146 Assert.assertEquals(DRIVER_SIDE_AREA_ID, result);
147
148 //test for the GLOBAL property
149 int globalAreaId =
150 mManager.getAreaId(CUSTOM_GLOBAL_MIXED_PROP_ID_2, VehicleAreaSeat.ROW_1_LEFT);
151 Assert.assertEquals(VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, globalAreaId);
152
153 //test exception
154 try {
155 int areaId = mManager.getAreaId(CUSTOM_GLOBAL_MIXED_PROP_ID_1,
156 VehicleAreaSeat.ROW_3_CENTER);
157 Assert.fail("Unexpected areaId: " + areaId);
158 } catch (IllegalArgumentException e) {
159 Log.v(TAG, e.getMessage());
160 }
161
162 try {
163 // test exception
164 int areaIdForFakeProp = mManager.getAreaId(FAKE_PROPERTY_ID,
165 VehicleAreaSeat.ROW_1_LEFT);
166 Assert.fail("Unexpected areaId for fake property: " + areaIdForFakeProp);
167 } catch (IllegalArgumentException e) {
168 Log.v(TAG, e.getMessage());
169 }
170 }
Kaif057bd42019-07-26 16:49:33 -0700171
Kai6e75d492020-02-20 16:11:40 -0800172 @Test
173 public void testNotReceiveOnErrorEvent() {
174 TestCallback callback = new TestCallback();
175 mManager.registerCallback(callback, VehiclePropertyIds.HVAC_TEMPERATURE_SET,
176 CarPropertyManager.SENSOR_RATE_ONCHANGE);
177 injectErrorEvent(VehiclePropertyIds.HVAC_TEMPERATURE_SET, PASSENGER_SIDE_AREA_ID,
178 CarPropertyManager.CAR_SET_PROPERTY_ERROR_CODE_UNKNOWN);
179 // app never change the value of HVAC_TEMPERATURE_SET, it won't get an error code.
180 SystemClock.sleep(SHORT_WAIT_TIMEOUT_MS);
181 Assert.assertFalse(callback.mReceivedErrorEventWithErrorCode);
182 Assert.assertFalse(callback.mReceivedErrorEventWithOutErrorCode);
183 }
184
185 @Test
186 public void testReceiveOnErrorEvent() {
187 TestCallback callback = new TestCallback();
188 mManager.registerCallback(callback, VehiclePropertyIds.HVAC_TEMPERATURE_SET,
189 CarPropertyManager.SENSOR_RATE_ONCHANGE);
190 mManager.setFloatProperty(
191 VehiclePropertyIds.HVAC_TEMPERATURE_SET, PASSENGER_SIDE_AREA_ID,
192 CHANGED_TEMP_VALUE);
193 injectErrorEvent(VehiclePropertyIds.HVAC_TEMPERATURE_SET, PASSENGER_SIDE_AREA_ID,
194 CarPropertyManager.CAR_SET_PROPERTY_ERROR_CODE_UNKNOWN);
195 SystemClock.sleep(SHORT_WAIT_TIMEOUT_MS);
196 Assert.assertTrue(callback.mReceivedErrorEventWithErrorCode);
197 Assert.assertEquals(CarPropertyManager.CAR_SET_PROPERTY_ERROR_CODE_UNKNOWN,
198 callback.mErrorCode);
199 Assert.assertFalse(callback.mReceivedErrorEventWithOutErrorCode);
200 }
201
202 @Test
203 public void testNotReceiveOnErrorEventAfterUnregister() {
204 TestCallback callback1 = new TestCallback();
205 TestCallback callback2 = new TestCallback();
206 mManager.registerCallback(callback1, VehiclePropertyIds.HVAC_TEMPERATURE_SET,
207 CarPropertyManager.SENSOR_RATE_ONCHANGE);
208 mManager.registerCallback(callback2, VehiclePropertyIds.HVAC_TEMPERATURE_SET,
209 CarPropertyManager.SENSOR_RATE_ONCHANGE);
210 mManager.setFloatProperty(
211 VehiclePropertyIds.HVAC_TEMPERATURE_SET, PASSENGER_SIDE_AREA_ID,
212 CHANGED_TEMP_VALUE);
213 mManager.unregisterCallback(callback1, VehiclePropertyIds.HVAC_TEMPERATURE_SET);
214 injectErrorEvent(VehiclePropertyIds.HVAC_TEMPERATURE_SET, PASSENGER_SIDE_AREA_ID,
215 CarPropertyManager.CAR_SET_PROPERTY_ERROR_CODE_UNKNOWN);
216 SystemClock.sleep(SHORT_WAIT_TIMEOUT_MS);
217 Assert.assertFalse(callback1.mReceivedErrorEventWithErrorCode);
218 Assert.assertFalse(callback1.mReceivedErrorEventWithOutErrorCode);
219 }
220
Kaif057bd42019-07-26 16:49:33 -0700221 @Override
222 protected synchronized void configureMockedHal() {
223 PropertyHandler handler = new PropertyHandler();
Kaida0ce5e2019-10-16 13:42:17 -0700224 addProperty(CUSTOM_GLOBAL_MIXED_PROP_ID_1, handler).setConfigArray(CONFIG_ARRAY_1)
225 .addAreaConfig(DRIVER_SIDE_AREA_ID).addAreaConfig(PASSENGER_SIDE_AREA_ID);
Kaif057bd42019-07-26 16:49:33 -0700226 addProperty(CUSTOM_GLOBAL_MIXED_PROP_ID_2, handler).setConfigArray(CONFIG_ARRAY_2);
Kai6e75d492020-02-20 16:11:40 -0800227
228 VehiclePropValue tempValue = new VehiclePropValue();
229 tempValue.value.floatValues.add(INIT_TEMP_VALUE);
230 tempValue.prop = VehiclePropertyIds.HVAC_TEMPERATURE_SET;
231 addProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, tempValue)
232 .addAreaConfig(DRIVER_SIDE_AREA_ID).addAreaConfig(PASSENGER_SIDE_AREA_ID);
Kaif057bd42019-07-26 16:49:33 -0700233 }
234
235 private class PropertyHandler implements VehicleHalPropertyHandler {
236 HashMap<Integer, VehiclePropValue> mMap = new HashMap<>();
237 @Override
238 public synchronized void onPropertySet(VehiclePropValue value) {
239 mMap.put(value.prop, value);
240 }
241
242 @Override
243 public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
244 VehiclePropValue currentValue = mMap.get(value.prop);
245 return currentValue != null ? currentValue : value;
246 }
247
248 @Override
249 public synchronized void onPropertySubscribe(int property, float sampleRate) {
250 Log.d(TAG, "onPropertySubscribe property "
251 + property + " sampleRate " + sampleRate);
252 }
253
254 @Override
255 public synchronized void onPropertyUnsubscribe(int property) {
256 Log.d(TAG, "onPropertyUnSubscribe property " + property);
257 }
258 }
Kai6e75d492020-02-20 16:11:40 -0800259
260 private static class TestCallback implements CarPropertyManager.CarPropertyEventCallback {
261
262 private static final String CALLBACK_TAG = "ErrorEventTest";
263 private boolean mReceivedErrorEventWithErrorCode = false;
264 private boolean mReceivedErrorEventWithOutErrorCode = false;
265 private int mErrorCode;
266 @Override
267 public void onChangeEvent(CarPropertyValue value) {
268 Log.d(CALLBACK_TAG, "onChangeEvent: " + value);
269 }
270
271 @Override
272 public void onErrorEvent(int propId, int zone) {
273 mReceivedErrorEventWithOutErrorCode = true;
274 Log.d(CALLBACK_TAG, "onErrorEvent, propId: " + propId + " zone: " + zone);
275 }
276
277 @Override
278 public void onErrorEvent(int propId, int areaId, int errorCode) {
279 mReceivedErrorEventWithErrorCode = true;
280 mErrorCode = errorCode;
281 Log.d(CALLBACK_TAG, "onErrorEvent, propId: " + propId + " areaId: " + areaId
282 + "errorCode: " + errorCode);
283 }
284 }
Kaif057bd42019-07-26 16:49:33 -0700285}