• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Car;
23 import android.car.VehicleAreaType;
24 import android.car.vms.VmsAssociatedLayer;
25 import android.car.vms.VmsAvailableLayers;
26 import android.car.vms.VmsLayer;
27 import android.car.vms.VmsSubscriberManager;
28 import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
29 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess;
30 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode;
31 import android.support.test.filters.MediumTest;
32 import android.support.test.runner.AndroidJUnit4;
33 
34 import com.android.car.vehiclehal.test.MockedVehicleHal;
35 
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Set;
44 import java.util.concurrent.Executor;
45 import java.util.concurrent.Semaphore;
46 import java.util.concurrent.TimeUnit;
47 
48 @RunWith(AndroidJUnit4.class)
49 @MediumTest
50 public class VmsPublisherSubscriberTest extends MockedCarTestBase {
51     private static final int LAYER_ID = 88;
52     private static final int LAYER_VERSION = 19;
53     private static final int LAYER_SUBTYPE = 55;
54     private static final String TAG = "VmsPubSubTest";
55 
56     // The expected publisher ID is 0 since it the expected assigned ID from the VMS core.
57     public static final int EXPECTED_PUBLISHER_ID = 0;
58     public static final VmsLayer LAYER = new VmsLayer(LAYER_ID, LAYER_SUBTYPE, LAYER_VERSION);
59     public static final VmsAssociatedLayer ASSOCIATED_LAYER =
60             new VmsAssociatedLayer(LAYER, new HashSet<>(Arrays.asList(EXPECTED_PUBLISHER_ID)));
61     public static final byte[] PAYLOAD = new byte[]{2, 3, 5, 7, 11, 13, 17};
62 
63     private static final List<VmsAssociatedLayer> AVAILABLE_ASSOCIATED_LAYERS =
64             new ArrayList<>(Arrays.asList(ASSOCIATED_LAYER));
65     private static final VmsAvailableLayers AVAILABLE_LAYERS_WITH_SEQ =
66             new VmsAvailableLayers(
67                     new HashSet(AVAILABLE_ASSOCIATED_LAYERS), 1);
68 
69 
70     private static final int SUBSCRIBED_LAYER_ID = 89;
71     public static final VmsLayer SUBSCRIBED_LAYER =
72             new VmsLayer(SUBSCRIBED_LAYER_ID, LAYER_SUBTYPE, LAYER_VERSION);
73     public static final VmsAssociatedLayer ASSOCIATED_SUBSCRIBED_LAYER =
74             new VmsAssociatedLayer(SUBSCRIBED_LAYER,
75                     new HashSet<>(Arrays.asList(EXPECTED_PUBLISHER_ID)));
76     private static final List<VmsAssociatedLayer>
77             AVAILABLE_ASSOCIATED_LAYERS_WITH_SUBSCRIBED_LAYER =
78             new ArrayList<>(Arrays.asList(ASSOCIATED_LAYER, ASSOCIATED_SUBSCRIBED_LAYER));
79     private static final VmsAvailableLayers AVAILABLE_LAYERS_WITH_SUBSCRIBED_LAYER_WITH_SEQ =
80             new VmsAvailableLayers(
81                     new HashSet(AVAILABLE_ASSOCIATED_LAYERS_WITH_SUBSCRIBED_LAYER), 1);
82     VmsSubscriberManager mVmsSubscriberManager;
83     TestClientCallback mClientCallback;
84     private HalHandler mHalHandler;
85     // Used to block until a value is propagated to the TestClientCallback.onVmsMessageReceived.
86     private Semaphore mSubscriberSemaphore;
87     private Semaphore mAvailabilitySemaphore;
88     private Executor mExecutor;
89 
90     private class ThreadPerTaskExecutor implements Executor {
execute(Runnable r)91         public void execute(Runnable r) {
92             new Thread(r).start();
93         }
94     }
95 
96 
97     @Override
configureMockedHal()98     protected synchronized void configureMockedHal() {
99         mHalHandler = new HalHandler();
100         addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalHandler)
101                 .setChangeMode(VehiclePropertyChangeMode.ON_CHANGE)
102                 .setAccess(VehiclePropertyAccess.READ_WRITE)
103                 .addAreaConfig(VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, 0, 0);
104     }
105 
106     @Override
configureResourceOverrides(MockResources resources)107     protected synchronized void configureResourceOverrides(MockResources resources) {
108         resources.overrideResource(com.android.car.R.array.vmsPublisherClients,
109                 new String[]{getFlattenComponent(VmsPublisherClientMockService.class)});
110     }
111 
112     /*
113      * The method setUp initializes all the Car services, including the VmsPublisherService.
114      * The VmsPublisherService will start and configure its list of clients. This list was
115      * overridden in the method getCarServiceContext. Therefore, only VmsPublisherClientMockService
116      * will be started. Method setUp() subscribes to a layer and triggers
117      * VmsPublisherClientMockService.onVmsSubscriptionChange.
118      * There is a race condition between publisher and subscriber starting time.
119      * So we wanted to make sure that the tests start only after the publisher is up. We achieve
120      * this by subscribing in setUp() and waiting on the semaphore at the beginning of each test
121      * case.
122      */
123 
124     @Override
setUp()125     public void setUp() throws Exception {
126         mExecutor = new ThreadPerTaskExecutor();
127         super.setUp();
128         mSubscriberSemaphore = new Semaphore(0);
129         mAvailabilitySemaphore = new Semaphore(0);
130 
131         mVmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
132                 Car.VMS_SUBSCRIBER_SERVICE);
133         mClientCallback = new TestClientCallback();
134         mVmsSubscriberManager.setVmsSubscriberClientCallback(mExecutor, mClientCallback);
135         mVmsSubscriberManager.subscribe(LAYER);
136     }
137 
postSetup()138     public void postSetup() throws Exception {
139         assertTrue(mAvailabilitySemaphore.tryAcquire(2L, TimeUnit.SECONDS));
140     }
141 
142     /*
143      * This test method subscribes to a layer and triggers
144      * VmsPublisherClientMockService.onVmsSubscriptionChange. In turn, the mock service will publish
145      * a message, which is validated in this test.
146      */
147 
148     @Test
testPublisherToSubscriber()149     public void testPublisherToSubscriber() throws Exception {
150         postSetup();
151         assertEquals(LAYER, mClientCallback.getLayer());
152         assertTrue(Arrays.equals(PAYLOAD, mClientCallback.getPayload()));
153     }
154 
155     /**
156      * The Mock service will get a publisher ID by sending its information when it will get
157      * ServiceReady as well as on SubscriptionChange. Since clients are not notified when
158      * publishers are assigned IDs, this test waits until the availability is changed which
159      * indicates
160      * that the Mock service has gotten its ServiceReady and publisherId.
161      */
162 
163 
164     @Test
testPublisherInfo()165     public void testPublisherInfo() throws Exception {
166         postSetup();
167 
168         // Inject a value and wait for its callback in TestClientCallback.onVmsMessageReceived.
169         byte[] info = mVmsSubscriberManager.getPublisherInfo(EXPECTED_PUBLISHER_ID);
170         assertTrue(Arrays.equals(PAYLOAD, info));
171     }
172 
173     /*
174      * The Mock service offers all the subscribed layers as available layers.
175      * In this test the client subscribes to a layer and verifies that it gets the
176      * notification that it is available.
177      */
178 
179     @Test
testAvailabilityWithSubscription()180     public void testAvailabilityWithSubscription() throws Exception {
181         postSetup();
182         mVmsSubscriberManager.subscribe(SUBSCRIBED_LAYER);
183         assertTrue(mAvailabilitySemaphore.tryAcquire(2L, TimeUnit.SECONDS));
184 
185         final Set<VmsAssociatedLayer> associatedLayers =
186                 AVAILABLE_LAYERS_WITH_SUBSCRIBED_LAYER_WITH_SEQ.getAssociatedLayers();
187         assertEquals(associatedLayers, mClientCallback.getAvailableLayers().getAssociatedLayers());
188         assertEquals(associatedLayers,
189                 mVmsSubscriberManager.getAvailableLayers().getAssociatedLayers());
190     }
191 
192     private class HalHandler implements MockedVehicleHal.VehicleHalPropertyHandler {
193     }
194 
195     private class TestClientCallback implements VmsSubscriberManager.VmsSubscriberClientCallback {
196         private VmsLayer mLayer;
197         private byte[] mPayload;
198         private VmsAvailableLayers mAvailableLayers;
199 
200         @Override
onVmsMessageReceived(VmsLayer layer, byte[] payload)201         public void onVmsMessageReceived(VmsLayer layer, byte[] payload) {
202             assertEquals(LAYER, layer);
203             assertTrue(Arrays.equals(PAYLOAD, payload));
204             mLayer = layer;
205             mPayload = payload;
206             mSubscriberSemaphore.release();
207         }
208 
209         @Override
onLayersAvailabilityChanged(VmsAvailableLayers availableLayers)210         public void onLayersAvailabilityChanged(VmsAvailableLayers availableLayers) {
211             mAvailableLayers = availableLayers;
212             mAvailabilitySemaphore.release();
213         }
214 
getLayer()215         public VmsLayer getLayer() {
216             return mLayer;
217         }
218 
getPayload()219         public byte[] getPayload() {
220             return mPayload;
221         }
222 
getAvailableLayers()223         public VmsAvailableLayers getAvailableLayers() {
224             return mAvailableLayers;
225         }
226     }
227 }
228