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 org.junit.Assert.assertEquals; 19 import static org.mockito.Mockito.reset; 20 import static org.mockito.Mockito.verify; 21 import static org.mockito.Mockito.when; 22 23 import android.car.vms.IVmsPublisherClient; 24 import android.car.vms.IVmsPublisherService; 25 import android.car.vms.IVmsSubscriberClient; 26 import android.car.vms.IVmsSubscriberService; 27 import android.car.vms.VmsAssociatedLayer; 28 import android.car.vms.VmsAvailableLayers; 29 import android.car.vms.VmsLayer; 30 import android.car.vms.VmsLayerDependency; 31 import android.car.vms.VmsLayersOffering; 32 import android.car.vms.VmsSubscriptionState; 33 import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig; 34 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; 35 import android.hardware.automotive.vehicle.V2_0.VehicleProperty; 36 import android.hardware.automotive.vehicle.V2_0.VmsMessageType; 37 import android.os.Binder; 38 import android.os.IBinder; 39 40 import org.junit.Before; 41 import org.junit.Rule; 42 import org.junit.Test; 43 import org.mockito.ArgumentCaptor; 44 import org.mockito.InOrder; 45 import org.mockito.Mock; 46 import org.mockito.Mockito; 47 import org.mockito.junit.MockitoJUnit; 48 import org.mockito.junit.MockitoRule; 49 50 import java.util.Arrays; 51 import java.util.Collections; 52 import java.util.LinkedHashSet; 53 import java.util.List; 54 import java.util.concurrent.CountDownLatch; 55 import java.util.concurrent.TimeUnit; 56 import java.util.function.Consumer; 57 58 public class VmsHalServiceTest { 59 private static final int LAYER_TYPE = 1; 60 private static final int LAYER_SUBTYPE = 2; 61 private static final int LAYER_VERSION = 3; 62 private static final VmsLayer LAYER = new VmsLayer(LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION); 63 private static final int PUBLISHER_ID = 12345; 64 private static final byte[] PAYLOAD = new byte[]{1, 2, 3, 4}; 65 private static final List<Byte> PAYLOAD_AS_LIST = Arrays.asList(new Byte[]{1, 2, 3, 4}); 66 private static final int CORE_ID = 54321; 67 private static final int CLIENT_ID = 98765; 68 69 @Rule 70 public MockitoRule mockito = MockitoJUnit.rule(); 71 @Mock 72 private VehicleHal mVehicleHal; 73 @Mock 74 private IVmsPublisherService mPublisherService; 75 @Mock 76 private IVmsSubscriberService mSubscriberService; 77 @Mock 78 private Consumer<IBinder> mPublisherOnHalConnected; 79 @Mock 80 private Runnable mPublisherOnHalDisconnected; 81 @Mock 82 private Consumer<IVmsSubscriberClient> mSubscriberOnHalDisconnected; 83 84 private IBinder mToken; 85 private VmsHalService mHalService; 86 private IVmsPublisherClient mPublisherClient; 87 private IVmsSubscriberClient mSubscriberClient; 88 89 @Before setUp()90 public void setUp() throws Exception { 91 mHalService = new VmsHalService(mVehicleHal, () -> (long) CORE_ID); 92 mHalService.setPublisherConnectionCallbacks( 93 mPublisherOnHalConnected, mPublisherOnHalDisconnected); 94 mHalService.setVmsSubscriberService(mSubscriberService, mSubscriberOnHalDisconnected); 95 96 VehiclePropConfig propConfig = new VehiclePropConfig(); 97 propConfig.prop = VehicleProperty.VEHICLE_MAP_SERVICE; 98 mHalService.takeSupportedProperties(Collections.singleton(propConfig)); 99 100 when(mSubscriberService.getAvailableLayers()).thenReturn( 101 new VmsAvailableLayers(Collections.emptySet(), 0)); 102 mHalService.init(); 103 waitForHandlerCompletion(); 104 105 // Verify START_SESSION message was sent 106 InOrder initOrder = 107 Mockito.inOrder(mPublisherOnHalConnected, mSubscriberService, mVehicleHal); 108 initOrder.verify(mVehicleHal).subscribeProperty(mHalService, 109 VehicleProperty.VEHICLE_MAP_SERVICE); 110 initOrder.verify(mVehicleHal).set(createHalMessage( 111 VmsMessageType.START_SESSION, // Message type 112 CORE_ID, // Core ID 113 -1)); // Client ID (unknown) 114 115 // Verify no more interections until handshake received 116 initOrder.verifyNoMoreInteractions(); 117 118 // Send START_SESSION response from client 119 sendHalMessage(createHalMessage( 120 VmsMessageType.START_SESSION, // Message type 121 0, // Core ID (unknown) 122 CLIENT_ID // Client ID 123 )); 124 waitForHandlerCompletion(); 125 126 // Verify client is marked as connected 127 ArgumentCaptor<IBinder> publisherCaptor = ArgumentCaptor.forClass(IBinder.class); 128 initOrder.verify(mPublisherOnHalConnected).accept(publisherCaptor.capture()); 129 mPublisherClient = IVmsPublisherClient.Stub.asInterface(publisherCaptor.getValue()); 130 131 mToken = new Binder(); 132 mPublisherClient.setVmsPublisherService(mToken, mPublisherService); 133 134 ArgumentCaptor<IVmsSubscriberClient> subscriberCaptor = ArgumentCaptor.forClass( 135 IVmsSubscriberClient.class); 136 initOrder.verify(mSubscriberService).addVmsSubscriberToNotifications( 137 subscriberCaptor.capture()); 138 mSubscriberClient = subscriberCaptor.getValue(); 139 140 initOrder.verify(mSubscriberService).getAvailableLayers(); 141 initOrder.verify(mVehicleHal).set(createHalMessage( 142 VmsMessageType.AVAILABILITY_CHANGE, // Message type 143 0, // Sequence number 144 0)); // # of associated layers 145 146 initOrder.verifyNoMoreInteractions(); 147 reset(mPublisherOnHalConnected, mSubscriberService, mVehicleHal); 148 } 149 150 @Test testCoreId_IntegerOverflow()151 public void testCoreId_IntegerOverflow() throws Exception { 152 mHalService = new VmsHalService(mVehicleHal, () -> (long) Integer.MAX_VALUE + CORE_ID); 153 154 VehiclePropConfig propConfig = new VehiclePropConfig(); 155 propConfig.prop = VehicleProperty.VEHICLE_MAP_SERVICE; 156 mHalService.takeSupportedProperties(Collections.singleton(propConfig)); 157 158 when(mSubscriberService.getAvailableLayers()).thenReturn( 159 new VmsAvailableLayers(Collections.emptySet(), 0)); 160 mHalService.init(); 161 waitForHandlerCompletion(); 162 163 verify(mVehicleHal).set(createHalMessage( 164 VmsMessageType.START_SESSION, // Message type 165 CORE_ID, // Core ID 166 -1)); // Client ID (unknown) 167 } 168 169 @Test testTakeSupportedProperties()170 public void testTakeSupportedProperties() { 171 VehiclePropConfig vmsPropConfig = new VehiclePropConfig(); 172 vmsPropConfig.prop = VehicleProperty.VEHICLE_MAP_SERVICE; 173 174 VehiclePropConfig otherPropConfig = new VehiclePropConfig(); 175 otherPropConfig.prop = VehicleProperty.CURRENT_GEAR; 176 177 assertEquals(Collections.singleton(vmsPropConfig), 178 mHalService.takeSupportedProperties(Arrays.asList(otherPropConfig, vmsPropConfig))); 179 } 180 181 /** 182 * DATA message format: 183 * <ul> 184 * <li>Message type 185 * <li>Layer ID 186 * <li>Layer subtype 187 * <li>Layer version 188 * <li>Publisher ID 189 * <li>Payload 190 * </ul> 191 */ 192 @Test testHandleDataEvent()193 public void testHandleDataEvent() throws Exception { 194 VehiclePropValue message = createHalMessage( 195 VmsMessageType.DATA, // Message type 196 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // VmsLayer 197 PUBLISHER_ID // PublisherId 198 ); 199 message.value.bytes.addAll(PAYLOAD_AS_LIST); 200 201 sendHalMessage(message); 202 verify(mPublisherService).publish(mToken, LAYER, PUBLISHER_ID, PAYLOAD); 203 } 204 205 /** 206 * SUBSCRIBE message format: 207 * <ul> 208 * <li>Message type 209 * <li>Layer ID 210 * <li>Layer subtype 211 * <li>Layer version 212 * </ul> 213 */ 214 @Test testHandleSubscribeEvent()215 public void testHandleSubscribeEvent() throws Exception { 216 VehiclePropValue message = createHalMessage( 217 VmsMessageType.SUBSCRIBE, // Message type 218 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION // VmsLayer 219 ); 220 221 sendHalMessage(message); 222 verify(mSubscriberService).addVmsSubscriber(mSubscriberClient, LAYER); 223 } 224 225 /** 226 * SUBSCRIBE_TO_PUBLISHER message format: 227 * <ul> 228 * <li>Message type 229 * <li>Layer ID 230 * <li>Layer subtype 231 * <li>Layer version 232 * <li>Publisher ID 233 * </ul> 234 */ 235 @Test testHandleSubscribeToPublisherEvent()236 public void testHandleSubscribeToPublisherEvent() throws Exception { 237 VehiclePropValue message = createHalMessage( 238 VmsMessageType.SUBSCRIBE_TO_PUBLISHER, // Message type 239 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // VmsLayer 240 PUBLISHER_ID // PublisherId 241 ); 242 243 sendHalMessage(message); 244 verify(mSubscriberService).addVmsSubscriberToPublisher(mSubscriberClient, LAYER, 245 PUBLISHER_ID); 246 } 247 248 /** 249 * UNSUBSCRIBE message format: 250 * <ul> 251 * <li>Message type 252 * <li>Layer ID 253 * <li>Layer subtype 254 * <li>Layer version 255 * </ul> 256 */ 257 @Test testHandleUnsubscribeEvent()258 public void testHandleUnsubscribeEvent() throws Exception { 259 VehiclePropValue message = createHalMessage( 260 VmsMessageType.UNSUBSCRIBE, // Message type 261 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION // VmsLayer 262 ); 263 264 sendHalMessage(message); 265 verify(mSubscriberService).removeVmsSubscriber(mSubscriberClient, LAYER); 266 } 267 268 /** 269 * UNSUBSCRIBE_TO_PUBLISHER message format: 270 * <ul> 271 * <li>Message type 272 * <li>Layer ID 273 * <li>Layer subtype 274 * <li>Layer version 275 * <li>Publisher ID 276 * </ul> 277 */ 278 @Test testHandleUnsubscribeFromPublisherEvent()279 public void testHandleUnsubscribeFromPublisherEvent() throws Exception { 280 VehiclePropValue message = createHalMessage( 281 VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER, // Message type 282 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // VmsLayer 283 PUBLISHER_ID // PublisherId 284 ); 285 286 sendHalMessage(message); 287 verify(mSubscriberService).removeVmsSubscriberToPublisher(mSubscriberClient, LAYER, 288 PUBLISHER_ID); 289 } 290 291 /** 292 * PUBLISHER_ID_REQUEST message format: 293 * <ul> 294 * <li>Message type 295 * <li>Publisher info (bytes) 296 * </ul> 297 * 298 * PUBLISHER_ID_RESPONSE message format: 299 * <ul> 300 * <li>Message type 301 * <li>Publisher ID 302 * </ul> 303 */ 304 @Test testHandlePublisherIdRequestEvent()305 public void testHandlePublisherIdRequestEvent() throws Exception { 306 VehiclePropValue request = createHalMessage( 307 VmsMessageType.PUBLISHER_ID_REQUEST // Message type 308 ); 309 request.value.bytes.addAll(PAYLOAD_AS_LIST); 310 311 when(mPublisherService.getPublisherId(PAYLOAD)).thenReturn(PUBLISHER_ID); 312 313 VehiclePropValue response = createHalMessage( 314 VmsMessageType.PUBLISHER_ID_RESPONSE, // Message type 315 PUBLISHER_ID // Publisher ID 316 ); 317 318 sendHalMessage(request); 319 verify(mVehicleHal).set(response); 320 } 321 322 /** 323 * PUBLISHER_INFORMATION_REQUEST message format: 324 * <ul> 325 * <li>Message type 326 * <li>Publisher ID 327 * </ul> 328 * 329 * PUBLISHER_INFORMATION_RESPONSE message format: 330 * <ul> 331 * <li>Message type 332 * <li>Publisher info (bytes) 333 * </ul> 334 */ 335 @Test testHandlePublisherInformationRequestEvent()336 public void testHandlePublisherInformationRequestEvent() throws Exception { 337 VehiclePropValue request = createHalMessage( 338 VmsMessageType.PUBLISHER_INFORMATION_REQUEST, // Message type 339 PUBLISHER_ID // Publisher ID 340 ); 341 342 when(mSubscriberService.getPublisherInfo(PUBLISHER_ID)).thenReturn(PAYLOAD); 343 344 VehiclePropValue response = createHalMessage( 345 VmsMessageType.PUBLISHER_INFORMATION_RESPONSE // Message type 346 ); 347 response.value.bytes.addAll(PAYLOAD_AS_LIST); 348 349 sendHalMessage(request); 350 verify(mVehicleHal).set(response); 351 } 352 353 /** 354 * OFFERING message format: 355 * <ul> 356 * <li>Message type 357 * <li>Publisher ID 358 * <li>Number of offerings. 359 * <li>Offerings (x number of offerings) 360 * <ul> 361 * <li>Layer ID 362 * <li>Layer subtype 363 * <li>Layer version 364 * <li>Number of layer dependencies. 365 * <li>Layer dependencies (x number of layer dependencies) 366 * <ul> 367 * <li>Layer ID 368 * <li>Layer subtype 369 * <li>Layer version 370 * </ul> 371 * </ul> 372 * </ul> 373 */ 374 @Test testHandleOfferingEvent_ZeroOfferings()375 public void testHandleOfferingEvent_ZeroOfferings() throws Exception { 376 VehiclePropValue message = createHalMessage( 377 VmsMessageType.OFFERING, // Message type 378 PUBLISHER_ID, // PublisherId 379 0 // # of offerings 380 ); 381 382 sendHalMessage(message); 383 verify(mPublisherService).setLayersOffering( 384 mToken, 385 new VmsLayersOffering(Collections.emptySet(), PUBLISHER_ID)); 386 } 387 388 @Test testHandleOfferingEvent_LayerOnly()389 public void testHandleOfferingEvent_LayerOnly() throws Exception { 390 VehiclePropValue message = createHalMessage( 391 VmsMessageType.OFFERING, // Message type 392 PUBLISHER_ID, // PublisherId 393 1, // # of offerings 394 // Offered layer 395 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, 396 0 // # of dependencies 397 ); 398 399 sendHalMessage(message); 400 verify(mPublisherService).setLayersOffering( 401 mToken, 402 new VmsLayersOffering(Collections.singleton( 403 new VmsLayerDependency(LAYER)), 404 PUBLISHER_ID)); 405 } 406 407 @Test testHandleOfferingEvent_LayerAndDependency()408 public void testHandleOfferingEvent_LayerAndDependency() throws Exception { 409 VehiclePropValue message = createHalMessage( 410 VmsMessageType.OFFERING, // Message type 411 PUBLISHER_ID, // PublisherId 412 1, // # of offerings 413 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 414 1, // # of dependencies 415 4, 5, 6 // Dependency layer 416 ); 417 418 sendHalMessage(message); 419 verify(mPublisherService).setLayersOffering( 420 mToken, 421 new VmsLayersOffering(Collections.singleton( 422 new VmsLayerDependency(LAYER, Collections.singleton( 423 new VmsLayer(4, 5, 6)))), 424 PUBLISHER_ID)); 425 } 426 427 @Test testHandleOfferingEvent_MultipleLayersAndDependencies()428 public void testHandleOfferingEvent_MultipleLayersAndDependencies() throws Exception { 429 VehiclePropValue message = createHalMessage( 430 VmsMessageType.OFFERING, // Message type 431 PUBLISHER_ID, // PublisherId 432 3, // # of offerings 433 // Offered layer #1 434 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 435 2, // # of dependencies 436 4, 5, 6, // Dependency layer 437 7, 8, 9, // Dependency layer 438 // Offered layer #2 439 3, 2, 1, // Layer 440 0, // # of dependencies 441 // Offered layer #3 442 6, 5, 4, // Layer 443 1, // # of dependencies 444 7, 8, 9 // Dependency layer 445 ); 446 447 sendHalMessage(message); 448 verify(mPublisherService).setLayersOffering( 449 mToken, 450 new VmsLayersOffering(new LinkedHashSet<>(Arrays.asList( 451 new VmsLayerDependency(LAYER, new LinkedHashSet<>(Arrays.asList( 452 new VmsLayer(4, 5, 6), 453 new VmsLayer(7, 8, 9) 454 ))), 455 new VmsLayerDependency(new VmsLayer(3, 2, 1), Collections.emptySet()), 456 new VmsLayerDependency(new VmsLayer(6, 5, 4), Collections.singleton( 457 new VmsLayer(7, 8, 9) 458 )))), 459 PUBLISHER_ID)); 460 } 461 462 /** 463 * AVAILABILITY_REQUEST message format: 464 * <ul> 465 * <li>Message type 466 * </ul> 467 * 468 * AVAILABILITY_RESPONSE message format: 469 * <ul> 470 * <li>Message type 471 * <li>Sequence number. 472 * <li>Number of associated layers. 473 * <li>Associated layers (x number of associated layers) 474 * <ul> 475 * <li>Layer ID 476 * <li>Layer subtype 477 * <li>Layer version 478 * <li>Number of publishers 479 * <li>Publisher ID (x number of publishers) 480 * </ul> 481 * </ul> 482 */ 483 @Test testHandleAvailabilityRequestEvent_ZeroLayers()484 public void testHandleAvailabilityRequestEvent_ZeroLayers() throws Exception { 485 VehiclePropValue request = createHalMessage( 486 VmsMessageType.AVAILABILITY_REQUEST // Message type 487 ); 488 489 when(mSubscriberService.getAvailableLayers()).thenReturn( 490 new VmsAvailableLayers(Collections.emptySet(), 123)); 491 492 VehiclePropValue response = createHalMessage( 493 VmsMessageType.AVAILABILITY_RESPONSE, // Message type 494 123, // Sequence number 495 0 // # of associated layers 496 ); 497 498 sendHalMessage(request); 499 verify(mVehicleHal).set(response); 500 } 501 502 @Test testHandleAvailabilityRequestEvent_OneLayer()503 public void testHandleAvailabilityRequestEvent_OneLayer() throws Exception { 504 VehiclePropValue request = createHalMessage( 505 VmsMessageType.AVAILABILITY_REQUEST // Message type 506 ); 507 508 when(mSubscriberService.getAvailableLayers()).thenReturn( 509 new VmsAvailableLayers(Collections.singleton( 510 new VmsAssociatedLayer(LAYER, Collections.singleton(PUBLISHER_ID))), 123)); 511 512 VehiclePropValue response = createHalMessage( 513 VmsMessageType.AVAILABILITY_RESPONSE, // Message type 514 123, // Sequence number 515 1, // # of associated layers 516 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 517 1, // # of publisher IDs 518 PUBLISHER_ID // Publisher ID 519 ); 520 521 sendHalMessage(request); 522 verify(mVehicleHal).set(response); 523 } 524 525 526 @Test testHandleAvailabilityRequestEvent_MultipleLayers()527 public void testHandleAvailabilityRequestEvent_MultipleLayers() throws Exception { 528 VehiclePropValue request = createHalMessage( 529 VmsMessageType.AVAILABILITY_REQUEST // Message type 530 ); 531 532 when(mSubscriberService.getAvailableLayers()).thenReturn( 533 new VmsAvailableLayers(new LinkedHashSet<>(Arrays.asList( 534 new VmsAssociatedLayer(LAYER, 535 new LinkedHashSet<>(Arrays.asList(PUBLISHER_ID, 54321))), 536 new VmsAssociatedLayer(new VmsLayer(3, 2, 1), 537 Collections.emptySet()), 538 new VmsAssociatedLayer(new VmsLayer(6, 5, 4), 539 Collections.singleton(99999)))), 540 123)); 541 542 VehiclePropValue response = createHalMessage( 543 VmsMessageType.AVAILABILITY_RESPONSE, // Message type 544 123, // Sequence number 545 3, // # of associated layers 546 // Associated layer #1 547 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 548 2, // # of publisher IDs 549 PUBLISHER_ID, // Publisher ID 550 54321, // Publisher ID #2 551 // Associated layer #2 552 3, 2, 1, // Layer 553 0, // # of publisher IDs 554 // Associated layer #3 555 6, 5, 4, // Layer 556 1, // # of publisher IDs 557 99999 // Publisher ID 558 559 ); 560 561 sendHalMessage(request); 562 verify(mVehicleHal).set(response); 563 } 564 565 /** 566 * START_SESSION message format: 567 * <ul> 568 * <li>Message type 569 * <li>Core ID 570 * <li>Client ID 571 * </ul> 572 */ 573 @Test testHandleStartSessionEvent()574 public void testHandleStartSessionEvent() throws Exception { 575 when(mSubscriberService.getAvailableLayers()).thenReturn( 576 new VmsAvailableLayers(Collections.emptySet(), 5)); 577 578 VehiclePropValue request = createHalMessage( 579 VmsMessageType.START_SESSION, // Message type 580 0, // Core ID (unknown) 581 CLIENT_ID // Client ID 582 ); 583 584 VehiclePropValue response = createHalMessage( 585 VmsMessageType.START_SESSION, // Message type 586 CORE_ID, // Core ID 587 CLIENT_ID // Client ID 588 ); 589 590 sendHalMessage(request); 591 InOrder inOrder = Mockito.inOrder(mVehicleHal); 592 inOrder.verify(mVehicleHal).set(response); 593 inOrder.verify(mVehicleHal).set(createHalMessage( 594 VmsMessageType.AVAILABILITY_CHANGE, // Message type 595 5, // Sequence number 596 0)); // # of associated layers 597 } 598 599 /** 600 * AVAILABILITY_CHANGE message format: 601 * <ul> 602 * <li>Message type 603 * <li>Sequence number. 604 * <li>Number of associated layers. 605 * <li>Associated layers (x number of associated layers) 606 * <ul> 607 * <li>Layer ID 608 * <li>Layer subtype 609 * <li>Layer version 610 * <li>Number of publishers 611 * <li>Publisher ID (x number of publishers) 612 * </ul> 613 * </ul> 614 */ 615 @Test testOnLayersAvailabilityChanged_ZeroLayers()616 public void testOnLayersAvailabilityChanged_ZeroLayers() throws Exception { 617 mSubscriberClient.onLayersAvailabilityChanged( 618 new VmsAvailableLayers(Collections.emptySet(), 123)); 619 620 VehiclePropValue message = createHalMessage( 621 VmsMessageType.AVAILABILITY_CHANGE, // Message type 622 123, // Sequence number 623 0 // # of associated layers 624 ); 625 626 waitForHandlerCompletion(); 627 verify(mVehicleHal).set(message); 628 } 629 630 @Test testOnLayersAvailabilityChanged_OneLayer()631 public void testOnLayersAvailabilityChanged_OneLayer() throws Exception { 632 mSubscriberClient.onLayersAvailabilityChanged( 633 new VmsAvailableLayers(Collections.singleton( 634 new VmsAssociatedLayer(LAYER, Collections.singleton(PUBLISHER_ID))), 123)); 635 636 VehiclePropValue message = createHalMessage( 637 VmsMessageType.AVAILABILITY_CHANGE, // Message type 638 123, // Sequence number 639 1, // # of associated layers 640 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 641 1, // # of publisher IDs 642 PUBLISHER_ID // Publisher ID 643 ); 644 645 waitForHandlerCompletion(); 646 verify(mVehicleHal).set(message); 647 } 648 649 650 @Test testOnLayersAvailabilityChanged_MultipleLayers()651 public void testOnLayersAvailabilityChanged_MultipleLayers() throws Exception { 652 mSubscriberClient.onLayersAvailabilityChanged( 653 new VmsAvailableLayers(new LinkedHashSet<>(Arrays.asList( 654 new VmsAssociatedLayer(LAYER, 655 new LinkedHashSet<>(Arrays.asList(PUBLISHER_ID, 54321))), 656 new VmsAssociatedLayer(new VmsLayer(3, 2, 1), 657 Collections.emptySet()), 658 new VmsAssociatedLayer(new VmsLayer(6, 5, 4), 659 Collections.singleton(99999)))), 660 123)); 661 662 VehiclePropValue message = createHalMessage( 663 VmsMessageType.AVAILABILITY_CHANGE, // Message type 664 123, // Sequence number 665 3, // # of associated layers 666 // Associated layer #1 667 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 668 2, // # of publisher IDs 669 PUBLISHER_ID, // Publisher ID 670 54321, // Publisher ID #2 671 // Associated layer #2 672 3, 2, 1, // Layer 673 0, // # of publisher IDs 674 // Associated layer #3 675 6, 5, 4, // Layer 676 1, // # of publisher IDs 677 99999 // Publisher ID 678 679 ); 680 681 waitForHandlerCompletion(); 682 verify(mVehicleHal).set(message); 683 } 684 685 /** 686 * SUBSCRIPTION_REQUEST message format: 687 * <ul> 688 * <li>Message type 689 * </ul> 690 * 691 * SUBSCRIPTION_RESPONSE message format: 692 * <ul> 693 * <li>Message type 694 * <li>Sequence number 695 * <li>Number of layers 696 * <li>Number of associated layers 697 * <li>Layers (x number of layers) 698 * <ul> 699 * <li>Layer ID 700 * <li>Layer subtype 701 * <li>Layer version 702 * </ul> 703 * <li>Associated layers (x number of associated layers) 704 * <ul> 705 * <li>Layer ID 706 * <li>Layer subtype 707 * <li>Layer version 708 * <li>Number of publishers 709 * <li>Publisher ID (x number of publishers) 710 * </ul> 711 * </ul> 712 */ 713 @Test testHandleSubscriptionsRequestEvent_ZeroLayers()714 public void testHandleSubscriptionsRequestEvent_ZeroLayers() throws Exception { 715 VehiclePropValue request = createHalMessage( 716 VmsMessageType.SUBSCRIPTIONS_REQUEST // Message type 717 ); 718 719 when(mPublisherService.getSubscriptions()).thenReturn( 720 new VmsSubscriptionState(123, Collections.emptySet(), Collections.emptySet())); 721 722 VehiclePropValue response = createHalMessage( 723 VmsMessageType.SUBSCRIPTIONS_RESPONSE, // Message type 724 123, // Sequence number 725 0, // # of layers 726 0 // # of associated layers 727 ); 728 729 sendHalMessage(request); 730 verify(mVehicleHal).set(response); 731 } 732 733 @Test testHandleSubscriptionsRequestEvent_OneLayer_ZeroAssociatedLayers()734 public void testHandleSubscriptionsRequestEvent_OneLayer_ZeroAssociatedLayers() 735 throws Exception { 736 VehiclePropValue request = createHalMessage( 737 VmsMessageType.SUBSCRIPTIONS_REQUEST // Message type 738 ); 739 740 when(mPublisherService.getSubscriptions()).thenReturn( 741 new VmsSubscriptionState(123, Collections.singleton(LAYER), 742 Collections.emptySet())); 743 744 VehiclePropValue response = createHalMessage( 745 VmsMessageType.SUBSCRIPTIONS_RESPONSE, // Message type 746 123, // Sequence number 747 1, // # of layers 748 0, // # of associated layers 749 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION // Layer 750 ); 751 752 sendHalMessage(request); 753 verify(mVehicleHal).set(response); 754 } 755 756 @Test testHandleSubscriptionsRequestEvent_ZeroLayers_OneAssociatedLayer()757 public void testHandleSubscriptionsRequestEvent_ZeroLayers_OneAssociatedLayer() 758 throws Exception { 759 VehiclePropValue request = createHalMessage( 760 VmsMessageType.SUBSCRIPTIONS_REQUEST // Message type 761 ); 762 763 when(mPublisherService.getSubscriptions()).thenReturn( 764 new VmsSubscriptionState(123, Collections.emptySet(), Collections.singleton( 765 new VmsAssociatedLayer(LAYER, Collections.singleton(PUBLISHER_ID))))); 766 767 VehiclePropValue response = createHalMessage( 768 VmsMessageType.SUBSCRIPTIONS_RESPONSE, // Message type 769 123, // Sequence number 770 0, // # of layers 771 1, // # of associated layers 772 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 773 1, // # of publisher IDs 774 PUBLISHER_ID // Publisher ID 775 ); 776 777 sendHalMessage(request); 778 verify(mVehicleHal).set(response); 779 } 780 781 @Test testHandleSubscriptionsRequestEvent_MultipleLayersAndAssociatedLayers()782 public void testHandleSubscriptionsRequestEvent_MultipleLayersAndAssociatedLayers() 783 throws Exception { 784 VehiclePropValue request = createHalMessage( 785 VmsMessageType.SUBSCRIPTIONS_REQUEST // Message type 786 ); 787 788 when(mPublisherService.getSubscriptions()).thenReturn( 789 new VmsSubscriptionState(123, 790 new LinkedHashSet<>(Arrays.asList( 791 LAYER, 792 new VmsLayer(4, 5, 6), 793 new VmsLayer(7, 8, 9) 794 )), 795 new LinkedHashSet<>(Arrays.asList( 796 new VmsAssociatedLayer(LAYER, Collections.emptySet()), 797 new VmsAssociatedLayer(new VmsLayer(6, 5, 4), 798 new LinkedHashSet<>(Arrays.asList( 799 PUBLISHER_ID, 800 54321)))))) 801 ); 802 803 VehiclePropValue response = createHalMessage( 804 VmsMessageType.SUBSCRIPTIONS_RESPONSE, // Message type 805 123, // Sequence number 806 3, // # of layers 807 2, // # of associated layers 808 // Layer #1 809 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 810 // Layer #2 811 4, 5, 6, // Layer 812 // Layer #3 813 7, 8, 9, // Layer 814 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 815 0, // # of publisher IDs 816 6, 5, 4, // Layer 817 2, // # of publisher IDs 818 PUBLISHER_ID, // Publisher ID 819 54321 // Publisher ID #2 820 ); 821 822 sendHalMessage(request); 823 verify(mVehicleHal).set(response); 824 } 825 826 /** 827 * SUBSCRIPTIONS_CHANGE message format: 828 * <ul> 829 * <li>Message type 830 * <li>Sequence number 831 * <li>Number of layers 832 * <li>Number of associated layers 833 * <li>Layers (x number of layers) 834 * <ul> 835 * <li>Layer ID 836 * <li>Layer subtype 837 * <li>Layer version 838 * </ul> 839 * <li>Associated layers (x number of associated layers) 840 * <ul> 841 * <li>Layer ID 842 * <li>Layer subtype 843 * <li>Layer version 844 * <li>Number of publishers 845 * <li>Publisher ID (x number of publishers) 846 * </ul> 847 * </ul> 848 */ 849 @Test testOnVmsSubscriptionChange_ZeroLayers()850 public void testOnVmsSubscriptionChange_ZeroLayers() throws Exception { 851 mPublisherClient.onVmsSubscriptionChange( 852 new VmsSubscriptionState(123, Collections.emptySet(), Collections.emptySet())); 853 854 VehiclePropValue response = createHalMessage( 855 VmsMessageType.SUBSCRIPTIONS_CHANGE, // Message type 856 123, // Sequence number 857 0, // # of layers 858 0 // # of associated layers 859 ); 860 861 waitForHandlerCompletion(); 862 verify(mVehicleHal).set(response); 863 } 864 865 @Test testOnVmsSubscriptionChange_OneLayer_ZeroAssociatedLayers()866 public void testOnVmsSubscriptionChange_OneLayer_ZeroAssociatedLayers() 867 throws Exception { 868 mPublisherClient.onVmsSubscriptionChange( 869 new VmsSubscriptionState(123, Collections.singleton(LAYER), 870 Collections.emptySet())); 871 872 VehiclePropValue response = createHalMessage( 873 VmsMessageType.SUBSCRIPTIONS_CHANGE, // Message type 874 123, // Sequence number 875 1, // # of layers 876 0, // # of associated layers 877 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION // Layer 878 ); 879 880 waitForHandlerCompletion(); 881 verify(mVehicleHal).set(response); 882 } 883 884 @Test testOnVmsSubscriptionChange_ZeroLayers_OneAssociatedLayer()885 public void testOnVmsSubscriptionChange_ZeroLayers_OneAssociatedLayer() 886 throws Exception { 887 mPublisherClient.onVmsSubscriptionChange( 888 new VmsSubscriptionState(123, Collections.emptySet(), Collections.singleton( 889 new VmsAssociatedLayer(LAYER, Collections.singleton(PUBLISHER_ID))))); 890 891 VehiclePropValue response = createHalMessage( 892 VmsMessageType.SUBSCRIPTIONS_CHANGE, // Message type 893 123, // Sequence number 894 0, // # of layers 895 1, // # of associated layers 896 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 897 1, // # of publisher IDs 898 PUBLISHER_ID // Publisher ID 899 ); 900 901 waitForHandlerCompletion(); 902 verify(mVehicleHal).set(response); 903 } 904 905 @Test testOnVmsSubscriptionChange_MultipleLayersAndAssociatedLayers()906 public void testOnVmsSubscriptionChange_MultipleLayersAndAssociatedLayers() 907 throws Exception { 908 mPublisherClient.onVmsSubscriptionChange( 909 new VmsSubscriptionState(123, 910 new LinkedHashSet<>(Arrays.asList( 911 LAYER, 912 new VmsLayer(4, 5, 6), 913 new VmsLayer(7, 8, 9) 914 )), 915 new LinkedHashSet<>(Arrays.asList( 916 new VmsAssociatedLayer(LAYER, Collections.emptySet()), 917 new VmsAssociatedLayer(new VmsLayer(6, 5, 4), 918 new LinkedHashSet<>(Arrays.asList( 919 PUBLISHER_ID, 920 54321)))))) 921 ); 922 923 VehiclePropValue response = createHalMessage( 924 VmsMessageType.SUBSCRIPTIONS_CHANGE, // Message type 925 123, // Sequence number 926 3, // # of layers 927 2, // # of associated layers 928 // Layer #1 929 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 930 // Layer #2 931 4, 5, 6, // Layer 932 // Layer #3 933 7, 8, 9, // Layer 934 LAYER_TYPE, LAYER_SUBTYPE, LAYER_VERSION, // Layer 935 0, // # of publisher IDs 936 6, 5, 4, // Layer 937 2, // # of publisher IDs 938 PUBLISHER_ID, // Publisher ID 939 54321 // Publisher ID #2 940 ); 941 942 waitForHandlerCompletion(); 943 verify(mVehicleHal).set(response); 944 } 945 createHalMessage(Integer... message)946 private static VehiclePropValue createHalMessage(Integer... message) { 947 VehiclePropValue result = new VehiclePropValue(); 948 result.prop = VehicleProperty.VEHICLE_MAP_SERVICE; 949 result.value.int32Values.addAll(Arrays.asList(message)); 950 return result; 951 } 952 sendHalMessage(VehiclePropValue message)953 private void sendHalMessage(VehiclePropValue message) { 954 mHalService.handleHalEvents(Collections.singletonList(message)); 955 } 956 waitForHandlerCompletion()957 private void waitForHandlerCompletion() throws Exception { 958 final CountDownLatch latch = new CountDownLatch(1); 959 mHalService.getHandler().post(latch::countDown); 960 latch.await(5, TimeUnit.SECONDS); 961 } 962 } 963