1 /* 2 * Copyright (C) 2017 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; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 22 import android.car.VehicleAreaType; 23 import android.car.vms.VmsLayer; 24 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; 25 import android.hardware.automotive.vehicle.V2_0.VehicleProperty; 26 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; 27 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode; 28 import android.hardware.automotive.vehicle.V2_0.VmsMessageType; 29 import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerIntegerValuesIndex; 30 import android.hardware.automotive.vehicle.V2_0.VmsSubscriptionsStateIntegerValuesIndex; 31 import android.support.test.filters.MediumTest; 32 import android.support.test.runner.AndroidJUnit4; 33 34 import com.android.car.vehiclehal.VehiclePropValueBuilder; 35 import com.android.car.vehiclehal.test.MockedVehicleHal; 36 import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; 37 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 import java.util.HashSet; 44 import java.util.List; 45 import java.util.concurrent.Semaphore; 46 import java.util.concurrent.TimeUnit; 47 48 @RunWith(AndroidJUnit4.class) 49 @MediumTest 50 public class VmsHalServiceSubscriptionEventTest extends MockedCarTestBase { 51 private static final String TAG = "VmsHalServiceTest"; 52 53 private HalHandler mHalHandler; 54 private MockedVehicleHal mHal; 55 // Used to block until the HAL property is updated in HalHandler.onPropertySet. 56 private Semaphore mHalHandlerSemaphore; 57 58 @Override configureMockedHal()59 protected synchronized void configureMockedHal() { 60 mHalHandler = new HalHandler(); 61 addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalHandler) 62 .setChangeMode(VehiclePropertyChangeMode.ON_CHANGE) 63 .setAccess(VehiclePropertyAccess.READ_WRITE) 64 .addAreaConfig(VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, 0, 0); 65 } 66 67 @Override setUp()68 public void setUp() throws Exception { 69 super.setUp(); 70 mHal = getMockedVehicleHal(); 71 mHalHandlerSemaphore = new Semaphore(0); 72 } 73 74 @Test testEmptySubscriptions()75 public void testEmptySubscriptions() throws Exception { 76 List<VmsLayer> layers = new ArrayList<>(); 77 subscriptionTestLogic(layers); 78 } 79 80 @Test testOneSubscription()81 public void testOneSubscription() throws Exception { 82 List<VmsLayer> layers = Arrays.asList(new VmsLayer(8, 0, 3)); 83 subscriptionTestLogic(layers); 84 } 85 86 @Test testManySubscriptions()87 public void testManySubscriptions() throws Exception { 88 List<VmsLayer> layers = Arrays.asList( 89 new VmsLayer(8, 1, 3), 90 new VmsLayer(5, 2, 1), 91 new VmsLayer(3, 3, 9), 92 new VmsLayer(2, 4, 7), 93 new VmsLayer(9, 5, 3)); 94 subscriptionTestLogic(layers); 95 } 96 97 /** 98 * First, it subscribes to the given layers. Then it validates that a subscription request 99 * responds with the same layers. 100 */ subscriptionTestLogic(List<VmsLayer> layers)101 private void subscriptionTestLogic(List<VmsLayer> layers) throws Exception { 102 for (VmsLayer layer : layers) { 103 subscribeViaHal(layer); 104 } 105 // Send subscription request. 106 mHal.injectEvent(createHalSubscriptionRequest()); 107 // Wait for response. 108 assertTrue(mHalHandlerSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); 109 // Validate response. 110 ArrayList<Integer> v = mHalHandler.getValues(); 111 int messageType = v.get(VmsSubscriptionsStateIntegerValuesIndex.MESSAGE_TYPE); 112 int sequenceNumber = v.get(VmsSubscriptionsStateIntegerValuesIndex.SEQUENCE_NUMBER); 113 int numberLayers = v.get(VmsSubscriptionsStateIntegerValuesIndex.NUMBER_OF_LAYERS); 114 assertEquals(VmsMessageType.SUBSCRIPTIONS_RESPONSE, messageType); 115 assertEquals(layers.size(), numberLayers); 116 List<VmsLayer> receivedLayers = new ArrayList<>(); 117 int start = VmsSubscriptionsStateIntegerValuesIndex.SUBSCRIPTIONS_START; 118 int end = VmsSubscriptionsStateIntegerValuesIndex.SUBSCRIPTIONS_START + 3 * numberLayers; 119 while (start < end) { 120 int type = v.get(start++); 121 int subtype = v.get(start++); 122 int version = v.get(start++); 123 receivedLayers.add(new VmsLayer(type, subtype, version)); 124 } 125 assertEquals(new HashSet<>(layers), new HashSet<>(receivedLayers)); 126 } 127 128 /** 129 * Subscribes to a layer, waits for the event to propagate back to the HAL layer and validates 130 * the propagated message. 131 */ subscribeViaHal(VmsLayer layer)132 private void subscribeViaHal(VmsLayer layer) throws Exception { 133 // Send subscribe request. 134 mHal.injectEvent(createHalSubscribeRequest(layer)); 135 // Wait for response. 136 assertTrue(mHalHandlerSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); 137 // Validate response. 138 ArrayList<Integer> v = mHalHandler.getValues(); 139 int messsageType = v.get(VmsMessageWithLayerIntegerValuesIndex.MESSAGE_TYPE); 140 int layerId = v.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_TYPE); 141 int layerVersion = v.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_VERSION); 142 int fused = v.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_SUBTYPE); 143 assertEquals(VmsMessageType.SUBSCRIBE, messsageType); 144 assertEquals(layer.getType(), layerId); 145 assertEquals(layer.getVersion(), layerVersion); 146 } 147 createHalSubscribeRequest(VmsLayer layer)148 private VehiclePropValue createHalSubscribeRequest(VmsLayer layer) { 149 return VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) 150 .addIntValue(VmsMessageType.SUBSCRIBE) 151 .addIntValue(layer.getType()) 152 .addIntValue(layer.getSubtype()) 153 .addIntValue(layer.getVersion()) 154 .build(); 155 } 156 createHalSubscriptionRequest()157 private VehiclePropValue createHalSubscriptionRequest() { 158 return VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) 159 .addIntValue(VmsMessageType.SUBSCRIPTIONS_REQUEST) 160 .build(); 161 } 162 163 private class HalHandler implements VehicleHalPropertyHandler { 164 private ArrayList<Integer> mValues; 165 166 @Override onPropertySet(VehiclePropValue value)167 public synchronized void onPropertySet(VehiclePropValue value) { 168 mValues = value.value.int32Values; 169 mHalHandlerSemaphore.release(); 170 } 171 getValues()172 public ArrayList<Integer> getValues() { 173 return mValues; 174 } 175 } 176 }