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.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNull;
22 
23 import android.car.vms.VmsAssociatedLayer;
24 import android.car.vms.VmsAvailableLayers;
25 import android.car.vms.VmsLayer;
26 import android.hardware.automotive.vehicle.V2_0.VmsAvailabilityStateIntegerValuesIndex;
27 import android.hardware.automotive.vehicle.V2_0.VmsMessageType;
28 import android.util.Pair;
29 
30 import androidx.test.ext.junit.runners.AndroidJUnit4;
31 import androidx.test.filters.MediumTest;
32 
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Collections;
39 import java.util.HashSet;
40 import java.util.Set;
41 
42 @RunWith(AndroidJUnit4.class)
43 @MediumTest
44 public class VmsSubscriberManagerTest extends MockedVmsTestBase {
45     private static final int PUBLISHER_ID = 17;
46     private static final int WRONG_PUBLISHER_ID = 26;
47     private static final Set<Integer> PUBLISHERS_LIST = Collections.singleton(PUBLISHER_ID);
48 
49     private static final int SUBSCRIPTION_LAYER_ID = 2;
50     private static final int SUBSCRIPTION_LAYER_VERSION = 3;
51     private static final int MOCK_PUBLISHER_LAYER_SUBTYPE = 444;
52     private static final VmsLayer SUBSCRIPTION_LAYER = new VmsLayer(SUBSCRIPTION_LAYER_ID,
53             MOCK_PUBLISHER_LAYER_SUBTYPE,
54             SUBSCRIPTION_LAYER_VERSION);
55     private static final VmsAssociatedLayer SUBSCRIPTION_ASSOCIATED_LAYER =
56             new VmsAssociatedLayer(SUBSCRIPTION_LAYER, PUBLISHERS_LIST);
57 
58     private static final int SUBSCRIPTION_DEPENDANT_LAYER_ID_1 = 4;
59     private static final int SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1 = 5;
60     private static final VmsLayer SUBSCRIPTION_DEPENDANT_LAYER_1 =
61             new VmsLayer(SUBSCRIPTION_DEPENDANT_LAYER_ID_1,
62                     MOCK_PUBLISHER_LAYER_SUBTYPE,
63                     SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1);
64 
65     private static final VmsAssociatedLayer SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_1 =
66             new VmsAssociatedLayer(SUBSCRIPTION_DEPENDANT_LAYER_1, PUBLISHERS_LIST);
67 
68     private static final int SUBSCRIPTION_DEPENDANT_LAYER_ID_2 = 6;
69     private static final int SUBSCRIPTION_DEPENDANT_LAYER_VERSION_2 = 7;
70     private static final VmsLayer SUBSCRIPTION_DEPENDANT_LAYER_2 =
71             new VmsLayer(SUBSCRIPTION_DEPENDANT_LAYER_ID_2,
72                     MOCK_PUBLISHER_LAYER_SUBTYPE,
73                     SUBSCRIPTION_DEPENDANT_LAYER_VERSION_2);
74 
75     private static final VmsAssociatedLayer SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_2 =
76             new VmsAssociatedLayer(SUBSCRIPTION_DEPENDANT_LAYER_2, PUBLISHERS_LIST);
77 
78     private static final int SUBSCRIPTION_UNSUPPORTED_LAYER_ID = 100;
79     private static final int SUBSCRIPTION_UNSUPPORTED_LAYER_VERSION = 200;
80 
81     private static final byte[] PAYLOAD = {0xa, 0xb};
82 
83     // Test injecting a value in the HAL and verifying it propagates to a subscriber.
84     @Test
testSubscribe()85     public void testSubscribe() throws Exception {
86         getSubscriberManager().subscribe(SUBSCRIPTION_LAYER);
87 
88         getMockHalClient().sendMessage(
89                 new int[]{
90                         VmsMessageType.DATA,
91                         SUBSCRIPTION_LAYER_ID,
92                         MOCK_PUBLISHER_LAYER_SUBTYPE,
93                         SUBSCRIPTION_LAYER_VERSION,
94                         PUBLISHER_ID
95                 },
96                 PAYLOAD);
97 
98         Pair<VmsLayer, byte[]> message = getMockSubscriberClient().receiveMessage();
99         assertEquals(SUBSCRIPTION_LAYER, message.first);
100         assertArrayEquals(PAYLOAD, message.second);
101     }
102 
103     // Test injecting a value in the HAL and verifying it propagates to a subscriber.
104     @Test
testSubscribeToPublisher()105     public void testSubscribeToPublisher() throws Exception {
106         getSubscriberManager().subscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID);
107 
108         getMockHalClient().sendMessage(
109                 new int[]{
110                         VmsMessageType.DATA,
111                         SUBSCRIPTION_LAYER_ID,
112                         MOCK_PUBLISHER_LAYER_SUBTYPE,
113                         SUBSCRIPTION_LAYER_VERSION,
114                         WRONG_PUBLISHER_ID
115                 },
116                 PAYLOAD);
117 
118         assertNull(getMockSubscriberClient().receiveMessage());
119     }
120 
121     // Test injecting a value in the HAL and verifying it propagates to a subscriber.
122     @Test
testSubscribeFromPublisher()123     public void testSubscribeFromPublisher() throws Exception {
124         getSubscriberManager().subscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID);
125 
126         getMockHalClient().sendMessage(
127                 new int[]{
128                         VmsMessageType.DATA,
129                         SUBSCRIPTION_LAYER_ID,
130                         MOCK_PUBLISHER_LAYER_SUBTYPE,
131                         SUBSCRIPTION_LAYER_VERSION,
132                         PUBLISHER_ID
133                 },
134                 PAYLOAD);
135 
136         Pair<VmsLayer, byte[]> message = getMockSubscriberClient().receiveMessage();
137         assertEquals(SUBSCRIPTION_LAYER, message.first);
138         assertArrayEquals(PAYLOAD, message.second);
139     }
140 
141     // Test injecting a value in the HAL and verifying it does not propagate to a subscriber.
142     @Test
testUnsubscribe()143     public void testUnsubscribe() throws Exception {
144         getSubscriberManager().subscribe(SUBSCRIPTION_LAYER);
145         getSubscriberManager().unsubscribe(SUBSCRIPTION_LAYER);
146 
147         getMockHalClient().sendMessage(
148                 new int[]{
149                         VmsMessageType.DATA,
150                         SUBSCRIPTION_LAYER_ID,
151                         MOCK_PUBLISHER_LAYER_SUBTYPE,
152                         SUBSCRIPTION_LAYER_VERSION,
153                         PUBLISHER_ID
154                 },
155                 PAYLOAD);
156 
157         assertNull(getMockSubscriberClient().receiveMessage());
158     }
159 
160     // Test injecting a value in the HAL and verifying it does not propagate to a subscriber.
161     @Test
testSubscribeFromWrongPublisher()162     public void testSubscribeFromWrongPublisher() throws Exception {
163         getSubscriberManager().subscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID);
164 
165         getMockHalClient().sendMessage(
166                 new int[]{
167                         VmsMessageType.DATA,
168                         SUBSCRIPTION_LAYER_ID,
169                         MOCK_PUBLISHER_LAYER_SUBTYPE,
170                         SUBSCRIPTION_LAYER_VERSION,
171                         WRONG_PUBLISHER_ID
172                 },
173                 PAYLOAD);
174 
175         assertNull(getMockSubscriberClient().receiveMessage());
176     }
177 
178     // Test injecting a value in the HAL and verifying it does not propagate to a subscriber.
179     @Test
testUnsubscribeFromPublisher()180     public void testUnsubscribeFromPublisher() throws Exception {
181         getSubscriberManager().subscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID);
182         getSubscriberManager().unsubscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID);
183 
184         getMockHalClient().sendMessage(
185                 new int[]{
186                         VmsMessageType.DATA,
187                         SUBSCRIPTION_LAYER_ID,
188                         MOCK_PUBLISHER_LAYER_SUBTYPE,
189                         SUBSCRIPTION_LAYER_VERSION,
190                         PUBLISHER_ID
191                 },
192                 PAYLOAD);
193 
194         assertNull(getMockSubscriberClient().receiveMessage());
195     }
196 
197     // Test injecting a value in the HAL and verifying it propagates to a subscriber.
198     @Test
testSubscribeAll()199     public void testSubscribeAll() throws Exception {
200         getSubscriberManager().startMonitoring();
201 
202         getMockHalClient().sendMessage(
203                 new int[]{
204                         VmsMessageType.DATA,
205                         SUBSCRIPTION_LAYER_ID,
206                         MOCK_PUBLISHER_LAYER_SUBTYPE,
207                         SUBSCRIPTION_LAYER_VERSION,
208                         PUBLISHER_ID
209                 },
210                 PAYLOAD);
211 
212         Pair<VmsLayer, byte[]> message = getMockSubscriberClient().receiveMessage();
213         assertEquals(SUBSCRIPTION_LAYER, message.first);
214         assertArrayEquals(PAYLOAD, message.second);
215     }
216 
217     // Test injecting a value in the HAL and verifying it propagates to a subscriber.
218     @Test
testSimpleAvailableLayers()219     public void testSimpleAvailableLayers() throws Exception {
220         //
221         // Offering:
222         // Layer             | Dependency
223         // ===============================
224         // (2, 3, 444), [17] | {}
225 
226         // Expected availability:
227         // {(2, 3, 444 [17])}
228         //
229         getMockHalClient().sendMessage(
230                 VmsMessageType.OFFERING,
231                 PUBLISHER_ID,
232                 1, // Number of offered layers
233 
234                 SUBSCRIPTION_LAYER_ID,
235                 MOCK_PUBLISHER_LAYER_SUBTYPE,
236                 SUBSCRIPTION_LAYER_VERSION,
237                 0 // number of dependencies for layer
238         );
239 
240         assertEquals(
241                 Collections.singleton(SUBSCRIPTION_ASSOCIATED_LAYER),
242                 getMockSubscriberClient().receiveLayerAvailability().getAssociatedLayers());
243     }
244 
245     // Test injecting a value in the HAL and verifying it propagates to a subscriber after it has
246     // subscribed to a layer.
247     @Test
testSimpleAvailableLayersAfterSubscription()248     public void testSimpleAvailableLayersAfterSubscription() throws Exception {
249         getSubscriberManager().subscribe(SUBSCRIPTION_LAYER);
250 
251         //
252         // Offering:
253         // Layer             | Dependency
254         // ===============================
255         // (2, 3, 444), [17] | {}
256 
257         // Expected availability:
258         // {(2, 3, 444 [17])}
259         //
260         getMockHalClient().sendMessage(
261                 VmsMessageType.OFFERING, // MessageType
262                 PUBLISHER_ID,
263                 1, // Number of offered layers
264 
265                 SUBSCRIPTION_LAYER_ID,
266                 MOCK_PUBLISHER_LAYER_SUBTYPE,
267                 SUBSCRIPTION_LAYER_VERSION,
268                 0 // number of dependencies for layer
269         );
270 
271         assertEquals(
272                 Collections.singleton(SUBSCRIPTION_ASSOCIATED_LAYER),
273                 getMockSubscriberClient().receiveLayerAvailability().getAssociatedLayers());
274     }
275 
276     // Test injecting a value in the HAL and verifying it does not propagates to a subscriber after
277     // it has cleared its callback.
278     @Test
testSimpleAvailableLayersAfterClear()279     public void testSimpleAvailableLayersAfterClear() throws Exception {
280         getSubscriberManager().clearVmsSubscriberClientCallback();
281         //
282         // Offering:
283         // Layer             | Dependency
284         // ===============================
285         // (2, 3, 444), [17] | {}
286 
287         // Expected availability:
288         // {(2, 3, 444 [17])}
289         //
290         getMockHalClient().sendMessage(
291                 VmsMessageType.OFFERING, // MessageType
292                 PUBLISHER_ID,
293                 1, // Number of offered layers
294 
295                 SUBSCRIPTION_LAYER_ID,
296                 SUBSCRIPTION_LAYER_VERSION,
297                 MOCK_PUBLISHER_LAYER_SUBTYPE,
298                 0 // number of dependencies for layer
299         );
300 
301         assertNull(getMockSubscriberClient().receiveLayerAvailability());
302     }
303 
304     // Test injecting a value in the HAL and verifying it propagates to a subscriber.
305     @Test
testComplexAvailableLayers()306     public void testComplexAvailableLayers() throws Exception {
307         //
308         // Offering:
309         // Layer             | Dependency
310         // =====================================
311         // (2, 3, 444), [17] | {}
312         // (4, 5, 444), [17] | {(2, 3)}
313         // (6, 7, 444), [17] | {(2, 3), (4, 5)}
314         // (6, 7, 444), [17] | {(100, 200)}
315 
316         // Expected availability:
317         // {(2, 3, 444 [17]), (4, 5, 444 [17]), (6, 7, 444 [17])}
318         //
319 
320         getMockHalClient().sendMessage(
321                 VmsMessageType.OFFERING, // MessageType
322                 PUBLISHER_ID,
323                 4, // Number of offered layers
324 
325                 SUBSCRIPTION_LAYER_ID,
326                 MOCK_PUBLISHER_LAYER_SUBTYPE,
327                 SUBSCRIPTION_LAYER_VERSION,
328                 0, // number of dependencies for layer
329 
330                 SUBSCRIPTION_DEPENDANT_LAYER_ID_1,
331                 MOCK_PUBLISHER_LAYER_SUBTYPE,
332                 SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1,
333                 1, // number of dependencies for layer
334                 SUBSCRIPTION_LAYER_ID,
335                 MOCK_PUBLISHER_LAYER_SUBTYPE,
336                 SUBSCRIPTION_LAYER_VERSION,
337 
338                 SUBSCRIPTION_DEPENDANT_LAYER_ID_2,
339                 MOCK_PUBLISHER_LAYER_SUBTYPE,
340                 SUBSCRIPTION_DEPENDANT_LAYER_VERSION_2,
341                 2, // number of dependencies for layer
342                 SUBSCRIPTION_LAYER_ID,
343                 MOCK_PUBLISHER_LAYER_SUBTYPE,
344                 SUBSCRIPTION_LAYER_VERSION,
345                 SUBSCRIPTION_DEPENDANT_LAYER_ID_1,
346                 MOCK_PUBLISHER_LAYER_SUBTYPE,
347                 SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1,
348 
349                 SUBSCRIPTION_DEPENDANT_LAYER_ID_2,
350                 MOCK_PUBLISHER_LAYER_SUBTYPE,
351                 SUBSCRIPTION_DEPENDANT_LAYER_VERSION_2,
352                 1, // number of dependencies for layer
353                 SUBSCRIPTION_UNSUPPORTED_LAYER_ID,
354                 MOCK_PUBLISHER_LAYER_SUBTYPE,
355                 SUBSCRIPTION_UNSUPPORTED_LAYER_VERSION
356         );
357 
358         Set<VmsAssociatedLayer> associatedLayers =
359                 new HashSet<>(Arrays.asList(
360                         SUBSCRIPTION_ASSOCIATED_LAYER,
361                         SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_1,
362                         SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_2
363                 ));
364 
365         // Verify applications API.
366         VmsAvailableLayers availableLayers = getMockSubscriberClient().receiveLayerAvailability();
367         assertEquals(associatedLayers, availableLayers.getAssociatedLayers());
368         assertEquals(1, availableLayers.getSequence());
369 
370         // Verify HAL API.
371         ArrayList<Integer> values = getMockHalClient().receiveMessage().value.int32Values;
372         int messageType = values.get(VmsAvailabilityStateIntegerValuesIndex.MESSAGE_TYPE);
373         int sequenceNumber = values.get(VmsAvailabilityStateIntegerValuesIndex.SEQUENCE_NUMBER);
374         int numberLayers =
375                 values.get(VmsAvailabilityStateIntegerValuesIndex.NUMBER_OF_ASSOCIATED_LAYERS);
376 
377         assertEquals(messageType, VmsMessageType.AVAILABILITY_CHANGE);
378         assertEquals(1, sequenceNumber);
379         assertEquals(3, numberLayers);
380     }
381 
382     // Test injecting a value in the HAL twice the sequence for availability is incremented.
383     @Test
testDoubleOfferingAvailableLayers()384     public void testDoubleOfferingAvailableLayers() throws Exception {
385         //
386         // Offering:
387         // Layer             | Dependency
388         // ===============================
389         // (2, 3, 444), [17] | {}
390 
391         // Expected availability:
392         // {(2, 3, 444 [17])}
393         //
394         int[] offeringMessage = {
395                 VmsMessageType.OFFERING, // MessageType
396                 PUBLISHER_ID,
397                 1, // Number of offered layers
398 
399                 SUBSCRIPTION_LAYER_ID,
400                 MOCK_PUBLISHER_LAYER_SUBTYPE,
401                 SUBSCRIPTION_LAYER_VERSION,
402                 0 // number of dependencies for layer
403         };
404 
405         // Inject first offer.
406         getMockHalClient().sendMessage(offeringMessage);
407 
408         // Verify applications API.
409         VmsAvailableLayers availableLayers = getMockSubscriberClient().receiveLayerAvailability();
410         assertEquals(
411                 Collections.singleton(SUBSCRIPTION_ASSOCIATED_LAYER),
412                 availableLayers.getAssociatedLayers());
413         assertEquals(1, availableLayers.getSequence());
414 
415         // Verify HAL API.
416         ArrayList<Integer> values = getMockHalClient().receiveMessage().value.int32Values;
417         int messageType = values.get(VmsAvailabilityStateIntegerValuesIndex.MESSAGE_TYPE);
418         int sequenceNumber = values.get(VmsAvailabilityStateIntegerValuesIndex.SEQUENCE_NUMBER);
419         int numberLayers =
420                 values.get(VmsAvailabilityStateIntegerValuesIndex.NUMBER_OF_ASSOCIATED_LAYERS);
421 
422         assertEquals(messageType, VmsMessageType.AVAILABILITY_CHANGE);
423         assertEquals(1, sequenceNumber);
424         assertEquals(1, numberLayers);
425 
426         int[] offeringMessage2 = {
427                 VmsMessageType.OFFERING, // MessageType
428                 PUBLISHER_ID,
429                 2, // Number of offered layers
430 
431                 SUBSCRIPTION_LAYER_ID,
432                 MOCK_PUBLISHER_LAYER_SUBTYPE,
433                 SUBSCRIPTION_LAYER_VERSION,
434                 0, // number of dependencies for layer
435 
436                 SUBSCRIPTION_DEPENDANT_LAYER_ID_1,
437                 MOCK_PUBLISHER_LAYER_SUBTYPE,
438                 SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1,
439                 1, // number of dependencies for layer
440                 SUBSCRIPTION_LAYER_ID,
441                 MOCK_PUBLISHER_LAYER_SUBTYPE,
442                 SUBSCRIPTION_LAYER_VERSION,
443         };
444 
445 
446         // Inject second offer.
447         getMockHalClient().sendMessage(offeringMessage2);
448 
449         // Verify applications API.
450         availableLayers = getMockSubscriberClient().receiveLayerAvailability();
451         assertEquals(
452                 new HashSet<>(Arrays.asList(
453                         SUBSCRIPTION_ASSOCIATED_LAYER,
454                         SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_1
455                 )),
456                 availableLayers.getAssociatedLayers());
457         assertEquals(2, availableLayers.getSequence());
458 
459         // Verify HAL API.
460         values = getMockHalClient().receiveMessage().value.int32Values;
461         messageType = values.get(VmsAvailabilityStateIntegerValuesIndex.MESSAGE_TYPE);
462         sequenceNumber = values.get(VmsAvailabilityStateIntegerValuesIndex.SEQUENCE_NUMBER);
463         numberLayers =
464                 values.get(VmsAvailabilityStateIntegerValuesIndex.NUMBER_OF_ASSOCIATED_LAYERS);
465 
466         assertEquals(messageType, VmsMessageType.AVAILABILITY_CHANGE);
467         assertEquals(2, sequenceNumber);
468         assertEquals(2, numberLayers);
469 
470     }
471 
472     // Test GetAvailableLayers().
473     @Test
testGetAvailableLayers()474     public void testGetAvailableLayers() throws Exception {
475         //
476         // Offering:
477         // Layer             | Dependency
478         // ===============================
479         // (2, 3, 444), [17] | {}
480 
481         // Expected availability:
482         // {(2, 3, 444 [17])}
483         //
484         getMockHalClient().sendMessage(
485                 VmsMessageType.OFFERING, // MessageType
486                 PUBLISHER_ID,
487                 1, // Number of offered layers
488 
489                 SUBSCRIPTION_LAYER_ID,
490                 MOCK_PUBLISHER_LAYER_SUBTYPE,
491                 SUBSCRIPTION_LAYER_VERSION,
492                 0 // number of dependencies for layer
493         );
494 
495         // Wait for an availability update to the subscriber to guarantee the state is settled.
496         getMockSubscriberClient().receiveLayerAvailability();
497 
498         VmsAvailableLayers availableLayers = getSubscriberManager().getAvailableLayers();
499         assertEquals(
500                 Collections.singleton(SUBSCRIPTION_ASSOCIATED_LAYER),
501                 availableLayers.getAssociatedLayers());
502         assertEquals(1, availableLayers.getSequence());
503     }
504 }
505