1 /* 2 * Copyright (C) 2021 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 com.android.car.hal; 18 19 import static android.car.VehiclePropertyIds.CLUSTER_DISPLAY_STATE; 20 import static android.car.VehiclePropertyIds.CLUSTER_HEARTBEAT; 21 import static android.car.VehiclePropertyIds.CLUSTER_NAVIGATION_STATE; 22 import static android.car.VehiclePropertyIds.CLUSTER_REPORT_STATE; 23 import static android.car.VehiclePropertyIds.CLUSTER_REQUEST_DISPLAY; 24 import static android.car.VehiclePropertyIds.CLUSTER_SWITCH_UI; 25 26 import static com.android.car.hal.ClusterHalService.DONT_CARE; 27 import static com.android.car.hal.VehicleHalTestingHelper.newSubscribableConfig; 28 29 import static com.google.common.truth.Truth.assertThat; 30 31 import static org.junit.Assert.assertThrows; 32 import static org.mockito.Mockito.times; 33 import static org.mockito.Mockito.verify; 34 import static org.mockito.Mockito.when; 35 36 import android.content.Context; 37 import android.content.res.Resources; 38 import android.graphics.Insets; 39 import android.graphics.Rect; 40 41 import com.android.car.R; 42 import com.android.car.hal.ClusterHalService.ClusterHalEventCallback; 43 44 import org.junit.After; 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.mockito.ArgumentCaptor; 49 import org.mockito.Captor; 50 import org.mockito.Mock; 51 import org.mockito.junit.MockitoJUnitRunner; 52 53 import java.util.ArrayList; 54 import java.util.Arrays; 55 import java.util.List; 56 57 @RunWith(MockitoJUnitRunner.class) 58 public class ClusterHalServiceTest { 59 private static final int NOT_ASSIGNED = -1; 60 61 private static final int ON = 1; 62 private static final int UI_TYPE_1 = 1; 63 private static final int UI_TYPE_2 = 2; 64 private static final byte[] UI_AVAILABILITY = new byte[] {(byte) 1, (byte) 1, (byte) 0}; 65 66 private static final int BOUNDS_LEFT = 0; 67 private static final int BOUNDS_TOP = 1; 68 private static final int BOUNDS_RIGHT = 800; 69 private static final int BOUNDS_BOTTOM = 601; 70 private static final int INSET_LEFT = 20; 71 private static final int INSET_TOP = 10; 72 private static final int INSET_RIGHT = 780; 73 private static final int INSET_BOTTOM = 590; 74 75 private static final HalPropValueBuilder PROP_VALUE_BUILDER = new HalPropValueBuilder( 76 /*isAidl=*/true); 77 78 @Mock 79 Context mMockContext; 80 @Mock 81 Resources mMockResources; 82 @Mock 83 VehicleHal mVehicleHal; 84 @Captor 85 ArgumentCaptor<HalPropValue> mPropCaptor; 86 87 private ClusterHalService mClusterHalService; 88 89 int mUiType = NOT_ASSIGNED; 90 int mOnOff = NOT_ASSIGNED; 91 Rect mBounds = null; 92 Insets mInsets = null; 93 94 private final ClusterHalEventCallback mHalEventListener = new ClusterHalEventCallback() { 95 public void onSwitchUi(int uiType) { 96 mUiType = uiType; 97 } 98 99 public void onDisplayState(int onOff, Rect bounds, Insets insets) { 100 mOnOff = onOff; 101 mBounds = bounds; 102 mInsets = insets; 103 } 104 }; 105 getIntValues(HalPropValue value)106 private ArrayList<Integer> getIntValues(HalPropValue value) { 107 ArrayList<Integer> intValues = new ArrayList<Integer>(); 108 for (int i = 0; i < value.getInt32ValuesSize(); i++) { 109 intValues.add(value.getInt32Value(i)); 110 } 111 return intValues; 112 } 113 getFullProperties()114 private static List<HalPropConfig> getFullProperties() { 115 return Arrays.asList( 116 newSubscribableConfig(CLUSTER_SWITCH_UI), 117 newSubscribableConfig(CLUSTER_DISPLAY_STATE), 118 newSubscribableConfig(CLUSTER_REPORT_STATE), 119 newSubscribableConfig(CLUSTER_REQUEST_DISPLAY), 120 newSubscribableConfig(CLUSTER_HEARTBEAT), 121 newSubscribableConfig(CLUSTER_NAVIGATION_STATE)); 122 } 123 getCoreProperties()124 private static List<HalPropConfig> getCoreProperties() { 125 return Arrays.asList( 126 newSubscribableConfig(CLUSTER_SWITCH_UI), 127 newSubscribableConfig(CLUSTER_DISPLAY_STATE), 128 newSubscribableConfig(CLUSTER_REPORT_STATE), 129 newSubscribableConfig(CLUSTER_REQUEST_DISPLAY)); 130 } 131 createLightModeServiceWithProperties(List<HalPropConfig> properties)132 private ClusterHalService createLightModeServiceWithProperties(List<HalPropConfig> properties) { 133 when(mMockResources.getInteger(R.integer.config_clusterHomeServiceMode)).thenReturn(1); 134 ClusterHalService lightModeService = new ClusterHalService(mMockContext, mVehicleHal); 135 lightModeService.takeProperties(properties); 136 lightModeService.setCallback(mHalEventListener); 137 138 return lightModeService; 139 } 140 141 @Before setUp()142 public void setUp() { 143 when(mMockContext.getResources()).thenReturn(mMockResources); 144 when(mMockResources.getInteger(R.integer.config_clusterHomeServiceMode)).thenReturn(0); 145 when(mVehicleHal.getHalPropValueBuilder()).thenReturn(PROP_VALUE_BUILDER); 146 mClusterHalService = new ClusterHalService(mMockContext, mVehicleHal); 147 mClusterHalService.setCallback(mHalEventListener); 148 } 149 150 @After tearDown()151 public void tearDown() { 152 mClusterHalService.release(); 153 mClusterHalService = null; 154 } 155 156 @Test testIsServiceEnabled_fullMode_coreProperties()157 public void testIsServiceEnabled_fullMode_coreProperties() { 158 mClusterHalService.takeProperties(getCoreProperties()); 159 160 assertThat(mClusterHalService.isServiceEnabled()).isTrue(); 161 } 162 163 @Test testIsServiceEnabled_fullMode_partialProperties()164 public void testIsServiceEnabled_fullMode_partialProperties() { 165 mClusterHalService.takeProperties(Arrays.asList( 166 newSubscribableConfig(CLUSTER_DISPLAY_STATE))); 167 168 assertThat(mClusterHalService.isServiceEnabled()).isFalse(); 169 } 170 171 @Test testIsServiceEnabled_fullMode_noProperties()172 public void testIsServiceEnabled_fullMode_noProperties() { 173 mClusterHalService.takeProperties(Arrays.asList()); 174 175 assertThat(mClusterHalService.isServiceEnabled()).isFalse(); 176 } 177 178 @Test testIsServiceEnabled_lightMode_partialProperties()179 public void testIsServiceEnabled_lightMode_partialProperties() { 180 ClusterHalService lightModeService = createLightModeServiceWithProperties(Arrays.asList( 181 newSubscribableConfig(CLUSTER_DISPLAY_STATE))); 182 183 assertThat(lightModeService.isServiceEnabled()).isTrue(); 184 } 185 186 @Test testIsServiceEnabled_lightMode_noProperties()187 public void testIsServiceEnabled_lightMode_noProperties() { 188 ClusterHalService lightModeService = createLightModeServiceWithProperties(Arrays.asList()); 189 190 assertThat(lightModeService.isServiceEnabled()).isTrue(); 191 } 192 193 @Test testInit_subscribePropertySafe_coreProperties()194 public void testInit_subscribePropertySafe_coreProperties() { 195 mClusterHalService.takeProperties(getCoreProperties()); 196 197 mClusterHalService.init(); 198 199 verify(mVehicleHal).subscribePropertySafe(mClusterHalService, CLUSTER_SWITCH_UI); 200 verify(mVehicleHal).subscribePropertySafe(mClusterHalService, CLUSTER_DISPLAY_STATE); 201 } 202 203 @Test testInit_subscribePropertySafe_lightMode_coreProperties()204 public void testInit_subscribePropertySafe_lightMode_coreProperties() { 205 ClusterHalService lightModeService = 206 createLightModeServiceWithProperties(getCoreProperties()); 207 208 lightModeService.init(); 209 210 verify(mVehicleHal, times(0)).subscribePropertySafe(lightModeService, CLUSTER_SWITCH_UI); 211 verify(mVehicleHal, times(0)).subscribePropertySafe(lightModeService, 212 CLUSTER_DISPLAY_STATE); 213 } 214 215 @Test testInit_subscribePropertySafe_noProperties()216 public void testInit_subscribePropertySafe_noProperties() { 217 mClusterHalService.takeProperties(Arrays.asList()); 218 219 mClusterHalService.init(); 220 221 verify(mVehicleHal, times(0)).subscribePropertySafe(mClusterHalService, CLUSTER_SWITCH_UI); 222 verify(mVehicleHal, times(0)).subscribePropertySafe(mClusterHalService, 223 CLUSTER_DISPLAY_STATE); 224 } 225 226 @Test testInit_lightMode_subscribePropertySafe_noProperties()227 public void testInit_lightMode_subscribePropertySafe_noProperties() { 228 ClusterHalService lightModeService = createLightModeServiceWithProperties(Arrays.asList()); 229 230 lightModeService.init(); 231 232 verify(mVehicleHal, times(0)).subscribePropertySafe(lightModeService, CLUSTER_SWITCH_UI); 233 verify(mVehicleHal, times(0)).subscribePropertySafe(lightModeService, 234 CLUSTER_DISPLAY_STATE); 235 } 236 237 @Test testInit_subscribePropertySafe_partialProperties()238 public void testInit_subscribePropertySafe_partialProperties() { 239 mClusterHalService.takeProperties(Arrays.asList( 240 newSubscribableConfig(CLUSTER_DISPLAY_STATE))); 241 242 mClusterHalService.init(); 243 244 verify(mVehicleHal, times(0)).subscribePropertySafe(mClusterHalService, CLUSTER_SWITCH_UI); 245 verify(mVehicleHal, times(0)).subscribePropertySafe(mClusterHalService, 246 CLUSTER_DISPLAY_STATE); 247 } 248 249 @Test testInit_lightMode_subscribePropertySafe_partialProperties()250 public void testInit_lightMode_subscribePropertySafe_partialProperties() { 251 ClusterHalService lightModeService = createLightModeServiceWithProperties(Arrays.asList( 252 newSubscribableConfig(CLUSTER_DISPLAY_STATE))); 253 254 lightModeService.init(); 255 256 verify(mVehicleHal, times(0)).subscribePropertySafe(lightModeService, CLUSTER_SWITCH_UI); 257 verify(mVehicleHal, times(0)).subscribePropertySafe(lightModeService, 258 CLUSTER_DISPLAY_STATE); 259 } 260 261 @Test testTakeProperties_fullMode_noProperties()262 public void testTakeProperties_fullMode_noProperties() { 263 mClusterHalService.takeProperties(Arrays.asList()); 264 265 assertThat(mClusterHalService.isFullModeEnabled()).isFalse(); 266 assertThat(mClusterHalService.isServiceEnabled()).isFalse(); 267 assertThat(mClusterHalService.isNavigationStateSupported()).isFalse(); 268 } 269 270 @Test testTakeProperties_lightMode_noProperties()271 public void testTakeProperties_lightMode_noProperties() { 272 ClusterHalService lightModeService = createLightModeServiceWithProperties(Arrays.asList()); 273 274 assertThat(lightModeService.isFullModeEnabled()).isFalse(); 275 assertThat(lightModeService.isServiceEnabled()).isTrue(); 276 assertThat(lightModeService.isNavigationStateSupported()).isFalse(); 277 } 278 279 @Test testTakeProperties_fullMode_partialProperties()280 public void testTakeProperties_fullMode_partialProperties() { 281 mClusterHalService.takeProperties(Arrays.asList( 282 newSubscribableConfig(CLUSTER_SWITCH_UI), 283 newSubscribableConfig(CLUSTER_DISPLAY_STATE), 284 newSubscribableConfig(CLUSTER_REPORT_STATE))); 285 286 assertThat(mClusterHalService.isFullModeEnabled()).isFalse(); 287 assertThat(mClusterHalService.isServiceEnabled()).isFalse(); 288 assertThat(mClusterHalService.isNavigationStateSupported()).isFalse(); 289 } 290 291 @Test testTakeProperties_lightMode_partialProperties()292 public void testTakeProperties_lightMode_partialProperties() { 293 ClusterHalService lightModeService = createLightModeServiceWithProperties(Arrays.asList( 294 newSubscribableConfig(CLUSTER_SWITCH_UI), 295 newSubscribableConfig(CLUSTER_DISPLAY_STATE), 296 newSubscribableConfig(CLUSTER_REPORT_STATE))); 297 298 assertThat(lightModeService.isFullModeEnabled()).isFalse(); 299 assertThat(lightModeService.isServiceEnabled()).isTrue(); 300 assertThat(lightModeService.isNavigationStateSupported()).isFalse(); 301 } 302 303 @Test testTakeProperties_fullMode_coreProperties()304 public void testTakeProperties_fullMode_coreProperties() { 305 mClusterHalService.takeProperties(getCoreProperties()); 306 307 assertThat(mClusterHalService.isFullModeEnabled()).isTrue(); 308 assertThat(mClusterHalService.isServiceEnabled()).isTrue(); 309 assertThat(mClusterHalService.isNavigationStateSupported()).isFalse(); 310 } 311 312 @Test testTakeProperties_fullMode_fullProperties()313 public void testTakeProperties_fullMode_fullProperties() { 314 mClusterHalService.takeProperties(getFullProperties()); 315 316 assertThat(mClusterHalService.isFullModeEnabled()).isTrue(); 317 assertThat(mClusterHalService.isServiceEnabled()).isTrue(); 318 assertThat(mClusterHalService.isNavigationStateSupported()).isTrue(); 319 } 320 321 @Test testTakeProperties_lightMode_fullProperties()322 public void testTakeProperties_lightMode_fullProperties() { 323 ClusterHalService lightModeService = 324 createLightModeServiceWithProperties(getFullProperties()); 325 326 assertThat(lightModeService.isFullModeEnabled()).isFalse(); 327 assertThat(lightModeService.isServiceEnabled()).isTrue(); 328 assertThat(lightModeService.isNavigationStateSupported()).isTrue(); 329 } 330 createSwitchUiEvent(int uiType)331 private static HalPropValue createSwitchUiEvent(int uiType) { 332 HalPropValue event = PROP_VALUE_BUILDER.build(CLUSTER_SWITCH_UI, /*areaId=*/0, uiType); 333 return event; 334 } 335 createDisplayStateEvent(int onOff, int boundsLeft, int boundsTop, int boundsRight, int boundsBottom, int insetsLeft, int insetsTop, int insetSRight, int insetSBottom)336 private static HalPropValue createDisplayStateEvent(int onOff, 337 int boundsLeft, int boundsTop, int boundsRight, int boundsBottom, 338 int insetsLeft, int insetsTop, int insetSRight, int insetSBottom) { 339 HalPropValue event = PROP_VALUE_BUILDER.build(CLUSTER_DISPLAY_STATE, /*areaId=*/0, 340 new int[]{onOff, boundsLeft, boundsTop, boundsRight, boundsBottom, insetsLeft, 341 insetsTop, insetSRight, insetSBottom}); 342 return event; 343 } 344 345 @Test testOnSwitchUi()346 public void testOnSwitchUi() { 347 mClusterHalService.takeProperties(getCoreProperties()); 348 349 mClusterHalService.onHalEvents(Arrays.asList(createSwitchUiEvent(UI_TYPE_1))); 350 351 assertThat(mUiType).isEqualTo(UI_TYPE_1); 352 } 353 354 @Test testOnSwitchUi_noListener()355 public void testOnSwitchUi_noListener() { 356 mClusterHalService.takeProperties(getCoreProperties()); 357 mClusterHalService.setCallback(null); 358 359 mClusterHalService.onHalEvents(Arrays.asList(createSwitchUiEvent(UI_TYPE_1))); 360 361 assertThat(mUiType).isEqualTo(NOT_ASSIGNED); 362 } 363 364 @Test testOnSwitchUi_noProperties()365 public void testOnSwitchUi_noProperties() { 366 mClusterHalService.takeProperties(Arrays.asList()); 367 368 mClusterHalService.onHalEvents(Arrays.asList(createSwitchUiEvent(UI_TYPE_1))); 369 370 assertThat(mUiType).isEqualTo(NOT_ASSIGNED); 371 } 372 373 @Test testOnDisplayState()374 public void testOnDisplayState() { 375 mClusterHalService.takeProperties(getCoreProperties()); 376 377 mClusterHalService.onHalEvents(Arrays.asList( 378 createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM, 379 INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM))); 380 381 assertThat(mOnOff).isEqualTo(ON); 382 assertThat(mBounds.left).isEqualTo(BOUNDS_LEFT); 383 assertThat(mBounds.top).isEqualTo(BOUNDS_TOP); 384 assertThat(mBounds.right).isEqualTo(BOUNDS_RIGHT); 385 assertThat(mBounds.bottom).isEqualTo(BOUNDS_BOTTOM); 386 assertThat(mInsets.left).isEqualTo(INSET_LEFT); 387 assertThat(mInsets.top).isEqualTo(INSET_TOP); 388 assertThat(mInsets.right).isEqualTo(INSET_RIGHT); 389 assertThat(mInsets.bottom).isEqualTo(INSET_BOTTOM); 390 } 391 392 @Test testOnDisplayState_DontAcceptPartialDontCare_Bounds()393 public void testOnDisplayState_DontAcceptPartialDontCare_Bounds() { 394 mClusterHalService.takeProperties(getCoreProperties()); 395 mClusterHalService.onHalEvents(Arrays.asList( 396 createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, DONT_CARE, 397 INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM))); 398 399 assertThat(mOnOff).isEqualTo(ON); 400 assertThat(mBounds).isNull(); 401 assertThat(mInsets.left).isEqualTo(INSET_LEFT); 402 assertThat(mInsets.top).isEqualTo(INSET_TOP); 403 assertThat(mInsets.right).isEqualTo(INSET_RIGHT); 404 assertThat(mInsets.bottom).isEqualTo(INSET_BOTTOM); 405 } 406 407 @Test testOnDisplayState_DontAcceptPartialDontCare_Inset()408 public void testOnDisplayState_DontAcceptPartialDontCare_Inset() { 409 mClusterHalService.takeProperties(getCoreProperties()); 410 mClusterHalService.onHalEvents(Arrays.asList( 411 createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM, 412 INSET_LEFT, INSET_TOP, INSET_RIGHT, DONT_CARE))); 413 414 assertThat(mOnOff).isEqualTo(ON); 415 assertThat(mBounds.left).isEqualTo(BOUNDS_LEFT); 416 assertThat(mBounds.top).isEqualTo(BOUNDS_TOP); 417 assertThat(mBounds.right).isEqualTo(BOUNDS_RIGHT); 418 assertThat(mBounds.bottom).isEqualTo(BOUNDS_BOTTOM); 419 assertThat(mInsets).isNull(); 420 } 421 422 @Test testOnDisplayState_noListener()423 public void testOnDisplayState_noListener() { 424 mClusterHalService.takeProperties(getCoreProperties()); 425 mClusterHalService.setCallback(null); 426 427 mClusterHalService.onHalEvents(Arrays.asList( 428 createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM, 429 INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM))); 430 431 assertThat(mOnOff).isEqualTo(NOT_ASSIGNED); 432 assertThat(mBounds).isNull(); 433 assertThat(mInsets).isNull(); 434 } 435 436 @Test testOnDisplayState_noProperties()437 public void testOnDisplayState_noProperties() { 438 mClusterHalService.takeProperties(Arrays.asList()); 439 440 mClusterHalService.onHalEvents(Arrays.asList( 441 createDisplayStateEvent(ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM, 442 INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM))); 443 444 assertThat(mOnOff).isEqualTo(NOT_ASSIGNED); 445 assertThat(mBounds).isNull(); 446 assertThat(mInsets).isNull(); 447 } 448 449 @Test testReportState()450 public void testReportState() { 451 mClusterHalService.takeProperties(getCoreProperties()); 452 mClusterHalService.reportState( 453 ON, new Rect(BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM), 454 Insets.of(INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM), 455 UI_TYPE_1, UI_TYPE_2, UI_AVAILABILITY); 456 457 verify(mVehicleHal).set(mPropCaptor.capture()); 458 HalPropValue prop = mPropCaptor.getValue(); 459 assertThat(prop.getPropId()).isEqualTo(CLUSTER_REPORT_STATE); 460 assertThat(getIntValues(prop)).containsExactly( 461 ON, BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM, 462 INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM, UI_TYPE_1, UI_TYPE_2); 463 assertThat(prop.getByteArray()).asList().containsExactly( 464 (Byte) UI_AVAILABILITY[0], (Byte) UI_AVAILABILITY[1], (Byte) UI_AVAILABILITY[2]); 465 } 466 467 @Test testReportState_noProperties()468 public void testReportState_noProperties() { 469 mClusterHalService.takeProperties(Arrays.asList()); 470 471 assertThrows(IllegalStateException.class, 472 () -> mClusterHalService.reportState( 473 ON, new Rect(BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM), 474 Insets.of(INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM), 475 UI_TYPE_1, UI_TYPE_2, UI_AVAILABILITY)); 476 } 477 478 @Test testReportState_lightMode_fullProperties()479 public void testReportState_lightMode_fullProperties() { 480 ClusterHalService lightModeService = 481 createLightModeServiceWithProperties(getFullProperties()); 482 483 assertThrows(IllegalStateException.class, 484 () -> lightModeService.reportState( 485 ON, new Rect(BOUNDS_LEFT, BOUNDS_TOP, BOUNDS_RIGHT, BOUNDS_BOTTOM), 486 Insets.of(INSET_LEFT, INSET_TOP, INSET_RIGHT, INSET_BOTTOM), 487 UI_TYPE_1, UI_TYPE_2, UI_AVAILABILITY)); 488 } 489 490 @Test testRequestDisplay()491 public void testRequestDisplay() { 492 mClusterHalService.takeProperties(getCoreProperties()); 493 mClusterHalService.requestDisplay(UI_TYPE_2); 494 495 verify(mVehicleHal).set(mPropCaptor.capture()); 496 HalPropValue prop = mPropCaptor.getValue(); 497 assertThat(prop.getPropId()).isEqualTo(CLUSTER_REQUEST_DISPLAY); 498 assertThat(getIntValues(prop)).containsExactly(UI_TYPE_2); 499 } 500 501 @Test testRequestDisplay_noProperties()502 public void testRequestDisplay_noProperties() { 503 mClusterHalService.takeProperties(Arrays.asList()); 504 505 assertThrows(IllegalStateException.class, 506 () -> mClusterHalService.requestDisplay(UI_TYPE_2)); 507 } 508 509 @Test testRequestDisplay_lightMode_fullProperties()510 public void testRequestDisplay_lightMode_fullProperties() { 511 ClusterHalService lightModeService = 512 createLightModeServiceWithProperties(getFullProperties()); 513 514 assertThrows(IllegalStateException.class, 515 () -> lightModeService.requestDisplay(UI_TYPE_2)); 516 } 517 518 @Test testSendNavigationState()519 public void testSendNavigationState() { 520 mClusterHalService.takeProperties(getFullProperties()); 521 mClusterHalService.sendNavigationState(new byte[]{1, 2, 3, 4}); 522 523 verify(mVehicleHal).set(mPropCaptor.capture()); 524 HalPropValue prop = mPropCaptor.getValue(); 525 assertThat(prop.getPropId()).isEqualTo(CLUSTER_NAVIGATION_STATE); 526 assertThat(prop.getByteArray()).asList() 527 .containsExactly((byte) 1, (byte) 2, (byte) 3, (byte) 4); 528 } 529 530 @Test testSendNavigationState_noProperties()531 public void testSendNavigationState_noProperties() { 532 mClusterHalService.takeProperties(Arrays.asList()); 533 534 mClusterHalService.sendNavigationState(new byte[]{1, 2, 3, 4}); 535 536 verify(mVehicleHal, times(0)).set(mPropCaptor.capture()); 537 } 538 539 @Test testSendHeartbeat_noProperties()540 public void testSendHeartbeat_noProperties() { 541 mClusterHalService.takeProperties(Arrays.asList()); 542 543 mClusterHalService.sendHeartbeat(/* epochTimeNs= */ 0, /* visibility= */ 0, 544 /* appMetadata= */ null); 545 546 verify(mVehicleHal, times(0)).set(mPropCaptor.capture()); 547 } 548 549 @Test testSendHeartbeat()550 public void testSendHeartbeat() { 551 mClusterHalService.takeProperties(getFullProperties()); 552 553 long epochTimeNs = 123456789; 554 long visibility = 1; 555 byte[] appMetadata = new byte[]{3, 2, 0, 1}; 556 mClusterHalService.sendHeartbeat(epochTimeNs, visibility, appMetadata); 557 558 verify(mVehicleHal).set(mPropCaptor.capture()); 559 HalPropValue prop = mPropCaptor.getValue(); 560 assertThat(prop.getPropId()).isEqualTo(CLUSTER_HEARTBEAT); 561 assertThat(prop.getInt64ContainerArray()).asList() 562 .containsExactly((long) epochTimeNs, (long) visibility); 563 assertThat(prop.getByteArray()).asList() 564 .containsExactly((byte) 3, (byte) 2, (byte) 0, (byte) 1); 565 } 566 567 } 568