blob: 5925e9b1c9666674f654f2d9418754bd3060d185 [file] [log] [blame]
keunyounge18e25d2015-08-28 15:57:19 -07001/*
2 * Copyright (C) 2015 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.vehiclenetwork;
17
Pavel Maltseve8f75372016-01-26 10:26:04 -080018import static com.android.car.vehiclenetwork.VehiclePropValueUtil.getVectorLength;
19import static com.android.car.vehiclenetwork.VehiclePropValueUtil.isCustomProperty;
20import static com.android.car.vehiclenetwork.VehiclePropValueUtil.toFloatArray;
21import static com.android.car.vehiclenetwork.VehiclePropValueUtil.toIntArray;
22
keunyounge18e25d2015-08-28 15:57:19 -070023import android.os.Handler;
24import android.os.Looper;
25import android.os.Message;
26import android.os.RemoteException;
27import android.os.ServiceManager;
28import android.util.Log;
29
keunyoungd32f4e62015-09-21 11:33:06 -070030import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
keunyounge18e25d2015-08-28 15:57:19 -070031import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
32import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
33import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValues;
Pavel Maltseve8f75372016-01-26 10:26:04 -080034import com.android.car.vehiclenetwork.VehicleNetworkProto.ZonedValue;
keunyoung1ab8e182015-09-24 09:25:22 -070035import com.android.internal.annotations.GuardedBy;
keunyounge18e25d2015-08-28 15:57:19 -070036
37import java.lang.ref.WeakReference;
38
39/**
40 * System API to access Vehicle network. This is only for system services and applications should
keunyoung15882e52015-09-16 16:57:58 -070041 * not use this. All APIs will fail with security error if normal app tries this.
keunyounge18e25d2015-08-28 15:57:19 -070042 */
43public class VehicleNetwork {
keunyoung1ab8e182015-09-24 09:25:22 -070044 /**
45 * Listener for VNS events.
46 */
keunyounge18e25d2015-08-28 15:57:19 -070047 public interface VehicleNetworkListener {
keunyoung1ab8e182015-09-24 09:25:22 -070048 /**
49 * Notify HAL events. This requires subscribing the property
50 */
keunyounge18e25d2015-08-28 15:57:19 -070051 void onVehicleNetworkEvents(VehiclePropValues values);
Keun-young Park28dd4702015-11-19 18:06:04 -080052 void onHalError(int errorCode, int property, int operation);
53 void onHalRestart(boolean inMocking);
keunyounge18e25d2015-08-28 15:57:19 -070054 }
55
keunyoung1ab8e182015-09-24 09:25:22 -070056 public interface VehicleNetworkHalMock {
57 VehiclePropConfigs onListProperties();
58 void onPropertySet(VehiclePropValue value);
Keun-young Park28dd4702015-11-19 18:06:04 -080059 VehiclePropValue onPropertyGet(VehiclePropValue value);
Keun-young Park0727f952015-12-21 14:30:07 -080060 void onPropertySubscribe(int property, float sampleRate, int zones);
keunyoung1ab8e182015-09-24 09:25:22 -070061 void onPropertyUnsubscribe(int property);
62 }
63
keunyounge18e25d2015-08-28 15:57:19 -070064 private static final String TAG = VehicleNetwork.class.getSimpleName();
65
66 private final IVehicleNetwork mService;
67 private final VehicleNetworkListener mListener;
68 private final IVehicleNetworkListenerImpl mVehicleNetworkListener;
69 private final EventHandler mEventHandler;
70
keunyoung1ab8e182015-09-24 09:25:22 -070071 @GuardedBy("this")
72 private VehicleNetworkHalMock mHalMock;
73 private IVehicleNetworkHalMock mHalMockImpl;
74
keunyoung217ca352015-11-17 14:45:38 -080075 private static final int VNS_CONNECT_MAX_RETRY = 10;
76 private static final long VNS_RETRY_WAIT_TIME_MS = 1000;
Pavel Maltseve8f75372016-01-26 10:26:04 -080077 private static final int NO_ZONE = -1;
keunyoung217ca352015-11-17 14:45:38 -080078
keunyoung5c7cb262015-10-19 10:47:45 -070079 /**
80 * Factory method to create VehicleNetwork
Pavel Maltseve8f75372016-01-26 10:26:04 -080081 *
keunyoung5c7cb262015-10-19 10:47:45 -070082 * @param listener listener for listening events
83 * @param looper Looper to dispatch listener events
keunyoung5c7cb262015-10-19 10:47:45 -070084 */
keunyoung15882e52015-09-16 16:57:58 -070085 public static VehicleNetwork createVehicleNetwork(VehicleNetworkListener listener,
86 Looper looper) {
keunyoung217ca352015-11-17 14:45:38 -080087 int retryCount = 0;
88 IVehicleNetwork service = null;
89 while (service == null) {
90 service = IVehicleNetwork.Stub.asInterface(ServiceManager.getService(
91 IVehicleNetwork.class.getCanonicalName()));
92 retryCount++;
93 if (retryCount > VNS_CONNECT_MAX_RETRY) {
94 break;
95 }
96 try {
97 Thread.sleep(VNS_RETRY_WAIT_TIME_MS);
98 } catch (InterruptedException e) {
99 //ignore
100 }
101 }
keunyounge18e25d2015-08-28 15:57:19 -0700102 if (service == null) {
keunyoung15882e52015-09-16 16:57:58 -0700103 throw new RuntimeException("Vehicle network service not available:" +
104 IVehicleNetwork.class.getCanonicalName());
keunyounge18e25d2015-08-28 15:57:19 -0700105 }
106 return new VehicleNetwork(service, listener, looper);
107 }
108
109 private VehicleNetwork(IVehicleNetwork service, VehicleNetworkListener listener,
110 Looper looper) {
111 mService = service;
112 mListener = listener;
113 mEventHandler = new EventHandler(looper);
114 mVehicleNetworkListener = new IVehicleNetworkListenerImpl(this);
115 }
116
keunyoung5c7cb262015-10-19 10:47:45 -0700117 /**
118 * List all properties from vehicle HAL
Pavel Maltseve8f75372016-01-26 10:26:04 -0800119 *
keunyoung5c7cb262015-10-19 10:47:45 -0700120 * @return all properties
121 */
keunyoung15882e52015-09-16 16:57:58 -0700122 public VehiclePropConfigs listProperties() {
123 return listProperties(0 /* all */);
124 }
125
keunyoung5c7cb262015-10-19 10:47:45 -0700126 /**
127 * Return configuration information of single property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800128 *
129 * @param property vehicle property number defined in {@link VehicleNetworkConsts}. 0 has has
130 * special meaning of list all properties.
keunyoung5c7cb262015-10-19 10:47:45 -0700131 * @return null if given property does not exist.
132 */
keunyounge18e25d2015-08-28 15:57:19 -0700133 public VehiclePropConfigs listProperties(int property) {
134 try {
135 VehiclePropConfigsParcelable parcelable = mService.listProperties(property);
136 if (parcelable != null) {
137 return parcelable.configs;
138 }
139 } catch (RemoteException e) {
140 handleRemoteException(e);
141 }
142 return null;
143 }
144
keunyoung5c7cb262015-10-19 10:47:45 -0700145 /**
146 * Set property which will lead into writing the value to vehicle HAL.
Pavel Maltseve8f75372016-01-26 10:26:04 -0800147 *
148 * @throws IllegalArgumentException If value set has wrong value like wrong valueType, wrong
149 * data, and etc.
keunyoung5c7cb262015-10-19 10:47:45 -0700150 */
151 public void setProperty(VehiclePropValue value) throws IllegalArgumentException {
keunyounge18e25d2015-08-28 15:57:19 -0700152 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
153 try {
keunyoung15882e52015-09-16 16:57:58 -0700154 mService.setProperty(parcelable);
keunyounge18e25d2015-08-28 15:57:19 -0700155 } catch (RemoteException e) {
156 handleRemoteException(e);
157 }
keunyounge18e25d2015-08-28 15:57:19 -0700158 }
159
keunyoung5c7cb262015-10-19 10:47:45 -0700160 /**
161 * Set integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800162 *
keunyoung5c7cb262015-10-19 10:47:45 -0700163 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
164 */
165 public void setIntProperty(int property, int value) throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700166 VehiclePropValue v = VehiclePropValueUtil.createIntValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700167 setProperty(v);
168 }
169
keunyoung5c7cb262015-10-19 10:47:45 -0700170 /**
171 * Set int vector type property. Length of passed values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700172 */
173 public void setIntVectorProperty(int property, int[] values) throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700174 VehiclePropValue v = VehiclePropValueUtil.createIntVectorValue(property, values, 0);
175 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700176 }
177
keunyoung5c7cb262015-10-19 10:47:45 -0700178 /**
179 * Set long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700180 */
181 public void setLongProperty(int property, long value) throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700182 VehiclePropValue v = VehiclePropValueUtil.createLongValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700183 setProperty(v);
184 }
185
keunyoung5c7cb262015-10-19 10:47:45 -0700186 /**
187 * Set float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700188 */
189 public void setFloatProperty(int property, float value) throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700190 VehiclePropValue v = VehiclePropValueUtil.createFloatValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700191 setProperty(v);
192 }
193
keunyoung5c7cb262015-10-19 10:47:45 -0700194 /**
195 * Set float vector type property. Length of values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700196 */
197 public void setFloatVectorProperty(int property, float[] values)
198 throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700199 VehiclePropValue v = VehiclePropValueUtil.createFloatVectorValue(property, values, 0);
200 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700201 }
202
keunyoung5c7cb262015-10-19 10:47:45 -0700203 /**
Steve Paik66481982015-10-27 15:22:38 -0700204 * Set zoned boolean type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800205 *
206 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
207 */
208 public void setBooleanProperty(int property, boolean value)
209 throws IllegalArgumentException {
210 VehiclePropValue v = VehiclePropValueUtil.createBooleanValue(property, value, 0);
211 setProperty(v);
212 }
213
214 /**
215 * Set zoned boolean type property
216 *
Steve Paik66481982015-10-27 15:22:38 -0700217 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
218 */
219 public void setZonedBooleanProperty(int property, int zone, boolean value)
220 throws IllegalArgumentException {
221 VehiclePropValue v = VehiclePropValueUtil.createZonedBooleanValue(property, zone, value, 0);
222 setProperty(v);
223 }
224
225 /**
226 * Set zoned float type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800227 *
Steve Paik66481982015-10-27 15:22:38 -0700228 * @throws IllegalArgumentException For type mismatch (=the property is not float type)
229 */
230 public void setZonedFloatProperty(int property, int zone, float value)
231 throws IllegalArgumentException {
232 VehiclePropValue v = VehiclePropValueUtil.createZonedFloatValue(property, zone, value, 0);
233 setProperty(v);
234 }
235
236 /**
237 * Set zoned integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800238 *
Steve Paik66481982015-10-27 15:22:38 -0700239 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
240 */
241 public void setZonedIntProperty(int property, int zone, int value)
242 throws IllegalArgumentException {
243 VehiclePropValue v = VehiclePropValueUtil.createZonedIntValue(property, zone, value, 0);
244 setProperty(v);
245 }
246
247 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800248 * Set zoned int vector type property. Length of passed values should match with vector length.
249 */
250 public void setZonedIntVectorProperty(int property, int zone, int[] values)
251 throws IllegalArgumentException {
252 VehiclePropValue v = VehiclePropValueUtil
253 .createZonedIntVectorValue(property, zone, values, 0);
254 setProperty(v);
255 }
256
257 /**
258 * Set zoned float vector type property. Length of passed values should match with vector
259 * length.
260 */
261 public void setZonedFloatVectorProperty(int property, int zone, float[] values)
262 throws IllegalArgumentException {
263 VehiclePropValue v = VehiclePropValueUtil
264 .createZonedFloatVectorValue(property, zone, values, 0);
265 setProperty(v);
266 }
267
268 /**
keunyoung5c7cb262015-10-19 10:47:45 -0700269 * Get property. This can be used for a property which does not require any other data.
keunyoung5c7cb262015-10-19 10:47:45 -0700270 */
271 public VehiclePropValue getProperty(int property) throws IllegalArgumentException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700272 int valueType = VehicleNetworkConsts.getVehicleValueType(property);
Pavel Maltsev169b7a62016-01-26 15:56:07 -0800273 if (valueType == 0) {
274 throw new IllegalArgumentException("Data type is unknown for property: " + property);
275 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700276 VehiclePropValue value = VehiclePropValueUtil.createBuilder(property, valueType, 0).build();
277 return getProperty(value);
278 }
279
keunyoung5c7cb262015-10-19 10:47:45 -0700280 /**
281 * Generic get method for any type of property. Some property may require setting data portion
282 * as get may return different result depending on the data set.
keunyoung5c7cb262015-10-19 10:47:45 -0700283 */
284 public VehiclePropValue getProperty(VehiclePropValue value) throws IllegalArgumentException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700285 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
keunyounge18e25d2015-08-28 15:57:19 -0700286 try {
keunyoung7d74e6d2015-10-14 15:43:10 -0700287 VehiclePropValueParcelable resParcelable = mService.getProperty(parcelable);
288 if (resParcelable != null) {
289 return resParcelable.value;
keunyounge18e25d2015-08-28 15:57:19 -0700290 }
291 } catch (RemoteException e) {
292 handleRemoteException(e);
293 }
294 return null;
295 }
296
keunyoung5c7cb262015-10-19 10:47:45 -0700297 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800298 * Get int type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700299 */
300 public int getIntProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800301 VehiclePropValue v = getProperty(
302 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
keunyoungd32f4e62015-09-21 11:33:06 -0700303 if (v.getInt32ValuesCount() != 1) {
304 throw new IllegalStateException();
305 }
306 return v.getInt32Values(0);
307 }
308
keunyoung5c7cb262015-10-19 10:47:45 -0700309 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800310 * Get zoned int type property.
311 */
312 public int getZonedIntProperty(int property, int zone) throws IllegalArgumentException {
313 VehiclePropValue v = getProperty(
314 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
315 if (v.getZonedValue().getInt32ValuesCount() != 1) {
316 throw new IllegalStateException();
317 }
318 return v.getZonedValue().getInt32Values(0);
319 }
320
321 /**
322 * Get int vector type property. Length of values should match vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700323 */
keunyoung4b0212c2015-10-29 17:11:57 -0700324 public int[] getIntVectorProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800325 VehiclePropValue v = getProperty(
326 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
327 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
328 return toIntArray(v.getInt32ValuesList());
329 }
330
331 /**
332 * Get zoned int vector type property. Length of values should match vector length.
333 */
334 public int[] getZonedIntVectorProperty(int property, int zone)
335 throws IllegalArgumentException {
336 VehiclePropValue v = getProperty(
337 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
338 assertVectorLength(v.getZonedValue().getInt32ValuesCount(), property, v.getValueType());
339 return toIntArray(v.getZonedValue().getInt32ValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700340 }
341
keunyoung5c7cb262015-10-19 10:47:45 -0700342 /**
343 * Get float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700344 */
345 public float getFloatProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800346 VehiclePropValue v = getProperty(
347 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
keunyoungd32f4e62015-09-21 11:33:06 -0700348 if (v.getFloatValuesCount() != 1) {
349 throw new IllegalStateException();
350 }
351 return v.getFloatValues(0);
352 }
353
keunyoung5c7cb262015-10-19 10:47:45 -0700354 /**
355 * Get float vector type property. Length of values should match vector's length.
keunyoung5c7cb262015-10-19 10:47:45 -0700356 */
Pavel Maltseve8f75372016-01-26 10:26:04 -0800357 public float[] getFloatVectorProperty(int property) throws IllegalArgumentException {
358 VehiclePropValue v = getProperty(
359 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
360 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
361 return toFloatArray(v.getFloatValuesList());
362 }
363
364 /**
365 * Get zoned float vector type property. Length of values should match vector's length.
366 */
367 public float[] getZonedFloatVectorProperty(int property, int zone)
keunyoung5c7cb262015-10-19 10:47:45 -0700368 throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800369 VehiclePropValue v = getProperty(property, zone,
370 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT);
371 assertVectorLength(v.getZonedValue().getFloatValuesCount(), property, v.getValueType());
372 return toFloatArray(v.getZonedValue().getFloatValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700373 }
374
keunyoung5c7cb262015-10-19 10:47:45 -0700375 /**
376 * Get long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700377 */
378 public long getLongProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800379 VehiclePropValue v = getProperty(
380 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT64);
keunyoungfe30ba02015-09-17 17:56:35 -0700381 return v.getInt64Value();
382 }
383
keunyoung5c7cb262015-10-19 10:47:45 -0700384 /**
385 * Get string type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700386 */
keunyoungfe30ba02015-09-17 17:56:35 -0700387 //TODO check UTF8 to java string conversion
keunyoung5c7cb262015-10-19 10:47:45 -0700388 public String getStringProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800389 VehiclePropValue v = getProperty(
390 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_STRING);
keunyoungfe30ba02015-09-17 17:56:35 -0700391 return v.getStringValue();
392 }
393
keunyoung5c7cb262015-10-19 10:47:45 -0700394 /**
395 * Subscribe given property with given sample rate.
keunyoung5c7cb262015-10-19 10:47:45 -0700396 */
397 public void subscribe(int property, float sampleRate) throws IllegalArgumentException {
Keun-young Park0727f952015-12-21 14:30:07 -0800398 subscribe(property, sampleRate, 0);
399 }
400
401 /**
402 * Subscribe given property with given sample rate.
Keun-young Park0727f952015-12-21 14:30:07 -0800403 */
404 public void subscribe(int property, float sampleRate, int zones)
405 throws IllegalArgumentException {
keunyounge18e25d2015-08-28 15:57:19 -0700406 try {
Keun-young Park0727f952015-12-21 14:30:07 -0800407 mService.subscribe(mVehicleNetworkListener, property, sampleRate, zones);
keunyounge18e25d2015-08-28 15:57:19 -0700408 } catch (RemoteException e) {
409 handleRemoteException(e);
410 }
keunyounge18e25d2015-08-28 15:57:19 -0700411 }
412
keunyoung5c7cb262015-10-19 10:47:45 -0700413 /**
414 * Stop subscribing the property.
keunyoung5c7cb262015-10-19 10:47:45 -0700415 */
keunyounge18e25d2015-08-28 15:57:19 -0700416 public void unsubscribe(int property) {
417 try {
418 mService.unsubscribe(mVehicleNetworkListener, property);
419 } catch (RemoteException e) {
420 handleRemoteException(e);
421 }
422 }
423
keunyoung5c7cb262015-10-19 10:47:45 -0700424 /**
425 * Inject given value to all clients subscribing the property. This is for testing.
keunyoung5c7cb262015-10-19 10:47:45 -0700426 */
keunyoung1ab8e182015-09-24 09:25:22 -0700427 public synchronized void injectEvent(VehiclePropValue value) {
428 try {
429 mService.injectEvent(new VehiclePropValueParcelable(value));
430 } catch (RemoteException e) {
431 handleRemoteException(e);
432 }
433 }
434
keunyoung5c7cb262015-10-19 10:47:45 -0700435 /**
436 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700437 */
keunyoung1ab8e182015-09-24 09:25:22 -0700438 public synchronized void startMocking(VehicleNetworkHalMock mock) {
439 mHalMock = mock;
440 mHalMockImpl = new IVehicleNetworkHalMockImpl(this);
441 try {
442 mService.startMocking(mHalMockImpl);
443 } catch (RemoteException e) {
444 handleRemoteException(e);
445 }
446 }
447
keunyoung5c7cb262015-10-19 10:47:45 -0700448 /**
449 * Stop mocking of vehicle HAL. For testing only.
450 */
keunyoung1ab8e182015-09-24 09:25:22 -0700451 public synchronized void stopMocking() {
Keun-young Park28dd4702015-11-19 18:06:04 -0800452 if (mHalMockImpl == null) {
453 return;
454 }
keunyoung1ab8e182015-09-24 09:25:22 -0700455 try {
456 mService.stopMocking(mHalMockImpl);
457 } catch (RemoteException e) {
458 handleRemoteException(e);
459 } finally {
460 mHalMock = null;
461 mHalMockImpl = null;
462 }
463 }
464
keunyoung5c7cb262015-10-19 10:47:45 -0700465 /**
466 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700467 */
keunyoung1ab8e182015-09-24 09:25:22 -0700468 public synchronized void startMocking(IVehicleNetworkHalMock mock) {
469 mHalMock = null;
470 mHalMockImpl = mock;
471 try {
472 mService.startMocking(mHalMockImpl);
473 } catch (RemoteException e) {
474 handleRemoteException(e);
475 }
476 }
477
keunyoung5c7cb262015-10-19 10:47:45 -0700478 /**
479 * Stop mocking of vehicle HAL. For testing only.
480 */
keunyoung1ab8e182015-09-24 09:25:22 -0700481 public synchronized void stopMocking(IVehicleNetworkHalMock mock) {
482 if (mock.asBinder() != mHalMockImpl.asBinder()) {
483 return;
484 }
485 try {
486 mService.stopMocking(mHalMockImpl);
487 } catch (RemoteException e) {
488 handleRemoteException(e);
489 } finally {
490 mHalMock = null;
491 mHalMockImpl = null;
492 }
493 }
494
Keun-young Park28dd4702015-11-19 18:06:04 -0800495 public synchronized void injectHalError(int errorCode, int property, int operation) {
496 try {
497 mService.injectHalError(errorCode, property, operation);
498 } catch (RemoteException e) {
499 handleRemoteException(e);
500 }
501 }
502
503 public synchronized void startErrorListening() {
504 try {
505 mService.startErrorListening(mVehicleNetworkListener);
506 } catch (RemoteException e) {
507 handleRemoteException(e);
508 }
509 }
510
511 public synchronized void stopErrorListening() {
512 try {
513 mService.stopErrorListening(mVehicleNetworkListener);
514 } catch (RemoteException e) {
515 handleRemoteException(e);
516 }
517 }
518
519 public synchronized void startHalRestartMonitoring() {
520 try {
521 mService.startHalRestartMonitoring(mVehicleNetworkListener);
522 } catch (RemoteException e) {
523 handleRemoteException(e);
524 }
525 }
526
527 public synchronized void stopHalRestartMonitoring() {
528 try {
529 mService.stopHalRestartMonitoring(mVehicleNetworkListener);
530 } catch (RemoteException e) {
531 handleRemoteException(e);
532 }
533 }
534
keunyoung1ab8e182015-09-24 09:25:22 -0700535 private synchronized VehicleNetworkHalMock getHalMock() {
536 return mHalMock;
537 }
538
keunyounge18e25d2015-08-28 15:57:19 -0700539 private void handleRemoteException(RemoteException e) {
540 throw new RuntimeException("Vehicle network service not working ", e);
541 }
542
543 private void handleVehicleNetworkEvents(VehiclePropValues values) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800544 mListener.onVehicleNetworkEvents(values);
keunyounge18e25d2015-08-28 15:57:19 -0700545 }
546
Keun-young Park28dd4702015-11-19 18:06:04 -0800547 private void handleHalError(int errorCode, int property, int operation) {
548 mListener.onHalError(errorCode, property, operation);
549 }
550
551 private void handleHalRestart(boolean inMocking) {
552 mListener.onHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700553 }
554
555 private class EventHandler extends Handler {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800556
keunyounge18e25d2015-08-28 15:57:19 -0700557 private static final int MSG_EVENTS = 0;
Keun-young Park28dd4702015-11-19 18:06:04 -0800558 private static final int MSG_HAL_ERROR = 1;
559 private static final int MSG_HAL_RESTART = 2;
keunyounge18e25d2015-08-28 15:57:19 -0700560
561 private EventHandler(Looper looper) {
562 super(looper);
563 }
564
565 private void notifyEvents(VehiclePropValues values) {
566 Message msg = obtainMessage(MSG_EVENTS, values);
567 sendMessage(msg);
568 }
569
Keun-young Park28dd4702015-11-19 18:06:04 -0800570 private void notifyHalError(int errorCode, int property, int operation) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800571 Message msg = obtainMessage(MSG_HAL_ERROR, errorCode, property, operation);
Keun-young Park28dd4702015-11-19 18:06:04 -0800572 sendMessage(msg);
573 }
574
575 private void notifyHalRestart(boolean inMocking) {
576 Message msg = obtainMessage(MSG_HAL_RESTART, inMocking ? 1 : 0, 0);
577 sendMessage(msg);
578 }
579
keunyounge18e25d2015-08-28 15:57:19 -0700580 @Override
581 public void handleMessage(Message msg) {
582 switch (msg.what) {
583 case MSG_EVENTS:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800584 handleVehicleNetworkEvents((VehiclePropValues) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800585 break;
586 case MSG_HAL_ERROR:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800587 handleHalError(msg.arg1, msg.arg2, (Integer) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800588 break;
589 case MSG_HAL_RESTART:
590 handleHalRestart(msg.arg1 == 1);
keunyounge18e25d2015-08-28 15:57:19 -0700591 break;
592 default:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800593 Log.w(TAG, "Unknown message:" + msg.what, new RuntimeException());
keunyounge18e25d2015-08-28 15:57:19 -0700594 break;
595 }
596 }
597 }
598
599 private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800600
keunyounge18e25d2015-08-28 15:57:19 -0700601 private final WeakReference<VehicleNetwork> mVehicleNetwork;
602
603 private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800604 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyounge18e25d2015-08-28 15:57:19 -0700605 }
606
607 @Override
608 public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) {
609 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
610 if (vehicleNetwork != null) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800611 vehicleNetwork.mEventHandler.notifyEvents(values.values);
612 }
613 }
614
615 @Override
616 public void onHalError(int errorCode, int property, int operation) {
617 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
618 if (vehicleNetwork != null) {
619 vehicleNetwork.mEventHandler.notifyHalError(errorCode, property, operation);
620 }
621 }
622
623 @Override
624 public void onHalRestart(boolean inMocking) {
625 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
626 if (vehicleNetwork != null) {
627 vehicleNetwork.mEventHandler.notifyHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700628 }
629 }
630 }
keunyoung1ab8e182015-09-24 09:25:22 -0700631
632 private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub {
633 private final WeakReference<VehicleNetwork> mVehicleNetwork;
634
635 private IVehicleNetworkHalMockImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800636 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyoung1ab8e182015-09-24 09:25:22 -0700637 }
638
639 @Override
640 public VehiclePropConfigsParcelable onListProperties() {
641 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
642 if (vehicleNetwork == null) {
643 return null;
644 }
645 VehiclePropConfigs configs = vehicleNetwork.getHalMock().onListProperties();
646 return new VehiclePropConfigsParcelable(configs);
647 }
648
649 @Override
650 public void onPropertySet(VehiclePropValueParcelable value) {
651 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
652 if (vehicleNetwork == null) {
653 return;
654 }
655 vehicleNetwork.getHalMock().onPropertySet(value.value);
656 }
657
658 @Override
keunyoung7d74e6d2015-10-14 15:43:10 -0700659 public VehiclePropValueParcelable onPropertyGet(VehiclePropValueParcelable value) {
keunyoung1ab8e182015-09-24 09:25:22 -0700660 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
661 if (vehicleNetwork == null) {
662 return null;
663 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700664 VehiclePropValue resValue = vehicleNetwork.getHalMock().onPropertyGet(value.value);
665 return new VehiclePropValueParcelable(resValue);
keunyoung1ab8e182015-09-24 09:25:22 -0700666 }
667
668 @Override
Keun-young Park0727f952015-12-21 14:30:07 -0800669 public void onPropertySubscribe(int property, float sampleRate, int zones) {
keunyoung1ab8e182015-09-24 09:25:22 -0700670 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
671 if (vehicleNetwork == null) {
672 return;
673 }
Keun-young Park0727f952015-12-21 14:30:07 -0800674 vehicleNetwork.getHalMock().onPropertySubscribe(property, sampleRate, zones);
keunyoung1ab8e182015-09-24 09:25:22 -0700675 }
676
677 @Override
678 public void onPropertyUnsubscribe(int property) {
679 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
680 if (vehicleNetwork == null) {
681 return;
682 }
683 vehicleNetwork.getHalMock().onPropertyUnsubscribe(property);
684 }
685 }
Pavel Maltseve8f75372016-01-26 10:26:04 -0800686
687 private VehiclePropValue getProperty(int property, int zone, int customPropetyDataType) {
688 boolean isCustom = isCustomProperty(property);
689 int valueType = isCustom
690 ? customPropetyDataType
691 : VehicleNetworkConsts.getVehicleValueType(property);
692
693 VehiclePropValue.Builder valuePrototypeBuilder =
694 VehiclePropValueUtil.createBuilder(property, valueType, 0);
695
696 if (zone != NO_ZONE) {
697 valuePrototypeBuilder.setZonedValue(ZonedValue.newBuilder().
698 setZoneOrWindow(zone).
699 build());
700 }
701
702 VehiclePropValue v = getProperty(valuePrototypeBuilder.build());
703 if (v == null) {
704 // if property is invalid, IllegalArgumentException should have been thrown
705 // from getProperty.
706 throw new IllegalStateException();
707 }
708
709 if (!isCustom && v.getValueType() != valueType) {
710 throw new IllegalArgumentException("Unexpected type: " + v.getValueType()
711 + ", expecting: " + valueType);
712 }
713 return v;
714 }
715
716 private void assertVectorLength(int actual, int property, int valueType) {
717 int expectedLen = getVectorLength(valueType);
718 if (expectedLen != actual) {
719 throw new IllegalStateException("Invalid array size for property: " + property
720 + ". Expected: " + expectedLen
721 + ", actual: " + actual);
722 }
723 }
keunyounge18e25d2015-08-28 15:57:19 -0700724}