1 /* 2 * Copyright (C) 2024 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 17 package android.car.hardware.property; 18 19 import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL; 20 import static android.car.VehiclePropertyIds.FUEL_DOOR_OPEN; 21 import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET; 22 import static android.car.VehiclePropertyIds.INFO_EV_CONNECTOR_TYPE; 23 import static android.car.VehiclePropertyIds.INFO_FUEL_DOOR_LOCATION; 24 import static android.car.VehiclePropertyIds.INITIAL_USER_INFO; 25 import static android.car.VehiclePropertyIds.INVALID; 26 import static android.car.hardware.property.CarPropertyManager.GetPropertyResult; 27 import static android.car.hardware.property.CarPropertyManager.PropertyAsyncError; 28 import static android.car.hardware.property.CarPropertyManager.SENSOR_RATE_ONCHANGE; 29 import static android.car.hardware.property.CarPropertyManager.SetPropertyRequest; 30 import static android.car.hardware.property.CarPropertyManager.SetPropertyResult; 31 32 import static com.android.car.internal.property.CarPropertyHelper.SYNC_OP_LIMIT_TRY_AGAIN; 33 34 import static com.google.common.truth.Truth.assertThat; 35 import static com.google.common.truth.Truth.assertWithMessage; 36 37 import static org.junit.Assert.assertThrows; 38 import static org.mockito.ArgumentMatchers.any; 39 import static org.mockito.ArgumentMatchers.anyInt; 40 import static org.mockito.ArgumentMatchers.anyLong; 41 import static org.mockito.ArgumentMatchers.eq; 42 import static org.mockito.Mockito.clearInvocations; 43 import static org.mockito.Mockito.doAnswer; 44 import static org.mockito.Mockito.doNothing; 45 import static org.mockito.Mockito.doThrow; 46 import static org.mockito.Mockito.mock; 47 import static org.mockito.Mockito.never; 48 import static org.mockito.Mockito.timeout; 49 import static org.mockito.Mockito.times; 50 import static org.mockito.Mockito.verify; 51 import static org.mockito.Mockito.when; 52 53 import android.car.VehicleAreaSeat; 54 import android.car.VehicleAreaType; 55 import android.car.VehiclePropertyIds; 56 import android.car.feature.FeatureFlags; 57 import android.car.hardware.CarPropertyConfig; 58 import android.car.hardware.CarPropertyValue; 59 import android.content.Context; 60 import android.content.pm.ApplicationInfo; 61 import android.os.Build; 62 import android.os.CancellationSignal; 63 import android.os.Handler; 64 import android.os.Looper; 65 import android.os.RemoteException; 66 import android.os.ServiceSpecificException; 67 import android.platform.test.annotations.IgnoreUnderRavenwood; 68 import android.platform.test.ravenwood.RavenwoodRule; 69 import android.util.ArraySet; 70 import android.util.SparseArray; 71 72 import com.android.car.internal.ICarBase; 73 import com.android.car.internal.property.AsyncPropertyServiceRequest; 74 import com.android.car.internal.property.AsyncPropertyServiceRequestList; 75 import com.android.car.internal.property.CarPropertyConfigList; 76 import com.android.car.internal.property.CarPropertyErrorCodes; 77 import com.android.car.internal.property.CarSubscription; 78 import com.android.car.internal.property.GetPropertyConfigListResult; 79 import com.android.car.internal.property.GetSetValueResult; 80 import com.android.car.internal.property.GetSetValueResultList; 81 import com.android.car.internal.property.IAsyncPropertyResultCallback; 82 import com.android.car.internal.util.IntArray; 83 84 import org.junit.Before; 85 import org.junit.Rule; 86 import org.junit.Test; 87 import org.junit.runner.RunWith; 88 import org.mockito.ArgumentCaptor; 89 import org.mockito.Captor; 90 import org.mockito.Mock; 91 import org.mockito.junit.MockitoJUnitRunner; 92 93 import java.time.Duration; 94 import java.util.ArrayList; 95 import java.util.List; 96 import java.util.Set; 97 import java.util.concurrent.Executor; 98 99 /** 100 * <p>This class contains unit tests for the {@link CarPropertyManager}. 101 */ 102 @RunWith(MockitoJUnitRunner.class) 103 public final class CarPropertyManagerUnitTest { 104 // Required to set the process ID and set the "main" thread for this test, otherwise 105 // getMainLooper will return null. 106 @Rule 107 public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() 108 .setProcessApp() 109 .setProvideMainThread(true) 110 .build(); 111 112 // Defined as vendor property. 113 private static final int VENDOR_CONTINUOUS_PROPERTY = 0x21100111; 114 private static final int VENDOR_ON_CHANGE_PROPERTY = 0x21100222; 115 private static final int VENDOR_STATIC_PROPERTY = 0x21100333; 116 117 private static final int BOOLEAN_PROP = FUEL_DOOR_OPEN; 118 private static final int INT32_PROP = INFO_FUEL_DOOR_LOCATION; 119 private static final int INT32_VEC_PROP = INFO_EV_CONNECTOR_TYPE; 120 private static final int FLOAT_PROP = HVAC_TEMPERATURE_SET; 121 122 private static final float MIN_UPDATE_RATE_HZ = 10; 123 private static final float MAX_UPDATE_RATE_HZ = 100; 124 private static final float FIRST_UPDATE_RATE_HZ = 50; 125 private static final float LARGER_UPDATE_RATE_HZ = 50.1f; 126 private static final float SMALLER_UPDATE_RATE_HZ = 49.9f; 127 128 private static final int VENDOR_ERROR_CODE = 0x2; 129 private static final int VENDOR_ERROR_CODE_SHIFT = 16; 130 private static final int UNKNOWN_ERROR = -101; 131 132 private static final long TEST_TIMESTAMP = 1234; 133 134 private Handler mMainHandler; 135 136 private CarPropertyConfig mContinuousCarPropertyConfig; 137 private CarPropertyConfig mOnChangeCarPropertyConfig; 138 private CarPropertyConfig mStaticCarPropertyConfig; 139 private final SparseArray<CarPropertyConfig> mCarPropertyConfigsById = new SparseArray<>(); 140 private final ArraySet<Integer> mUnsupportedPropIds = new ArraySet<>(); 141 private final ArraySet<Integer> mMissingPermissionPropIds = new ArraySet<>(); 142 143 @Mock 144 private ICarBase mCar; 145 @Mock 146 private ApplicationInfo mApplicationInfo; 147 @Mock 148 private ICarProperty mICarProperty; 149 @Mock 150 private Context mContext; 151 @Mock 152 private CarPropertyManager.CarPropertyEventCallback mCarPropertyEventCallback; 153 @Mock 154 private CarPropertyManager.CarPropertyEventCallback mCarPropertyEventCallback2; 155 @Mock 156 private CarPropertyManager.GetPropertyCallback mGetPropertyCallback; 157 @Mock 158 private CarPropertyManager.SetPropertyCallback mSetPropertyCallback; 159 @Mock 160 private Executor mMockExecutor1; 161 @Mock 162 private Executor mMockExecutor2; 163 @Mock 164 private FeatureFlags mFeatureFlags; 165 166 @Captor 167 private ArgumentCaptor<Integer> mPropertyIdCaptor; 168 @Captor 169 private ArgumentCaptor<List> mCarSubscriptionCaptor; 170 @Captor 171 private ArgumentCaptor<AsyncPropertyServiceRequestList> mAsyncPropertyServiceRequestCaptor; 172 @Captor 173 private ArgumentCaptor<PropertyAsyncError> mPropertyAsyncErrorCaptor; 174 @Captor 175 private ArgumentCaptor<GetPropertyResult<?>> mGetPropertyResultCaptor; 176 @Captor 177 private ArgumentCaptor<SetPropertyResult> mSetPropertyResultCaptor; 178 private CarPropertyManager mCarPropertyManager; 179 combineErrors(int systemError, int vendorError)180 private static int combineErrors(int systemError, int vendorError) { 181 return vendorError << VENDOR_ERROR_CODE_SHIFT | systemError; 182 } 183 createErrorCarPropertyEventList()184 private static List<CarPropertyEvent> createErrorCarPropertyEventList() { 185 CarPropertyValue<Integer> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 186 CarPropertyValue.STATUS_AVAILABLE, 0, -1); 187 CarPropertyEvent carPropertyEvent = new CarPropertyEvent( 188 CarPropertyEvent.PROPERTY_EVENT_ERROR, value, 189 CarPropertyManager.CAR_SET_PROPERTY_ERROR_CODE_UNKNOWN); 190 return List.of(carPropertyEvent); 191 } 192 createCarPropertyEventList()193 private static List<CarPropertyEvent> createCarPropertyEventList() { 194 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 17.0f); 195 CarPropertyEvent carPropertyEvent = new CarPropertyEvent( 196 CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE, value); 197 return List.of(carPropertyEvent); 198 } 199 createCarSubscriptionOption(int propertyId, int[] areaId, float updateRateHz)200 private static CarSubscription createCarSubscriptionOption(int propertyId, 201 int[] areaId, float updateRateHz) { 202 return createCarSubscriptionOption(propertyId, areaId, updateRateHz, 203 /* enableVur= */ false); 204 } 205 createCarSubscriptionOption(int propertyId, int[] areaId, float updateRateHz, boolean enableVur)206 private static CarSubscription createCarSubscriptionOption(int propertyId, 207 int[] areaId, float updateRateHz, boolean enableVur) { 208 CarSubscription options = new CarSubscription(); 209 options.propertyId = propertyId; 210 options.areaIds = areaId; 211 options.updateRateHz = updateRateHz; 212 options.enableVariableUpdateRate = enableVur; 213 return options; 214 } 215 addCarPropertyConfig(CarPropertyConfig config)216 private void addCarPropertyConfig(CarPropertyConfig config) { 217 mCarPropertyConfigsById.put(config.getPropertyId(), config); 218 } 219 setPropIdWithoutPermission(int propId)220 private void setPropIdWithoutPermission(int propId) { 221 mCarPropertyConfigsById.remove(propId); 222 mMissingPermissionPropIds.add(propId); 223 } 224 setPropIdWithoutConfig(int propId)225 private void setPropIdWithoutConfig(int propId) { 226 mCarPropertyConfigsById.remove(propId); 227 mUnsupportedPropIds.add(propId); 228 } 229 230 @Before setUp()231 public void setUp() throws RemoteException { 232 mMainHandler = new Handler(Looper.getMainLooper()); 233 when(mCar.getContext()).thenReturn(mContext); 234 when(mCar.getEventHandler()).thenReturn(mMainHandler); 235 when(mCar.handleRemoteExceptionFromCarService(any(RemoteException.class), any())) 236 .thenAnswer((inv) -> { 237 return inv.getArgument(1); 238 }); 239 240 mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.R; 241 when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); 242 243 mContinuousCarPropertyConfig = CarPropertyConfig.newBuilder(Integer.class, 244 VENDOR_CONTINUOUS_PROPERTY, VEHICLE_AREA_TYPE_GLOBAL) 245 .setChangeMode(CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS) 246 .setMinSampleRate(MIN_UPDATE_RATE_HZ) 247 .setMaxSampleRate(MAX_UPDATE_RATE_HZ) 248 .addAreaIdConfig(new AreaIdConfig.Builder<Integer>(0) 249 .setSupportVariableUpdateRate(true).build()) 250 .build(); 251 mOnChangeCarPropertyConfig = CarPropertyConfig.newBuilder(Integer.class, 252 VENDOR_ON_CHANGE_PROPERTY, VEHICLE_AREA_TYPE_GLOBAL) 253 .setChangeMode(CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE) 254 .addAreaIdConfig(new AreaIdConfig.Builder<Integer>(0).build()) 255 .build(); 256 mStaticCarPropertyConfig = CarPropertyConfig.newBuilder(Integer.class, 257 VENDOR_STATIC_PROPERTY, VEHICLE_AREA_TYPE_GLOBAL) 258 .setChangeMode(CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_STATIC) 259 .addAreaIdConfig(new AreaIdConfig.Builder<Integer>(0).build()) 260 .build(); 261 262 when(mICarProperty.getPropertyConfigList(any())).thenAnswer((invocation) -> { 263 Object[] args = invocation.getArguments(); 264 int[] propIds = (int[]) args[0]; 265 GetPropertyConfigListResult result = new GetPropertyConfigListResult(); 266 IntArray unsupportedPropIds = new IntArray(); 267 IntArray missingPermissionPropIds = new IntArray(); 268 List<CarPropertyConfig> configs = new ArrayList<>(); 269 for (int propId : propIds) { 270 if (mUnsupportedPropIds.contains(propId)) { 271 unsupportedPropIds.add(propId); 272 continue; 273 } 274 if (mMissingPermissionPropIds.contains(propId)) { 275 missingPermissionPropIds.add(propId); 276 continue; 277 } 278 var config = mCarPropertyConfigsById.get(propId); 279 if (config == null) { 280 unsupportedPropIds.add(propId); 281 continue; 282 } 283 configs.add(config); 284 } 285 286 result.carPropertyConfigList = new CarPropertyConfigList(configs); 287 result.unsupportedPropIds = unsupportedPropIds.toArray(); 288 result.missingPermissionPropIds = missingPermissionPropIds.toArray(); 289 return result; 290 }); 291 292 addCarPropertyConfig(mContinuousCarPropertyConfig); 293 addCarPropertyConfig(mOnChangeCarPropertyConfig); 294 addCarPropertyConfig(mStaticCarPropertyConfig); 295 when(mICarProperty.getSupportedNoReadPermPropIds(any())).thenReturn(new int[0]); 296 mCarPropertyManager = new CarPropertyManager(mCar, mICarProperty); 297 // Enable the features. 298 when(mFeatureFlags.variableUpdateRate()).thenReturn(true); 299 mCarPropertyManager.setFeatureFlags(mFeatureFlags); 300 } 301 302 @Test testGetProperty_returnsValue()303 public void testGetProperty_returnsValue() throws RemoteException { 304 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 17.0f); 305 306 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 307 308 assertThat(mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)).isEqualTo(value); 309 } 310 311 @Test testGetProperty_unsupportedProperty_exceptionAtU()312 public void testGetProperty_unsupportedProperty_exceptionAtU() throws Exception { 313 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 314 315 assertThrows(IllegalArgumentException.class, 316 () -> mCarPropertyManager.getProperty(INVALID, 0)); 317 } 318 319 @Test testGetProperty_unsupportedProperty_nullBeforeU()320 public void testGetProperty_unsupportedProperty_nullBeforeU() throws Exception { 321 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 322 323 assertThat(mCarPropertyManager.getProperty(INVALID, 0)).isNull(); 324 } 325 326 @Test testGetProperty_unsupportedPropertyInSvc_exceptionAtU()327 public void testGetProperty_unsupportedPropertyInSvc_exceptionAtU() throws Exception { 328 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 329 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 330 new IllegalArgumentException()); 331 332 assertThrows(IllegalArgumentException.class, 333 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 334 } 335 336 @Test testGetProperty_unsupportedPropertyInSvc_nullBeforeU()337 public void testGetProperty_unsupportedPropertyInSvc_nullBeforeU() throws Exception { 338 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 339 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 340 new IllegalArgumentException()); 341 342 assertThat(mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)).isNull(); 343 } 344 345 @Test testGetProperty_syncOpTryAgain()346 public void testGetProperty_syncOpTryAgain() throws RemoteException { 347 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 17.0f); 348 349 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 350 new ServiceSpecificException(SYNC_OP_LIMIT_TRY_AGAIN)).thenReturn(value); 351 352 assertThat(mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)).isEqualTo(value); 353 verify(mICarProperty, times(2)).getProperty(HVAC_TEMPERATURE_SET, 0); 354 } 355 356 @Test testGetProperty_syncOpTryAgain_exceedRetryCountLimit()357 public void testGetProperty_syncOpTryAgain_exceedRetryCountLimit() throws RemoteException { 358 // Car service will throw CarInternalException with version >= R. 359 setAppTargetSdk(Build.VERSION_CODES.R); 360 361 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 362 new ServiceSpecificException(SYNC_OP_LIMIT_TRY_AGAIN)); 363 364 assertThrows(CarInternalErrorException.class, () -> 365 mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 366 verify(mICarProperty, times(10)).getProperty(HVAC_TEMPERATURE_SET, 0); 367 } 368 setAppTargetSdk(int appTargetSdk)369 private void setAppTargetSdk(int appTargetSdk) { 370 mApplicationInfo.targetSdkVersion = appTargetSdk; 371 mCarPropertyManager = new CarPropertyManager(mCar, mICarProperty); 372 } 373 374 @Test testGetProperty_notAvailableBeforeR()375 public void testGetProperty_notAvailableBeforeR() throws Exception { 376 setAppTargetSdk(Build.VERSION_CODES.Q); 377 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 378 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE)); 379 380 assertThrows(IllegalStateException.class, 381 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 382 } 383 384 @Test testGetProperty_notAvailableEqualAfterR()385 public void testGetProperty_notAvailableEqualAfterR() throws Exception { 386 setAppTargetSdk(Build.VERSION_CODES.R); 387 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 388 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE)); 389 390 assertThrows(PropertyNotAvailableException.class, 391 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 392 } 393 394 @Test testGetProperty_tryAgainBeforeR()395 public void testGetProperty_tryAgainBeforeR() throws Exception { 396 setAppTargetSdk(Build.VERSION_CODES.Q); 397 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 398 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 399 400 assertThat(mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)).isNull(); 401 } 402 403 @Test testGetProperty_tryAgainEqualAfterR()404 public void testGetProperty_tryAgainEqualAfterR() throws Exception { 405 setAppTargetSdk(Build.VERSION_CODES.R); 406 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 407 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 408 409 assertThrows(PropertyNotAvailableAndRetryException.class, 410 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 411 } 412 413 @Test testGetProperty_accessDeniedBeforeR()414 public void testGetProperty_accessDeniedBeforeR() throws Exception { 415 setAppTargetSdk(Build.VERSION_CODES.Q); 416 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 417 new ServiceSpecificException(VehicleHalStatusCode.STATUS_ACCESS_DENIED)); 418 419 assertThrows(IllegalStateException.class, 420 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 421 } 422 423 @Test testGetProperty_accessDeniedEqualAfterR()424 public void testGetProperty_accessDeniedEqualAfterR() throws Exception { 425 setAppTargetSdk(Build.VERSION_CODES.R); 426 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 427 new ServiceSpecificException(VehicleHalStatusCode.STATUS_ACCESS_DENIED)); 428 429 assertThrows(PropertyAccessDeniedSecurityException.class, 430 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 431 } 432 433 @Test testGetProperty_internalErrorBeforeR()434 public void testGetProperty_internalErrorBeforeR() throws Exception { 435 setAppTargetSdk(Build.VERSION_CODES.Q); 436 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 437 new ServiceSpecificException(VehicleHalStatusCode.STATUS_INTERNAL_ERROR)); 438 439 assertThrows(IllegalStateException.class, 440 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 441 } 442 443 @Test testGetProperty_internalErrorEqualAfterR()444 public void testGetProperty_internalErrorEqualAfterR() throws Exception { 445 setAppTargetSdk(Build.VERSION_CODES.R); 446 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 447 new ServiceSpecificException(VehicleHalStatusCode.STATUS_INTERNAL_ERROR)); 448 449 assertThrows(CarInternalErrorException.class, 450 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 451 } 452 453 @Test testGetProperty_internalErrorEqualAfterU_withVendorErrorCode()454 public void testGetProperty_internalErrorEqualAfterU_withVendorErrorCode() throws Exception { 455 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 456 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 457 new ServiceSpecificException(combineErrors( 458 VehicleHalStatusCode.STATUS_INTERNAL_ERROR, VENDOR_ERROR_CODE))); 459 460 CarInternalErrorException exception = assertThrows(CarInternalErrorException.class, 461 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 462 463 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 464 } 465 466 @Test testGetProperty_unknownErrorBeforeR()467 public void testGetProperty_unknownErrorBeforeR() throws Exception { 468 setAppTargetSdk(Build.VERSION_CODES.Q); 469 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 470 new ServiceSpecificException(UNKNOWN_ERROR)); 471 472 assertThrows(IllegalStateException.class, 473 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 474 } 475 476 @Test testGetProperty_unknownErrorEqualAfterR()477 public void testGetProperty_unknownErrorEqualAfterR() throws Exception { 478 setAppTargetSdk(Build.VERSION_CODES.R); 479 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 480 new ServiceSpecificException(UNKNOWN_ERROR)); 481 482 assertThrows(CarInternalErrorException.class, 483 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 484 } 485 486 @Test testGetProperty_returnsValueWithUnavailableStatusBeforeU()487 public void testGetProperty_returnsValueWithUnavailableStatusBeforeU() throws RemoteException { 488 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 489 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 490 CarPropertyValue.STATUS_UNAVAILABLE, TEST_TIMESTAMP, 17.0f); 491 492 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 493 494 assertThat(mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, /*areaId=*/ 0)).isEqualTo( 495 new CarPropertyValue<>(HVAC_TEMPERATURE_SET, /*areaId=*/0, 496 CarPropertyValue.STATUS_UNAVAILABLE, TEST_TIMESTAMP, 17.0f)); 497 } 498 499 @Test testGetProperty_valueWithUnavailableStatusThrowsAfterU()500 public void testGetProperty_valueWithUnavailableStatusThrowsAfterU() throws RemoteException { 501 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 502 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 503 CarPropertyValue.STATUS_UNAVAILABLE, TEST_TIMESTAMP, 17.0f); 504 505 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 506 507 assertThrows(PropertyNotAvailableException.class, 508 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 509 } 510 511 @Test testGetProperty_returnsValueWithErrorStatusBeforeU()512 public void testGetProperty_returnsValueWithErrorStatusBeforeU() throws RemoteException { 513 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 514 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 515 CarPropertyValue.STATUS_ERROR, TEST_TIMESTAMP, 17.0f); 516 517 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 518 519 assertThat(mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, /*areaId=*/ 0)).isEqualTo( 520 new CarPropertyValue<>(HVAC_TEMPERATURE_SET, /*areaId=*/0, 521 CarPropertyValue.STATUS_ERROR, TEST_TIMESTAMP, 17.0f)); 522 } 523 524 @Test testGetProperty_valueWithErrorStatusThrowsAfterU()525 public void testGetProperty_valueWithErrorStatusThrowsAfterU() throws RemoteException { 526 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 527 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 528 CarPropertyValue.STATUS_ERROR, TEST_TIMESTAMP, 17.0f); 529 530 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 531 532 assertThrows(CarInternalErrorException.class, 533 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 534 } 535 536 @Test testGetProperty_returnsValueWithUnknownStatusBeforeU()537 public void testGetProperty_returnsValueWithUnknownStatusBeforeU() throws RemoteException { 538 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 539 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 540 /*unknown status=*/999, TEST_TIMESTAMP, 17.0f); 541 542 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 543 544 assertThat(mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, /*areaId=*/ 0)).isEqualTo( 545 new CarPropertyValue<>(HVAC_TEMPERATURE_SET, /*areaId=*/0, /*status=*/999, 546 TEST_TIMESTAMP, 17.0f)); 547 } 548 549 @Test testGetProperty_valueWithUnknownStatusThrowsAfterU()550 public void testGetProperty_valueWithUnknownStatusThrowsAfterU() throws RemoteException { 551 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 552 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 553 /*unknown status=*/999, TEST_TIMESTAMP, 17.0f); 554 555 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 556 557 assertThrows(CarInternalErrorException.class, 558 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 559 } 560 561 @Test testGetPropertyWithClass()562 public void testGetPropertyWithClass() throws Exception { 563 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 17.0f); 564 565 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 566 567 assertThat(mCarPropertyManager.getProperty(Float.class, HVAC_TEMPERATURE_SET, 0).getValue()) 568 .isEqualTo(17.0f); 569 } 570 571 @Test testGetPropertyWithClass_mismatchClass()572 public void testGetPropertyWithClass_mismatchClass() throws Exception { 573 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 17.0f); 574 575 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 576 577 assertThrows(IllegalArgumentException.class, 578 () -> mCarPropertyManager.getProperty(Integer.class, HVAC_TEMPERATURE_SET, 0)); 579 } 580 581 @Test testGetPropertyWithClass_tryAgainBeforeR()582 public void testGetPropertyWithClass_tryAgainBeforeR() throws Exception { 583 setAppTargetSdk(Build.VERSION_CODES.Q); 584 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 585 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 586 587 assertThat(mCarPropertyManager.getProperty(Float.class, HVAC_TEMPERATURE_SET, 0)) 588 .isNull(); 589 } 590 591 @Test testGetPropertyWithClass_tryAgainEqualAfterR()592 public void testGetPropertyWithClass_tryAgainEqualAfterR() throws Exception { 593 setAppTargetSdk(Build.VERSION_CODES.R); 594 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 595 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 596 597 assertThrows(PropertyNotAvailableAndRetryException.class, 598 () -> mCarPropertyManager.getProperty(Float.class, HVAC_TEMPERATURE_SET, 0)); 599 } 600 601 602 @Test testGetBooleanProperty()603 public void testGetBooleanProperty() throws Exception { 604 setAppTargetSdk(Build.VERSION_CODES.R); 605 CarPropertyValue<Boolean> value = new CarPropertyValue<>(BOOLEAN_PROP, 0, true); 606 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenReturn(value); 607 608 assertThat(mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)).isTrue(); 609 } 610 611 @Test testGetBooleanProperty_notAvailableBeforeR()612 public void testGetBooleanProperty_notAvailableBeforeR() throws Exception { 613 setAppTargetSdk(Build.VERSION_CODES.Q); 614 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 615 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE)); 616 617 assertThrows(IllegalStateException.class, 618 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 619 } 620 621 @Test testGetBooleanProperty_notAvailableEqualAfterR()622 public void testGetBooleanProperty_notAvailableEqualAfterR() throws Exception { 623 setAppTargetSdk(Build.VERSION_CODES.R); 624 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 625 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE)); 626 627 assertThrows(PropertyNotAvailableException.class, 628 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 629 } 630 631 @Test testGetProperty_notAvailableEqualAfterU_withVendorErrorCode()632 public void testGetProperty_notAvailableEqualAfterU_withVendorErrorCode() throws Exception { 633 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 634 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 635 new ServiceSpecificException(combineErrors( 636 VehicleHalStatusCode.STATUS_NOT_AVAILABLE, VENDOR_ERROR_CODE))); 637 638 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 639 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 640 641 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 642 } 643 644 @Test testGetProperty_notAvailableDisabledBeforeU()645 public void testGetProperty_notAvailableDisabledBeforeU() throws Exception { 646 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 647 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 648 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_DISABLED)); 649 650 assertThrows(PropertyNotAvailableException.class, 651 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 652 } 653 654 @Test testGetProperty_notAvailableDisabledAfterU()655 public void testGetProperty_notAvailableDisabledAfterU() throws Exception { 656 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 657 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 658 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_DISABLED)); 659 660 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 661 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 662 assertThat(exception.getDetailedErrorCode()) 663 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_DISABLED); 664 } 665 666 @Test testGetProperty_notAvailableDisabledAfterU_withVendorErrorCode()667 public void testGetProperty_notAvailableDisabledAfterU_withVendorErrorCode() throws Exception { 668 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 669 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 670 new ServiceSpecificException(combineErrors( 671 VehicleHalStatusCode.STATUS_NOT_AVAILABLE_DISABLED, VENDOR_ERROR_CODE))); 672 673 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 674 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 675 676 assertThat(exception.getDetailedErrorCode()) 677 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_DISABLED); 678 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 679 } 680 681 @Test testGetProperty_notAvailableSafetyBeforeU()682 public void testGetProperty_notAvailableSafetyBeforeU() throws Exception { 683 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 684 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 685 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SAFETY)); 686 687 assertThrows(PropertyNotAvailableException.class, 688 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 689 } 690 691 @Test testGetProperty_notAvailableSafetyAfterU()692 public void testGetProperty_notAvailableSafetyAfterU() throws Exception { 693 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 694 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 695 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SAFETY)); 696 697 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 698 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 699 assertThat(exception.getDetailedErrorCode()) 700 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SAFETY); 701 } 702 703 @Test testGetProperty_notAvailableSafetyAfterU_withVendorErrorCode()704 public void testGetProperty_notAvailableSafetyAfterU_withVendorErrorCode() throws Exception { 705 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 706 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 707 new ServiceSpecificException(combineErrors( 708 VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SAFETY, VENDOR_ERROR_CODE))); 709 710 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 711 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 712 713 assertThat(exception.getDetailedErrorCode()) 714 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SAFETY); 715 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 716 } 717 718 @Test testGetProperty_notAvailableSpeedHighBeforeU()719 public void testGetProperty_notAvailableSpeedHighBeforeU() throws Exception { 720 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 721 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 722 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_HIGH)); 723 724 assertThrows(PropertyNotAvailableException.class, 725 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 726 } 727 728 @Test testGetProperty_notAvailableSpeedHighAfterU()729 public void testGetProperty_notAvailableSpeedHighAfterU() throws Exception { 730 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 731 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 732 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_HIGH)); 733 734 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 735 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 736 assertThat(exception.getDetailedErrorCode()) 737 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SPEED_HIGH); 738 } 739 740 @Test testGetProperty_notAvailableSpeedHighAfterU_withVendorErrorCode()741 public void testGetProperty_notAvailableSpeedHighAfterU_withVendorErrorCode() throws Exception { 742 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 743 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 744 new ServiceSpecificException(combineErrors( 745 VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_HIGH, VENDOR_ERROR_CODE))); 746 747 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 748 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 749 750 assertThat(exception.getDetailedErrorCode()) 751 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SPEED_HIGH); 752 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 753 } 754 755 @Test testGetProperty_notAvailableSpeedLowBeforeU()756 public void testGetProperty_notAvailableSpeedLowBeforeU() throws Exception { 757 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 758 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 759 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_LOW)); 760 761 assertThrows(PropertyNotAvailableException.class, 762 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 763 } 764 765 @Test testGetProperty_notAvailableSpeedLowAfterU()766 public void testGetProperty_notAvailableSpeedLowAfterU() throws Exception { 767 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 768 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 769 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_LOW)); 770 771 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 772 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 773 assertThat(exception.getDetailedErrorCode()) 774 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SPEED_LOW); 775 } 776 777 @Test testGetProperty_notAvailableSpeedLowAfterU_withVendorErrorCode()778 public void testGetProperty_notAvailableSpeedLowAfterU_withVendorErrorCode() throws Exception { 779 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 780 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 781 new ServiceSpecificException(combineErrors( 782 VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_LOW, VENDOR_ERROR_CODE))); 783 784 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 785 () -> mCarPropertyManager.getProperty(HVAC_TEMPERATURE_SET, 0)); 786 787 assertThat(exception.getDetailedErrorCode()) 788 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SPEED_LOW); 789 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 790 } 791 792 @Test testGetBooleanProperty_tryAgainBeforeR()793 public void testGetBooleanProperty_tryAgainBeforeR() throws Exception { 794 setAppTargetSdk(Build.VERSION_CODES.Q); 795 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 796 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 797 798 assertThat(mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)).isFalse(); 799 } 800 801 @Test testGetBooleanProperty_tryAgainEqualAfterR()802 public void testGetBooleanProperty_tryAgainEqualAfterR() throws Exception { 803 setAppTargetSdk(Build.VERSION_CODES.R); 804 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 805 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 806 807 assertThrows(PropertyNotAvailableAndRetryException.class, 808 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 809 } 810 811 @Test testGetBooleanProperty_accessDeniedBeforeR()812 public void testGetBooleanProperty_accessDeniedBeforeR() throws Exception { 813 setAppTargetSdk(Build.VERSION_CODES.Q); 814 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 815 new ServiceSpecificException(VehicleHalStatusCode.STATUS_ACCESS_DENIED)); 816 817 assertThrows(IllegalStateException.class, 818 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 819 } 820 821 @Test testGetBooleanProperty_accessDeniedEqualAfterR()822 public void testGetBooleanProperty_accessDeniedEqualAfterR() throws Exception { 823 setAppTargetSdk(Build.VERSION_CODES.R); 824 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 825 new ServiceSpecificException(VehicleHalStatusCode.STATUS_ACCESS_DENIED)); 826 827 assertThrows(PropertyAccessDeniedSecurityException.class, 828 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 829 } 830 831 @Test testGetBooleanProperty_internalErrorBeforeR()832 public void testGetBooleanProperty_internalErrorBeforeR() throws Exception { 833 setAppTargetSdk(Build.VERSION_CODES.Q); 834 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 835 new ServiceSpecificException(VehicleHalStatusCode.STATUS_INTERNAL_ERROR)); 836 837 assertThrows(IllegalStateException.class, 838 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 839 } 840 841 @Test testGetBooleanProperty_internalErrorEqualAfterR()842 public void testGetBooleanProperty_internalErrorEqualAfterR() throws Exception { 843 setAppTargetSdk(Build.VERSION_CODES.R); 844 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 845 new ServiceSpecificException(VehicleHalStatusCode.STATUS_INTERNAL_ERROR)); 846 847 assertThrows(CarInternalErrorException.class, 848 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 849 } 850 851 @Test testGetBooleanProperty_unknownErrorBeforeR()852 public void testGetBooleanProperty_unknownErrorBeforeR() throws Exception { 853 setAppTargetSdk(Build.VERSION_CODES.Q); 854 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 855 new ServiceSpecificException(UNKNOWN_ERROR)); 856 857 assertThrows(IllegalStateException.class, 858 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 859 } 860 861 @Test testGetBooleanProperty_unknownErrorEqualAfterR()862 public void testGetBooleanProperty_unknownErrorEqualAfterR() throws Exception { 863 setAppTargetSdk(Build.VERSION_CODES.R); 864 when(mICarProperty.getProperty(BOOLEAN_PROP, 0)).thenThrow( 865 new ServiceSpecificException(UNKNOWN_ERROR)); 866 867 assertThrows(CarInternalErrorException.class, 868 () -> mCarPropertyManager.getBooleanProperty(BOOLEAN_PROP, 0)); 869 } 870 871 @Test testGetIntProperty()872 public void testGetIntProperty() throws Exception { 873 setAppTargetSdk(Build.VERSION_CODES.R); 874 CarPropertyValue<Integer> value = new CarPropertyValue<>(INT32_PROP, 0, 1); 875 when(mICarProperty.getProperty(INT32_PROP, 0)).thenReturn(value); 876 877 assertThat(mCarPropertyManager.getIntProperty(INT32_PROP, 0)).isEqualTo(1); 878 } 879 880 @Test testGetIntProperty_tryAgainBeforeR()881 public void testGetIntProperty_tryAgainBeforeR() throws Exception { 882 setAppTargetSdk(Build.VERSION_CODES.Q); 883 when(mICarProperty.getProperty(INT32_PROP, 0)).thenThrow( 884 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 885 886 assertThat(mCarPropertyManager.getIntProperty(INT32_PROP, 0)).isEqualTo(0); 887 } 888 889 @Test testGetIntProperty_tryAgainEqualAfterR()890 public void testGetIntProperty_tryAgainEqualAfterR() throws Exception { 891 setAppTargetSdk(Build.VERSION_CODES.R); 892 when(mICarProperty.getProperty(INT32_PROP, 0)).thenThrow( 893 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 894 895 assertThrows(PropertyNotAvailableAndRetryException.class, 896 () -> mCarPropertyManager.getIntProperty(INT32_PROP, 0)); 897 } 898 899 @Test testGetIntProperty_wrongType()900 public void testGetIntProperty_wrongType() throws Exception { 901 CarPropertyValue<Integer> value = new CarPropertyValue<>(INT32_PROP, 0, 1); 902 when(mICarProperty.getProperty(INT32_PROP, 0)).thenReturn(value); 903 904 assertThrows(IllegalArgumentException.class, 905 () -> mCarPropertyManager.getFloatProperty(INT32_PROP, 0)); 906 } 907 908 @Test testGetIntArrayProperty()909 public void testGetIntArrayProperty() throws Exception { 910 setAppTargetSdk(Build.VERSION_CODES.R); 911 CarPropertyValue<Float> value = new CarPropertyValue<>(FLOAT_PROP, 0, 1f); 912 when(mICarProperty.getProperty(FLOAT_PROP, 0)).thenReturn(value); 913 914 assertThrows(IllegalArgumentException.class, 915 () -> mCarPropertyManager.getIntArrayProperty(FLOAT_PROP, 0)); 916 } 917 918 @Test testGetIntArrayProperty_tryAgainBeforeR()919 public void testGetIntArrayProperty_tryAgainBeforeR() throws Exception { 920 setAppTargetSdk(Build.VERSION_CODES.Q); 921 when(mICarProperty.getProperty(INT32_VEC_PROP, 0)).thenThrow( 922 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 923 924 assertThat(mCarPropertyManager.getIntArrayProperty(INT32_VEC_PROP, 0)).isEqualTo( 925 new int[0]); 926 } 927 928 @Test testGetIntArrayProperty_tryAgainEqualAfterR()929 public void testGetIntArrayProperty_tryAgainEqualAfterR() throws Exception { 930 setAppTargetSdk(Build.VERSION_CODES.R); 931 when(mICarProperty.getProperty(INT32_VEC_PROP, 0)).thenThrow( 932 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 933 934 assertThrows(PropertyNotAvailableAndRetryException.class, 935 () -> mCarPropertyManager.getIntArrayProperty(INT32_VEC_PROP, 0)); 936 } 937 938 @Test testGetFloatProperty()939 public void testGetFloatProperty() throws Exception { 940 setAppTargetSdk(Build.VERSION_CODES.R); 941 CarPropertyValue<Float> value = new CarPropertyValue<>(FLOAT_PROP, 0, 1.f); 942 when(mICarProperty.getProperty(FLOAT_PROP, 0)).thenReturn(value); 943 944 assertThat(mCarPropertyManager.getFloatProperty(FLOAT_PROP, 0)).isEqualTo(1.f); 945 } 946 947 @Test testGetFloatProperty_tryAgainBeforeR()948 public void testGetFloatProperty_tryAgainBeforeR() throws Exception { 949 setAppTargetSdk(Build.VERSION_CODES.Q); 950 when(mICarProperty.getProperty(FLOAT_PROP, 0)).thenThrow( 951 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 952 953 assertThat(mCarPropertyManager.getFloatProperty(FLOAT_PROP, 0)).isEqualTo(0.f); 954 } 955 956 @Test testGetFloatProperty_tryAgainEqualAfterR()957 public void testGetFloatProperty_tryAgainEqualAfterR() throws Exception { 958 setAppTargetSdk(Build.VERSION_CODES.R); 959 when(mICarProperty.getProperty(FLOAT_PROP, 0)).thenThrow( 960 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 961 962 assertThrows(PropertyNotAvailableAndRetryException.class, 963 () -> mCarPropertyManager.getFloatProperty(FLOAT_PROP, 0)); 964 } 965 966 @Test testGetFloatProperty_wrongType()967 public void testGetFloatProperty_wrongType() throws Exception { 968 CarPropertyValue<Integer> value = new CarPropertyValue<>(INT32_PROP, 0, 1); 969 when(mICarProperty.getProperty(INT32_PROP, 0)).thenReturn(value); 970 971 assertThrows(IllegalArgumentException.class, 972 () -> mCarPropertyManager.getFloatProperty(INT32_PROP, 0)); 973 } 974 createGetPropertyRequest()975 private CarPropertyManager.GetPropertyRequest createGetPropertyRequest() { 976 return mCarPropertyManager.generateGetPropertyRequest(HVAC_TEMPERATURE_SET, 0); 977 } 978 979 @Test testGetPropertiesAsync()980 public void testGetPropertiesAsync() throws RemoteException { 981 mCarPropertyManager.getPropertiesAsync(List.of(createGetPropertyRequest()), null, null, 982 mGetPropertyCallback); 983 984 ArgumentCaptor<AsyncPropertyServiceRequestList> argumentCaptor = ArgumentCaptor.forClass( 985 AsyncPropertyServiceRequestList.class); 986 verify(mICarProperty).getPropertiesAsync(argumentCaptor.capture(), any(), anyLong()); 987 assertThat(argumentCaptor.getValue().getList().get(0).getRequestId()).isEqualTo(0); 988 assertThat(argumentCaptor.getValue().getList().get(0).getPropertyId()) 989 .isEqualTo(HVAC_TEMPERATURE_SET); 990 assertThat(argumentCaptor.getValue().getList().get(0).getAreaId()).isEqualTo(0); 991 } 992 993 @Test testGetPropertiesAsyncWithTimeout()994 public void testGetPropertiesAsyncWithTimeout() throws RemoteException { 995 mCarPropertyManager.getPropertiesAsync(List.of(createGetPropertyRequest()), 996 /* timeoutInMs= */ 1000, null, null, mGetPropertyCallback); 997 998 ArgumentCaptor<AsyncPropertyServiceRequestList> argumentCaptor = ArgumentCaptor.forClass( 999 AsyncPropertyServiceRequestList.class); 1000 verify(mICarProperty).getPropertiesAsync(argumentCaptor.capture(), any(), eq(1000L)); 1001 assertThat(argumentCaptor.getValue().getList().get(0).getRequestId()).isEqualTo(0); 1002 assertThat(argumentCaptor.getValue().getList().get(0).getPropertyId()) 1003 .isEqualTo(HVAC_TEMPERATURE_SET); 1004 assertThat(argumentCaptor.getValue().getList().get(0).getAreaId()).isEqualTo(0); 1005 } 1006 1007 @Test testGetPropertiesAsync_illegalArgumentException()1008 public void testGetPropertiesAsync_illegalArgumentException() throws RemoteException { 1009 IllegalArgumentException exception = new IllegalArgumentException(); 1010 doThrow(exception).when(mICarProperty).getPropertiesAsync(any( 1011 AsyncPropertyServiceRequestList.class), 1012 any(IAsyncPropertyResultCallback.class), anyLong()); 1013 1014 assertThrows(IllegalArgumentException.class, 1015 () -> mCarPropertyManager.getPropertiesAsync( 1016 List.of(createGetPropertyRequest()), null, null, mGetPropertyCallback)); 1017 } 1018 1019 @Test testGetPropertiesAsync_SecurityException()1020 public void testGetPropertiesAsync_SecurityException() throws RemoteException { 1021 SecurityException exception = new SecurityException(); 1022 doThrow(exception).when(mICarProperty).getPropertiesAsync(any( 1023 AsyncPropertyServiceRequestList.class), 1024 any(IAsyncPropertyResultCallback.class), anyLong()); 1025 1026 assertThrows(SecurityException.class, 1027 () -> mCarPropertyManager.getPropertiesAsync( 1028 List.of(createGetPropertyRequest()), null, null, mGetPropertyCallback)); 1029 } 1030 1031 @Test tsetGetPropertiesAsync_unsupportedProperty()1032 public void tsetGetPropertiesAsync_unsupportedProperty() throws Exception { 1033 assertThrows(IllegalArgumentException.class, 1034 () -> mCarPropertyManager.getPropertiesAsync( 1035 List.of(mCarPropertyManager.generateGetPropertyRequest(INVALID, 0)), null, 1036 null, mGetPropertyCallback)); 1037 } 1038 1039 @Test testGetPropertiesAsync_remoteException()1040 public void testGetPropertiesAsync_remoteException() throws RemoteException { 1041 RemoteException remoteException = new RemoteException(); 1042 doThrow(remoteException).when(mICarProperty).getPropertiesAsync(any( 1043 AsyncPropertyServiceRequestList.class), 1044 any(IAsyncPropertyResultCallback.class), anyLong()); 1045 1046 mCarPropertyManager.getPropertiesAsync(List.of(createGetPropertyRequest()), null, null, 1047 mGetPropertyCallback); 1048 1049 verify(mCar).handleRemoteExceptionFromCarService(any(RemoteException.class)); 1050 } 1051 1052 @Test testGetPropertiesAsync_clearRequestIdAfterFailed()1053 public void testGetPropertiesAsync_clearRequestIdAfterFailed() throws RemoteException { 1054 CarPropertyManager.GetPropertyRequest getPropertyRequest = createGetPropertyRequest(); 1055 IllegalArgumentException exception = new IllegalArgumentException(); 1056 doThrow(exception).when(mICarProperty).getPropertiesAsync(any( 1057 AsyncPropertyServiceRequestList.class), 1058 any(IAsyncPropertyResultCallback.class), anyLong()); 1059 1060 assertThrows(IllegalArgumentException.class, 1061 () -> mCarPropertyManager.getPropertiesAsync(List.of(getPropertyRequest), null, 1062 null, mGetPropertyCallback)); 1063 1064 clearInvocations(mICarProperty); 1065 doNothing().when(mICarProperty).getPropertiesAsync(any( 1066 AsyncPropertyServiceRequestList.class), 1067 any(IAsyncPropertyResultCallback.class), anyLong()); 1068 ArgumentCaptor<AsyncPropertyServiceRequestList> argumentCaptor = ArgumentCaptor.forClass( 1069 AsyncPropertyServiceRequestList.class); 1070 1071 mCarPropertyManager.getPropertiesAsync(List.of(getPropertyRequest), null, null, 1072 mGetPropertyCallback); 1073 1074 verify(mICarProperty).getPropertiesAsync(argumentCaptor.capture(), any(), anyLong()); 1075 assertThat(argumentCaptor.getValue().getList().get(0).getRequestId()).isEqualTo(0); 1076 assertThat(argumentCaptor.getValue().getList().get(0).getPropertyId()) 1077 .isEqualTo(HVAC_TEMPERATURE_SET); 1078 assertThat(argumentCaptor.getValue().getList().get(0).getAreaId()).isEqualTo(0); 1079 } 1080 1081 @Test 1082 @IgnoreUnderRavenwood(blockedBy = android.os.CancellationSignal.class) testGetPropertiesAsync_cancellationSignalCancelRequests()1083 public void testGetPropertiesAsync_cancellationSignalCancelRequests() throws Exception { 1084 CarPropertyManager.GetPropertyRequest getPropertyRequest = createGetPropertyRequest(); 1085 CancellationSignal cancellationSignal = new CancellationSignal(); 1086 List<IAsyncPropertyResultCallback> callbackWrapper = new ArrayList<>(); 1087 doAnswer((invocation) -> { 1088 Object[] args = invocation.getArguments(); 1089 callbackWrapper.add((IAsyncPropertyResultCallback) args[1]); 1090 return null; 1091 }).when(mICarProperty).getPropertiesAsync(any(), any(), anyLong()); 1092 1093 mCarPropertyManager.getPropertiesAsync(List.of(getPropertyRequest), cancellationSignal, 1094 /* callbackExecutor= */ null, mGetPropertyCallback); 1095 1096 // Cancel the pending request. 1097 cancellationSignal.cancel(); 1098 1099 verify(mICarProperty).cancelRequests(new int[]{0}); 1100 1101 // Call the manager callback after the request is already cancelled. 1102 GetSetValueResult getValueResult = GetSetValueResult.newErrorResult( 1103 0, 1104 new CarPropertyErrorCodes( 1105 CarPropertyManager.STATUS_ERROR_INTERNAL_ERROR, 1106 /* vendorErrorCode= */ 0, 1107 /* systemErrorCode= */ 0)); 1108 assertThat(callbackWrapper.size()).isEqualTo(1); 1109 callbackWrapper.get(0).onGetValueResults( 1110 new GetSetValueResultList(List.of(getValueResult))); 1111 1112 // No client callbacks should be called. 1113 verify(mGetPropertyCallback, never()).onFailure(any()); 1114 verify(mGetPropertyCallback, never()).onSuccess(any()); 1115 } 1116 1117 @Test testOnGetValueResult_onSuccess()1118 public void testOnGetValueResult_onSuccess() throws RemoteException { 1119 doAnswer((invocation) -> { 1120 Object[] args = invocation.getArguments(); 1121 AsyncPropertyServiceRequestList asyncGetPropertyServiceRequestList = 1122 (AsyncPropertyServiceRequestList) args[0]; 1123 List getPropertyServiceList = asyncGetPropertyServiceRequestList.getList(); 1124 AsyncPropertyServiceRequest getPropertyServiceRequest = 1125 (AsyncPropertyServiceRequest) getPropertyServiceList.get(0); 1126 IAsyncPropertyResultCallback getAsyncPropertyResultCallback = 1127 (IAsyncPropertyResultCallback) args[1]; 1128 1129 assertThat(getPropertyServiceRequest.getRequestId()).isEqualTo(0); 1130 assertThat(getPropertyServiceRequest.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1131 1132 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 17.0f); 1133 GetSetValueResult getValueResult = GetSetValueResult.newGetValueResult(0, value); 1134 1135 getAsyncPropertyResultCallback.onGetValueResults( 1136 new GetSetValueResultList(List.of(getValueResult))); 1137 return null; 1138 }).when(mICarProperty).getPropertiesAsync(any(), any(), anyLong()); 1139 1140 mCarPropertyManager.getPropertiesAsync(List.of(createGetPropertyRequest()), null, null, 1141 mGetPropertyCallback); 1142 1143 verify(mGetPropertyCallback, timeout(1000)).onSuccess( 1144 mGetPropertyResultCaptor.capture()); 1145 GetPropertyResult<Float> gotResult = (GetPropertyResult<Float>) 1146 mGetPropertyResultCaptor.getValue(); 1147 assertThat(gotResult.getRequestId()).isEqualTo(0); 1148 assertThat(gotResult.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1149 assertThat(gotResult.getAreaId()).isEqualTo(0); 1150 assertThat(gotResult.getValue()).isEqualTo(17.0f); 1151 } 1152 1153 @Test testOnGetValueResult_onSuccessMultipleRequests()1154 public void testOnGetValueResult_onSuccessMultipleRequests() throws RemoteException { 1155 doAnswer((invocation) -> { 1156 Object[] args = invocation.getArguments(); 1157 AsyncPropertyServiceRequestList getPropertyServiceRequest = 1158 (AsyncPropertyServiceRequestList) args[0]; 1159 List<AsyncPropertyServiceRequest> getPropertyServiceRequests = 1160 getPropertyServiceRequest.getList(); 1161 IAsyncPropertyResultCallback getAsyncPropertyResultCallback = 1162 (IAsyncPropertyResultCallback) args[1]; 1163 1164 assertThat(getPropertyServiceRequests.size()).isEqualTo(2); 1165 assertThat(getPropertyServiceRequests.get(0).getRequestId()).isEqualTo(0); 1166 assertThat(getPropertyServiceRequests.get(0).getPropertyId()).isEqualTo( 1167 HVAC_TEMPERATURE_SET); 1168 assertThat(getPropertyServiceRequests.get(1).getRequestId()).isEqualTo(1); 1169 assertThat(getPropertyServiceRequests.get(1).getPropertyId()).isEqualTo( 1170 HVAC_TEMPERATURE_SET); 1171 1172 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 17.0f); 1173 List<GetSetValueResult> getValueResults = List.of( 1174 GetSetValueResult.newGetValueResult(0, value), 1175 GetSetValueResult.newGetValueResult(1, value)); 1176 1177 getAsyncPropertyResultCallback.onGetValueResults( 1178 new GetSetValueResultList(getValueResults)); 1179 return null; 1180 }).when(mICarProperty).getPropertiesAsync(any(), any(), anyLong()); 1181 1182 List<CarPropertyManager.GetPropertyRequest> getPropertyRequests = new ArrayList<>(); 1183 getPropertyRequests.add(createGetPropertyRequest()); 1184 getPropertyRequests.add(createGetPropertyRequest()); 1185 1186 mCarPropertyManager.getPropertiesAsync(getPropertyRequests, null, null, 1187 mGetPropertyCallback); 1188 1189 verify(mGetPropertyCallback, timeout(1000).times(2)).onSuccess( 1190 mGetPropertyResultCaptor.capture()); 1191 List<GetPropertyResult<?>> gotPropertyResults = mGetPropertyResultCaptor.getAllValues(); 1192 assertThat(gotPropertyResults.get(0).getRequestId()).isEqualTo(0); 1193 assertThat(gotPropertyResults.get(0).getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1194 assertThat(gotPropertyResults.get(0).getAreaId()).isEqualTo(0); 1195 assertThat(gotPropertyResults.get(0).getValue()).isEqualTo(17.0f); 1196 assertThat(gotPropertyResults.get(1).getRequestId()).isEqualTo(1); 1197 assertThat(gotPropertyResults.get(1).getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1198 assertThat(gotPropertyResults.get(1).getAreaId()).isEqualTo(0); 1199 assertThat(gotPropertyResults.get(1).getValue()).isEqualTo(17.0f); 1200 } 1201 1202 @Test testOnGetValueResult_onFailure()1203 public void testOnGetValueResult_onFailure() throws RemoteException { 1204 doAnswer((invocation) -> { 1205 Object[] args = invocation.getArguments(); 1206 AsyncPropertyServiceRequestList asyncPropertyServiceREquestList = 1207 (AsyncPropertyServiceRequestList) args[0]; 1208 List getPropertyServiceList = asyncPropertyServiceREquestList.getList(); 1209 AsyncPropertyServiceRequest getPropertyServiceRequest = 1210 (AsyncPropertyServiceRequest) getPropertyServiceList.get(0); 1211 IAsyncPropertyResultCallback getAsyncPropertyResultCallback = 1212 (IAsyncPropertyResultCallback) args[1]; 1213 1214 assertThat(getPropertyServiceRequest.getRequestId()).isEqualTo(0); 1215 assertThat(getPropertyServiceRequest.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1216 1217 GetSetValueResult getValueResult = GetSetValueResult.newErrorResult( 1218 0, 1219 new CarPropertyErrorCodes( 1220 CarPropertyManager.STATUS_ERROR_INTERNAL_ERROR, VENDOR_ERROR_CODE, 0)); 1221 1222 getAsyncPropertyResultCallback.onGetValueResults( 1223 new GetSetValueResultList(List.of(getValueResult))); 1224 return null; 1225 }).when(mICarProperty).getPropertiesAsync(any(), any(), anyLong()); 1226 1227 1228 mCarPropertyManager.getPropertiesAsync(List.of(createGetPropertyRequest()), null, null, 1229 mGetPropertyCallback); 1230 1231 verify(mGetPropertyCallback, timeout(1000)).onFailure(mPropertyAsyncErrorCaptor.capture()); 1232 PropertyAsyncError error = mPropertyAsyncErrorCaptor.getValue(); 1233 assertThat(error.getRequestId()).isEqualTo(0); 1234 assertThat(error.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1235 assertThat(error.getAreaId()).isEqualTo(0); 1236 assertThat(error.getErrorCode()).isEqualTo( 1237 CarPropertyManager.STATUS_ERROR_INTERNAL_ERROR); 1238 assertThat(error.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 1239 } 1240 1241 @Test testSetProperty_setsValue()1242 public void testSetProperty_setsValue() throws RemoteException { 1243 mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f); 1244 1245 ArgumentCaptor<CarPropertyValue> value = ArgumentCaptor.forClass(CarPropertyValue.class); 1246 1247 verify(mICarProperty).setProperty(value.capture(), any()); 1248 assertThat(value.getValue().getValue()).isEqualTo(17.0f); 1249 } 1250 1251 @Test testSetProperty_syncOpTryAgain()1252 public void testSetProperty_syncOpTryAgain() throws RemoteException { 1253 doThrow(new ServiceSpecificException(SYNC_OP_LIMIT_TRY_AGAIN)).doNothing() 1254 .when(mICarProperty).setProperty(any(), any()); 1255 1256 mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f); 1257 1258 verify(mICarProperty, times(2)).setProperty(any(), any()); 1259 } 1260 1261 @Test testSetProperty_unsupportedProperty()1262 public void testSetProperty_unsupportedProperty() throws RemoteException { 1263 assertThrows(IllegalArgumentException.class, 1264 () -> mCarPropertyManager.setProperty(Float.class, INVALID, 0, 17.0f)); 1265 } 1266 createSetPropertyRequest()1267 private SetPropertyRequest<Float> createSetPropertyRequest() { 1268 return mCarPropertyManager.generateSetPropertyRequest(HVAC_TEMPERATURE_SET, 0, 1269 Float.valueOf(17.0f)); 1270 } 1271 1272 @Test testSetPropertiesAsync()1273 public void testSetPropertiesAsync() throws RemoteException { 1274 SetPropertyRequest<Float> setPropertyRequest = createSetPropertyRequest(); 1275 setPropertyRequest.setUpdateRateHz(10.1f); 1276 setPropertyRequest.setWaitForPropertyUpdate(false); 1277 mCarPropertyManager.setPropertiesAsync(List.of(setPropertyRequest), null, null, 1278 mSetPropertyCallback); 1279 1280 verify(mICarProperty).setPropertiesAsync(mAsyncPropertyServiceRequestCaptor.capture(), 1281 any(), anyLong()); 1282 1283 AsyncPropertyServiceRequest request = mAsyncPropertyServiceRequestCaptor.getValue() 1284 .getList().get(0); 1285 1286 assertThat(request.getRequestId()).isEqualTo(0); 1287 assertThat(request.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1288 assertThat(request.getAreaId()).isEqualTo(0); 1289 assertThat(request.isWaitForPropertyUpdate()).isFalse(); 1290 assertThat(request.getUpdateRateHz()).isEqualTo(10.1f); 1291 CarPropertyValue requestValue = request.getCarPropertyValue(); 1292 assertThat(requestValue).isNotNull(); 1293 assertThat(requestValue.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1294 assertThat(requestValue.getAreaId()).isEqualTo(0); 1295 assertThat(requestValue.getValue()).isEqualTo(17.0f); 1296 } 1297 1298 @Test testSetPropertiesAsync_nullRequests()1299 public void testSetPropertiesAsync_nullRequests() throws RemoteException { 1300 assertThrows(NullPointerException.class, 1301 () -> mCarPropertyManager.setPropertiesAsync( 1302 null, null, null, mSetPropertyCallback)); 1303 } 1304 1305 @Test testSetPropertiesAsync_nullCallback()1306 public void testSetPropertiesAsync_nullCallback() throws RemoteException { 1307 assertThrows(NullPointerException.class, 1308 () -> mCarPropertyManager.setPropertiesAsync( 1309 List.of(createSetPropertyRequest()), null, null, null)); 1310 } 1311 1312 @Test testSetPropertiesAsyncWithTimeout()1313 public void testSetPropertiesAsyncWithTimeout() throws RemoteException { 1314 mCarPropertyManager.setPropertiesAsync(List.of(createSetPropertyRequest()), 1315 /* timeoutInMs= */ 1000, /* cancellationSignal= */ null, 1316 /* callbackExecutor= */ null, mSetPropertyCallback); 1317 1318 verify(mICarProperty).setPropertiesAsync(mAsyncPropertyServiceRequestCaptor.capture(), 1319 any(), eq(1000L)); 1320 AsyncPropertyServiceRequest request = mAsyncPropertyServiceRequestCaptor.getValue() 1321 .getList().get(0); 1322 assertThat(request.getRequestId()).isEqualTo(0); 1323 assertThat(request.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1324 assertThat(request.getAreaId()).isEqualTo(0); 1325 CarPropertyValue requestValue = request.getCarPropertyValue(); 1326 assertThat(requestValue).isNotNull(); 1327 assertThat(requestValue.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1328 assertThat(requestValue.getAreaId()).isEqualTo(0); 1329 assertThat(requestValue.getValue()).isEqualTo(17.0f); 1330 } 1331 1332 @Test testSetPropertiesAsync_illegalArgumentException()1333 public void testSetPropertiesAsync_illegalArgumentException() throws RemoteException { 1334 doThrow(new IllegalArgumentException()).when(mICarProperty).setPropertiesAsync( 1335 any(AsyncPropertyServiceRequestList.class), any(IAsyncPropertyResultCallback.class), 1336 anyLong()); 1337 1338 assertThrows(IllegalArgumentException.class, 1339 () -> mCarPropertyManager.setPropertiesAsync( 1340 List.of(createSetPropertyRequest()), null, null, mSetPropertyCallback)); 1341 } 1342 1343 @Test testSetPropertiesAsync_SecurityException()1344 public void testSetPropertiesAsync_SecurityException() throws RemoteException { 1345 doThrow(new SecurityException()).when(mICarProperty).setPropertiesAsync( 1346 any(AsyncPropertyServiceRequestList.class), 1347 any(IAsyncPropertyResultCallback.class), anyLong()); 1348 1349 assertThrows(SecurityException.class, 1350 () -> mCarPropertyManager.setPropertiesAsync( 1351 List.of(createSetPropertyRequest()), null, null, mSetPropertyCallback)); 1352 } 1353 1354 @Test testSetPropertiesAsync_unsupportedProperty()1355 public void testSetPropertiesAsync_unsupportedProperty() throws Exception { 1356 assertThrows(IllegalArgumentException.class, 1357 () -> mCarPropertyManager.setPropertiesAsync( 1358 List.of(mCarPropertyManager.generateSetPropertyRequest( 1359 INVALID, 0, Integer.valueOf(0))), 1360 null, null, mSetPropertyCallback)); 1361 } 1362 1363 @Test testSetPropertiesAsync_remoteException()1364 public void testSetPropertiesAsync_remoteException() throws RemoteException { 1365 doThrow(new RemoteException()).when(mICarProperty).setPropertiesAsync( 1366 any(AsyncPropertyServiceRequestList.class), 1367 any(IAsyncPropertyResultCallback.class), anyLong()); 1368 1369 mCarPropertyManager.setPropertiesAsync(List.of(createSetPropertyRequest()), null, null, 1370 mSetPropertyCallback); 1371 1372 verify(mCar).handleRemoteExceptionFromCarService(any(RemoteException.class)); 1373 } 1374 1375 @Test testSetPropertiesAsync_duplicateRequestId()1376 public void testSetPropertiesAsync_duplicateRequestId() throws RemoteException { 1377 SetPropertyRequest request = createSetPropertyRequest(); 1378 1379 mCarPropertyManager.setPropertiesAsync(List.of(request), null, null, 1380 mSetPropertyCallback); 1381 1382 // Send the same request again with the same request ID is not allowed. 1383 assertThrows(IllegalArgumentException.class, 1384 () -> mCarPropertyManager.setPropertiesAsync(List.of(request), null, null, 1385 mSetPropertyCallback)); 1386 } 1387 1388 @Test testSetPropertiesAsync_clearRequestIdAfterFailed()1389 public void testSetPropertiesAsync_clearRequestIdAfterFailed() throws RemoteException { 1390 SetPropertyRequest setPropertyRequest = createSetPropertyRequest(); 1391 IllegalArgumentException exception = new IllegalArgumentException(); 1392 doThrow(exception).when(mICarProperty).setPropertiesAsync( 1393 any(AsyncPropertyServiceRequestList.class), any(IAsyncPropertyResultCallback.class), 1394 anyLong()); 1395 1396 assertThrows(IllegalArgumentException.class, 1397 () -> mCarPropertyManager.setPropertiesAsync(List.of(setPropertyRequest), null, 1398 null, mSetPropertyCallback)); 1399 1400 clearInvocations(mICarProperty); 1401 doNothing().when(mICarProperty).setPropertiesAsync( 1402 any(AsyncPropertyServiceRequestList.class), 1403 any(IAsyncPropertyResultCallback.class), anyLong()); 1404 1405 // After the first request failed, the request ID map should be cleared so we can use the 1406 // same request ID again. 1407 mCarPropertyManager.setPropertiesAsync(List.of(setPropertyRequest), null, null, 1408 mSetPropertyCallback); 1409 1410 verify(mICarProperty).setPropertiesAsync(any(), any(), anyLong()); 1411 } 1412 1413 @Test testSetProperty_notAvailableAfterU_withVendorErrorCode()1414 public void testSetProperty_notAvailableAfterU_withVendorErrorCode() throws Exception { 1415 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1416 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1417 HVAC_TEMPERATURE_SET, 0, 17.0f); 1418 doThrow(new ServiceSpecificException(combineErrors( 1419 VehicleHalStatusCode.STATUS_NOT_AVAILABLE, VENDOR_ERROR_CODE))).when(mICarProperty) 1420 .setProperty(eq(carPropertyValue), any()); 1421 1422 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1423 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1424 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 1425 } 1426 1427 @Test testSetProperty_internalErrorAfterU_withVendorErrorCode()1428 public void testSetProperty_internalErrorAfterU_withVendorErrorCode() throws Exception { 1429 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1430 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1431 HVAC_TEMPERATURE_SET, 0, 17.0f); 1432 doThrow(new ServiceSpecificException(combineErrors( 1433 VehicleHalStatusCode.STATUS_INTERNAL_ERROR, VENDOR_ERROR_CODE))).when(mICarProperty) 1434 .setProperty(eq(carPropertyValue), any()); 1435 1436 CarInternalErrorException exception = assertThrows(CarInternalErrorException.class, 1437 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1438 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 1439 } 1440 1441 @Test testSetProperty_notAvailableDisabledBeforeU()1442 public void testSetProperty_notAvailableDisabledBeforeU() throws Exception { 1443 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 1444 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1445 HVAC_TEMPERATURE_SET, 0, 17.0f); 1446 doThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_DISABLED)) 1447 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1448 1449 assertThrows(PropertyNotAvailableException.class, 1450 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1451 } 1452 1453 @Test testSetProperty_notAvailableDisabledAfterU()1454 public void testSetProperty_notAvailableDisabledAfterU() throws Exception { 1455 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1456 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1457 HVAC_TEMPERATURE_SET, 0, 17.0f); 1458 doThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_DISABLED)) 1459 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1460 1461 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1462 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1463 assertThat(exception.getDetailedErrorCode()) 1464 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_DISABLED); 1465 } 1466 1467 @Test testSetProperty_notAvailableDisabledAfterU_withVendorErrorCode()1468 public void testSetProperty_notAvailableDisabledAfterU_withVendorErrorCode() throws Exception { 1469 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1470 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1471 HVAC_TEMPERATURE_SET, 0, 17.0f); 1472 doThrow(new ServiceSpecificException(combineErrors( 1473 VehicleHalStatusCode.STATUS_NOT_AVAILABLE_DISABLED, VENDOR_ERROR_CODE))) 1474 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1475 1476 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1477 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1478 assertThat(exception.getDetailedErrorCode()) 1479 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_DISABLED); 1480 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 1481 } 1482 1483 @Test testSetProperty_notAvailableSafetyBeforeU()1484 public void testSetProperty_notAvailableSafetyBeforeU() throws Exception { 1485 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 1486 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1487 HVAC_TEMPERATURE_SET, 0, 17.0f); 1488 doThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SAFETY)) 1489 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1490 1491 assertThrows(PropertyNotAvailableException.class, 1492 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1493 } 1494 1495 @Test testSetProperty_notAvailableSafetyAfterU()1496 public void testSetProperty_notAvailableSafetyAfterU() throws Exception { 1497 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1498 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1499 HVAC_TEMPERATURE_SET, 0, 17.0f); 1500 doThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SAFETY)) 1501 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1502 1503 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1504 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1505 assertThat(exception.getDetailedErrorCode()) 1506 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SAFETY); 1507 } 1508 1509 @Test testSetProperty_notAvailableSafetyAfterU_withVendorErrorCode()1510 public void testSetProperty_notAvailableSafetyAfterU_withVendorErrorCode() throws Exception { 1511 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1512 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1513 HVAC_TEMPERATURE_SET, 0, 17.0f); 1514 doThrow(new ServiceSpecificException(combineErrors( 1515 VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SAFETY, VENDOR_ERROR_CODE))) 1516 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1517 1518 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1519 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1520 assertThat(exception.getDetailedErrorCode()) 1521 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SAFETY); 1522 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 1523 } 1524 1525 @Test testSetProperty_notAvailableSpeedHighBeforeU()1526 public void testSetProperty_notAvailableSpeedHighBeforeU() throws Exception { 1527 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 1528 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1529 HVAC_TEMPERATURE_SET, 0, 17.0f); 1530 doThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_HIGH)) 1531 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1532 1533 assertThrows(PropertyNotAvailableException.class, 1534 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1535 } 1536 1537 @Test testSetProperty_notAvailableSpeedHighAfterU()1538 public void testSetProperty_notAvailableSpeedHighAfterU() throws Exception { 1539 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1540 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1541 HVAC_TEMPERATURE_SET, 0, 17.0f); 1542 doThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_HIGH)) 1543 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1544 1545 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1546 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1547 assertThat(exception.getDetailedErrorCode()) 1548 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SPEED_HIGH); 1549 } 1550 1551 @Test testSetProperty_notAvailableSpeedHighAfterU_withVendorErrorCode()1552 public void testSetProperty_notAvailableSpeedHighAfterU_withVendorErrorCode() throws Exception { 1553 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1554 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1555 HVAC_TEMPERATURE_SET, 0, 17.0f); 1556 doThrow(new ServiceSpecificException(combineErrors( 1557 VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_HIGH, VENDOR_ERROR_CODE))) 1558 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1559 1560 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1561 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1562 assertThat(exception.getDetailedErrorCode()) 1563 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SPEED_HIGH); 1564 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 1565 } 1566 1567 @Test testSetProperty_notAvailableSpeedLowBeforeU()1568 public void testSetProperty_notAvailableSpeedLowBeforeU() throws Exception { 1569 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 1570 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1571 HVAC_TEMPERATURE_SET, 0, 17.0f); 1572 doThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_LOW)) 1573 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1574 1575 assertThrows(PropertyNotAvailableException.class, 1576 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1577 } 1578 1579 @Test testSetProperty_notAvailableSpeedLowAfterU()1580 public void testSetProperty_notAvailableSpeedLowAfterU() throws Exception { 1581 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1582 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1583 HVAC_TEMPERATURE_SET, 0, 17.0f); 1584 doThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_LOW)) 1585 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1586 1587 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1588 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1589 assertThat(exception.getDetailedErrorCode()) 1590 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SPEED_LOW); 1591 } 1592 1593 @Test testSetProperty_notAvailableSpeedLowAfterU_withVendorErrorCode()1594 public void testSetProperty_notAvailableSpeedLowAfterU_withVendorErrorCode() throws Exception { 1595 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 1596 CarPropertyValue<Float> carPropertyValue = new CarPropertyValue<>( 1597 HVAC_TEMPERATURE_SET, 0, 17.0f); 1598 doThrow(new ServiceSpecificException(combineErrors( 1599 VehicleHalStatusCode.STATUS_NOT_AVAILABLE_SPEED_LOW, VENDOR_ERROR_CODE))) 1600 .when(mICarProperty).setProperty(eq(carPropertyValue), any()); 1601 1602 PropertyNotAvailableException exception = assertThrows(PropertyNotAvailableException.class, 1603 () -> mCarPropertyManager.setProperty(Float.class, HVAC_TEMPERATURE_SET, 0, 17.0f)); 1604 assertThat(exception.getDetailedErrorCode()) 1605 .isEqualTo(PropertyNotAvailableErrorCode.NOT_AVAILABLE_SPEED_LOW); 1606 assertThat(exception.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 1607 } 1608 1609 @Test testOnSetValueResult_onSuccess()1610 public void testOnSetValueResult_onSuccess() throws RemoteException { 1611 doAnswer((invocation) -> { 1612 Object[] args = invocation.getArguments(); 1613 AsyncPropertyServiceRequestList setPropertyRequest = 1614 (AsyncPropertyServiceRequestList) args[0]; 1615 List setPropertyServiceList = setPropertyRequest.getList(); 1616 AsyncPropertyServiceRequest setPropertyServiceRequest = 1617 (AsyncPropertyServiceRequest) setPropertyServiceList.get(0); 1618 IAsyncPropertyResultCallback setAsyncPropertyResultCallback = 1619 (IAsyncPropertyResultCallback) args[1]; 1620 1621 assertThat(setPropertyServiceRequest.getRequestId()).isEqualTo(0); 1622 assertThat(setPropertyServiceRequest.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1623 assertThat(setPropertyServiceRequest.getCarPropertyValue().getValue()).isEqualTo( 1624 17.0f); 1625 1626 GetSetValueResult setValueResult = GetSetValueResult.newSetValueResult(0, 1627 /* updateTimestampNanos= */ TEST_TIMESTAMP); 1628 1629 setAsyncPropertyResultCallback.onSetValueResults( 1630 new GetSetValueResultList(List.of(setValueResult))); 1631 return null; 1632 }).when(mICarProperty).setPropertiesAsync(any(), any(), anyLong()); 1633 1634 1635 mCarPropertyManager.setPropertiesAsync(List.of(createSetPropertyRequest()), null, null, 1636 mSetPropertyCallback); 1637 1638 verify(mSetPropertyCallback, timeout(1000)).onSuccess(mSetPropertyResultCaptor.capture()); 1639 SetPropertyResult gotResult = mSetPropertyResultCaptor.getValue(); 1640 assertThat(gotResult.getRequestId()).isEqualTo(0); 1641 assertThat(gotResult.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1642 assertThat(gotResult.getAreaId()).isEqualTo(0); 1643 assertThat(gotResult.getUpdateTimestampNanos()).isEqualTo(TEST_TIMESTAMP); 1644 } 1645 1646 @Test testOnSetValueResult_onSuccessMultipleRequests()1647 public void testOnSetValueResult_onSuccessMultipleRequests() throws RemoteException { 1648 doAnswer((invocation) -> { 1649 Object[] args = invocation.getArguments(); 1650 AsyncPropertyServiceRequestList setPropertyServiceRequest = 1651 (AsyncPropertyServiceRequestList) args[0]; 1652 List<AsyncPropertyServiceRequest> setPropertyServiceRequests = 1653 setPropertyServiceRequest.getList(); 1654 IAsyncPropertyResultCallback setAsyncPropertyResultCallback = 1655 (IAsyncPropertyResultCallback) args[1]; 1656 1657 assertThat(setPropertyServiceRequests.size()).isEqualTo(2); 1658 assertThat(setPropertyServiceRequests.get(0).getRequestId()).isEqualTo(0); 1659 assertThat(setPropertyServiceRequests.get(0).getPropertyId()).isEqualTo( 1660 HVAC_TEMPERATURE_SET); 1661 assertThat(setPropertyServiceRequests.get(1).getRequestId()).isEqualTo(1); 1662 assertThat(setPropertyServiceRequests.get(1).getPropertyId()).isEqualTo( 1663 HVAC_TEMPERATURE_SET); 1664 1665 List<GetSetValueResult> setValueResults = List.of( 1666 GetSetValueResult.newSetValueResult(0, 1667 /* updateTimestampNanos= */ TEST_TIMESTAMP), 1668 GetSetValueResult.newSetValueResult(1, 1669 /* updateTimestampNanos= */ TEST_TIMESTAMP)); 1670 1671 setAsyncPropertyResultCallback.onSetValueResults( 1672 new GetSetValueResultList(setValueResults)); 1673 return null; 1674 }).when(mICarProperty).setPropertiesAsync(any(), any(), anyLong()); 1675 1676 List<SetPropertyRequest<?>> setPropertyRequests = new ArrayList<>(); 1677 setPropertyRequests.add(createSetPropertyRequest()); 1678 setPropertyRequests.add(createSetPropertyRequest()); 1679 1680 mCarPropertyManager.setPropertiesAsync(setPropertyRequests, null, null, 1681 mSetPropertyCallback); 1682 1683 verify(mSetPropertyCallback, timeout(1000).times(2)).onSuccess( 1684 mSetPropertyResultCaptor.capture()); 1685 List<SetPropertyResult> gotPropertyResults = mSetPropertyResultCaptor.getAllValues(); 1686 assertThat(gotPropertyResults.get(0).getRequestId()).isEqualTo(0); 1687 assertThat(gotPropertyResults.get(0).getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1688 assertThat(gotPropertyResults.get(0).getAreaId()).isEqualTo(0); 1689 assertThat(gotPropertyResults.get(0).getUpdateTimestampNanos()).isEqualTo(TEST_TIMESTAMP); 1690 assertThat(gotPropertyResults.get(1).getRequestId()).isEqualTo(1); 1691 assertThat(gotPropertyResults.get(1).getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1692 assertThat(gotPropertyResults.get(1).getAreaId()).isEqualTo(0); 1693 assertThat(gotPropertyResults.get(1).getUpdateTimestampNanos()).isEqualTo(TEST_TIMESTAMP); 1694 } 1695 1696 @Test testOnSetValueResult_onFailure()1697 public void testOnSetValueResult_onFailure() throws RemoteException { 1698 doAnswer((invocation) -> { 1699 Object[] args = invocation.getArguments(); 1700 AsyncPropertyServiceRequestList setPropertyService = 1701 (AsyncPropertyServiceRequestList) args[0]; 1702 List setPropertyServiceList = setPropertyService.getList(); 1703 AsyncPropertyServiceRequest setPropertyServiceRequest = 1704 (AsyncPropertyServiceRequest) setPropertyServiceList.get(0); 1705 IAsyncPropertyResultCallback setAsyncPropertyResultCallback = 1706 (IAsyncPropertyResultCallback) args[1]; 1707 1708 assertThat(setPropertyServiceRequest.getRequestId()).isEqualTo(0); 1709 assertThat(setPropertyServiceRequest.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1710 1711 GetSetValueResult setValueResult = GetSetValueResult.newErrorSetValueResult( 1712 0, 1713 new CarPropertyErrorCodes( 1714 CarPropertyManager.STATUS_ERROR_INTERNAL_ERROR, VENDOR_ERROR_CODE, 0)); 1715 1716 setAsyncPropertyResultCallback.onSetValueResults( 1717 new GetSetValueResultList(List.of(setValueResult))); 1718 return null; 1719 }).when(mICarProperty).setPropertiesAsync(any(), any(), anyLong()); 1720 1721 mCarPropertyManager.setPropertiesAsync(List.of(createSetPropertyRequest()), null, null, 1722 mSetPropertyCallback); 1723 1724 verify(mSetPropertyCallback, timeout(1000)).onFailure(mPropertyAsyncErrorCaptor.capture()); 1725 PropertyAsyncError error = mPropertyAsyncErrorCaptor.getValue(); 1726 assertThat(error.getRequestId()).isEqualTo(0); 1727 assertThat(error.getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 1728 assertThat(error.getAreaId()).isEqualTo(0); 1729 assertThat(error.getErrorCode()).isEqualTo( 1730 CarPropertyManager.STATUS_ERROR_INTERNAL_ERROR); 1731 assertThat(error.getVendorErrorCode()).isEqualTo(VENDOR_ERROR_CODE); 1732 } 1733 1734 @Test testRegisterCallback_returnsFalseIfPropertyIdNotSupportedInVehicle()1735 public void testRegisterCallback_returnsFalseIfPropertyIdNotSupportedInVehicle() 1736 throws RemoteException { 1737 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1738 VehiclePropertyIds.INVALID, FIRST_UPDATE_RATE_HZ)).isFalse(); 1739 verify(mICarProperty, never()).registerListener(any(), 1740 any(ICarPropertyEventListener.class)); 1741 } 1742 1743 @Test testRegisterCallback_registersWithServiceOnFirstCallback()1744 public void testRegisterCallback_registersWithServiceOnFirstCallback() throws RemoteException { 1745 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1746 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 1747 verify(mICarProperty).registerListener(eq(List.of( 1748 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 1749 FIRST_UPDATE_RATE_HZ))), any(ICarPropertyEventListener.class)); 1750 } 1751 1752 @Test testRegisterCallback_registersWithMaxUpdateRateOnFirstCallback()1753 public void testRegisterCallback_registersWithMaxUpdateRateOnFirstCallback() 1754 throws RemoteException { 1755 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1756 VENDOR_CONTINUOUS_PROPERTY, MAX_UPDATE_RATE_HZ + 1)).isTrue(); 1757 verify(mICarProperty).registerListener(eq(List.of( 1758 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 1759 MAX_UPDATE_RATE_HZ))), any(ICarPropertyEventListener.class)); 1760 } 1761 1762 @Test testRegisterCallback_registersWithMinUpdateRateOnFirstCallback()1763 public void testRegisterCallback_registersWithMinUpdateRateOnFirstCallback() 1764 throws RemoteException { 1765 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1766 VENDOR_CONTINUOUS_PROPERTY, MIN_UPDATE_RATE_HZ - 1)).isTrue(); 1767 verify(mICarProperty).registerListener(eq(List.of( 1768 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 1769 MIN_UPDATE_RATE_HZ))), any(ICarPropertyEventListener.class)); 1770 } 1771 1772 @Test testRegisterCallback_registersWithOnChangeRateForOnChangeProperty()1773 public void testRegisterCallback_registersWithOnChangeRateForOnChangeProperty() 1774 throws RemoteException { 1775 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1776 VENDOR_ON_CHANGE_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 1777 verify(mICarProperty).registerListener(eq(List.of( 1778 createCarSubscriptionOption(VENDOR_ON_CHANGE_PROPERTY, new int[]{0}, 1779 CarPropertyManager.SENSOR_RATE_ONCHANGE))), 1780 any(ICarPropertyEventListener.class)); 1781 } 1782 1783 @Test testRegisterCallback_registersWithOnChangeRateForStaticProperty()1784 public void testRegisterCallback_registersWithOnChangeRateForStaticProperty() 1785 throws RemoteException { 1786 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1787 VENDOR_STATIC_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 1788 verify(mICarProperty).registerListener(eq(List.of( 1789 createCarSubscriptionOption(VENDOR_STATIC_PROPERTY, new int[]{0}, 1790 CarPropertyManager.SENSOR_RATE_ONCHANGE))), 1791 any(ICarPropertyEventListener.class)); 1792 } 1793 1794 @Test testRegisterCallback_returnsFalseForRemoteException()1795 public void testRegisterCallback_returnsFalseForRemoteException() throws RemoteException { 1796 RemoteException remoteException = new RemoteException(); 1797 doThrow(remoteException).when(mICarProperty).registerListener( 1798 eq(List.of(createCarSubscriptionOption(VENDOR_ON_CHANGE_PROPERTY, new int[] {0}, 1799 CarPropertyManager.SENSOR_RATE_ONCHANGE))), 1800 any(ICarPropertyEventListener.class)); 1801 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1802 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isFalse(); 1803 } 1804 1805 @Test testRegisterCallback_recoversAfterFirstRemoteException()1806 public void testRegisterCallback_recoversAfterFirstRemoteException() throws RemoteException { 1807 RemoteException remoteException = new RemoteException(); 1808 doThrow(remoteException).doNothing().when(mICarProperty) 1809 .registerListener(eq(List.of( 1810 createCarSubscriptionOption(VENDOR_ON_CHANGE_PROPERTY, new int[] {0}, 1811 SENSOR_RATE_ONCHANGE))), 1812 any(ICarPropertyEventListener.class)); 1813 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1814 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isFalse(); 1815 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1816 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isTrue(); 1817 verify(mICarProperty, times(2)).registerListener( 1818 eq(List.of(createCarSubscriptionOption(VENDOR_ON_CHANGE_PROPERTY, new int[] {0}, 1819 CarPropertyManager.SENSOR_RATE_ONCHANGE))), 1820 any(ICarPropertyEventListener.class)); 1821 } 1822 1823 @Test testRegisterCallback_returnsFalseForIllegalArgumentException()1824 public void testRegisterCallback_returnsFalseForIllegalArgumentException() 1825 throws RemoteException { 1826 doThrow(IllegalArgumentException.class).when(mICarProperty) 1827 .registerListener(eq(List.of(createCarSubscriptionOption( 1828 VENDOR_ON_CHANGE_PROPERTY, new int[] {0}, SENSOR_RATE_ONCHANGE))), 1829 any(ICarPropertyEventListener.class)); 1830 1831 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1832 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isFalse(); 1833 } 1834 1835 @Test testRegisterCallback_registersTwiceWithHigherRateCallback()1836 public void testRegisterCallback_registersTwiceWithHigherRateCallback() throws RemoteException { 1837 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1838 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 1839 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback2, 1840 VENDOR_CONTINUOUS_PROPERTY, LARGER_UPDATE_RATE_HZ)).isTrue(); 1841 verify(mICarProperty, times(2)).registerListener( 1842 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 1843 assertThat(mCarSubscriptionCaptor.getAllValues()).containsExactly( 1844 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1845 LARGER_UPDATE_RATE_HZ)), 1846 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1847 FIRST_UPDATE_RATE_HZ))); 1848 } 1849 1850 @Test testRegisterCallback_registersOnSecondHigherRateWithSameCallback()1851 public void testRegisterCallback_registersOnSecondHigherRateWithSameCallback() 1852 throws RemoteException { 1853 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1854 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 1855 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback2, 1856 VENDOR_CONTINUOUS_PROPERTY, LARGER_UPDATE_RATE_HZ)).isTrue(); 1857 verify(mICarProperty, times(2)).registerListener( 1858 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 1859 assertThat(mCarSubscriptionCaptor.getAllValues()).containsExactly( 1860 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1861 LARGER_UPDATE_RATE_HZ)), 1862 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1863 FIRST_UPDATE_RATE_HZ))); 1864 } 1865 1866 @Test testRegisterCallback_registersOnSecondLowerRateWithSameCallback()1867 public void testRegisterCallback_registersOnSecondLowerRateWithSameCallback() 1868 throws RemoteException { 1869 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1870 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 1871 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1872 VENDOR_CONTINUOUS_PROPERTY, SMALLER_UPDATE_RATE_HZ)).isTrue(); 1873 verify(mICarProperty, times(2)).registerListener( 1874 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 1875 assertThat(mCarSubscriptionCaptor.getAllValues()).containsExactly( 1876 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1877 FIRST_UPDATE_RATE_HZ)), 1878 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1879 SMALLER_UPDATE_RATE_HZ))); 1880 } 1881 1882 @Test testRegisterCallback_doesNotRegistersOnSecondLowerRateCallback()1883 public void testRegisterCallback_doesNotRegistersOnSecondLowerRateCallback() 1884 throws RemoteException { 1885 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1886 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 1887 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback2, 1888 VENDOR_CONTINUOUS_PROPERTY, SMALLER_UPDATE_RATE_HZ)).isTrue(); 1889 verify(mICarProperty).registerListener(eq(List.of( 1890 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 1891 FIRST_UPDATE_RATE_HZ))), 1892 any(ICarPropertyEventListener.class)); 1893 } 1894 1895 @Test testRegisterCallback_registersTwiceForDifferentProperties()1896 public void testRegisterCallback_registersTwiceForDifferentProperties() throws RemoteException { 1897 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1898 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 1899 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 1900 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isTrue(); 1901 verify(mICarProperty, times(2)).registerListener( 1902 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 1903 assertThat(mCarSubscriptionCaptor.getAllValues()).containsExactly( 1904 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1905 FIRST_UPDATE_RATE_HZ)), 1906 List.of(createCarSubscriptionOption(VENDOR_ON_CHANGE_PROPERTY, new int[] {0}, 1907 CarPropertyManager.SENSOR_RATE_ONCHANGE))); 1908 } 1909 1910 @Test testRegisterCallback_registerInvalidProp()1911 public void testRegisterCallback_registerInvalidProp() throws Exception { 1912 assertThat(mCarPropertyManager.registerCallback( 1913 mCarPropertyEventCallback, /* propertyId= */ -1, FIRST_UPDATE_RATE_HZ)).isFalse(); 1914 } 1915 1916 // We annotate the update rate to be within 0 and 100, however, in the actual implementation, 1917 // we will fit update rate outside this range to the min and max update rate. 1918 @Test testRegisterCallback_updateRateOutsideFloatRangeMustNotThrow_tooLarge()1919 public void testRegisterCallback_updateRateOutsideFloatRangeMustNotThrow_tooLarge() 1920 throws Exception { 1921 assertThat(mCarPropertyManager.registerCallback( 1922 mCarPropertyEventCallback, VENDOR_CONTINUOUS_PROPERTY, /* updateRateHz= */ 101.f)) 1923 .isTrue(); 1924 1925 verify(mICarProperty).registerListener( 1926 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 1927 assertThat(mCarSubscriptionCaptor.getValue()).isEqualTo( 1928 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1929 MAX_UPDATE_RATE_HZ))); 1930 } 1931 1932 @Test testRegisterCallback_updateRateOutsideFloatRangeMustNotThrow_tooSmall()1933 public void testRegisterCallback_updateRateOutsideFloatRangeMustNotThrow_tooSmall() 1934 throws Exception { 1935 assertThat(mCarPropertyManager.registerCallback( 1936 mCarPropertyEventCallback, VENDOR_CONTINUOUS_PROPERTY, /* updateRateHz= */ -1.f)) 1937 .isTrue(); 1938 1939 verify(mICarProperty).registerListener( 1940 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 1941 assertThat(mCarSubscriptionCaptor.getValue()).isEqualTo( 1942 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1943 MIN_UPDATE_RATE_HZ))); 1944 } 1945 1946 @Test testRegisterCallback_isSupportedAndHasWritePermissionOnly()1947 public void testRegisterCallback_isSupportedAndHasWritePermissionOnly() throws Exception { 1948 int propId = VENDOR_CONTINUOUS_PROPERTY; 1949 when(mICarProperty.isSupportedAndHasWritePermissionOnly(propId)).thenReturn(true); 1950 1951 assertThrows(SecurityException.class, () -> mCarPropertyManager.registerCallback( 1952 mCarPropertyEventCallback, VENDOR_CONTINUOUS_PROPERTY, 0)); 1953 } 1954 1955 @Test testRegisterCallback_isSupportedAndHasWritePermissionOnly_remoteException()1956 public void testRegisterCallback_isSupportedAndHasWritePermissionOnly_remoteException() 1957 throws Exception { 1958 int propId = VENDOR_CONTINUOUS_PROPERTY; 1959 when(mICarProperty.isSupportedAndHasWritePermissionOnly(propId)).thenThrow( 1960 new RemoteException()); 1961 1962 assertThat(mCarPropertyManager.registerCallback( 1963 mCarPropertyEventCallback, VENDOR_CONTINUOUS_PROPERTY, 0)).isFalse(); 1964 } 1965 1966 @Test testSubscribePropertyEvents_registerMultipleEvents()1967 public void testSubscribePropertyEvents_registerMultipleEvents() throws Exception { 1968 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 1969 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 1970 .setUpdateRateFast().build(), 1971 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).addAreaId(0).build()), 1972 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 1973 1974 verify(mICarProperty).registerListener( 1975 eq(List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 1976 CarPropertyManager.SENSOR_RATE_FAST, /* enableVur= */ true), 1977 createCarSubscriptionOption(VENDOR_ON_CHANGE_PROPERTY, new int[]{0}, 1978 CarPropertyManager.SENSOR_RATE_ONCHANGE))), 1979 any(ICarPropertyEventListener.class)); 1980 } 1981 1982 @Test testSubscribePropertyEvents_sanitizeSampleRate()1983 public void testSubscribePropertyEvents_sanitizeSampleRate() throws Exception { 1984 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 1985 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 1986 .setUpdateRateHz(0.f).build()), 1987 /* callbackExecutor= */ null, mCarPropertyEventCallback)) 1988 .isTrue(); 1989 1990 verify(mICarProperty).registerListener( 1991 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 1992 assertThat(mCarSubscriptionCaptor.getValue()).isEqualTo( 1993 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[] {0}, 1994 MIN_UPDATE_RATE_HZ, /* enableVur= */ true))); 1995 } 1996 1997 @Test testSubscribePropertyEvents_registerMultipleEventsSameProperty_throws()1998 public void testSubscribePropertyEvents_registerMultipleEventsSameProperty_throws() 1999 throws Exception { 2000 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, 2001 () -> mCarPropertyManager.subscribePropertyEvents(List.of( 2002 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2003 .addAreaId(0).setUpdateRateFast().build(), 2004 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2005 .addAreaId(0).build()), 2006 /* callbackExecutor= */ null, mCarPropertyEventCallback)); 2007 2008 assertWithMessage("Overlapping areaIds").that(thrown).hasMessageThat() 2009 .contains("Subscribe options contain overlapping propertyId"); 2010 } 2011 2012 @Test testSubscribePropertyEvents_registerMultipleEvents_unsubscribe()2013 public void testSubscribePropertyEvents_registerMultipleEvents_unsubscribe() throws Exception { 2014 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2015 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 2016 .setUpdateRateFast().build(), 2017 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).addAreaId(0) 2018 .build()), 2019 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2020 2021 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback); 2022 verify(mICarProperty).unregisterListener(eq(VENDOR_CONTINUOUS_PROPERTY), 2023 any(ICarPropertyEventListener.class)); 2024 verify(mICarProperty).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2025 any(ICarPropertyEventListener.class)); 2026 } 2027 2028 @Test testSubscribePropertyEvents_registerMultipleEventsWithSameProperty_unsubscribe()2029 public void testSubscribePropertyEvents_registerMultipleEventsWithSameProperty_unsubscribe() 2030 throws Exception { 2031 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2032 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 2033 .setUpdateRateFastest().build(), 2034 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).addAreaId(0) 2035 .build()), 2036 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2037 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2038 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 2039 .setUpdateRateFast().build()), 2040 /* callbackExecutor= */ null, mCarPropertyEventCallback2)).isTrue(); 2041 clearInvocations(mICarProperty); 2042 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback); 2043 2044 verify(mICarProperty).registerListener(eq(List.of( 2045 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2046 CarPropertyManager.SENSOR_RATE_FAST, /* enableVur= */ true))), 2047 any(ICarPropertyEventListener.class)); 2048 verify(mICarProperty).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2049 any(ICarPropertyEventListener.class)); 2050 } 2051 2052 @Test testSubscribePropertyEvents_withPropertyIdCallback()2053 public void testSubscribePropertyEvents_withPropertyIdCallback() throws Exception { 2054 assertThat(mCarPropertyManager.subscribePropertyEvents( 2055 VENDOR_CONTINUOUS_PROPERTY, mCarPropertyEventCallback)).isTrue(); 2056 2057 verify(mICarProperty).registerListener(eq(List.of( 2058 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2059 MIN_UPDATE_RATE_HZ, /* enableVur= */ true))), 2060 any(ICarPropertyEventListener.class)); 2061 } 2062 2063 @Test testSubscribePropertyEvents_withPropertyIdUpdateRateCallback()2064 public void testSubscribePropertyEvents_withPropertyIdUpdateRateCallback() throws Exception { 2065 assertThat(mCarPropertyManager.subscribePropertyEvents( 2066 VENDOR_CONTINUOUS_PROPERTY, CarPropertyManager.SENSOR_RATE_FAST, 2067 mCarPropertyEventCallback)).isTrue(); 2068 2069 verify(mICarProperty).registerListener(eq(List.of( 2070 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2071 CarPropertyManager.SENSOR_RATE_FAST, /* enableVur= */ true))), 2072 any(ICarPropertyEventListener.class)); 2073 } 2074 2075 @Test testSubscribePropertyEvents_withPropertyIdAreaIdCallback()2076 public void testSubscribePropertyEvents_withPropertyIdAreaIdCallback() throws Exception { 2077 assertThat(mCarPropertyManager.subscribePropertyEvents( 2078 VENDOR_CONTINUOUS_PROPERTY, /* areaId= */ 0, 2079 mCarPropertyEventCallback)).isTrue(); 2080 2081 verify(mICarProperty).registerListener(eq(List.of( 2082 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2083 MIN_UPDATE_RATE_HZ, /* enableVur= */ true))), 2084 any(ICarPropertyEventListener.class)); 2085 } 2086 2087 @Test testSubscribePropertyEvents_withPropertyIdAreaIdUpdateRateCallback()2088 public void testSubscribePropertyEvents_withPropertyIdAreaIdUpdateRateCallback() 2089 throws Exception { 2090 assertThat(mCarPropertyManager.subscribePropertyEvents( 2091 VENDOR_CONTINUOUS_PROPERTY, /* areaId= */ 0, 2092 CarPropertyManager.SENSOR_RATE_FAST, 2093 mCarPropertyEventCallback)).isTrue(); 2094 2095 verify(mICarProperty).registerListener(eq(List.of( 2096 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2097 CarPropertyManager.SENSOR_RATE_FAST, /* enableVur= */ false))), 2098 any(ICarPropertyEventListener.class)); 2099 } 2100 2101 @Test testSubscribePropertyEvents_noReadPermission()2102 public void testSubscribePropertyEvents_noReadPermission() throws Exception { 2103 int propId = VENDOR_CONTINUOUS_PROPERTY; 2104 when(mICarProperty.getSupportedNoReadPermPropIds(any())) 2105 .thenReturn(new int[] {propId}); 2106 2107 assertThrows(SecurityException.class, () -> mCarPropertyManager.subscribePropertyEvents( 2108 propId, mCarPropertyEventCallback)); 2109 } 2110 2111 @Test testSubscribePropertyEvents_getSupportedNoReadPermPropIds_remoteException()2112 public void testSubscribePropertyEvents_getSupportedNoReadPermPropIds_remoteException() 2113 throws Exception { 2114 int propId = VENDOR_CONTINUOUS_PROPERTY; 2115 when(mICarProperty.getSupportedNoReadPermPropIds(any())) 2116 .thenThrow(new RemoteException()); 2117 2118 assertThat(mCarPropertyManager.subscribePropertyEvents( 2119 propId, mCarPropertyEventCallback)).isFalse(); 2120 } 2121 2122 @Test testRegisterCallback_registersAgainWithDifferentExecutor_throws()2123 public void testRegisterCallback_registersAgainWithDifferentExecutor_throws() throws Exception { 2124 mCarPropertyManager.subscribePropertyEvents(List.of( 2125 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 2126 .setUpdateRateFast().build(), 2127 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).addAreaId(0) 2128 .build()), 2129 mMockExecutor1, mCarPropertyEventCallback); 2130 2131 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> 2132 mCarPropertyManager.subscribePropertyEvents(List.of( 2133 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 2134 .setUpdateRateFast().build(), 2135 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).addAreaId(0) 2136 .build()), 2137 mMockExecutor2, mCarPropertyEventCallback)); 2138 assertWithMessage("Two executor subscription").that(thrown).hasMessageThat() 2139 .contains("A different executor is already associated with this callback," 2140 + " please use the same executor"); 2141 } 2142 2143 @Test testRegisterCallback_registersAgainWithSameExecutor()2144 public void testRegisterCallback_registersAgainWithSameExecutor() throws Exception { 2145 mCarPropertyManager.subscribePropertyEvents(List.of( 2146 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 2147 .setUpdateRateFast().build(), 2148 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).addAreaId(0) 2149 .build()), 2150 mMockExecutor1, mCarPropertyEventCallback); 2151 mCarPropertyManager.subscribePropertyEvents(List.of( 2152 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY).addAreaId(0) 2153 .setUpdateRateFast().build(), 2154 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).addAreaId(0) 2155 .build()), 2156 mMockExecutor1, mCarPropertyEventCallback); 2157 2158 verify(mICarProperty).registerListener( 2159 eq(List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2160 CarPropertyManager.SENSOR_RATE_FAST, /* enableVur= */ true), 2161 createCarSubscriptionOption(VENDOR_ON_CHANGE_PROPERTY, new int[]{0}, 2162 CarPropertyManager.SENSOR_RATE_ONCHANGE))), 2163 any(ICarPropertyEventListener.class)); 2164 } 2165 2166 @Test testRegisterCallback_registersAgainIfTheFirstCallbackReturnsFalse()2167 public void testRegisterCallback_registersAgainIfTheFirstCallbackReturnsFalse() 2168 throws RemoteException { 2169 doThrow(IllegalArgumentException.class).doNothing().when(mICarProperty) 2170 .registerListener(eq(List.of( 2171 createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, 2172 new int[]{0}, FIRST_UPDATE_RATE_HZ))), 2173 any(ICarPropertyEventListener.class)); 2174 2175 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2176 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isFalse(); 2177 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2178 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2179 } 2180 2181 @Test testRegisterCallback_restoresOriginalRateHzIfTheSecondCallbackReturnsFalse()2182 public void testRegisterCallback_restoresOriginalRateHzIfTheSecondCallbackReturnsFalse() 2183 throws RemoteException { 2184 Float smallerUpdate = 1F; 2185 Float largerUpdate = 2F; 2186 doThrow(IllegalArgumentException.class).when(mICarProperty) 2187 .registerListener(eq(List.of(createCarSubscriptionOption( 2188 HVAC_TEMPERATURE_SET, new int[]{0}, largerUpdate))), 2189 any(ICarPropertyEventListener.class)); 2190 2191 CarPropertyValue<Float> goodValue = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 2192 Duration.ofSeconds(1).toNanos(), 17.0f); 2193 CarPropertyValue<Float> almostFreshValue = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 2194 Duration.ofMillis(1899).toNanos(), 18.0f); 2195 List<CarPropertyEvent> eventList = List.of( 2196 new CarPropertyEvent(CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE, goodValue), 2197 new CarPropertyEvent(CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE, 2198 almostFreshValue) 2199 ); 2200 CarPropertyConfig config = CarPropertyConfig.newBuilder(Float.class, HVAC_TEMPERATURE_SET, 2201 VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL) 2202 .addAreaIdConfig(new AreaIdConfig.Builder<Float>(0).build()) 2203 .setChangeMode(CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS) 2204 .setMinSampleRate(0f) 2205 .setMaxSampleRate(10f).build(); 2206 addCarPropertyConfig(config); 2207 ICarPropertyEventListener listener = getCarPropertyEventListener(); 2208 ArgumentCaptor<CarPropertyValue> valueCaptor = 2209 ArgumentCaptor.forClass(CarPropertyValue.class); 2210 2211 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2212 HVAC_TEMPERATURE_SET, smallerUpdate)).isTrue(); 2213 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2214 HVAC_TEMPERATURE_SET, largerUpdate)).isFalse(); 2215 verify(mICarProperty, times(3)).registerListener( 2216 any(), any(ICarPropertyEventListener.class)); 2217 2218 listener.onEvent(eventList); 2219 verify(mCarPropertyEventCallback, timeout(5000)).onChangeEvent(valueCaptor.capture()); 2220 assertThat(valueCaptor.getAllValues()).containsExactly(goodValue); 2221 } 2222 2223 @Test testUnregisterCallback_doesNothingIfNothingRegistered()2224 public void testUnregisterCallback_doesNothingIfNothingRegistered() throws Exception { 2225 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, VENDOR_STATIC_PROPERTY); 2226 verify(mICarProperty, never()).unregisterListener(anyInt(), 2227 any(ICarPropertyEventListener.class)); 2228 } 2229 2230 @Test testUnsubscribePropertyEvents_doesNothingIfNothingRegistered()2231 public void testUnsubscribePropertyEvents_doesNothingIfNothingRegistered() throws Exception { 2232 mCarPropertyManager.unsubscribePropertyEvents(VENDOR_STATIC_PROPERTY, 2233 mCarPropertyEventCallback); 2234 verify(mICarProperty, never()).unregisterListener(anyInt(), 2235 any(ICarPropertyEventListener.class)); 2236 } 2237 2238 @Test testUnregisterCallback_doesNothingIfPropertyIsNotRegisteredForCallback()2239 public void testUnregisterCallback_doesNothingIfPropertyIsNotRegisteredForCallback() 2240 throws Exception { 2241 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2242 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2243 2244 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, VENDOR_STATIC_PROPERTY); 2245 verify(mICarProperty, never()).unregisterListener(anyInt(), 2246 any(ICarPropertyEventListener.class)); 2247 } 2248 2249 @Test testUnsubscribePropertyEvents_doesNothingIfNothingIsNotRegisteredForCallback()2250 public void testUnsubscribePropertyEvents_doesNothingIfNothingIsNotRegisteredForCallback() 2251 throws Exception { 2252 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2253 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2254 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2255 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2256 2257 mCarPropertyManager.unsubscribePropertyEvents(VENDOR_STATIC_PROPERTY, 2258 mCarPropertyEventCallback); 2259 verify(mICarProperty, never()).unregisterListener(anyInt(), 2260 any(ICarPropertyEventListener.class)); 2261 } 2262 2263 @Test testUnregisterCallback_doesNothingIfCallbackIsNotRegisteredForProperty()2264 public void testUnregisterCallback_doesNothingIfCallbackIsNotRegisteredForProperty() 2265 throws Exception { 2266 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2267 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2268 2269 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback2, 2270 VENDOR_CONTINUOUS_PROPERTY); 2271 verify(mICarProperty, never()).unregisterListener(anyInt(), 2272 any(ICarPropertyEventListener.class)); 2273 } 2274 2275 @Test testUnsubscribePropertyEvents_doesNothingIfCallbackIsNotRegisteredForProperty()2276 public void testUnsubscribePropertyEvents_doesNothingIfCallbackIsNotRegisteredForProperty() 2277 throws Exception { 2278 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2279 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2280 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2281 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2282 2283 mCarPropertyManager.unsubscribePropertyEvents(VENDOR_CONTINUOUS_PROPERTY, 2284 mCarPropertyEventCallback2); 2285 verify(mICarProperty, never()).unregisterListener(anyInt(), 2286 any(ICarPropertyEventListener.class)); 2287 } 2288 2289 @Test testUnregisterCallback_doesNothingIfCarPropertyConfigNull()2290 public void testUnregisterCallback_doesNothingIfCarPropertyConfigNull() throws Exception { 2291 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2292 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2293 2294 setPropIdWithoutConfig(VENDOR_CONTINUOUS_PROPERTY); 2295 2296 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2297 VENDOR_CONTINUOUS_PROPERTY); 2298 verify(mICarProperty, never()).unregisterListener(anyInt(), 2299 any(ICarPropertyEventListener.class)); 2300 } 2301 2302 @Test testUnregisterCallback_doesNothingIfNoPermission()2303 public void testUnregisterCallback_doesNothingIfNoPermission() throws Exception { 2304 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2305 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2306 2307 setPropIdWithoutPermission(VENDOR_CONTINUOUS_PROPERTY); 2308 2309 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2310 VENDOR_CONTINUOUS_PROPERTY); 2311 verify(mICarProperty, never()).unregisterListener(anyInt(), 2312 any(ICarPropertyEventListener.class)); 2313 } 2314 2315 @Test testUnsubscribePropertyEvents_doesNothingIfCarPropertyConfigNull()2316 public void testUnsubscribePropertyEvents_doesNothingIfCarPropertyConfigNull() 2317 throws Exception { 2318 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2319 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2320 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2321 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2322 2323 setPropIdWithoutConfig(VENDOR_CONTINUOUS_PROPERTY); 2324 2325 mCarPropertyManager.unsubscribePropertyEvents(VENDOR_CONTINUOUS_PROPERTY, 2326 mCarPropertyEventCallback); 2327 verify(mICarProperty, never()).unregisterListener(anyInt(), 2328 any(ICarPropertyEventListener.class)); 2329 } 2330 2331 @Test testUnsubscribePropertyEvents_doesNothingIfNoPermission()2332 public void testUnsubscribePropertyEvents_doesNothingIfNoPermission() 2333 throws Exception { 2334 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2335 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2336 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2337 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2338 2339 setPropIdWithoutPermission(VENDOR_CONTINUOUS_PROPERTY); 2340 2341 mCarPropertyManager.unsubscribePropertyEvents(VENDOR_CONTINUOUS_PROPERTY, 2342 mCarPropertyEventCallback); 2343 verify(mICarProperty, never()).unregisterListener(anyInt(), 2344 any(ICarPropertyEventListener.class)); 2345 } 2346 2347 @Test testUnregisterCallback_unregistersCallbackForSingleProperty()2348 public void testUnregisterCallback_unregistersCallbackForSingleProperty() 2349 throws Exception { 2350 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2351 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2352 2353 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2354 VENDOR_CONTINUOUS_PROPERTY); 2355 verify(mICarProperty).unregisterListener(eq(VENDOR_CONTINUOUS_PROPERTY), 2356 any(ICarPropertyEventListener.class)); 2357 } 2358 2359 @Test testUnregisterCallback_unsubscribeCallbackForSingleProperty()2360 public void testUnregisterCallback_unsubscribeCallbackForSingleProperty() 2361 throws Exception { 2362 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2363 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2364 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2365 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2366 2367 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2368 VENDOR_CONTINUOUS_PROPERTY); 2369 verify(mICarProperty).unregisterListener(eq(VENDOR_CONTINUOUS_PROPERTY), 2370 any(ICarPropertyEventListener.class)); 2371 } 2372 2373 @Test testUnregisterCallback_unregistersCallbackForSpecificProperty()2374 public void testUnregisterCallback_unregistersCallbackForSpecificProperty() 2375 throws Exception { 2376 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2377 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2378 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2379 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isTrue(); 2380 2381 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2382 VENDOR_ON_CHANGE_PROPERTY); 2383 verify(mICarProperty).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2384 any(ICarPropertyEventListener.class)); 2385 } 2386 2387 @Test testUnsubscribePropertyEvents_ignoreUserHalProp()2388 public void testUnsubscribePropertyEvents_ignoreUserHalProp() 2389 throws Exception { 2390 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 2391 2392 mCarPropertyManager.unsubscribePropertyEvents(INITIAL_USER_INFO, 2393 mCarPropertyEventCallback); 2394 2395 verify(mICarProperty, never()).unregisterListener(anyInt(), any()); 2396 } 2397 2398 @Test testUnregisterCallback_ignoreUserHalProp_beforeU()2399 public void testUnregisterCallback_ignoreUserHalProp_beforeU() 2400 throws Exception { 2401 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 2402 2403 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, INITIAL_USER_INFO); 2404 2405 verify(mICarProperty, never()).unregisterListener(anyInt(), any()); 2406 } 2407 2408 @Test testUnregisterCallback_ignoreUserHalProp_afterU()2409 public void testUnregisterCallback_ignoreUserHalProp_afterU() 2410 throws Exception { 2411 setAppTargetSdk(Build.VERSION_CODES.UPSIDE_DOWN_CAKE); 2412 2413 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, INITIAL_USER_INFO); 2414 2415 verify(mICarProperty, never()).unregisterListener(anyInt(), any()); 2416 } 2417 2418 @Test testUnsubscribePropertyEvents_unsubscribeCallbackForSpecificProperty()2419 public void testUnsubscribePropertyEvents_unsubscribeCallbackForSpecificProperty() 2420 throws Exception { 2421 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2422 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2423 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build(), 2424 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY) 2425 .build()), 2426 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2427 2428 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2429 VENDOR_CONTINUOUS_PROPERTY); 2430 verify(mICarProperty).unregisterListener(eq(VENDOR_CONTINUOUS_PROPERTY), 2431 any(ICarPropertyEventListener.class)); 2432 verify(mICarProperty, never()).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2433 any(ICarPropertyEventListener.class)); 2434 } 2435 2436 @Test testUnregisterCallback_unregistersCallbackForBothProperties()2437 public void testUnregisterCallback_unregistersCallbackForBothProperties() 2438 throws Exception { 2439 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2440 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2441 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2442 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isTrue(); 2443 2444 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback); 2445 verify(mICarProperty, times(2)).unregisterListener(mPropertyIdCaptor.capture(), 2446 any(ICarPropertyEventListener.class)); 2447 assertThat(mPropertyIdCaptor.getAllValues()).containsExactly(VENDOR_CONTINUOUS_PROPERTY, 2448 VENDOR_ON_CHANGE_PROPERTY); 2449 } 2450 2451 @Test testUnsubscribePropertyEvents_unsubscribeCallbackForBothProperties()2452 public void testUnsubscribePropertyEvents_unsubscribeCallbackForBothProperties() 2453 throws Exception { 2454 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2455 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2456 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build(), 2457 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY) 2458 .setUpdateRateNormal().build()), 2459 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2460 2461 mCarPropertyManager.unsubscribePropertyEvents(VENDOR_CONTINUOUS_PROPERTY, 2462 mCarPropertyEventCallback); 2463 verify(mICarProperty).unregisterListener(eq(VENDOR_CONTINUOUS_PROPERTY), 2464 any(ICarPropertyEventListener.class)); 2465 } 2466 2467 @Test testUnregisterCallback_unregistersAllCallbackForSingleProperty()2468 public void testUnregisterCallback_unregistersAllCallbackForSingleProperty() 2469 throws Exception { 2470 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2471 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2472 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback2, 2473 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isTrue(); 2474 2475 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback); 2476 verify(mICarProperty).unregisterListener(eq(VENDOR_CONTINUOUS_PROPERTY), 2477 any(ICarPropertyEventListener.class)); 2478 } 2479 2480 @Test testUnsubscribePropertyEvents_unsubscribeAllCallbackForSingleProperty()2481 public void testUnsubscribePropertyEvents_unsubscribeAllCallbackForSingleProperty() 2482 throws Exception { 2483 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2484 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2485 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2486 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2487 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2488 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY) 2489 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2490 /* callbackExecutor= */ null, mCarPropertyEventCallback2)).isTrue(); 2491 2492 mCarPropertyManager.unsubscribePropertyEvents(VENDOR_CONTINUOUS_PROPERTY, 2493 mCarPropertyEventCallback); 2494 verify(mICarProperty).unregisterListener(eq(VENDOR_CONTINUOUS_PROPERTY), 2495 any(ICarPropertyEventListener.class)); 2496 verify(mICarProperty, never()).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2497 any(ICarPropertyEventListener.class)); 2498 } 2499 2500 @Test testUnregisterCallback_registerCalledIfBiggerRateRemoved()2501 public void testUnregisterCallback_registerCalledIfBiggerRateRemoved() throws Exception { 2502 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2503 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2504 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback2, 2505 VENDOR_CONTINUOUS_PROPERTY, LARGER_UPDATE_RATE_HZ)).isTrue(); 2506 2507 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback2); 2508 verify(mICarProperty, never()).unregisterListener(anyInt(), 2509 any(ICarPropertyEventListener.class)); 2510 verify(mICarProperty, times(3)).registerListener( 2511 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 2512 assertThat(mCarSubscriptionCaptor.getAllValues()).containsExactly( 2513 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2514 FIRST_UPDATE_RATE_HZ)), 2515 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2516 LARGER_UPDATE_RATE_HZ)), 2517 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2518 FIRST_UPDATE_RATE_HZ)) 2519 ); 2520 } 2521 2522 @Test testUnsubscribePropertyEvents_registerCalledIfBiggerRateRemoved()2523 public void testUnsubscribePropertyEvents_registerCalledIfBiggerRateRemoved() 2524 throws Exception { 2525 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2526 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2527 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2528 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2529 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2530 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2531 .setUpdateRateHz(LARGER_UPDATE_RATE_HZ).build()), 2532 /* callbackExecutor= */ null, mCarPropertyEventCallback2)).isTrue(); 2533 clearInvocations(mICarProperty); 2534 2535 mCarPropertyManager.unsubscribePropertyEvents(mCarPropertyEventCallback2); 2536 2537 verify(mICarProperty, never()).unregisterListener(anyInt(), 2538 any(ICarPropertyEventListener.class)); 2539 verify(mICarProperty, times(1)).registerListener( 2540 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 2541 assertThat(mCarSubscriptionCaptor.getAllValues()).containsExactly( 2542 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2543 FIRST_UPDATE_RATE_HZ, /* enableVur= */ true)) 2544 ); 2545 } 2546 2547 @Test testUnregisterCallback_registerNotCalledIfSmallerRateRemoved()2548 public void testUnregisterCallback_registerNotCalledIfSmallerRateRemoved() 2549 throws Exception { 2550 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2551 VENDOR_CONTINUOUS_PROPERTY, FIRST_UPDATE_RATE_HZ)).isTrue(); 2552 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback2, 2553 VENDOR_CONTINUOUS_PROPERTY, LARGER_UPDATE_RATE_HZ)).isTrue(); 2554 2555 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback); 2556 verify(mICarProperty, never()).unregisterListener(anyInt(), 2557 any(ICarPropertyEventListener.class)); 2558 verify(mICarProperty, times(2)).registerListener( 2559 mCarSubscriptionCaptor.capture(), any(ICarPropertyEventListener.class)); 2560 assertThat(mCarSubscriptionCaptor.getAllValues()).containsExactly( 2561 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2562 FIRST_UPDATE_RATE_HZ)), 2563 List.of(createCarSubscriptionOption(VENDOR_CONTINUOUS_PROPERTY, new int[]{0}, 2564 LARGER_UPDATE_RATE_HZ))); 2565 } 2566 2567 @Test testUnsubscribePropertyEvents_subscribeNotCalledIfSmallerRateremoved()2568 public void testUnsubscribePropertyEvents_subscribeNotCalledIfSmallerRateremoved() 2569 throws Exception { 2570 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2571 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2572 .setUpdateRateHz(FIRST_UPDATE_RATE_HZ).build()), 2573 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2574 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2575 new Subscription.Builder(VENDOR_CONTINUOUS_PROPERTY) 2576 .setUpdateRateHz(LARGER_UPDATE_RATE_HZ).build()), 2577 /* callbackExecutor= */ null, mCarPropertyEventCallback2)).isTrue(); 2578 clearInvocations(mICarProperty); 2579 2580 mCarPropertyManager.unsubscribePropertyEvents(mCarPropertyEventCallback2); 2581 2582 verify(mICarProperty, never()).unregisterListener(anyInt(), 2583 any(ICarPropertyEventListener.class)); 2584 } 2585 2586 @Test testUnregisterCallback_doesNothingWithPropertyIdIfNothingRegistered()2587 public void testUnregisterCallback_doesNothingWithPropertyIdIfNothingRegistered() 2588 throws Exception { 2589 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback); 2590 verify(mICarProperty, never()).unregisterListener(anyInt(), 2591 any(ICarPropertyEventListener.class)); 2592 } 2593 2594 @Test testUnsubscribePropertyEvents_doesNothingWithPropertyIdIfNothingRegistered()2595 public void testUnsubscribePropertyEvents_doesNothingWithPropertyIdIfNothingRegistered() 2596 throws Exception { 2597 mCarPropertyManager.unsubscribePropertyEvents(mCarPropertyEventCallback); 2598 verify(mICarProperty, never()).unregisterListener(anyInt(), 2599 any(ICarPropertyEventListener.class)); 2600 } 2601 2602 @Test testUnregisterCallback_returnsVoidForIllegalArgumentException()2603 public void testUnregisterCallback_returnsVoidForIllegalArgumentException() 2604 throws RemoteException { 2605 doThrow(IllegalArgumentException.class).when(mICarProperty).unregisterListener( 2606 eq(VENDOR_ON_CHANGE_PROPERTY), any(ICarPropertyEventListener.class)); 2607 2608 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2609 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isTrue(); 2610 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2611 VENDOR_ON_CHANGE_PROPERTY); 2612 2613 verify(mICarProperty).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2614 any(ICarPropertyEventListener.class)); 2615 } 2616 2617 @Test testUnsubscribePropertyEvents_returnsVoidForIllegalArgumentException()2618 public void testUnsubscribePropertyEvents_returnsVoidForIllegalArgumentException() 2619 throws Exception { 2620 doThrow(IllegalArgumentException.class).when(mICarProperty).unregisterListener( 2621 eq(VENDOR_ON_CHANGE_PROPERTY), any(ICarPropertyEventListener.class)); 2622 2623 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2624 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).build()), 2625 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2626 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2627 VENDOR_ON_CHANGE_PROPERTY); 2628 2629 verify(mICarProperty).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2630 any(ICarPropertyEventListener.class)); 2631 } 2632 2633 @Test testUnregisterCallback_SecurityException()2634 public void testUnregisterCallback_SecurityException() throws Exception { 2635 doThrow(SecurityException.class).when(mICarProperty).unregisterListener( 2636 eq(VENDOR_ON_CHANGE_PROPERTY), any(ICarPropertyEventListener.class)); 2637 2638 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2639 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isTrue(); 2640 assertThrows(SecurityException.class, 2641 () -> mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2642 VENDOR_ON_CHANGE_PROPERTY)); 2643 } 2644 2645 @Test testUnsubscribePropertyEvents_SecurityException()2646 public void testUnsubscribePropertyEvents_SecurityException() throws Exception { 2647 doThrow(SecurityException.class).when(mICarProperty).unregisterListener( 2648 eq(VENDOR_ON_CHANGE_PROPERTY), any(ICarPropertyEventListener.class)); 2649 2650 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2651 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).build()), 2652 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2653 2654 assertThrows(SecurityException.class, 2655 () -> mCarPropertyManager.unsubscribePropertyEvents(VENDOR_ON_CHANGE_PROPERTY, 2656 mCarPropertyEventCallback)); 2657 } 2658 2659 @Test testUnregisterCallback_recoversAfterSecurityException()2660 public void testUnregisterCallback_recoversAfterSecurityException() throws Exception { 2661 doThrow(SecurityException.class).doNothing().when(mICarProperty).unregisterListener( 2662 eq(VENDOR_ON_CHANGE_PROPERTY), any(ICarPropertyEventListener.class)); 2663 2664 assertThat(mCarPropertyManager.registerCallback(mCarPropertyEventCallback, 2665 VENDOR_ON_CHANGE_PROPERTY, CarPropertyManager.SENSOR_RATE_ONCHANGE)).isTrue(); 2666 assertThrows(SecurityException.class, 2667 () -> mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2668 VENDOR_ON_CHANGE_PROPERTY)); 2669 2670 mCarPropertyManager.unregisterCallback(mCarPropertyEventCallback, 2671 VENDOR_ON_CHANGE_PROPERTY); 2672 2673 verify(mICarProperty, times(2)).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2674 any(ICarPropertyEventListener.class)); 2675 } 2676 2677 @Test testUnsubscribePropertyEvents_recoversAfterSecurityException()2678 public void testUnsubscribePropertyEvents_recoversAfterSecurityException() throws Exception { 2679 doThrow(SecurityException.class).doNothing().when(mICarProperty).unregisterListener( 2680 eq(VENDOR_ON_CHANGE_PROPERTY), any(ICarPropertyEventListener.class)); 2681 assertThat(mCarPropertyManager.subscribePropertyEvents(List.of( 2682 new Subscription.Builder(VENDOR_ON_CHANGE_PROPERTY).build()), 2683 /* callbackExecutor= */ null, mCarPropertyEventCallback)).isTrue(); 2684 2685 assertThrows(SecurityException.class, 2686 () -> mCarPropertyManager.unsubscribePropertyEvents(VENDOR_ON_CHANGE_PROPERTY, 2687 mCarPropertyEventCallback)); 2688 mCarPropertyManager.unsubscribePropertyEvents(VENDOR_ON_CHANGE_PROPERTY, 2689 mCarPropertyEventCallback); 2690 2691 verify(mICarProperty, times(2)).unregisterListener(eq(VENDOR_ON_CHANGE_PROPERTY), 2692 any(ICarPropertyEventListener.class)); 2693 } 2694 2695 @Test testOnErrorEvent_callbackIsCalledWithErrorEvent()2696 public void testOnErrorEvent_callbackIsCalledWithErrorEvent() throws RemoteException { 2697 List<CarPropertyEvent> eventList = createErrorCarPropertyEventList(); 2698 CarPropertyConfig config = CarPropertyConfig.newBuilder(Float.class, HVAC_TEMPERATURE_SET, 2699 VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL) 2700 .addAreaIdConfig(new AreaIdConfig.Builder<Float>(0).build()).build(); 2701 addCarPropertyConfig(config); 2702 ICarPropertyEventListener listener = getCarPropertyEventListener(); 2703 2704 listener.onEvent(eventList); 2705 2706 // Wait until we get the on error event for the initial value. 2707 verify(mCarPropertyEventCallback, timeout(5000)).onErrorEvent(HVAC_TEMPERATURE_SET, 0, 2708 CarPropertyManager.CAR_SET_PROPERTY_ERROR_CODE_UNKNOWN); 2709 } 2710 2711 @Test testOnChangeEvent_callbackIsCalledWithEvent()2712 public void testOnChangeEvent_callbackIsCalledWithEvent() throws RemoteException { 2713 List<CarPropertyEvent> eventList = createCarPropertyEventList(); 2714 CarPropertyConfig config = CarPropertyConfig.newBuilder(Float.class, HVAC_TEMPERATURE_SET, 2715 VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL) 2716 .addAreaIdConfig(new AreaIdConfig.Builder<Float>(0).build()).build(); 2717 addCarPropertyConfig(config); 2718 ICarPropertyEventListener listener = getCarPropertyEventListener(); 2719 ArgumentCaptor<CarPropertyValue> value = ArgumentCaptor.forClass(CarPropertyValue.class); 2720 2721 listener.onEvent(eventList); 2722 2723 // Wait until we get the on property change event for the initial value. 2724 verify(mCarPropertyEventCallback, timeout(5000)).onChangeEvent(value.capture()); 2725 assertThat(value.getValue().getPropertyId()).isEqualTo(HVAC_TEMPERATURE_SET); 2726 assertThat(value.getValue().getValue()).isEqualTo(17.0f); 2727 } 2728 getCarPropertyEventListener()2729 private ICarPropertyEventListener getCarPropertyEventListener() throws RemoteException { 2730 ArgumentCaptor<ICarPropertyEventListener> carPropertyEventListenerArgumentCaptor = 2731 ArgumentCaptor.forClass(ICarPropertyEventListener.class); 2732 mCarPropertyManager.registerCallback(mCarPropertyEventCallback, HVAC_TEMPERATURE_SET, 2733 SENSOR_RATE_ONCHANGE); 2734 2735 verify(mICarProperty).registerListener(eq(List.of( 2736 createCarSubscriptionOption(HVAC_TEMPERATURE_SET, new int[]{0}, 2737 SENSOR_RATE_ONCHANGE))), 2738 carPropertyEventListenerArgumentCaptor.capture()); 2739 2740 return carPropertyEventListenerArgumentCaptor.getValue(); 2741 } 2742 2743 @Test testGetPropertyList()2744 public void testGetPropertyList() throws Exception { 2745 List<CarPropertyConfig> expectedConfigs = mock(List.class); 2746 when(mICarProperty.getPropertyList()) 2747 .thenReturn(new CarPropertyConfigList(expectedConfigs)); 2748 2749 2750 assertThat(mCarPropertyManager.getPropertyList()).isEqualTo(expectedConfigs); 2751 } 2752 2753 @Test testGetPropertyList_withPropertyIds()2754 public void testGetPropertyList_withPropertyIds() throws Exception { 2755 ArraySet<Integer> requestedPropertyIds = new ArraySet<>(Set.of( 2756 VENDOR_CONTINUOUS_PROPERTY, HVAC_TEMPERATURE_SET)); 2757 CarPropertyConfig config1 = CarPropertyConfig.newBuilder(Integer.class, 2758 VENDOR_CONTINUOUS_PROPERTY, 2759 VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL) 2760 .addAreaIdConfig(new AreaIdConfig.Builder<Integer>(0).build()).build(); 2761 CarPropertyConfig config2 = CarPropertyConfig.newBuilder(Float.class, 2762 HVAC_TEMPERATURE_SET, 2763 VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL) 2764 .addAreaIdConfig(new AreaIdConfig.Builder<Float>(0).build()).build(); 2765 addCarPropertyConfig(config1); 2766 addCarPropertyConfig(config2); 2767 2768 assertThat(mCarPropertyManager.getPropertyList(requestedPropertyIds)) 2769 .containsExactly(config1, config2); 2770 } 2771 2772 @Test testGetPropertyList_filterUnsupportedPropertyIds()2773 public void testGetPropertyList_filterUnsupportedPropertyIds() throws Exception { 2774 ArraySet<Integer> requestedPropertyIds = new ArraySet<>(Set.of( 2775 0, 1, VENDOR_CONTINUOUS_PROPERTY, HVAC_TEMPERATURE_SET)); 2776 CarPropertyConfig config1 = CarPropertyConfig.newBuilder(Integer.class, 2777 VENDOR_CONTINUOUS_PROPERTY, 2778 VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL) 2779 .addAreaIdConfig(new AreaIdConfig.Builder<Integer>(0).build()).build(); 2780 CarPropertyConfig config2 = CarPropertyConfig.newBuilder(Float.class, 2781 HVAC_TEMPERATURE_SET, 2782 VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL) 2783 .addAreaIdConfig(new AreaIdConfig.Builder<Float>(0).build()).build(); 2784 addCarPropertyConfig(config1); 2785 addCarPropertyConfig(config2); 2786 2787 assertThat(mCarPropertyManager.getPropertyList(requestedPropertyIds)) 2788 .containsExactly(config1, config2); 2789 } 2790 2791 @Test testGetCarPropertyConfig()2792 public void testGetCarPropertyConfig() throws Exception { 2793 assertThat(mCarPropertyManager.getCarPropertyConfig(VENDOR_ON_CHANGE_PROPERTY)) 2794 .isEqualTo(mOnChangeCarPropertyConfig); 2795 } 2796 2797 @Test testGetCarPropertyConfig_noConfigReturned_notSupported()2798 public void testGetCarPropertyConfig_noConfigReturned_notSupported() throws Exception { 2799 setPropIdWithoutConfig(HVAC_TEMPERATURE_SET); 2800 2801 assertThat(mCarPropertyManager.getCarPropertyConfig(HVAC_TEMPERATURE_SET)).isNull(); 2802 } 2803 2804 @Test testGetCarPropertyConfig_noConfigReturned_noPermission()2805 public void testGetCarPropertyConfig_noConfigReturned_noPermission() throws Exception { 2806 setPropIdWithoutPermission(HVAC_TEMPERATURE_SET); 2807 2808 assertThat(mCarPropertyManager.getCarPropertyConfig(HVAC_TEMPERATURE_SET)).isNull(); 2809 } 2810 2811 @Test testGetCarPropertyConfig_unsupported()2812 public void testGetCarPropertyConfig_unsupported() throws Exception { 2813 assertThat(mCarPropertyManager.getCarPropertyConfig(/* propId= */ 0)).isNull(); 2814 } 2815 2816 @Test testGetAreaId_global()2817 public void testGetAreaId_global() throws Exception { 2818 assertThat(mCarPropertyManager.getAreaId(VENDOR_ON_CHANGE_PROPERTY, 0)).isEqualTo(0); 2819 } 2820 2821 @Test testGetAreaId_withArea()2822 public void testGetAreaId_withArea() throws Exception { 2823 int areaId = VehicleAreaSeat.SEAT_ROW_1_LEFT | VehicleAreaSeat.SEAT_ROW_1_CENTER; 2824 CarPropertyConfig config1 = CarPropertyConfig.newBuilder(Integer.class, 2825 HVAC_TEMPERATURE_SET, 2826 VehicleAreaType.VEHICLE_AREA_TYPE_SEAT) 2827 .addAreaIdConfig(new AreaIdConfig.Builder<Integer>(areaId) 2828 .build()).build(); 2829 addCarPropertyConfig(config1); 2830 2831 assertThat(mCarPropertyManager.getAreaId( 2832 HVAC_TEMPERATURE_SET, VehicleAreaSeat.SEAT_ROW_1_LEFT)).isEqualTo(areaId); 2833 assertThat(mCarPropertyManager.getAreaId( 2834 HVAC_TEMPERATURE_SET, VehicleAreaSeat.SEAT_ROW_1_CENTER)).isEqualTo(areaId); 2835 } 2836 2837 @Test testGetAreaId_areaNotSupported()2838 public void testGetAreaId_areaNotSupported() throws Exception { 2839 int areaId = VehicleAreaSeat.SEAT_ROW_1_LEFT | VehicleAreaSeat.SEAT_ROW_1_CENTER; 2840 CarPropertyConfig config1 = CarPropertyConfig.newBuilder(Integer.class, 2841 HVAC_TEMPERATURE_SET, 2842 VehicleAreaType.VEHICLE_AREA_TYPE_SEAT) 2843 .addAreaIdConfig(new AreaIdConfig.Builder<Integer>(areaId) 2844 .build()).build(); 2845 addCarPropertyConfig(config1); 2846 2847 assertThrows(IllegalArgumentException.class, () -> mCarPropertyManager.getAreaId( 2848 HVAC_TEMPERATURE_SET, VehicleAreaSeat.SEAT_ROW_1_RIGHT)); 2849 } 2850 2851 @Test testGetAreaId_propertyNotSupported()2852 public void testGetAreaId_propertyNotSupported() throws Exception { 2853 setPropIdWithoutConfig(HVAC_TEMPERATURE_SET); 2854 2855 assertThrows(IllegalArgumentException.class, () -> mCarPropertyManager.getAreaId( 2856 HVAC_TEMPERATURE_SET, 0)); 2857 } 2858 2859 @Test testGetAreaId_noPermissionToProperty()2860 public void testGetAreaId_noPermissionToProperty() throws Exception { 2861 setPropIdWithoutPermission(HVAC_TEMPERATURE_SET); 2862 2863 assertThrows(IllegalArgumentException.class, () -> mCarPropertyManager.getAreaId( 2864 HVAC_TEMPERATURE_SET, 0)); 2865 } 2866 2867 @Test testGetAreaId_remoteExceptionFromCarService()2868 public void testGetAreaId_remoteExceptionFromCarService() throws Exception { 2869 when(mICarProperty.getPropertyConfigList(new int[]{HVAC_TEMPERATURE_SET})) 2870 .thenThrow(new RemoteException()); 2871 2872 assertThrows(IllegalArgumentException.class, () -> mCarPropertyManager.getAreaId( 2873 HVAC_TEMPERATURE_SET, 0)); 2874 } 2875 2876 @Test testIsPropertyAvailable_withValueWithNotAvailableStatus()2877 public void testIsPropertyAvailable_withValueWithNotAvailableStatus() throws Exception { 2878 CarPropertyValue<Float> value = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 0, 2879 CarPropertyValue.STATUS_ERROR, TEST_TIMESTAMP, 17.0f); 2880 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(value); 2881 2882 assertThat(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_SET, /* areaId= */ 0)) 2883 .isFalse(); 2884 } 2885 2886 @Test testIsPropertyAvailable()2887 public void testIsPropertyAvailable() throws Exception { 2888 CarPropertyValue<Integer> expectedValue = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 2889 /* areaId= */ 0, CarPropertyValue.STATUS_AVAILABLE, /* timestamp= */ 0, 2890 /* value= */ 1); 2891 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenReturn(expectedValue); 2892 2893 assertThat(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_SET, /* areaId= */ 0)) 2894 .isTrue(); 2895 } 2896 2897 @Test testIsPropertyAvailable_syncOpTryAgain()2898 public void testIsPropertyAvailable_syncOpTryAgain() throws Exception { 2899 CarPropertyValue<Integer> expectedValue = new CarPropertyValue<>(HVAC_TEMPERATURE_SET, 2900 /* areaId= */ 0, CarPropertyValue.STATUS_AVAILABLE, /* timestamp= */ 0, 2901 /* value= */ 1); 2902 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 2903 new ServiceSpecificException(SYNC_OP_LIMIT_TRY_AGAIN)).thenReturn(expectedValue); 2904 2905 assertThat(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_SET, /* areaId= */ 0)) 2906 .isTrue(); 2907 verify(mICarProperty, times(2)).getProperty(HVAC_TEMPERATURE_SET, 0); 2908 } 2909 2910 @Test testIsPropertyAvailable_notAvailable()2911 public void testIsPropertyAvailable_notAvailable() throws Exception { 2912 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 2913 new ServiceSpecificException(VehicleHalStatusCode.STATUS_NOT_AVAILABLE)); 2914 2915 assertThat(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_SET, /* areaId= */ 0)) 2916 .isFalse(); 2917 } 2918 2919 @Test testIsPropertyAvailable_tryAgain()2920 public void testIsPropertyAvailable_tryAgain() throws Exception { 2921 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 2922 new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN)); 2923 2924 assertThat(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_SET, /* areaId= */ 0)) 2925 .isFalse(); 2926 } 2927 2928 2929 @Test testIsPropertyAvailable_RemoteException()2930 public void testIsPropertyAvailable_RemoteException() throws Exception { 2931 when(mICarProperty.getProperty(HVAC_TEMPERATURE_SET, 0)).thenThrow( 2932 new RemoteException()); 2933 2934 assertThat(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_SET, /* areaId= */ 0)) 2935 .isFalse(); 2936 } 2937 2938 @Test testIsPropertyAvailable_unsupported()2939 public void testIsPropertyAvailable_unsupported() throws Exception { 2940 assertThat(mCarPropertyManager.isPropertyAvailable(/* propId= */ 0, /* areaId= */ 0)) 2941 .isFalse(); 2942 } 2943 2944 @Test testGetCarPropertyConfig_userHalProperty()2945 public void testGetCarPropertyConfig_userHalProperty() throws Exception { 2946 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 2947 2948 assertThrows(IllegalArgumentException.class, 2949 () -> mCarPropertyManager.getCarPropertyConfig(INITIAL_USER_INFO)); 2950 } 2951 2952 @Test testGetPropertyList_userHalProperty()2953 public void testGetPropertyList_userHalProperty() throws Exception { 2954 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 2955 2956 assertThrows(IllegalArgumentException.class, 2957 () -> mCarPropertyManager.getPropertyList( 2958 new ArraySet<Integer>(Set.of(HVAC_TEMPERATURE_SET, INITIAL_USER_INFO)))); 2959 } 2960 2961 @Test testGetAreaId_userHalProperty()2962 public void testGetAreaId_userHalProperty() throws Exception { 2963 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 2964 2965 assertThrows(IllegalArgumentException.class, 2966 () -> mCarPropertyManager.getAreaId(INITIAL_USER_INFO, /* area= */ 0)); 2967 } 2968 2969 @Test testGetReadPermission_userHalProperty()2970 public void testGetReadPermission_userHalProperty() throws Exception { 2971 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 2972 2973 assertThrows(IllegalArgumentException.class, 2974 () -> mCarPropertyManager.getReadPermission(INITIAL_USER_INFO)); 2975 } 2976 2977 @Test testGetWritePermission_userHalProperty()2978 public void testGetWritePermission_userHalProperty() throws Exception { 2979 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 2980 2981 assertThrows(IllegalArgumentException.class, 2982 () -> mCarPropertyManager.getWritePermission(INITIAL_USER_INFO)); 2983 } 2984 2985 @Test testIsPropertyAvailable_userHalProperty()2986 public void testIsPropertyAvailable_userHalProperty() throws Exception { 2987 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 2988 2989 assertThrows(IllegalArgumentException.class, 2990 () -> mCarPropertyManager.isPropertyAvailable(INITIAL_USER_INFO, /* areaId= */ 0)); 2991 } 2992 2993 @Test testGetProperty_userHalProperty()2994 public void testGetProperty_userHalProperty() throws Exception { 2995 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 2996 2997 assertThrows(IllegalArgumentException.class, 2998 () -> mCarPropertyManager.getProperty(INITIAL_USER_INFO, /* areaId= */ 0)); 2999 } 3000 3001 @Test testGetBooleanProperty_userHalProperty()3002 public void testGetBooleanProperty_userHalProperty() throws Exception { 3003 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 3004 3005 assertThrows(IllegalArgumentException.class, 3006 () -> mCarPropertyManager.getBooleanProperty(INITIAL_USER_INFO, /* areaId= */ 0)); 3007 } 3008 3009 @Test testSetBooleanProperty_userHalProperty()3010 public void testSetBooleanProperty_userHalProperty() throws Exception { 3011 setAppTargetSdk(Build.VERSION_CODES.TIRAMISU); 3012 3013 assertThrows(IllegalArgumentException.class, 3014 () -> mCarPropertyManager.setBooleanProperty(INITIAL_USER_INFO, /* areaId= */ 0, 3015 true)); 3016 } 3017 } 3018