1 /* 2 * Copyright (C) 2018 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 package com.android.car.hal; 17 18 import static com.android.car.CarServiceUtils.toByteArray; 19 import static com.android.car.CarServiceUtils.toIntArray; 20 21 import static org.junit.Assert.assertArrayEquals; 22 import static org.junit.Assert.assertEquals; 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.anyInt; 25 import static org.mockito.Mockito.doThrow; 26 import static org.mockito.Mockito.reset; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.verifyNoMoreInteractions; 29 import static org.mockito.Mockito.when; 30 31 import android.car.hardware.property.VehicleHalStatusCode; 32 import android.car.test.util.TemporaryFile; 33 import android.car.vms.VmsAssociatedLayer; 34 import android.car.vms.VmsAvailableLayers; 35 import android.car.vms.VmsClient; 36 import android.car.vms.VmsClientManager.VmsClientCallback; 37 import android.car.vms.VmsLayer; 38 import android.car.vms.VmsLayerDependency; 39 import android.car.vms.VmsSubscriptionState; 40 import android.content.Context; 41 import android.content.res.Resources; 42 import android.hardware.automotive.vehicle.VehiclePropConfig; 43 import android.hardware.automotive.vehicle.VehicleProperty; 44 import android.hardware.automotive.vehicle.VehiclePropertyGroup; 45 import android.hardware.automotive.vehicle.VmsMessageType; 46 import android.os.Handler; 47 import android.os.ServiceSpecificException; 48 49 import com.android.car.R; 50 51 import org.junit.Before; 52 import org.junit.Test; 53 import org.junit.runner.RunWith; 54 import org.mockito.InOrder; 55 import org.mockito.Mock; 56 import org.mockito.Mockito; 57 import org.mockito.junit.MockitoJUnitRunner; 58 59 import java.io.FileDescriptor; 60 import java.io.FileInputStream; 61 import java.io.FileOutputStream; 62 import java.util.ArrayList; 63 import java.util.Arrays; 64 import java.util.Collections; 65 import java.util.HashSet; 66 import java.util.LinkedHashSet; 67 import java.util.List; 68 import java.util.Set; 69 import java.util.concurrent.CountDownLatch; 70 import java.util.concurrent.TimeUnit; 71 72 @RunWith(MockitoJUnitRunner.class) 73 public class VmsHalServiceTest { 74 private static final int LAYER_TYPE = 1; 75 private static final int LAYER_SUBTYPE = 2; 76 private static final int LAYER_VERSION = 3; 77 private static final VmsLayer LAYER = new VmsLayer(LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION); 78 private static final int PUBLISHER_ID = 12345; 79 private static final byte[] PAYLOAD = new byte[]{1, 2, 3, 4}; 80 private static final List<Byte> PAYLOAD_AS_LIST = Arrays.asList(new Byte[]{1, 2, 3, 4}); 81 private static final int CORE_ID = 54321; 82 private static final int CLIENT_ID = 98765; 83 84 private final HalPropValueBuilder mPropValueBuilder = new HalPropValueBuilder(/*isAidl=*/true); 85 86 @Mock 87 private Context mContext; 88 @Mock 89 private Resources mResources; 90 @Mock 91 private VehicleHal mVehicleHal; 92 @Mock 93 private VmsClient mVmsClient; 94 95 private VmsHalService mHalService; 96 private VmsClientCallback mEventCallback; 97 private int mVmsInitCount; 98 99 @Before setUp()100 public void setUp() throws Exception { 101 initHalService(true); 102 } 103 initHalService(boolean propagatePropertyException)104 private void initHalService(boolean propagatePropertyException) throws Exception { 105 mVmsInitCount = 0; 106 when(mContext.getResources()).thenReturn(mResources); 107 when(mVehicleHal.getHalPropValueBuilder()).thenReturn(mPropValueBuilder); 108 mHalService = new VmsHalService(mContext, mVehicleHal, () -> (long) CORE_ID, 109 this::initVmsClient, propagatePropertyException); 110 111 VehiclePropConfig propConfig = new VehiclePropConfig(); 112 propConfig.prop = VehicleProperty.VEHICLE_MAP_SERVICE; 113 HalPropConfig halPropConfig = new AidlHalPropConfig(propConfig); 114 mHalService.takeProperties(Collections.singleton(halPropConfig)); 115 116 when(mVmsClient.getAvailableLayers()).thenReturn( 117 new VmsAvailableLayers(Collections.emptySet(), 0)); 118 mHalService.init(); 119 waitForHandlerCompletion(); 120 121 // Verify START_SESSION message was sent 122 InOrder initOrder = Mockito.inOrder(mVehicleHal); 123 initOrder.verify(mVehicleHal).subscribePropertySafe(mHalService, 124 VehicleProperty.VEHICLE_MAP_SERVICE); 125 initOrder.verify(mVehicleHal).set(createHalMessage( 126 VmsMessageType.START_SESSION, // Message type 127 CORE_ID, // Core ID 128 -1)); // Client ID (unknown) 129 130 // Verify no more interections until handshake received 131 initOrder.verifyNoMoreInteractions(); 132 133 // Send START_SESSION response from client 134 sendHalMessage(createHalMessage( 135 VmsMessageType.START_SESSION, // Message type 136 CORE_ID, // Core ID 137 CLIENT_ID // Client ID 138 )); 139 waitForHandlerCompletion(); 140 141 initOrder.verify(mVehicleHal).set(createHalMessage( 142 VmsMessageType.AVAILABILITY_CHANGE, // Message type 143 0, // Sequence number 144 0)); // # of associated layers 145 146 147 waitForHandlerCompletion(); 148 initOrder.verifyNoMoreInteractions(); 149 assertEquals(1, mVmsInitCount); 150 reset(mVmsClient, mVehicleHal); 151 } 152 initVmsClient(Handler handler, VmsClientCallback callback)153 private VmsClient initVmsClient(Handler handler, VmsClientCallback callback) { 154 mEventCallback = callback; 155 mVmsInitCount++; 156 return mVmsClient; 157 } 158 159 @Test testCoreId_IntegerOverflow()160 public void testCoreId_IntegerOverflow() throws Exception { 161 when(mVehicleHal.getHalPropValueBuilder()).thenReturn(mPropValueBuilder); 162 mHalService = new VmsHalService(mContext, mVehicleHal, 163 () -> (long) Integer.MAX_VALUE + CORE_ID, this::initVmsClient, true); 164 165 VehiclePropConfig propConfig = new VehiclePropConfig(); 166 propConfig.prop = VehicleProperty.VEHICLE_MAP_SERVICE; 167 HalPropConfig halPropConfig = new AidlHalPropConfig(propConfig); 168 mHalService.takeProperties(Collections.singleton(halPropConfig)); 169 170 when(mVmsClient.getAvailableLayers()).thenReturn( 171 new VmsAvailableLayers(Collections.emptySet(), 0)); 172 mHalService.init(); 173 waitForHandlerCompletion(); 174 175 verify(mVehicleHal).set(createHalMessage( 176 VmsMessageType.START_SESSION, // Message type 177 CORE_ID, // Core ID 178 -1)); // Client ID (unknown) 179 } 180 181 @Test testTakeSupportedProperties()182 public void testTakeSupportedProperties() { 183 VehiclePropConfig vmsPropConfig = new VehiclePropConfig(); 184 vmsPropConfig.prop = VehicleProperty.VEHICLE_MAP_SERVICE; 185 HalPropConfig vmsHalPropConfig = new AidlHalPropConfig(vmsPropConfig); 186 187 VehiclePropConfig otherPropConfig = new VehiclePropConfig(); 188 otherPropConfig.prop = VehicleProperty.CURRENT_GEAR; 189 HalPropConfig otherHalPropConfig = new AidlHalPropConfig(otherPropConfig); 190 191 mHalService.takeProperties(Arrays.asList(vmsHalPropConfig, otherHalPropConfig)); 192 } 193 194 /** 195 * DATA message format: 196 * <ul> 197 * <li>Message type 198 * <li>Layer ID 199 * <li>Layer subtype 200 * <li>Layer version 201 * <li>Publisher ID 202 * <li>Payload 203 * </ul> 204 */ 205 @Test testHandleDataEvent()206 public void testHandleDataEvent() { 207 HalPropValue message = createHalMessage( 208 toByteArray(PAYLOAD_AS_LIST), 209 VmsMessageType.DATA, // Message type 210 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // VmsLayer 211 PUBLISHER_ID // PublisherId 212 ); 213 214 sendHalMessage(message); 215 verify(mVmsClient).publishPacket(PUBLISHER_ID, LAYER, PAYLOAD); 216 } 217 218 @Test testHandleInvalidEvent()219 public void testHandleInvalidEvent() { 220 // Invalid message with no message type. 221 HalPropValue message = mPropValueBuilder.build(VehicleProperty.VEHICLE_MAP_SERVICE, 222 /*areaId=*/0, "1234"); 223 224 sendHalMessage(message); 225 verify(mVmsClient, Mockito.never()).publishPacket( 226 Mockito.anyInt(), Mockito.any(), Mockito.any()); 227 228 // Incomplete VmsLayer. 229 ArrayList<Integer> int32Values = 230 new ArrayList<Integer>( 231 Arrays.asList(VmsMessageType.DATA, LAYER_TYPE, LAYER_SUBTYPE)); 232 message = mPropValueBuilder.build(VehicleProperty.VEHICLE_MAP_SERVICE, 233 /*areaId=*/0, /*timestamp=*/0, /*status=*/0, 234 /*int32Values=*/toIntArray(int32Values), /*floatValues=*/new float[0], 235 /*int64Values=*/new long[0], "1234", /*byteValues=*/new byte[0]); 236 237 sendHalMessage(message); 238 verify(mVmsClient, Mockito.never()).publishPacket( 239 Mockito.anyInt(), Mockito.any(), Mockito.any()); 240 241 // No publisher ID. 242 int32Values.add(LAYER_VERSION); 243 message = mPropValueBuilder.build(VehicleProperty.VEHICLE_MAP_SERVICE, 244 /*areaId=*/0, /*timestamp=*/0, /*status=*/0, 245 /*int32Values=*/toIntArray(int32Values), /*floatValues=*/new float[0], 246 /*int64Values=*/new long[0], "1234", /*byteValues=*/new byte[0]); 247 248 sendHalMessage(message); 249 verify(mVmsClient, Mockito.never()).publishPacket( 250 Mockito.anyInt(), Mockito.any(), Mockito.any()); 251 252 // No payload. 253 int32Values.add(PUBLISHER_ID); 254 message = mPropValueBuilder.build(VehicleProperty.VEHICLE_MAP_SERVICE, 255 /*areaId=*/0, /*timestamp=*/0, /*status=*/0, 256 /*int32Values=*/toIntArray(int32Values), /*floatValues=*/new float[0], 257 /*int64Values=*/new long[0], "1234", /*byteValues=*/new byte[0]); 258 259 sendHalMessage(message); 260 verify(mVmsClient, Mockito.never()).publishPacket( 261 Mockito.anyInt(), Mockito.any(), Mockito.any()); 262 263 // No payload for publisherID event. 264 int32Values.set(0, VmsMessageType.PUBLISHER_ID_REQUEST); 265 message = mPropValueBuilder.build(VehicleProperty.VEHICLE_MAP_SERVICE, 266 /*areaId=*/0, /*timestamp=*/0, /*status=*/0, 267 /*int32Values=*/toIntArray(int32Values), /*floatValues=*/new float[0], 268 /*int64Values=*/new long[0], "1234", /*byteValues=*/new byte[0]); 269 270 sendHalMessage(message); 271 verify(mVmsClient, Mockito.never()).publishPacket( 272 Mockito.anyInt(), Mockito.any(), Mockito.any()); 273 } 274 275 @Test testOnPacketReceivedEvent()276 public void testOnPacketReceivedEvent() throws Exception { 277 HalPropValue message = createHalMessage( 278 toByteArray(PAYLOAD_AS_LIST), 279 VmsMessageType.DATA, // Message type 280 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // VmsLayer 281 PUBLISHER_ID // PublisherId 282 ); 283 284 mEventCallback.onPacketReceived(PUBLISHER_ID, LAYER, PAYLOAD); 285 verify(mVehicleHal).set(message); 286 } 287 288 /** 289 * SUBSCRIBE message format: 290 * <ul> 291 * <li>Message type 292 * <li>Layer ID 293 * <li>Layer subtype 294 * <li>Layer version 295 * </ul> 296 */ 297 @Test testHandleSubscribeEvent()298 public void testHandleSubscribeEvent() { 299 HalPropValue message = createHalMessage( 300 VmsMessageType.SUBSCRIBE, // Message type 301 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION // VmsLayer 302 ); 303 304 sendHalMessage(message); 305 verify(mVmsClient).setSubscriptions(asSet(new VmsAssociatedLayer(LAYER, asSet()))); 306 } 307 308 /** 309 * SUBSCRIBE_TO_PUBLISHER message format: 310 * <ul> 311 * <li>Message type 312 * <li>Layer ID 313 * <li>Layer subtype 314 * <li>Layer version 315 * <li>Publisher ID 316 * </ul> 317 */ 318 @Test testHandleSubscribeToPublisherEvent()319 public void testHandleSubscribeToPublisherEvent() { 320 HalPropValue message = createHalMessage( 321 VmsMessageType.SUBSCRIBE_TO_PUBLISHER, // Message type 322 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // VmsLayer 323 PUBLISHER_ID // PublisherId 324 ); 325 326 sendHalMessage(message); 327 verify(mVmsClient).setSubscriptions(asSet( 328 new VmsAssociatedLayer(LAYER, asSet(PUBLISHER_ID)))); 329 } 330 331 /** 332 * UNSUBSCRIBE message format: 333 * <ul> 334 * <li>Message type 335 * <li>Layer ID 336 * <li>Layer subtype 337 * <li>Layer version 338 * </ul> 339 */ 340 @Test testHandleUnsubscribeEvent()341 public void testHandleUnsubscribeEvent() { 342 testHandleSubscribeEvent(); 343 344 HalPropValue message = createHalMessage( 345 VmsMessageType.UNSUBSCRIBE, // Message type 346 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION // VmsLayer 347 ); 348 349 sendHalMessage(message); 350 verify(mVmsClient).setSubscriptions(asSet()); 351 } 352 353 /** 354 * UNSUBSCRIBE_TO_PUBLISHER message format: 355 * <ul> 356 * <li>Message type 357 * <li>Layer ID 358 * <li>Layer subtype 359 * <li>Layer version 360 * <li>Publisher ID 361 * </ul> 362 */ 363 @Test testHandleUnsubscribeFromPublisherEvent()364 public void testHandleUnsubscribeFromPublisherEvent() { 365 testHandleSubscribeToPublisherEvent(); 366 367 HalPropValue message = createHalMessage( 368 VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER, // Message type 369 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // VmsLayer 370 PUBLISHER_ID // PublisherId 371 ); 372 373 sendHalMessage(message); 374 verify(mVmsClient).setSubscriptions(asSet()); 375 } 376 377 /** 378 * PUBLISHER_ID_REQUEST message format: 379 * <ul> 380 * <li>Message type 381 * <li>Publisher info (bytes) 382 * </ul> 383 * 384 * PUBLISHER_ID_RESPONSE message format: 385 * <ul> 386 * <li>Message type 387 * <li>Publisher ID 388 * </ul> 389 */ 390 @Test testHandlePublisherIdRequestEvent()391 public void testHandlePublisherIdRequestEvent() throws Exception { 392 HalPropValue request = createHalMessage( 393 toByteArray(PAYLOAD_AS_LIST), 394 VmsMessageType.PUBLISHER_ID_REQUEST // Message type 395 ); 396 397 when(mVmsClient.registerProvider(PAYLOAD)).thenReturn(PUBLISHER_ID); 398 399 HalPropValue response = createHalMessage( 400 VmsMessageType.PUBLISHER_ID_RESPONSE, // Message type 401 PUBLISHER_ID // Publisher ID 402 ); 403 404 sendHalMessage(request); 405 verify(mVehicleHal).set(response); 406 } 407 408 /** 409 * PUBLISHER_INFORMATION_REQUEST message format: 410 * <ul> 411 * <li>Message type 412 * <li>Publisher ID 413 * </ul> 414 * 415 * PUBLISHER_INFORMATION_RESPONSE message format: 416 * <ul> 417 * <li>Message type 418 * <li>Publisher info (bytes) 419 * </ul> 420 */ 421 @Test testHandlePublisherInformationRequestEvent()422 public void testHandlePublisherInformationRequestEvent() throws Exception { 423 HalPropValue request = createHalMessage( 424 VmsMessageType.PUBLISHER_INFORMATION_REQUEST, // Message type 425 PUBLISHER_ID // Publisher ID 426 ); 427 428 when(mVmsClient.getProviderDescription(PUBLISHER_ID)).thenReturn(PAYLOAD); 429 430 HalPropValue response = createHalMessage( 431 toByteArray(PAYLOAD_AS_LIST), 432 VmsMessageType.PUBLISHER_INFORMATION_RESPONSE // Message type 433 ); 434 435 sendHalMessage(request); 436 verify(mVehicleHal).set(response); 437 } 438 439 /** 440 * OFFERING message format: 441 * <ul> 442 * <li>Message type 443 * <li>Publisher ID 444 * <li>Number of offerings. 445 * <li>Offerings (x number of offerings) 446 * <ul> 447 * <li>Layer ID 448 * <li>Layer subtype 449 * <li>Layer version 450 * <li>Number of layer dependencies. 451 * <li>Layer dependencies (x number of layer dependencies) 452 * <ul> 453 * <li>Layer ID 454 * <li>Layer subtype 455 * <li>Layer version 456 * </ul> 457 * </ul> 458 * </ul> 459 */ 460 @Test testHandleOfferingEvent_ZeroOfferings()461 public void testHandleOfferingEvent_ZeroOfferings() { 462 HalPropValue message = createHalMessage( 463 VmsMessageType.OFFERING, // Message type 464 PUBLISHER_ID, // PublisherId 465 0 // # of offerings 466 ); 467 468 sendHalMessage(message); 469 verify(mVmsClient).setProviderOfferings(PUBLISHER_ID, asSet()); 470 } 471 472 @Test testHandleOfferingEvent_LayerOnly()473 public void testHandleOfferingEvent_LayerOnly() { 474 HalPropValue message = createHalMessage( 475 VmsMessageType.OFFERING, // Message type 476 PUBLISHER_ID, // PublisherId 477 1, // # of offerings 478 // Offered layer 479 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, 480 0 // # of dependencies 481 ); 482 483 sendHalMessage(message); 484 verify(mVmsClient).setProviderOfferings( 485 PUBLISHER_ID, 486 asSet(new VmsLayerDependency(LAYER))); 487 } 488 489 @Test testHandleOfferingEvent_LayerAndDependency()490 public void testHandleOfferingEvent_LayerAndDependency() { 491 HalPropValue message = createHalMessage( 492 VmsMessageType.OFFERING, // Message type 493 PUBLISHER_ID, // PublisherId 494 1, // # of offerings 495 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 496 1, // # of dependencies 497 4, 5, 6 // Dependency layer 498 ); 499 500 sendHalMessage(message); 501 verify(mVmsClient).setProviderOfferings( 502 PUBLISHER_ID, 503 asSet( 504 new VmsLayerDependency(LAYER, Collections.singleton( 505 new VmsLayer(4, 5, 6))))); 506 } 507 508 @Test testHandleOfferingEvent_MultipleLayersAndDependencies()509 public void testHandleOfferingEvent_MultipleLayersAndDependencies() { 510 HalPropValue message = createHalMessage( 511 VmsMessageType.OFFERING, // Message type 512 PUBLISHER_ID, // PublisherId 513 3, // # of offerings 514 // Offered layer #1 515 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 516 2, // # of dependencies 517 4, 5, 6, // Dependency layer 518 7, 8, 9, // Dependency layer 519 // Offered layer #2 520 3, 2, 1, // Layer 521 0, // # of dependencies 522 // Offered layer #3 523 6, 5, 4, // Layer 524 1, // # of dependencies 525 7, 8, 9 // Dependency layer 526 ); 527 528 sendHalMessage(message); 529 verify(mVmsClient).setProviderOfferings( 530 PUBLISHER_ID, 531 asSet( 532 new VmsLayerDependency(LAYER, new LinkedHashSet<>(Arrays.asList( 533 new VmsLayer(4, 5, 6), 534 new VmsLayer(7, 8, 9) 535 ))), 536 new VmsLayerDependency(new VmsLayer(3, 2, 1), Collections.emptySet()), 537 new VmsLayerDependency(new VmsLayer(6, 5, 4), Collections.singleton( 538 new VmsLayer(7, 8, 9) 539 )))); 540 } 541 542 /** 543 * AVAILABILITY_REQUEST message format: 544 * <ul> 545 * <li>Message type 546 * </ul> 547 * 548 * AVAILABILITY_RESPONSE message format: 549 * <ul> 550 * <li>Message type 551 * <li>Sequence number. 552 * <li>Number of associated layers. 553 * <li>Associated layers (x number of associated layers) 554 * <ul> 555 * <li>Layer ID 556 * <li>Layer subtype 557 * <li>Layer version 558 * <li>Number of publishers 559 * <li>Publisher ID (x number of publishers) 560 * </ul> 561 * </ul> 562 */ 563 @Test testHandleAvailabilityRequestEvent_ZeroLayers()564 public void testHandleAvailabilityRequestEvent_ZeroLayers() throws Exception { 565 HalPropValue request = createHalMessage( 566 VmsMessageType.AVAILABILITY_REQUEST // Message type 567 ); 568 569 when(mVmsClient.getAvailableLayers()).thenReturn( 570 new VmsAvailableLayers(Collections.emptySet(), 123)); 571 572 HalPropValue response = createHalMessage( 573 VmsMessageType.AVAILABILITY_RESPONSE, // Message type 574 123, // Sequence number 575 0 // # of associated layers 576 ); 577 578 sendHalMessage(request); 579 verify(mVehicleHal).set(response); 580 } 581 582 @Test testHandleAvailabilityRequestEvent_OneLayer()583 public void testHandleAvailabilityRequestEvent_OneLayer() throws Exception { 584 HalPropValue request = createHalMessage( 585 VmsMessageType.AVAILABILITY_REQUEST // Message type 586 ); 587 588 when(mVmsClient.getAvailableLayers()).thenReturn( 589 new VmsAvailableLayers(Collections.singleton( 590 new VmsAssociatedLayer(LAYER, Collections.singleton(PUBLISHER_ID))), 123)); 591 592 HalPropValue response = createHalMessage( 593 VmsMessageType.AVAILABILITY_RESPONSE, // Message type 594 123, // Sequence number 595 1, // # of associated layers 596 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 597 1, // # of publisher IDs 598 PUBLISHER_ID // Publisher ID 599 ); 600 601 sendHalMessage(request); 602 verify(mVehicleHal).set(response); 603 } 604 605 606 @Test testHandleAvailabilityRequestEvent_MultipleLayers()607 public void testHandleAvailabilityRequestEvent_MultipleLayers() throws Exception { 608 HalPropValue request = createHalMessage( 609 VmsMessageType.AVAILABILITY_REQUEST // Message type 610 ); 611 612 when(mVmsClient.getAvailableLayers()).thenReturn( 613 new VmsAvailableLayers(new LinkedHashSet<>(Arrays.asList( 614 new VmsAssociatedLayer(LAYER, 615 new LinkedHashSet<>(Arrays.asList(PUBLISHER_ID, 54321))), 616 new VmsAssociatedLayer(new VmsLayer(3, 2, 1), 617 Collections.emptySet()), 618 new VmsAssociatedLayer(new VmsLayer(6, 5, 4), 619 Collections.singleton(99999)))), 620 123)); 621 622 HalPropValue response = createHalMessage( 623 VmsMessageType.AVAILABILITY_RESPONSE, // Message type 624 123, // Sequence number 625 3, // # of associated layers 626 // Associated layer #1 627 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 628 2, // # of publisher IDs 629 PUBLISHER_ID, // Publisher ID 630 54321, // Publisher ID #2 631 // Associated layer #2 632 3, 2, 1, // Layer 633 0, // # of publisher IDs 634 // Associated layer #3 635 6, 5, 4, // Layer 636 1, // # of publisher IDs 637 99999 // Publisher ID 638 639 ); 640 641 sendHalMessage(request); 642 verify(mVehicleHal).set(response); 643 } 644 645 /** 646 * START_SESSION message format: 647 * <ul> 648 * <li>Message type 649 * <li>Core ID 650 * <li>Client ID 651 * </ul> 652 */ 653 @Test testHandleStartSessionEvent()654 public void testHandleStartSessionEvent() throws Exception { 655 when(mVmsClient.getAvailableLayers()).thenReturn( 656 new VmsAvailableLayers(Collections.emptySet(), 5)); 657 658 HalPropValue request = createHalMessage( 659 VmsMessageType.START_SESSION, // Message type 660 -1, // Core ID (unknown) 661 CLIENT_ID // Client ID 662 ); 663 664 HalPropValue response = createHalMessage( 665 VmsMessageType.START_SESSION, // Message type 666 CORE_ID, // Core ID 667 CLIENT_ID // Client ID 668 ); 669 670 sendHalMessage(request); 671 672 InOrder inOrder = Mockito.inOrder(mVehicleHal, mVmsClient); 673 inOrder.verify(mVmsClient).unregister(); 674 inOrder.verify(mVehicleHal).set(response); 675 assertEquals(2, mVmsInitCount); 676 677 waitForHandlerCompletion(); 678 inOrder.verify(mVehicleHal).set(createHalMessage( 679 VmsMessageType.AVAILABILITY_CHANGE, // Message type 680 5, // Sequence number 681 0)); // # of associated layers 682 683 } 684 685 /** 686 * AVAILABILITY_CHANGE message format: 687 * <ul> 688 * <li>Message type 689 * <li>Sequence number. 690 * <li>Number of associated layers. 691 * <li>Associated layers (x number of associated layers) 692 * <ul> 693 * <li>Layer ID 694 * <li>Layer subtype 695 * <li>Layer version 696 * <li>Number of publishers 697 * <li>Publisher ID (x number of publishers) 698 * </ul> 699 * </ul> 700 */ 701 @Test testOnLayersAvailabilityChanged_ZeroLayers()702 public void testOnLayersAvailabilityChanged_ZeroLayers() throws Exception { 703 mEventCallback.onLayerAvailabilityChanged( 704 new VmsAvailableLayers(Collections.emptySet(), 123)); 705 706 HalPropValue message = createHalMessage( 707 VmsMessageType.AVAILABILITY_CHANGE, // Message type 708 123, // Sequence number 709 0 // # of associated layers 710 ); 711 712 waitForHandlerCompletion(); 713 verify(mVehicleHal).set(message); 714 } 715 716 @Test testOnLayersAvailabilityChanged_OneLayer()717 public void testOnLayersAvailabilityChanged_OneLayer() throws Exception { 718 mEventCallback.onLayerAvailabilityChanged( 719 new VmsAvailableLayers(Collections.singleton( 720 new VmsAssociatedLayer(LAYER, Collections.singleton(PUBLISHER_ID))), 123)); 721 722 HalPropValue message = createHalMessage( 723 VmsMessageType.AVAILABILITY_CHANGE, // Message type 724 123, // Sequence number 725 1, // # of associated layers 726 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 727 1, // # of publisher IDs 728 PUBLISHER_ID // Publisher ID 729 ); 730 731 waitForHandlerCompletion(); 732 verify(mVehicleHal).set(message); 733 } 734 735 736 @Test testOnLayersAvailabilityChanged_MultipleLayers()737 public void testOnLayersAvailabilityChanged_MultipleLayers() throws Exception { 738 mEventCallback.onLayerAvailabilityChanged( 739 new VmsAvailableLayers(new LinkedHashSet<>(Arrays.asList( 740 new VmsAssociatedLayer(LAYER, 741 new LinkedHashSet<>(Arrays.asList(PUBLISHER_ID, 54321))), 742 new VmsAssociatedLayer(new VmsLayer(3, 2, 1), 743 Collections.emptySet()), 744 new VmsAssociatedLayer(new VmsLayer(6, 5, 4), 745 Collections.singleton(99999)))), 746 123)); 747 748 HalPropValue message = createHalMessage( 749 VmsMessageType.AVAILABILITY_CHANGE, // Message type 750 123, // Sequence number 751 3, // # of associated layers 752 // Associated layer #1 753 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 754 2, // # of publisher IDs 755 PUBLISHER_ID, // Publisher ID 756 54321, // Publisher ID #2 757 // Associated layer #2 758 3, 2, 1, // Layer 759 0, // # of publisher IDs 760 // Associated layer #3 761 6, 5, 4, // Layer 762 1, // # of publisher IDs 763 99999 // Publisher ID 764 765 ); 766 767 waitForHandlerCompletion(); 768 verify(mVehicleHal).set(message); 769 } 770 771 /** 772 * SUBSCRIPTION_REQUEST message format: 773 * <ul> 774 * <li>Message type 775 * </ul> 776 * 777 * SUBSCRIPTION_RESPONSE message format: 778 * <ul> 779 * <li>Message type 780 * <li>Sequence number 781 * <li>Number of layers 782 * <li>Number of associated layers 783 * <li>Layers (x number of layers) 784 * <ul> 785 * <li>Layer ID 786 * <li>Layer subtype 787 * <li>Layer version 788 * </ul> 789 * <li>Associated layers (x number of associated layers) 790 * <ul> 791 * <li>Layer ID 792 * <li>Layer subtype 793 * <li>Layer version 794 * <li>Number of publishers 795 * <li>Publisher ID (x number of publishers) 796 * </ul> 797 * </ul> 798 */ 799 @Test testHandleSubscriptionsRequestEvent_ZeroLayers()800 public void testHandleSubscriptionsRequestEvent_ZeroLayers() throws Exception { 801 HalPropValue request = createHalMessage( 802 VmsMessageType.SUBSCRIPTIONS_REQUEST // Message type 803 ); 804 805 when(mVmsClient.getSubscriptionState()).thenReturn( 806 new VmsSubscriptionState(123, Collections.emptySet(), Collections.emptySet())); 807 808 HalPropValue response = createHalMessage( 809 VmsMessageType.SUBSCRIPTIONS_RESPONSE, // Message type 810 123, // Sequence number 811 0, // # of layers 812 0 // # of associated layers 813 ); 814 815 sendHalMessage(request); 816 verify(mVehicleHal).set(response); 817 } 818 819 @Test testHandleSubscriptionsRequestEvent_OneLayer_ZeroAssociatedLayers()820 public void testHandleSubscriptionsRequestEvent_OneLayer_ZeroAssociatedLayers() 821 throws Exception { 822 HalPropValue request = createHalMessage( 823 VmsMessageType.SUBSCRIPTIONS_REQUEST // Message type 824 ); 825 826 when(mVmsClient.getSubscriptionState()).thenReturn( 827 new VmsSubscriptionState(123, Collections.singleton(LAYER), 828 Collections.emptySet())); 829 830 HalPropValue response = createHalMessage( 831 VmsMessageType.SUBSCRIPTIONS_RESPONSE, // Message type 832 123, // Sequence number 833 1, // # of layers 834 0, // # of associated layers 835 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION // Layer 836 ); 837 838 sendHalMessage(request); 839 verify(mVehicleHal).set(response); 840 } 841 842 @Test testHandleSubscriptionsRequestEvent_ZeroLayers_OneAssociatedLayer()843 public void testHandleSubscriptionsRequestEvent_ZeroLayers_OneAssociatedLayer() 844 throws Exception { 845 HalPropValue request = createHalMessage( 846 VmsMessageType.SUBSCRIPTIONS_REQUEST // Message type 847 ); 848 849 when(mVmsClient.getSubscriptionState()).thenReturn( 850 new VmsSubscriptionState(123, Collections.emptySet(), Collections.singleton( 851 new VmsAssociatedLayer(LAYER, Collections.singleton(PUBLISHER_ID))))); 852 853 HalPropValue response = createHalMessage( 854 VmsMessageType.SUBSCRIPTIONS_RESPONSE, // Message type 855 123, // Sequence number 856 0, // # of layers 857 1, // # of associated layers 858 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 859 1, // # of publisher IDs 860 PUBLISHER_ID // Publisher ID 861 ); 862 863 sendHalMessage(request); 864 verify(mVehicleHal).set(response); 865 } 866 867 @Test testHandleSubscriptionsRequestEvent_MultipleLayersAndAssociatedLayers()868 public void testHandleSubscriptionsRequestEvent_MultipleLayersAndAssociatedLayers() 869 throws Exception { 870 HalPropValue request = createHalMessage( 871 VmsMessageType.SUBSCRIPTIONS_REQUEST // Message type 872 ); 873 874 when(mVmsClient.getSubscriptionState()).thenReturn( 875 new VmsSubscriptionState(123, 876 new LinkedHashSet<>(Arrays.asList( 877 LAYER, 878 new VmsLayer(4, 5, 6), 879 new VmsLayer(7, 8, 9) 880 )), 881 new LinkedHashSet<>(Arrays.asList( 882 new VmsAssociatedLayer(LAYER, Collections.emptySet()), 883 new VmsAssociatedLayer(new VmsLayer(6, 5, 4), 884 new LinkedHashSet<>(Arrays.asList( 885 PUBLISHER_ID, 886 54321)))))) 887 ); 888 889 HalPropValue response = createHalMessage( 890 VmsMessageType.SUBSCRIPTIONS_RESPONSE, // Message type 891 123, // Sequence number 892 3, // # of layers 893 2, // # of associated layers 894 // Layer #1 895 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 896 // Layer #2 897 4, 5, 6, // Layer 898 // Layer #3 899 7, 8, 9, // Layer 900 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 901 0, // # of publisher IDs 902 6, 5, 4, // Layer 903 2, // # of publisher IDs 904 PUBLISHER_ID, // Publisher ID 905 54321 // Publisher ID #2 906 ); 907 908 sendHalMessage(request); 909 verify(mVehicleHal).set(response); 910 } 911 912 /** 913 * SUBSCRIPTIONS_CHANGE message format: 914 * <ul> 915 * <li>Message type 916 * <li>Sequence number 917 * <li>Number of layers 918 * <li>Number of associated layers 919 * <li>Layers (x number of layers) 920 * <ul> 921 * <li>Layer ID 922 * <li>Layer subtype 923 * <li>Layer version 924 * </ul> 925 * <li>Associated layers (x number of associated layers) 926 * <ul> 927 * <li>Layer ID 928 * <li>Layer subtype 929 * <li>Layer version 930 * <li>Number of publishers 931 * <li>Publisher ID (x number of publishers) 932 * </ul> 933 * </ul> 934 */ 935 @Test testOnVmsSubscriptionChange_ZeroLayers()936 public void testOnVmsSubscriptionChange_ZeroLayers() throws Exception { 937 mEventCallback.onSubscriptionStateChanged( 938 new VmsSubscriptionState(123, Collections.emptySet(), Collections.emptySet())); 939 940 HalPropValue response = createHalMessage( 941 VmsMessageType.SUBSCRIPTIONS_CHANGE, // Message type 942 123, // Sequence number 943 0, // # of layers 944 0 // # of associated layers 945 ); 946 947 waitForHandlerCompletion(); 948 verify(mVehicleHal).set(response); 949 } 950 951 @Test testOnVmsSubscriptionChange_OneLayer_ZeroAssociatedLayers()952 public void testOnVmsSubscriptionChange_OneLayer_ZeroAssociatedLayers() 953 throws Exception { 954 mEventCallback.onSubscriptionStateChanged( 955 new VmsSubscriptionState(123, Collections.singleton(LAYER), 956 Collections.emptySet())); 957 958 HalPropValue response = createHalMessage( 959 VmsMessageType.SUBSCRIPTIONS_CHANGE, // Message type 960 123, // Sequence number 961 1, // # of layers 962 0, // # of associated layers 963 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION // Layer 964 ); 965 966 waitForHandlerCompletion(); 967 verify(mVehicleHal).set(response); 968 } 969 970 @Test testOnVmsSubscriptionChange_ZeroLayers_OneAssociatedLayer()971 public void testOnVmsSubscriptionChange_ZeroLayers_OneAssociatedLayer() 972 throws Exception { 973 mEventCallback.onSubscriptionStateChanged( 974 new VmsSubscriptionState(123, Collections.emptySet(), Collections.singleton( 975 new VmsAssociatedLayer(LAYER, Collections.singleton(PUBLISHER_ID))))); 976 977 HalPropValue response = createHalMessage( 978 VmsMessageType.SUBSCRIPTIONS_CHANGE, // Message type 979 123, // Sequence number 980 0, // # of layers 981 1, // # of associated layers 982 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 983 1, // # of publisher IDs 984 PUBLISHER_ID // Publisher ID 985 ); 986 987 waitForHandlerCompletion(); 988 verify(mVehicleHal).set(response); 989 } 990 991 @Test testOnVmsSubscriptionChange_MultipleLayersAndAssociatedLayers()992 public void testOnVmsSubscriptionChange_MultipleLayersAndAssociatedLayers() 993 throws Exception { 994 mEventCallback.onSubscriptionStateChanged( 995 new VmsSubscriptionState(123, 996 new LinkedHashSet<>(Arrays.asList( 997 LAYER, 998 new VmsLayer(4, 5, 6), 999 new VmsLayer(7, 8, 9) 1000 )), 1001 new LinkedHashSet<>(Arrays.asList( 1002 new VmsAssociatedLayer(LAYER, Collections.emptySet()), 1003 new VmsAssociatedLayer(new VmsLayer(6, 5, 4), 1004 new LinkedHashSet<>(Arrays.asList( 1005 PUBLISHER_ID, 1006 54321)))))) 1007 ); 1008 1009 HalPropValue response = createHalMessage( 1010 VmsMessageType.SUBSCRIPTIONS_CHANGE, // Message type 1011 123, // Sequence number 1012 3, // # of layers 1013 2, // # of associated layers 1014 // Layer #1 1015 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 1016 // Layer #2 1017 4, 5, 6, // Layer 1018 // Layer #3 1019 7, 8, 9, // Layer 1020 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 1021 0, // # of publisher IDs 1022 6, 5, 4, // Layer 1023 2, // # of publisher IDs 1024 PUBLISHER_ID, // Publisher ID 1025 54321 // Publisher ID #2 1026 ); 1027 1028 waitForHandlerCompletion(); 1029 verify(mVehicleHal).set(response); 1030 } 1031 1032 @Test testPropertySetExceptionNotPropagated_CoreStartSession()1033 public void testPropertySetExceptionNotPropagated_CoreStartSession() throws Exception { 1034 doThrow(new RuntimeException()).when(mVehicleHal).set(any()); 1035 initHalService(false); 1036 1037 waitForHandlerCompletion(); 1038 } 1039 1040 @Test testPropertySetExceptionNotPropagated_ClientStartSession()1041 public void testPropertySetExceptionNotPropagated_ClientStartSession() throws Exception { 1042 initHalService(false); 1043 1044 when(mVmsClient.getAvailableLayers()).thenReturn( 1045 new VmsAvailableLayers(Collections.emptySet(), 0)); 1046 doThrow(new RuntimeException()).when(mVehicleHal).set(any()); 1047 1048 HalPropValue request = createHalMessage( 1049 VmsMessageType.START_SESSION, // Message type 1050 -1, // Core ID (unknown) 1051 CLIENT_ID // Client ID 1052 ); 1053 1054 sendHalMessage(request); 1055 waitForHandlerCompletion(); 1056 } 1057 1058 @Test testDumpMetrics_DefaultConfig()1059 public void testDumpMetrics_DefaultConfig() { 1060 mHalService.dumpMetrics(new FileDescriptor()); 1061 verifyNoMoreInteractions(mVehicleHal); 1062 } 1063 1064 @Test testDumpMetrics_NonVendorProperty()1065 public void testDumpMetrics_NonVendorProperty() throws Exception { 1066 HalPropValue vehicleProp = mPropValueBuilder.build(/* prop= */ 0, /* areaId= */ 0, 1067 toByteArray(PAYLOAD_AS_LIST)); 1068 when(mVehicleHal.get(anyInt())).thenReturn(vehicleProp); 1069 1070 when(mResources.getInteger( 1071 R.integer.vmsHalClientMetricsProperty)).thenReturn( 1072 VehicleProperty.VEHICLE_MAP_SERVICE); 1073 setUp(); 1074 1075 mHalService.dumpMetrics(new FileDescriptor()); 1076 verifyNoMoreInteractions(mVehicleHal); 1077 } 1078 1079 @Test testDumpMetrics_VendorProperty()1080 public void testDumpMetrics_VendorProperty() throws Exception { 1081 int metricsPropertyId = VehiclePropertyGroup.VENDOR | 1; 1082 when(mResources.getInteger( 1083 R.integer.vmsHalClientMetricsProperty)).thenReturn( 1084 metricsPropertyId); 1085 setUp(); 1086 1087 HalPropValue metricsProperty = mPropValueBuilder.build(/* prop= */ 0, /* areaId= */ 0, 1088 toByteArray(PAYLOAD_AS_LIST)); 1089 when(mVehicleHal.get(metricsPropertyId)).thenReturn(metricsProperty); 1090 1091 try (TemporaryFile dumpsysFile = new TemporaryFile("VmsHalServiceTest")) { 1092 try (FileOutputStream outputStream = new FileOutputStream(dumpsysFile.getFile())) { 1093 mHalService.dumpMetrics(outputStream.getFD()); 1094 verify(mVehicleHal).get(metricsPropertyId); 1095 } 1096 1097 try (FileInputStream inputStream = new FileInputStream(dumpsysFile.getFile())) { 1098 byte[] dumpsysOutput = new byte[PAYLOAD.length]; 1099 assertEquals(PAYLOAD.length, inputStream.read(dumpsysOutput)); 1100 assertArrayEquals(PAYLOAD, dumpsysOutput); 1101 } 1102 } 1103 } 1104 1105 @Test testDumpMetrics_VendorProperty_Timeout()1106 public void testDumpMetrics_VendorProperty_Timeout() throws Exception { 1107 int metricsPropertyId = VehiclePropertyGroup.VENDOR | 1; 1108 when(mResources.getInteger( 1109 R.integer.vmsHalClientMetricsProperty)).thenReturn( 1110 metricsPropertyId); 1111 setUp(); 1112 1113 when(mVehicleHal.get(metricsPropertyId)) 1114 .thenThrow(new ServiceSpecificException(VehicleHalStatusCode.STATUS_TRY_AGAIN, 1115 "propertyId: 0x" + Integer.toHexString(metricsPropertyId))); 1116 1117 mHalService.dumpMetrics(new FileDescriptor()); 1118 verify(mVehicleHal).get(metricsPropertyId); 1119 } 1120 1121 @Test testDumpMetrics_VendorProperty_Unavailable()1122 public void testDumpMetrics_VendorProperty_Unavailable() throws Exception { 1123 int metricsPropertyId = VehiclePropertyGroup.VENDOR | 1; 1124 when(mResources.getInteger( 1125 R.integer.vmsHalClientMetricsProperty)).thenReturn( 1126 metricsPropertyId); 1127 setUp(); 1128 1129 when(mVehicleHal.get(metricsPropertyId)).thenReturn(null); 1130 1131 mHalService.dumpMetrics(new FileDescriptor()); 1132 verify(mVehicleHal).get(metricsPropertyId); 1133 } 1134 createHalMessage(Integer... message)1135 private HalPropValue createHalMessage(Integer... message) { 1136 HalPropValue result = mPropValueBuilder.build(VehicleProperty.VEHICLE_MAP_SERVICE, 1137 /*areaId=*/0, toIntArray(Arrays.asList(message))); 1138 return result; 1139 } 1140 createHalMessage(byte[] payload, Integer... message)1141 private HalPropValue createHalMessage(byte[] payload, Integer... message) { 1142 HalPropValue result = mPropValueBuilder.build( 1143 VehicleProperty.VEHICLE_MAP_SERVICE, 1144 /*areaId=*/0, /*timestamp=*/0, /*status=*/0, 1145 /*int32Values=*/toIntArray(Arrays.asList(message)), /*floatValues=*/new float[0], 1146 /*int64Values=*/new long[0], /*stringValue=*/new String(), /*byteValues=*/payload); 1147 return result; 1148 } 1149 sendHalMessage(HalPropValue message)1150 private void sendHalMessage(HalPropValue message) { 1151 mHalService.onHalEvents(Collections.singletonList(message)); 1152 } 1153 waitForHandlerCompletion()1154 private void waitForHandlerCompletion() throws Exception { 1155 final CountDownLatch latch = new CountDownLatch(1); 1156 mHalService.getHandler().post(latch::countDown); 1157 latch.await(5, TimeUnit.SECONDS); 1158 } 1159 1160 @SafeVarargs asSet(T... values)1161 private static <T> Set<T> asSet(T... values) { 1162 return new HashSet<>(Arrays.asList(values)); 1163 } 1164 } 1165