CarVendorExtensionManagerTest.java revision cfe93105f637c2822da113308f113ed418d0b319
1/* 2 * Copyright (C) 2016 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.test; 18 19import static com.android.car.CarServiceUtils.toByteArray; 20 21import android.car.Car; 22import android.car.hardware.CarPropertyConfig; 23import android.car.hardware.CarVendorExtensionManager; 24import android.hardware.automotive.vehicle.V2_0.StatusCode; 25import android.hardware.automotive.vehicle.V2_0.VehicleArea; 26import android.hardware.automotive.vehicle.V2_0.VehicleAreaZone; 27import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig; 28import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; 29import android.hardware.automotive.vehicle.V2_0.VehiclePropertyGroup; 30import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType; 31import android.os.SystemClock; 32import android.util.Log; 33import android.util.SparseArray; 34 35import com.android.car.vehiclehal.test.MockedVehicleHal; 36import com.android.car.vehiclehal.test.VehiclePropConfigBuilder; 37 38import org.junit.Assert; 39 40import java.util.Arrays; 41import java.util.List; 42import java.util.Random; 43 44/** 45 * Tests for {@link CarVendorExtensionManager} 46 */ 47public class CarVendorExtensionManagerTest extends MockedCarTestBase { 48 49 private static final String TAG = CarVendorExtensionManager.class.getSimpleName(); 50 51 private static final int CUSTOM_GLOBAL_INT_PROP_ID = 52 0x1 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.INT32 | VehicleArea.GLOBAL; 53 54 private static final int CUSTOM_ZONED_FLOAT_PROP_ID = 55 0x2 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.FLOAT | VehicleArea.ZONE; 56 57 private static final int CUSTOM_BYTES_PROP_ID_1 = 58 0x3 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.BYTES | VehicleArea.ZONE; 59 60 private static final int CUSTOM_BYTES_PROP_ID_2 = 61 0x4 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.BYTES | VehicleArea.GLOBAL; 62 63 private static final int CUSTOM_STRING_PROP_ID = 64 0x5 | VehiclePropertyGroup.VENDOR | VehiclePropertyType.STRING | VehicleArea.GLOBAL; 65 66 private static final float EPS = 1e-9f; 67 private static final int MILLION = 1000 * 1000; 68 69 private static final int MIN_PROP_INT32 = 0x0000005; 70 private static final int MAX_PROP_INT32 = 0xDeadBee; 71 72 private static final float MIN_PROP_FLOAT = 10.42f; 73 private static final float MAX_PROP_FLOAT = 42.10f; 74 75// private static final MockedVehicleHal mVehicleHal = new MockedVehicleHal(); 76 77 private static final VehiclePropConfig mConfigs[] = new VehiclePropConfig[] { 78 VehiclePropConfigBuilder.newBuilder(CUSTOM_GLOBAL_INT_PROP_ID) 79 .addAreaConfig(0, MIN_PROP_INT32, MAX_PROP_INT32) 80 .build(), 81 VehiclePropConfigBuilder.newBuilder(CUSTOM_ZONED_FLOAT_PROP_ID) 82 .setSupportedAreas(VehicleAreaZone.ROW_1_LEFT | VehicleAreaZone.ROW_1_RIGHT) 83 .addAreaConfig(VehicleAreaZone.ROW_1_LEFT, MIN_PROP_FLOAT, MAX_PROP_FLOAT) 84 .addAreaConfig(VehicleAreaZone.ROW_2_RIGHT, MIN_PROP_FLOAT, MAX_PROP_FLOAT) 85 .build(), 86 VehiclePropConfigBuilder.newBuilder(CUSTOM_BYTES_PROP_ID_1) 87 .setSupportedAreas(VehicleAreaZone.ROW_1_LEFT | VehicleAreaZone.ROW_1_RIGHT) 88 .build(), 89 VehiclePropConfigBuilder.newBuilder(CUSTOM_BYTES_PROP_ID_2).build(), 90 VehiclePropConfigBuilder.newBuilder(CUSTOM_STRING_PROP_ID).build(), 91 }; 92 93 private CarVendorExtensionManager mManager; 94 95 @Override 96 protected void setUp() throws Exception { 97 super.setUp(); 98 99 mManager = (CarVendorExtensionManager) getCar().getCarManager(Car.VENDOR_EXTENSION_SERVICE); 100 assertNotNull(mManager); 101 } 102 103 @Override 104 protected void tearDown() throws Exception { 105 super.tearDown(); 106 } 107 108 public void testPropertyList() throws Exception { 109 List<CarPropertyConfig> configs = mManager.getProperties(); 110 assertEquals(mConfigs.length, configs.size()); 111 112 SparseArray<CarPropertyConfig> configById = new SparseArray<>(configs.size()); 113 for (CarPropertyConfig config : configs) { 114 configById.put(config.getPropertyId(), config); 115 } 116 117 CarPropertyConfig prop1 = configById.get(CUSTOM_GLOBAL_INT_PROP_ID); 118 assertNotNull(prop1); 119 assertEquals(Integer.class, prop1.getPropertyType()); 120 assertEquals(MIN_PROP_INT32, prop1.getMinValue()); 121 assertEquals(MAX_PROP_INT32, prop1.getMaxValue()); 122 } 123 124 public void testIntGlobalProperty() throws Exception { 125 final int value = 0xbeef; 126 mManager.setGlobalProperty(Integer.class, CUSTOM_GLOBAL_INT_PROP_ID, value); 127 int actualValue = mManager.getGlobalProperty(Integer.class, CUSTOM_GLOBAL_INT_PROP_ID); 128 assertEquals(value, actualValue); 129 } 130 131 public void testFloatZonedProperty() throws Exception { 132 final float value = MIN_PROP_FLOAT + 1; 133 mManager.setProperty( 134 Float.class, 135 CUSTOM_ZONED_FLOAT_PROP_ID, 136 VehicleAreaZone.ROW_1_RIGHT, 137 value); 138 139 float actualValue = mManager.getProperty( 140 Float.class, CUSTOM_ZONED_FLOAT_PROP_ID, VehicleAreaZone.ROW_1_RIGHT); 141 assertEquals(value, actualValue, EPS); 142 } 143 144 public void testByteArrayProperty() throws Exception { 145 final byte[] expectedData = new byte[] { 1, 2, 3, 4, -1, 127, -127, 0 }; 146 147 // Write to CUSTOM_BYTES_PROP_ID_1 and read this value from CUSTOM_BYTES_PROP_ID_2 148 mManager.setGlobalProperty( 149 byte[].class, 150 CUSTOM_BYTES_PROP_ID_1, 151 expectedData); 152 153 byte[] actualData = mManager.getGlobalProperty( 154 byte[].class, 155 CUSTOM_BYTES_PROP_ID_2); 156 157 assertEquals(Arrays.toString(expectedData), Arrays.toString(actualData)); 158 } 159 160 public void testLargeByteArrayProperty() throws Exception { 161 // Allocate array of byte which is greater than binder transaction buffer limitation. 162 byte[] expectedData = new byte[3 * MILLION]; 163 164 new Random(SystemClock.elapsedRealtimeNanos()) 165 .nextBytes(expectedData); 166 167 // Write to CUSTOM_BYTES_PROP_ID_1 and read this value from CUSTOM_BYTES_PROP_ID_2 168 mManager.setGlobalProperty( 169 byte[].class, 170 CUSTOM_BYTES_PROP_ID_1, 171 expectedData); 172 173 byte[] actualData = mManager.getGlobalProperty( 174 byte[].class, 175 CUSTOM_BYTES_PROP_ID_2); 176 177 Assert.assertArrayEquals(expectedData, actualData); 178 } 179 180 public void testLargeStringProperty() throws Exception { 181 // Allocate string which is greater than binder transaction buffer limitation. 182 String expectedString = generateRandomString(2 * MILLION, 183 "abcdefghijKLMNεὕρηκα!@#$%^&*()[]{}:\"\t\n\r!'"); 184 185 mManager.setGlobalProperty( 186 String.class, 187 CUSTOM_STRING_PROP_ID, 188 expectedString); 189 190 String actualString = mManager.getGlobalProperty( 191 String.class, 192 CUSTOM_STRING_PROP_ID); 193 194 assertEquals(expectedString, actualString); 195 } 196 197 public void testStringProperty() throws Exception { 198 final String expectedString = "εὕρηκα!"; // Test some utf as well. 199 200 mManager.setGlobalProperty( 201 String.class, 202 CUSTOM_STRING_PROP_ID, 203 expectedString); 204 205 String actualString = mManager.getGlobalProperty( 206 String.class, 207 CUSTOM_STRING_PROP_ID); 208 209 assertEquals(expectedString, actualString); 210 } 211 212 private static String generateRandomString(int length, String allowedSymbols) { 213 Random r = new Random(SystemClock.elapsedRealtimeNanos()); 214 StringBuilder sb = new StringBuilder(length); 215 char[] chars = allowedSymbols.toCharArray(); 216 for (int i = 0; i < length; i++) { 217 sb.append(chars[r.nextInt(chars.length)]); 218 } 219 return sb.toString(); 220 } 221 222 @Override 223 protected synchronized MockedVehicleHal createMockedVehicleHal() { 224 MockedVehicleHal hal = new VendorExtMockedVehicleHal(); 225 hal.addProperties(mConfigs); 226 return hal; 227 } 228 229 private static class VendorExtMockedVehicleHal extends MockedVehicleHal { 230 private final SparseArray<VehiclePropValue> mValues = new SparseArray<>(); 231 232 private byte[] mBytes = null; 233 234 @Override 235 public synchronized int set(VehiclePropValue propValue) { 236 if (propValue.prop == CUSTOM_BYTES_PROP_ID_1) { 237 mBytes = toByteArray(propValue.value.bytes); 238 } 239 240 mValues.put(propValue.prop, propValue); 241 return StatusCode.OK; 242 } 243 244 @Override 245 public synchronized void get(VehiclePropValue requestedPropValue, getCallback cb) { 246 if (!isVendorProperty(requestedPropValue.prop)) { 247 cb.onValues(StatusCode.INVALID_ARG, null); 248 return; 249 } 250 VehiclePropValue result = new VehiclePropValue(); 251 result.prop = requestedPropValue.prop; 252 result.areaId = requestedPropValue.areaId; 253 254 if (requestedPropValue.prop == CUSTOM_BYTES_PROP_ID_2 && mBytes != null) { 255 Log.d(TAG, "Returning byte array property, value: " + Arrays.toString(mBytes)); 256 for (byte b : mBytes) { 257 result.value.bytes.add(b); 258 } 259 } else { 260 VehiclePropValue existingValue = mValues.get(requestedPropValue.prop); 261 if (existingValue != null) { 262 result = existingValue; 263 } else { 264 result = requestedPropValue; 265 } 266 } 267 cb.onValues(StatusCode.OK, result); 268 } 269 270 private boolean isVendorProperty(int prop) { 271 return VehiclePropertyGroup.VENDOR == (prop & VehiclePropertyGroup.VENDOR); 272 } 273 } 274} 275