• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertTrue;
20 
21 import android.car.Car;
22 import android.car.VehicleAreaType;
23 import android.car.vms.VmsAvailableLayers;
24 import android.car.vms.VmsLayer;
25 import android.car.vms.VmsPublisherClientService;
26 import android.car.vms.VmsSubscriberManager;
27 import android.car.vms.VmsSubscriptionState;
28 import android.content.Intent;
29 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
30 import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
31 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess;
32 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode;
33 import android.hardware.automotive.vehicle.V2_0.VmsAvailabilityStateIntegerValuesIndex;
34 import android.hardware.automotive.vehicle.V2_0.VmsBaseMessageIntegerValuesIndex;
35 import android.hardware.automotive.vehicle.V2_0.VmsMessageType;
36 import android.hardware.automotive.vehicle.V2_0.VmsStartSessionMessageIntegerValuesIndex;
37 import android.os.UserHandle;
38 import android.util.Log;
39 import android.util.Pair;
40 
41 import com.android.car.vehiclehal.VehiclePropValueBuilder;
42 import com.android.car.vehiclehal.test.MockedVehicleHal;
43 
44 import org.junit.Before;
45 
46 import java.util.List;
47 import java.util.concurrent.BlockingQueue;
48 import java.util.concurrent.CountDownLatch;
49 import java.util.concurrent.Executors;
50 import java.util.concurrent.LinkedBlockingQueue;
51 import java.util.concurrent.TimeUnit;
52 
53 public class MockedVmsTestBase extends MockedCarTestBase {
54     public static final long PUBLISHER_BIND_TIMEOUT_SECS = 2L;
55 
56     private static final String TAG = "MockedVmsTestBase";
57     private static CountDownLatch sPublisherIsReady = new CountDownLatch(1);
58     private static MockPublisherClient sPublisherClient;
59     private VmsSubscriberManager mVmsSubscriberManager;
60     private MockSubscriberClient mSubscriberClient;
61     private MockHalClient mHalClient;
62 
63     @Override
configureResourceOverrides(MockResources resources)64     protected synchronized void configureResourceOverrides(MockResources resources) {
65         super.configureResourceOverrides(resources);
66         // Override publisher client endpoint configurations
67         // Both lists must be set, but only one will be used (see setUp)
68         resources.overrideResource(com.android.car.R.array.vmsPublisherSystemClients,
69                 new String[]{getFlattenComponent(MockPublisherClient.class)});
70         resources.overrideResource(com.android.car.R.array.vmsPublisherUserClients,
71                 new String[]{getFlattenComponent(MockPublisherClient.class)});
72     }
73 
74     @Override
configureMockedHal()75     protected synchronized void configureMockedHal() {
76         mHalClient = new MockHalClient();
77         addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalClient)
78                 .setChangeMode(VehiclePropertyChangeMode.ON_CHANGE)
79                 .setAccess(VehiclePropertyAccess.READ_WRITE)
80                 .addAreaConfig(VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, 0, 0);
81     }
82 
83     @Before
setUpVms()84     public void setUpVms() throws Exception {
85         // Trigger VmsClientManager to bind to the MockPublisherClient
86         getContext().sendBroadcastAsUser(new Intent(Intent.ACTION_USER_UNLOCKED), UserHandle.ALL);
87 
88         mVmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
89                 Car.VMS_SUBSCRIBER_SERVICE);
90         mSubscriberClient = new MockSubscriberClient();
91         mVmsSubscriberManager.setVmsSubscriberClientCallback(Executors.newSingleThreadExecutor(),
92                 mSubscriberClient);
93 
94         // Validate session handshake
95         List<Integer> v = mHalClient.receiveMessage().value.int32Values;
96         assertEquals(VmsMessageType.START_SESSION,
97                 (int) v.get(VmsBaseMessageIntegerValuesIndex.MESSAGE_TYPE));
98         int coreId = v.get(VmsStartSessionMessageIntegerValuesIndex.SERVICE_ID);
99         assertTrue(coreId > 0);
100         assertEquals(-1, (int) v.get(VmsStartSessionMessageIntegerValuesIndex.CLIENT_ID));
101 
102         // Send handshake acknowledgement
103         mHalClient.sendMessage(
104                 VmsMessageType.START_SESSION,
105                 coreId,
106                 12345 // Client ID
107         );
108 
109         // Validate layer availability sent to HAL
110         v = mHalClient.receiveMessage().value.int32Values;
111         assertEquals(VmsMessageType.AVAILABILITY_CHANGE,
112                 (int) v.get(VmsAvailabilityStateIntegerValuesIndex.MESSAGE_TYPE));
113         assertEquals(0,
114                 (int) v.get(VmsAvailabilityStateIntegerValuesIndex.SEQUENCE_NUMBER));
115         assertEquals(0,
116                 (int) v.get(VmsAvailabilityStateIntegerValuesIndex.NUMBER_OF_ASSOCIATED_LAYERS));
117     }
118 
119     @Override
tearDown()120     public void tearDown() throws Exception {
121         super.tearDown();
122         sPublisherIsReady = new CountDownLatch(1);
123         sPublisherClient = null;
124     }
125 
getSubscriberManager()126     VmsSubscriberManager getSubscriberManager() {
127         return mVmsSubscriberManager;
128     }
129 
getMockPublisherClient()130     MockPublisherClient getMockPublisherClient() {
131         try {
132             assertTrue(
133                     "Timeout while waiting for publisher client to be ready",
134                     sPublisherIsReady.await(PUBLISHER_BIND_TIMEOUT_SECS, TimeUnit.SECONDS));
135         } catch (InterruptedException e) {
136             throw new RuntimeException(e);
137         }
138         return sPublisherClient;
139     }
140 
getMockSubscriberClient()141     MockSubscriberClient getMockSubscriberClient() {
142         return mSubscriberClient;
143     }
144 
getMockHalClient()145     MockHalClient getMockHalClient() {
146         return mHalClient;
147     }
148 
149     public static class MockPublisherClient extends VmsPublisherClientService {
150         private BlockingQueue<VmsSubscriptionState> mSubscriptionState =
151                 new LinkedBlockingQueue<>();
152 
153         @Override
onVmsPublisherServiceReady()154         protected void onVmsPublisherServiceReady() {
155             Log.d(TAG, "MockPublisherClient.onVmsPublisherServiceReady");
156             sPublisherClient = this;
157             sPublisherIsReady.countDown();
158         }
159 
160         @Override
onVmsSubscriptionChange(VmsSubscriptionState subscriptionState)161         public void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState) {
162             Log.d(TAG, "MockPublisherClient.onVmsSubscriptionChange");
163             mSubscriptionState.add(subscriptionState);
164         }
165 
receiveSubscriptionState()166         VmsSubscriptionState receiveSubscriptionState() {
167             return receiveWithTimeout(mSubscriptionState);
168         }
169     }
170 
171     class MockSubscriberClient implements VmsSubscriberManager.VmsSubscriberClientCallback {
172         private BlockingQueue<Pair<VmsLayer, byte[]>> mMessages = new LinkedBlockingQueue<>();
173         private BlockingQueue<VmsAvailableLayers> mAvailableLayers = new LinkedBlockingQueue<>();
174 
175         @Override
onVmsMessageReceived(VmsLayer layer, byte[] payload)176         public void onVmsMessageReceived(VmsLayer layer, byte[] payload) {
177             Log.d(TAG, "MockSubscriberClient.onVmsMessageReceived");
178             mMessages.add(Pair.create(layer, payload));
179         }
180 
181         @Override
onLayersAvailabilityChanged(VmsAvailableLayers availableLayers)182         public void onLayersAvailabilityChanged(VmsAvailableLayers availableLayers) {
183             Log.d(TAG, "MockSubscriberClient.onVmsMessageReceived");
184             mAvailableLayers.add(availableLayers);
185         }
186 
receiveMessage()187         Pair<VmsLayer, byte[]> receiveMessage() {
188             return receiveWithTimeout(mMessages);
189         }
190 
receiveLayerAvailability()191         VmsAvailableLayers receiveLayerAvailability() {
192             return receiveWithTimeout(mAvailableLayers);
193         }
194     }
195 
196     class MockHalClient implements MockedVehicleHal.VehicleHalPropertyHandler {
197         private BlockingQueue<VehiclePropValue> mMessages = new LinkedBlockingQueue<>();
198 
199         @Override
onPropertySet(VehiclePropValue value)200         public void onPropertySet(VehiclePropValue value) {
201             Log.d(TAG, "MockHalClient.onPropertySet");
202             if (value.prop == VehicleProperty.VEHICLE_MAP_SERVICE) {
203                 mMessages.add(value);
204             }
205         }
206 
sendMessage(int... message)207         void sendMessage(int... message) {
208             getMockedVehicleHal().injectEvent(
209                     VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE)
210                             .addIntValue(message)
211                             .build());
212         }
213 
sendMessage(int[] message, byte[] payload)214         void sendMessage(int[] message, byte[] payload) {
215             getMockedVehicleHal().injectEvent(
216                     VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE)
217                             .addIntValue(message)
218                             .addByteValue(payload)
219                             .build());
220         }
221 
receiveMessage()222         VehiclePropValue receiveMessage() {
223             return receiveWithTimeout(mMessages);
224         }
225     }
226 
receiveWithTimeout(BlockingQueue<T> queue)227     private static <T> T receiveWithTimeout(BlockingQueue<T> queue) {
228         try {
229             return queue.poll(2L, TimeUnit.SECONDS);
230         } catch (InterruptedException e) {
231             throw new RuntimeException(e);
232         }
233     }
234 }
235