blob: ef33b31fbcfcf9cf7b23e71ba3d21e53a670b2f9 [file] [log] [blame]
Antonio Cortes734010a2017-01-19 20:09:22 -08001/*
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 */
16package com.android.car.hal;
17
asafro99e4f082017-02-09 13:11:42 -080018import static com.android.car.CarServiceUtils.toByteArray;
Anna Linetsky5c45fca2018-04-26 14:29:16 -070019
Antonio Cortes734010a2017-01-19 20:09:22 -080020import static java.lang.Integer.toHexString;
21
Asaf Rosenfeld39e4f032017-09-16 11:33:50 -070022import android.annotation.SystemApi;
Antonio Cortes734010a2017-01-19 20:09:22 -080023import android.car.VehicleAreaType;
Asaf Rosenfeld2ca6f8c2017-03-20 12:59:33 -070024import android.car.vms.IVmsSubscriberClient;
Asaf Rosenfeld43900532017-06-16 11:16:55 -070025import android.car.vms.VmsAssociatedLayer;
Asaf Rosenfeld908811e2018-01-22 09:13:47 -080026import android.car.vms.VmsAvailableLayers;
Anna Linetsky5c45fca2018-04-26 14:29:16 -070027import android.car.vms.VmsLayer;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070028import android.car.vms.VmsLayerDependency;
29import android.car.vms.VmsLayersOffering;
Demyn Plantenberg3ca12892017-06-20 21:01:34 -070030import android.car.vms.VmsOperationRecorder;
Antonio Cortes2febe9f2017-03-24 09:42:17 -070031import android.car.vms.VmsSubscriptionState;
Pavel Maltsevcfe93102017-02-02 12:38:08 -080032import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig;
33import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
Pavel Maltsev99e1a752017-08-24 15:15:05 -070034import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
35import android.hardware.automotive.vehicle.V2_0.VmsBaseMessageIntegerValuesIndex;
36import android.hardware.automotive.vehicle.V2_0.VmsMessageType;
37import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerAndPublisherIdIntegerValuesIndex;
Pavel Maltsev99e1a752017-08-24 15:15:05 -070038import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerIntegerValuesIndex;
Anna Linetsky5c45fca2018-04-26 14:29:16 -070039import android.hardware.automotive.vehicle.V2_0.VmsOfferingMessageIntegerValuesIndex;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070040import android.os.Binder;
41import android.os.IBinder;
Antonio Cortes734010a2017-01-19 20:09:22 -080042import android.util.Log;
Anna Linetsky5c45fca2018-04-26 14:29:16 -070043
Antonio Cortes734010a2017-01-19 20:09:22 -080044import com.android.car.CarLog;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070045import com.android.car.VmsLayersAvailability;
Asaf Rosenfeld60284892017-05-19 12:59:56 -070046import com.android.car.VmsPublishersInfo;
asafro25a87402017-02-28 16:08:17 -080047import com.android.car.VmsRouting;
Antonio Cortes734010a2017-01-19 20:09:22 -080048import com.android.internal.annotations.GuardedBy;
Asaf Rosenfeld43900532017-06-16 11:16:55 -070049
Antonio Cortes734010a2017-01-19 20:09:22 -080050import java.io.PrintWriter;
Antonio Cortes40b90262017-02-06 11:43:57 -080051import java.util.ArrayList;
Anna Linetsky5c45fca2018-04-26 14:29:16 -070052import java.util.Arrays;
Antonio Cortes734010a2017-01-19 20:09:22 -080053import java.util.Collection;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070054import java.util.Collections;
55import java.util.HashMap;
asafro99e4f082017-02-09 13:11:42 -080056import java.util.HashSet;
Antonio Cortes734010a2017-01-19 20:09:22 -080057import java.util.LinkedList;
58import java.util.List;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070059import java.util.Map;
asafro99e4f082017-02-09 13:11:42 -080060import java.util.Set;
asafro99e4f082017-02-09 13:11:42 -080061import java.util.concurrent.CopyOnWriteArrayList;
Antonio Cortes734010a2017-01-19 20:09:22 -080062
63/**
64 * This is a glue layer between the VehicleHal and the VmsService. It sends VMS properties back and
65 * forth.
66 */
Asaf Rosenfeld39e4f032017-09-16 11:33:50 -070067@SystemApi
Antonio Cortes734010a2017-01-19 20:09:22 -080068public class VmsHalService extends HalServiceBase {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070069
Antonio Cortes734010a2017-01-19 20:09:22 -080070 private static final boolean DBG = true;
71 private static final int HAL_PROPERTY_ID = VehicleProperty.VEHICLE_MAP_SERVICE;
72 private static final String TAG = "VmsHalService";
73
Asaf Rosenfeld43900532017-06-16 11:16:55 -070074 private final static List<Integer> AVAILABILITY_MESSAGE_TYPES = Collections.unmodifiableList(
75 Arrays.asList(
76 VmsMessageType.AVAILABILITY_RESPONSE,
77 VmsMessageType.AVAILABILITY_CHANGE));
78
Antonio Cortes734010a2017-01-19 20:09:22 -080079 private boolean mIsSupported = false;
asafro99e4f082017-02-09 13:11:42 -080080 private CopyOnWriteArrayList<VmsHalPublisherListener> mPublisherListeners =
Asaf Rosenfeld43900532017-06-16 11:16:55 -070081 new CopyOnWriteArrayList<>();
asafro99e4f082017-02-09 13:11:42 -080082 private CopyOnWriteArrayList<VmsHalSubscriberListener> mSubscriberListeners =
Asaf Rosenfeld43900532017-06-16 11:16:55 -070083 new CopyOnWriteArrayList<>();
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070084
85 private final IBinder mHalPublisherToken = new Binder();
Antonio Cortes734010a2017-01-19 20:09:22 -080086 private final VehicleHal mVehicleHal;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070087
Asaf Rosenfeld60284892017-05-19 12:59:56 -070088 private final Object mLock = new Object();
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070089 private final VmsRouting mRouting = new VmsRouting();
Asaf Rosenfeld60284892017-05-19 12:59:56 -070090 @GuardedBy("mLock")
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070091 private final Map<IBinder, VmsLayersOffering> mOfferings = new HashMap<>();
Asaf Rosenfeld60284892017-05-19 12:59:56 -070092 @GuardedBy("mLock")
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -070093 private final VmsLayersAvailability mAvailableLayers = new VmsLayersAvailability();
Asaf Rosenfeld60284892017-05-19 12:59:56 -070094 private final VmsPublishersInfo mPublishersInfo = new VmsPublishersInfo();
Antonio Cortes734010a2017-01-19 20:09:22 -080095
96 /**
asafro99e4f082017-02-09 13:11:42 -080097 * The VmsPublisherService implements this interface to receive data from the HAL.
98 */
99 public interface VmsHalPublisherListener {
Antonio Cortes2febe9f2017-03-24 09:42:17 -0700100 void onChange(VmsSubscriptionState subscriptionState);
asafro99e4f082017-02-09 13:11:42 -0800101 }
102
103 /**
104 * The VmsSubscriberService implements this interface to receive data from the HAL.
105 */
106 public interface VmsHalSubscriberListener {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700107 // Notifies the listener on a data Message from a publisher.
108 void onDataMessage(VmsLayer layer, int publisherId, byte[] payload);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700109
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700110 // Notifies the listener on a change in available layers.
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800111 void onLayersAvaiabilityChange(VmsAvailableLayers availableLayers);
asafro99e4f082017-02-09 13:11:42 -0800112 }
113
114 /**
Antonio Cortes734010a2017-01-19 20:09:22 -0800115 * The VmsService implements this interface to receive data from the HAL.
116 */
Antonio Cortes734010a2017-01-19 20:09:22 -0800117 protected VmsHalService(VehicleHal vehicleHal) {
118 mVehicleHal = vehicleHal;
119 if (DBG) {
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700120 Log.d(TAG, "Started VmsHalService!");
Antonio Cortes734010a2017-01-19 20:09:22 -0800121 }
122 }
123
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700124 /**
125 * VMS subscribers should wait for a layers availability message which indicates
126 * the subscriber service is ready to handle subscription requests.
127 */
128 public void signalSubscriberServiceIsReady() {
129 notifyOfAvailabilityChange();
130 }
131
132 /**
133 * VMS publishers should wait for a subscription state message which indicates
134 * the publisher service is ready to handle offerings and publishing.
135 */
136 public void signalPublisherServiceIsReady() {
137 notifyOfSubscriptionChange();
138 }
139
asafro99e4f082017-02-09 13:11:42 -0800140 public void addPublisherListener(VmsHalPublisherListener listener) {
141 mPublisherListeners.add(listener);
Antonio Cortes40b90262017-02-06 11:43:57 -0800142 }
143
asafro99e4f082017-02-09 13:11:42 -0800144 public void addSubscriberListener(VmsHalSubscriberListener listener) {
145 mSubscriberListeners.add(listener);
Antonio Cortes734010a2017-01-19 20:09:22 -0800146 }
147
asafro99e4f082017-02-09 13:11:42 -0800148 public void removePublisherListener(VmsHalPublisherListener listener) {
149 mPublisherListeners.remove(listener);
Antonio Cortes734010a2017-01-19 20:09:22 -0800150 }
151
asafro99e4f082017-02-09 13:11:42 -0800152 public void removeSubscriberListener(VmsHalSubscriberListener listener) {
153 mSubscriberListeners.remove(listener);
Antonio Cortes734010a2017-01-19 20:09:22 -0800154 }
155
Asaf Rosenfeld2ca6f8c2017-03-20 12:59:33 -0700156 public void addSubscription(IVmsSubscriberClient listener, VmsLayer layer) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700157 boolean firstSubscriptionForLayer = false;
Anna Linetsky5c45fca2018-04-26 14:29:16 -0700158 if (DBG) {
159 Log.d(TAG, "Checking for first subscription. Layer: " + layer);
160 }
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700161 synchronized (mLock) {
asafro25a87402017-02-28 16:08:17 -0800162 // Check if publishers need to be notified about this change in subscriptions.
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700163 firstSubscriptionForLayer = !mRouting.hasLayerSubscriptions(layer);
asafro25a87402017-02-28 16:08:17 -0800164
165 // Add the listeners subscription to the layer
166 mRouting.addSubscription(listener, layer);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700167 }
168 if (firstSubscriptionForLayer) {
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700169 notifyHalPublishers(layer, true);
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700170 notifyOfSubscriptionChange();
asafro25a87402017-02-28 16:08:17 -0800171 }
172 }
173
Asaf Rosenfeld2ca6f8c2017-03-20 12:59:33 -0700174 public void removeSubscription(IVmsSubscriberClient listener, VmsLayer layer) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700175 boolean layerHasSubscribers = true;
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700176 synchronized (mLock) {
asafro25a87402017-02-28 16:08:17 -0800177 if (!mRouting.hasLayerSubscriptions(layer)) {
Anna Linetsky5c45fca2018-04-26 14:29:16 -0700178 if (DBG) {
179 Log.d(TAG, "Trying to remove a layer with no subscription: " + layer);
180 }
asafro25a87402017-02-28 16:08:17 -0800181 return;
182 }
183
184 // Remove the listeners subscription to the layer
185 mRouting.removeSubscription(listener, layer);
186
187 // Check if publishers need to be notified about this change in subscriptions.
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700188 layerHasSubscribers = mRouting.hasLayerSubscriptions(layer);
189 }
190 if (!layerHasSubscribers) {
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700191 notifyHalPublishers(layer, false);
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700192 notifyOfSubscriptionChange();
asafro25a87402017-02-28 16:08:17 -0800193 }
194 }
195
Asaf Rosenfeld2ca6f8c2017-03-20 12:59:33 -0700196 public void addSubscription(IVmsSubscriberClient listener) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700197 synchronized (mLock) {
asafro25a87402017-02-28 16:08:17 -0800198 mRouting.addSubscription(listener);
199 }
200 }
201
Asaf Rosenfeld2ca6f8c2017-03-20 12:59:33 -0700202 public void removeSubscription(IVmsSubscriberClient listener) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700203 synchronized (mLock) {
asafro25a87402017-02-28 16:08:17 -0800204 mRouting.removeSubscription(listener);
205 }
206 }
207
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700208 public void addSubscription(IVmsSubscriberClient listener, VmsLayer layer, int publisherId) {
209 boolean firstSubscriptionForLayer = false;
210 synchronized (mLock) {
211 // Check if publishers need to be notified about this change in subscriptions.
212 firstSubscriptionForLayer = !(mRouting.hasLayerSubscriptions(layer) ||
213 mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId));
214
215 // Add the listeners subscription to the layer
216 mRouting.addSubscription(listener, layer, publisherId);
217 }
218 if (firstSubscriptionForLayer) {
219 notifyHalPublishers(layer, true);
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700220 notifyOfSubscriptionChange();
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700221 }
222 }
223
224 public void removeSubscription(IVmsSubscriberClient listener, VmsLayer layer, int publisherId) {
225 boolean layerHasSubscribers = true;
226 synchronized (mLock) {
227 if (!mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId)) {
228 Log.i(TAG, "Trying to remove a layer with no subscription: " +
229 layer + ", publisher ID:" + publisherId);
230 return;
231 }
232
233 // Remove the listeners subscription to the layer
234 mRouting.removeSubscription(listener, layer, publisherId);
235
236 // Check if publishers need to be notified about this change in subscriptions.
237 layerHasSubscribers = mRouting.hasLayerSubscriptions(layer) ||
238 mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId);
239 }
240 if (!layerHasSubscribers) {
241 notifyHalPublishers(layer, false);
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700242 notifyOfSubscriptionChange();
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700243 }
244 }
245
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700246 public void removeDeadSubscriber(IVmsSubscriberClient listener) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700247 synchronized (mLock) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700248 mRouting.removeDeadSubscriber(listener);
asafro25a87402017-02-28 16:08:17 -0800249 }
250 }
251
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700252 public Set<IVmsSubscriberClient> getSubscribersForLayerFromPublisher(VmsLayer layer,
253 int publisherId) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700254 synchronized (mLock) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700255 return mRouting.getSubscribersForLayerFromPublisher(layer, publisherId);
Antonio Cortes8b350092017-03-16 16:02:51 -0700256 }
asafro25a87402017-02-28 16:08:17 -0800257 }
258
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700259 public Set<IVmsSubscriberClient> getAllSubscribers() {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700260 synchronized (mLock) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700261 return mRouting.getAllSubscribers();
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700262 }
263 }
264
asafro25a87402017-02-28 16:08:17 -0800265 public boolean isHalSubscribed(VmsLayer layer) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700266 synchronized (mLock) {
Antonio Cortes8b350092017-03-16 16:02:51 -0700267 return mRouting.isHalSubscribed(layer);
268 }
asafro25a87402017-02-28 16:08:17 -0800269 }
270
Antonio Cortes2febe9f2017-03-24 09:42:17 -0700271 public VmsSubscriptionState getSubscriptionState() {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700272 synchronized (mLock) {
Antonio Cortes2febe9f2017-03-24 09:42:17 -0700273 return mRouting.getSubscriptionState();
Antonio Cortes8b350092017-03-16 16:02:51 -0700274 }
asafro25a87402017-02-28 16:08:17 -0800275 }
276
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700277 /**
278 * Assigns an idempotent ID for publisherInfo and stores it. The idempotency in this case means
279 * that the same publisherInfo will always, within a trip of the vehicle, return the same ID.
280 * The publisherInfo should be static for a binary and should only change as part of a software
281 * update. The publisherInfo is a serialized proto message which VMS clients can interpret.
282 */
Asaf Rosenfeld2e45d812017-08-31 23:51:12 -0700283 public int getPublisherId(byte[] publisherInfo) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700284 if (DBG) {
285 Log.i(TAG, "Getting publisher static ID");
286 }
287 synchronized (mLock) {
288 return mPublishersInfo.getIdForInfo(publisherInfo);
289 }
290 }
291
292 public byte[] getPublisherInfo(int publisherId) {
293 if (DBG) {
294 Log.i(TAG, "Getting information for publisher ID: " + publisherId);
295 }
296 synchronized (mLock) {
297 return mPublishersInfo.getPublisherInfo(publisherId);
298 }
299 }
300
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700301 private void addHalSubscription(VmsLayer layer) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700302 boolean firstSubscriptionForLayer = true;
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700303 synchronized (mLock) {
asafro25a87402017-02-28 16:08:17 -0800304 // Check if publishers need to be notified about this change in subscriptions.
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700305 firstSubscriptionForLayer = !mRouting.hasLayerSubscriptions(layer);
asafro25a87402017-02-28 16:08:17 -0800306
307 // Add the listeners subscription to the layer
308 mRouting.addHalSubscription(layer);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700309 }
310 if (firstSubscriptionForLayer) {
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700311 notifyHalPublishers(layer, true);
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700312 notifyOfSubscriptionChange();
asafro25a87402017-02-28 16:08:17 -0800313 }
314 }
315
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700316 private void addHalSubscriptionToPublisher(VmsLayer layer, int publisherId) {
317 boolean firstSubscriptionForLayer = true;
318 synchronized (mLock) {
319 // Check if publishers need to be notified about this change in subscriptions.
320 firstSubscriptionForLayer = !(mRouting.hasLayerSubscriptions(layer) ||
321 mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId));
322
323 // Add the listeners subscription to the layer
324 mRouting.addHalSubscriptionToPublisher(layer, publisherId);
325 }
326 if (firstSubscriptionForLayer) {
327 notifyHalPublishers(layer, publisherId, true);
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700328 notifyOfSubscriptionChange();
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700329 }
330 }
331
332 private void removeHalSubscription(VmsLayer layer) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700333 boolean layerHasSubscribers = true;
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700334 synchronized (mLock) {
asafro25a87402017-02-28 16:08:17 -0800335 if (!mRouting.hasLayerSubscriptions(layer)) {
336 Log.i(TAG, "Trying to remove a layer with no subscription: " + layer);
337 return;
338 }
339
340 // Remove the listeners subscription to the layer
341 mRouting.removeHalSubscription(layer);
342
343 // Check if publishers need to be notified about this change in subscriptions.
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700344 layerHasSubscribers = mRouting.hasLayerSubscriptions(layer);
345 }
346 if (!layerHasSubscribers) {
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700347 notifyHalPublishers(layer, false);
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700348 notifyOfSubscriptionChange();
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700349 }
350 }
351
352 public void removeHalSubscriptionFromPublisher(VmsLayer layer, int publisherId) {
353 boolean layerHasSubscribers = true;
354 synchronized (mLock) {
355 if (!mRouting.hasLayerSubscriptions(layer)) {
356 Log.i(TAG, "Trying to remove a layer with no subscription: " + layer);
357 return;
358 }
359
360 // Remove the listeners subscription to the layer
361 mRouting.removeHalSubscriptionToPublisher(layer, publisherId);
362
363 // Check if publishers need to be notified about this change in subscriptions.
364 layerHasSubscribers = mRouting.hasLayerSubscriptions(layer) ||
365 mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId);
366 }
367 if (!layerHasSubscribers) {
368 notifyHalPublishers(layer, publisherId, false);
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700369 notifyOfSubscriptionChange();
asafro25a87402017-02-28 16:08:17 -0800370 }
371 }
372
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700373 public boolean containsSubscriber(IVmsSubscriberClient subscriber) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700374 synchronized (mLock) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700375 return mRouting.containsSubscriber(subscriber);
Antonio Cortes8b350092017-03-16 16:02:51 -0700376 }
asafro25a87402017-02-28 16:08:17 -0800377 }
378
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700379 public void setPublisherLayersOffering(IBinder publisherToken, VmsLayersOffering offering) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700380 synchronized (mLock) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700381 updateOffering(publisherToken, offering);
Demyn Plantenberg3ca12892017-06-20 21:01:34 -0700382 VmsOperationRecorder.get().setPublisherLayersOffering(offering);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700383 }
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700384 }
385
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800386 public VmsAvailableLayers getAvailableLayers() {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700387 synchronized (mLock) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700388 return mAvailableLayers.getAvailableLayers();
389 }
390 }
391
asafro25a87402017-02-28 16:08:17 -0800392 /**
393 * Notify all the publishers and the HAL on subscription changes regardless of who triggered
394 * the change.
395 *
Antonio Cortes9db963a2017-03-10 15:15:28 -0800396 * @param layer layer which is being subscribed to or unsubscribed from.
397 * @param hasSubscribers indicates if the notification is for subscription or unsubscription.
asafro25a87402017-02-28 16:08:17 -0800398 */
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700399 private void notifyHalPublishers(VmsLayer layer, boolean hasSubscribers) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700400 // notify the HAL
401 setSubscriptionRequest(layer, hasSubscribers);
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700402 }
asafro25a87402017-02-28 16:08:17 -0800403
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700404 private void notifyHalPublishers(VmsLayer layer, int publisherId, boolean hasSubscribers) {
405 // notify the HAL
406 setSubscriptionToPublisherRequest(layer, publisherId, hasSubscribers);
407 }
408
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700409 private void notifyOfSubscriptionChange() {
410 if (DBG) {
411 Log.d(TAG, "Notifying publishers on subscriptions");
412 }
413
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700414 // Notify the App publishers
415 for (VmsHalPublisherListener listener : mPublisherListeners) {
416 // Besides the list of layers, also a timestamp is provided to the clients.
417 // They should ignore any notification with a timestamp that is older than the most
418 // recent timestamp they have seen.
419 listener.onChange(getSubscriptionState());
420 }
421 }
422
423 /**
424 * Notify all the subscribers and the HAL on layers availability change.
425 *
426 * @param availableLayers the layers which publishers claim they made publish.
427 */
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700428 private void notifyOfAvailabilityChange() {
429 if (DBG) {
430 Log.d(TAG, "Notifying subscribers on layers availability");
431 }
432
433 VmsAvailableLayers availableLayers;
434 synchronized (mLock) {
435 availableLayers = mAvailableLayers.getAvailableLayers();
436 }
437
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700438 // notify the HAL
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700439 notifyAvailabilityChangeToHal(availableLayers);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700440
441 // Notify the App subscribers
442 for (VmsHalSubscriberListener listener : mSubscriberListeners) {
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800443 listener.onLayersAvaiabilityChange(availableLayers);
asafro25a87402017-02-28 16:08:17 -0800444 }
445 }
446
Antonio Cortes734010a2017-01-19 20:09:22 -0800447 @Override
448 public void init() {
Antonio Cortes734010a2017-01-19 20:09:22 -0800449 if (mIsSupported) {
Pavel Maltsev79d5e122017-03-24 12:46:40 -0700450 mVehicleHal.subscribeProperty(this, HAL_PROPERTY_ID);
Asaf Rosenfeld4d473f42018-08-14 12:13:21 -0700451 if (DBG) {
452 Log.d(TAG, "Initializing VmsHalService VHAL property");
453 }
454 } else {
455 if (DBG) {
456 Log.d(TAG, "VmsHalService VHAL property not supported");
457 }
Antonio Cortes734010a2017-01-19 20:09:22 -0800458 }
459 }
460
461 @Override
462 public void release() {
463 if (DBG) {
Asaf Rosenfeld4d473f42018-08-14 12:13:21 -0700464 Log.d(TAG, "Releasing VmsHalService");
Antonio Cortes734010a2017-01-19 20:09:22 -0800465 }
466 if (mIsSupported) {
467 mVehicleHal.unsubscribeProperty(this, HAL_PROPERTY_ID);
468 }
asafro99e4f082017-02-09 13:11:42 -0800469 mPublisherListeners.clear();
470 mSubscriberListeners.clear();
Antonio Cortes734010a2017-01-19 20:09:22 -0800471 }
472
473 @Override
474 public Collection<VehiclePropConfig> takeSupportedProperties(
475 Collection<VehiclePropConfig> allProperties) {
476 List<VehiclePropConfig> taken = new LinkedList<>();
477 for (VehiclePropConfig p : allProperties) {
478 if (p.prop == HAL_PROPERTY_ID) {
479 taken.add(p);
480 mIsSupported = true;
481 if (DBG) {
482 Log.d(TAG, "takeSupportedProperties: " + toHexString(p.prop));
483 }
484 break;
485 }
486 }
487 return taken;
488 }
489
Antonio Cortese0824d72017-04-06 11:13:35 -0700490 /**
491 * Consumes/produces HAL messages. The format of these messages is defined in:
492 * hardware/interfaces/automotive/vehicle/2.1/types.hal
493 */
Antonio Cortes734010a2017-01-19 20:09:22 -0800494 @Override
495 public void handleHalEvents(List<VehiclePropValue> values) {
asafro25a87402017-02-28 16:08:17 -0800496 if (DBG) {
497 Log.d(TAG, "Handling a VMS property change");
498 }
asafro99e4f082017-02-09 13:11:42 -0800499 for (VehiclePropValue v : values) {
500 ArrayList<Integer> vec = v.value.int32Values;
Asaf Rosenfeld58e180b2017-07-27 21:06:30 -0700501 int messageType = vec.get(VmsBaseMessageIntegerValuesIndex.MESSAGE_TYPE);
asafro99e4f082017-02-09 13:11:42 -0800502
asafro25a87402017-02-28 16:08:17 -0800503 if (DBG) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700504 Log.d(TAG, "Handling VMS message type: " + messageType);
asafro25a87402017-02-28 16:08:17 -0800505 }
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700506 switch (messageType) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700507 case VmsMessageType.DATA:
508 handleDataEvent(vec, toByteArray(v.value.bytes));
509 break;
510 case VmsMessageType.SUBSCRIBE:
511 handleSubscribeEvent(vec);
512 break;
513 case VmsMessageType.UNSUBSCRIBE:
514 handleUnsubscribeEvent(vec);
515 break;
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700516 case VmsMessageType.SUBSCRIBE_TO_PUBLISHER:
517 handleSubscribeToPublisherEvent(vec);
518 break;
519 case VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER:
520 handleUnsubscribeFromPublisherEvent(vec);
521 break;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700522 case VmsMessageType.OFFERING:
523 handleOfferingEvent(vec);
524 break;
Asaf Rosenfeld1ab389c2017-04-25 11:24:17 -0700525 case VmsMessageType.AVAILABILITY_REQUEST:
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700526 handleHalAvailabilityRequestEvent();
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700527 break;
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700528 case VmsMessageType.SUBSCRIPTIONS_REQUEST:
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800529 handleSubscriptionsRequestEvent();
Antonio Cortese0824d72017-04-06 11:13:35 -0700530 break;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700531 default:
532 throw new IllegalArgumentException("Unexpected message type: " + messageType);
Antonio Cortes734010a2017-01-19 20:09:22 -0800533 }
534 }
535 }
536
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700537 private VmsLayer parseVmsLayerFromSimpleMessageIntegerValues(List<Integer> integerValues) {
Asaf Rosenfeld58e180b2017-07-27 21:06:30 -0700538 return new VmsLayer(integerValues.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_TYPE),
Asaf Rosenfeld2e45d812017-08-31 23:51:12 -0700539 integerValues.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_SUBTYPE),
540 integerValues.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_VERSION));
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700541 }
542
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700543 private VmsLayer parseVmsLayerFromDataMessageIntegerValues(List<Integer> integerValues) {
544 return parseVmsLayerFromSimpleMessageIntegerValues(integerValues);
545 }
546
547 private int parsePublisherIdFromDataMessageIntegerValues(List<Integer> integerValues) {
Asaf Rosenfeld58e180b2017-07-27 21:06:30 -0700548 return integerValues.get(VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.PUBLISHER_ID);
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700549 }
550
551
Antonio Cortese0824d72017-04-06 11:13:35 -0700552 /**
553 * Data message format:
554 * <ul>
555 * <li>Message type.
556 * <li>Layer id.
557 * <li>Layer version.
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700558 * <li>Layer subtype.
559 * <li>Publisher ID.
Antonio Cortese0824d72017-04-06 11:13:35 -0700560 * <li>Payload.
561 * </ul>
562 */
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700563 private void handleDataEvent(List<Integer> integerValues, byte[] payload) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700564 VmsLayer vmsLayer = parseVmsLayerFromDataMessageIntegerValues(integerValues);
565 int publisherId = parsePublisherIdFromDataMessageIntegerValues(integerValues);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700566 if (DBG) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700567 Log.d(TAG, "Handling a data event for Layer: " + vmsLayer);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700568 }
569
570 // Send the message.
571 for (VmsHalSubscriberListener listener : mSubscriberListeners) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700572 listener.onDataMessage(vmsLayer, publisherId, payload);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700573 }
574 }
575
Antonio Cortese0824d72017-04-06 11:13:35 -0700576 /**
577 * Subscribe message format:
578 * <ul>
579 * <li>Message type.
580 * <li>Layer id.
581 * <li>Layer version.
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700582 * <li>Layer subtype.
Antonio Cortese0824d72017-04-06 11:13:35 -0700583 * </ul>
584 */
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700585 private void handleSubscribeEvent(List<Integer> integerValues) {
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700586 VmsLayer vmsLayer = parseVmsLayerFromSimpleMessageIntegerValues(integerValues);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700587 if (DBG) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700588 Log.d(TAG, "Handling a subscribe event for Layer: " + vmsLayer);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700589 }
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700590 addHalSubscription(vmsLayer);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700591 }
592
Antonio Cortese0824d72017-04-06 11:13:35 -0700593 /**
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700594 * Subscribe message format:
595 * <ul>
596 * <li>Message type.
597 * <li>Layer id.
598 * <li>Layer version.
599 * <li>Layer subtype.
600 * <li>Publisher ID
601 * </ul>
602 */
603 private void handleSubscribeToPublisherEvent(List<Integer> integerValues) {
604 VmsLayer vmsLayer = parseVmsLayerFromSimpleMessageIntegerValues(integerValues);
605 if (DBG) {
606 Log.d(TAG, "Handling a subscribe event for Layer: " + vmsLayer);
607 }
608 int publisherId =
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700609 integerValues.get(VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.PUBLISHER_ID);
610 addHalSubscriptionToPublisher(vmsLayer, publisherId);
611 }
612
613 /**
Antonio Cortese0824d72017-04-06 11:13:35 -0700614 * Unsubscribe message format:
615 * <ul>
616 * <li>Message type.
617 * <li>Layer id.
618 * <li>Layer version.
619 * </ul>
620 */
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700621 private void handleUnsubscribeEvent(List<Integer> integerValues) {
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700622 VmsLayer vmsLayer = parseVmsLayerFromSimpleMessageIntegerValues(integerValues);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700623 if (DBG) {
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700624 Log.d(TAG, "Handling an unsubscribe event for Layer: " + vmsLayer);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700625 }
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700626 removeHalSubscription(vmsLayer);
627 }
628
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700629 /**
630 * Unsubscribe message format:
631 * <ul>
632 * <li>Message type.
633 * <li>Layer id.
634 * <li>Layer version.
635 * </ul>
636 */
637 private void handleUnsubscribeFromPublisherEvent(List<Integer> integerValues) {
638 VmsLayer vmsLayer = parseVmsLayerFromSimpleMessageIntegerValues(integerValues);
639 int publisherId =
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700640 integerValues.get(VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.PUBLISHER_ID);
641 if (DBG) {
642 Log.d(TAG, "Handling an unsubscribe event for Layer: " + vmsLayer);
643 }
644 removeHalSubscriptionFromPublisher(vmsLayer, publisherId);
645 }
646
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700647 private static int NUM_INTEGERS_IN_VMS_LAYER = 3;
648
649 private VmsLayer parseVmsLayerFromIndex(List<Integer> integerValues, int index) {
Asaf Rosenfeld2e45d812017-08-31 23:51:12 -0700650 int layerType = integerValues.get(index++);
651 int layerSutype = integerValues.get(index++);
652 int layerVersion = integerValues.get(index++);
653 return new VmsLayer(layerType, layerSutype, layerVersion);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700654 }
655
Antonio Cortese0824d72017-04-06 11:13:35 -0700656 /**
657 * Offering message format:
658 * <ul>
659 * <li>Message type.
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700660 * <li>Publisher ID.
Antonio Cortese0824d72017-04-06 11:13:35 -0700661 * <li>Number of offerings.
662 * <li>Each offering consists of:
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700663 * <ul>
664 * <li>Layer id.
665 * <li>Layer version.
666 * <li>Number of layer dependencies.
667 * <li>Layer type/subtype/version.
668 * </ul>
Antonio Cortese0824d72017-04-06 11:13:35 -0700669 * </ul>
670 */
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700671 private void handleOfferingEvent(List<Integer> integerValues) {
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700672 int publisherId = integerValues.get(VmsOfferingMessageIntegerValuesIndex.PUBLISHER_ID);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700673 int numLayersDependencies =
Asaf Rosenfeld800cb072017-07-18 10:56:11 -0700674 integerValues.get(
Asaf Rosenfeld58e180b2017-07-27 21:06:30 -0700675 VmsOfferingMessageIntegerValuesIndex.NUMBER_OF_OFFERS);
676 int idx = VmsOfferingMessageIntegerValuesIndex.OFFERING_START;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700677
Asaf Rosenfeld2e45d812017-08-31 23:51:12 -0700678 Set<VmsLayerDependency> offeredLayers = new HashSet<>();
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700679
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700680 // An offering is layerId, LayerVersion, LayerType, NumDeps, <LayerId, LayerVersion> X NumDeps.
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700681 for (int i = 0; i < numLayersDependencies; i++) {
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700682 VmsLayer offeredLayer = parseVmsLayerFromIndex(integerValues, idx);
683 idx += NUM_INTEGERS_IN_VMS_LAYER;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700684
685 int numDependenciesForLayer = integerValues.get(idx++);
686 if (numDependenciesForLayer == 0) {
687 offeredLayers.add(new VmsLayerDependency(offeredLayer));
688 } else {
689 Set<VmsLayer> dependencies = new HashSet<>();
690
691 for (int j = 0; j < numDependenciesForLayer; j++) {
Asaf Rosenfeldbcf7df12017-06-02 18:31:28 -0700692 VmsLayer dependantLayer = parseVmsLayerFromIndex(integerValues, idx);
693 idx += NUM_INTEGERS_IN_VMS_LAYER;
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700694 dependencies.add(dependantLayer);
695 }
696 offeredLayers.add(new VmsLayerDependency(offeredLayer, dependencies));
697 }
698 }
699 // Store the HAL offering.
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700700 VmsLayersOffering offering = new VmsLayersOffering(offeredLayers, publisherId);
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700701 synchronized (mLock) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700702 updateOffering(mHalPublisherToken, offering);
Demyn Plantenberg3ca12892017-06-20 21:01:34 -0700703 VmsOperationRecorder.get().setHalPublisherLayersOffering(offering);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700704 }
705 }
706
Antonio Cortese0824d72017-04-06 11:13:35 -0700707 /**
708 * Availability message format:
709 * <ul>
710 * <li>Message type.
711 * <li>Number of layers.
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700712 * <li>Layer type/subtype/version.
Antonio Cortese0824d72017-04-06 11:13:35 -0700713 * </ul>
714 */
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700715 private void handleHalAvailabilityRequestEvent() {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700716 synchronized (mLock) {
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800717 VmsAvailableLayers availableLayers = mAvailableLayers.getAvailableLayers();
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700718 VehiclePropValue vehiclePropertyValue =
719 toAvailabilityUpdateVehiclePropValue(
720 availableLayers,
721 VmsMessageType.AVAILABILITY_RESPONSE);
722
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700723 setPropertyValue(vehiclePropertyValue);
724 }
725 }
726
Antonio Cortese0824d72017-04-06 11:13:35 -0700727 /**
728 * VmsSubscriptionRequestFormat:
729 * <ul>
730 * <li>Message type.
731 * </ul>
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700732 * <p>
Antonio Cortese0824d72017-04-06 11:13:35 -0700733 * VmsSubscriptionResponseFormat:
734 * <ul>
735 * <li>Message type.
736 * <li>Sequence number.
737 * <li>Number of layers.
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700738 * <li>Layer type/subtype/version.
Antonio Cortese0824d72017-04-06 11:13:35 -0700739 * </ul>
740 */
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800741 private void handleSubscriptionsRequestEvent() {
Antonio Cortese0824d72017-04-06 11:13:35 -0700742 VmsSubscriptionState subscription = getSubscriptionState();
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700743 VehiclePropValue vehicleProp =
744 toTypedVmsVehiclePropValue(VmsMessageType.SUBSCRIPTIONS_RESPONSE);
Antonio Cortese0824d72017-04-06 11:13:35 -0700745 VehiclePropValue.RawValue v = vehicleProp.value;
746 v.int32Values.add(subscription.getSequenceNumber());
Asaf Rosenfeld2e45d812017-08-31 23:51:12 -0700747 Set<VmsLayer> layers = subscription.getLayers();
Antonio Cortese0824d72017-04-06 11:13:35 -0700748 v.int32Values.add(layers.size());
Asaf Rosenfeld58e180b2017-07-27 21:06:30 -0700749
750 //TODO(asafro): get the real number of associated layers in the subscriptions
751 // state and send the associated layers themselves.
752 v.int32Values.add(0);
753
Antonio Cortese0824d72017-04-06 11:13:35 -0700754 for (VmsLayer layer : layers) {
Asaf Rosenfeld2e45d812017-08-31 23:51:12 -0700755 v.int32Values.add(layer.getType());
756 v.int32Values.add(layer.getSubtype());
Asaf Rosenfeld58e180b2017-07-27 21:06:30 -0700757 v.int32Values.add(layer.getVersion());
Antonio Cortese0824d72017-04-06 11:13:35 -0700758 }
759 setPropertyValue(vehicleProp);
760 }
761
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700762 private void updateOffering(IBinder publisherToken, VmsLayersOffering offering) {
Asaf Rosenfeld60284892017-05-19 12:59:56 -0700763 synchronized (mLock) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700764 mOfferings.put(publisherToken, offering);
765
766 // Update layers availability.
767 mAvailableLayers.setPublishersOffering(mOfferings.values());
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700768 }
Asaf Rosenfeldc1622902018-07-31 16:15:06 -0700769 notifyOfAvailabilityChange();
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700770 }
771
Antonio Cortes734010a2017-01-19 20:09:22 -0800772 @Override
773 public void dump(PrintWriter writer) {
774 writer.println(TAG);
775 writer.println("VmsProperty " + (mIsSupported ? "" : "not") + " supported.");
776 }
777
asafro99e4f082017-02-09 13:11:42 -0800778 /**
779 * Updates the VMS HAL property with the given value.
780 *
Antonio Cortes01a60392017-03-22 13:00:02 -0700781 * @param layer layer data to update the hal property.
782 * @param hasSubscribers if it is a subscribe or unsubscribe message.
783 * @return true if the call to the HAL to update the property was successful.
asafro99e4f082017-02-09 13:11:42 -0800784 */
Antonio Cortes01a60392017-03-22 13:00:02 -0700785 public boolean setSubscriptionRequest(VmsLayer layer, boolean hasSubscribers) {
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700786 VehiclePropValue vehiclePropertyValue = toTypedVmsVehiclePropValueWithLayer(
787 hasSubscribers ? VmsMessageType.SUBSCRIBE : VmsMessageType.UNSUBSCRIBE, layer);
asafro99e4f082017-02-09 13:11:42 -0800788 return setPropertyValue(vehiclePropertyValue);
789 }
790
Asaf Rosenfeld1a56ab92017-07-23 15:48:09 -0700791 public boolean setSubscriptionToPublisherRequest(VmsLayer layer,
792 int publisherId,
793 boolean hasSubscribers) {
794 VehiclePropValue vehiclePropertyValue = toTypedVmsVehiclePropValueWithLayer(
795 hasSubscribers ?
796 VmsMessageType.SUBSCRIBE_TO_PUBLISHER :
797 VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER, layer);
798 vehiclePropertyValue.value.int32Values.add(publisherId);
799 return setPropertyValue(vehiclePropertyValue);
800 }
801
Antonio Cortes01a60392017-03-22 13:00:02 -0700802 public boolean setDataMessage(VmsLayer layer, byte[] payload) {
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700803 VehiclePropValue vehiclePropertyValue =
804 toTypedVmsVehiclePropValueWithLayer(VmsMessageType.DATA, layer);
805 VehiclePropValue.RawValue v = vehiclePropertyValue.value;
806 v.bytes.ensureCapacity(payload.length);
807 for (byte b : payload) {
808 v.bytes.add(b);
809 }
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700810 return setPropertyValue(vehiclePropertyValue);
811 }
812
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800813 public boolean notifyAvailabilityChangeToHal(VmsAvailableLayers availableLayers) {
Asaf Rosenfeld1ab389c2017-04-25 11:24:17 -0700814 VehiclePropValue vehiclePropertyValue =
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700815 toAvailabilityUpdateVehiclePropValue(
816 availableLayers,
817 VmsMessageType.AVAILABILITY_CHANGE);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700818
asafro99e4f082017-02-09 13:11:42 -0800819 return setPropertyValue(vehiclePropertyValue);
820 }
821
Asaf Rosenfeld4d473f42018-08-14 12:13:21 -0700822 private boolean setPropertyValue(VehiclePropValue vehiclePropertyValue) {
823 if (mIsSupported) {
824 try {
825 mVehicleHal.set(vehiclePropertyValue);
826 return true;
827 } catch (PropertyTimeoutException e) {
828 Log.e(CarLog.TAG_PROPERTY,
829 "set, property not ready 0x" + toHexString(HAL_PROPERTY_ID));
830 }
asafro99e4f082017-02-09 13:11:42 -0800831 }
832 return false;
833 }
834
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700835 private static VehiclePropValue toTypedVmsVehiclePropValue(int messageType) {
Antonio Cortes734010a2017-01-19 20:09:22 -0800836 VehiclePropValue vehicleProp = new VehiclePropValue();
837 vehicleProp.prop = HAL_PROPERTY_ID;
Steve Paik419f5ef2018-06-04 14:53:47 -0700838 vehicleProp.areaId = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
Antonio Cortes734010a2017-01-19 20:09:22 -0800839 VehiclePropValue.RawValue v = vehicleProp.value;
asafro99e4f082017-02-09 13:11:42 -0800840
841 v.int32Values.add(messageType);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700842 return vehicleProp;
843 }
844
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700845 /**
846 * Creates a {@link VehiclePropValue}
847 */
848 private static VehiclePropValue toTypedVmsVehiclePropValueWithLayer(
849 int messageType, VmsLayer layer) {
850 VehiclePropValue vehicleProp = toTypedVmsVehiclePropValue(messageType);
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700851 VehiclePropValue.RawValue v = vehicleProp.value;
Asaf Rosenfeld2e45d812017-08-31 23:51:12 -0700852 v.int32Values.add(layer.getType());
853 v.int32Values.add(layer.getSubtype());
Asaf Rosenfeld58e180b2017-07-27 21:06:30 -0700854 v.int32Values.add(layer.getVersion());
asafro99e4f082017-02-09 13:11:42 -0800855 return vehicleProp;
856 }
857
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700858 private static VehiclePropValue toAvailabilityUpdateVehiclePropValue(
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800859 VmsAvailableLayers availableLayers, int messageType) {
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700860
861 if (!AVAILABILITY_MESSAGE_TYPES.contains(messageType)) {
862 throw new IllegalArgumentException("Unsupported availability type: " + messageType);
asafro99e4f082017-02-09 13:11:42 -0800863 }
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700864 VehiclePropValue vehicleProp =
865 toTypedVmsVehiclePropValue(messageType);
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800866 populateAvailabilityPropValueFields(availableLayers, vehicleProp);
Antonio Cortes734010a2017-01-19 20:09:22 -0800867 return vehicleProp;
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700868
Antonio Cortes734010a2017-01-19 20:09:22 -0800869 }
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700870
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700871 private static void populateAvailabilityPropValueFields(
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800872 VmsAvailableLayers availableAssociatedLayers,
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700873 VehiclePropValue vehicleProp) {
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700874 VehiclePropValue.RawValue v = vehicleProp.value;
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800875 v.int32Values.add(availableAssociatedLayers.getSequence());
876 int numLayers = availableAssociatedLayers.getAssociatedLayers().size();
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700877 v.int32Values.add(numLayers);
Asaf Rosenfeld908811e2018-01-22 09:13:47 -0800878 for (VmsAssociatedLayer layer : availableAssociatedLayers.getAssociatedLayers()) {
Asaf Rosenfeld2e45d812017-08-31 23:51:12 -0700879 v.int32Values.add(layer.getVmsLayer().getType());
880 v.int32Values.add(layer.getVmsLayer().getSubtype());
Asaf Rosenfeld43900532017-06-16 11:16:55 -0700881 v.int32Values.add(layer.getVmsLayer().getVersion());
882 v.int32Values.add(layer.getPublisherIds().size());
883 for (int publisherId : layer.getPublisherIds()) {
884 v.int32Values.add(publisherId);
885 }
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700886 }
Asaf Rosenfeldeb541d42017-03-31 14:32:10 -0700887 }
888}