blob: f7ef2c444906d490ebfa1192f577ff7d0eb3bb96 [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;
Keun-young Parkba485482016-03-24 13:24:31 -070028import android.os.ServiceSpecificException;
keunyounge18e25d2015-08-28 15:57:19 -070029import android.util.Log;
30
keunyoungd32f4e62015-09-21 11:33:06 -070031import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
keunyounge18e25d2015-08-28 15:57:19 -070032import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
33import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
34import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValues;
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 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700151 public void setProperty(VehiclePropValue value)
152 throws IllegalArgumentException, ServiceSpecificException {
keunyounge18e25d2015-08-28 15:57:19 -0700153 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
154 try {
keunyoung15882e52015-09-16 16:57:58 -0700155 mService.setProperty(parcelable);
keunyounge18e25d2015-08-28 15:57:19 -0700156 } catch (RemoteException e) {
157 handleRemoteException(e);
158 }
keunyounge18e25d2015-08-28 15:57:19 -0700159 }
160
keunyoung5c7cb262015-10-19 10:47:45 -0700161 /**
162 * Set integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800163 *
keunyoung5c7cb262015-10-19 10:47:45 -0700164 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
165 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700166 public void setIntProperty(int property, int value)
167 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700168 VehiclePropValue v = VehiclePropValueUtil.createIntValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700169 setProperty(v);
170 }
171
keunyoung5c7cb262015-10-19 10:47:45 -0700172 /**
173 * Set int vector type property. Length of passed values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700174 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700175 public void setIntVectorProperty(int property, int[] values)
176 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700177 VehiclePropValue v = VehiclePropValueUtil.createIntVectorValue(property, values, 0);
178 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700179 }
180
keunyoung5c7cb262015-10-19 10:47:45 -0700181 /**
182 * Set long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700183 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700184 public void setLongProperty(int property, long value)
185 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700186 VehiclePropValue v = VehiclePropValueUtil.createLongValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700187 setProperty(v);
188 }
189
keunyoung5c7cb262015-10-19 10:47:45 -0700190 /**
191 * Set float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700192 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700193 public void setFloatProperty(int property, float value)
194 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700195 VehiclePropValue v = VehiclePropValueUtil.createFloatValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700196 setProperty(v);
197 }
198
keunyoung5c7cb262015-10-19 10:47:45 -0700199 /**
200 * Set float vector type property. Length of values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700201 */
202 public void setFloatVectorProperty(int property, float[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700203 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700204 VehiclePropValue v = VehiclePropValueUtil.createFloatVectorValue(property, values, 0);
205 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700206 }
207
keunyoung5c7cb262015-10-19 10:47:45 -0700208 /**
Steve Paik66481982015-10-27 15:22:38 -0700209 * Set zoned boolean type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800210 *
211 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
212 */
213 public void setBooleanProperty(int property, boolean value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700214 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800215 VehiclePropValue v = VehiclePropValueUtil.createBooleanValue(property, value, 0);
216 setProperty(v);
217 }
218
219 /**
220 * Set zoned boolean type property
221 *
Steve Paik66481982015-10-27 15:22:38 -0700222 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
223 */
224 public void setZonedBooleanProperty(int property, int zone, boolean value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700225 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700226 VehiclePropValue v = VehiclePropValueUtil.createZonedBooleanValue(property, zone, value, 0);
227 setProperty(v);
228 }
229
230 /**
231 * Set zoned float type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800232 *
Steve Paik66481982015-10-27 15:22:38 -0700233 * @throws IllegalArgumentException For type mismatch (=the property is not float type)
234 */
235 public void setZonedFloatProperty(int property, int zone, float value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700236 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700237 VehiclePropValue v = VehiclePropValueUtil.createZonedFloatValue(property, zone, value, 0);
238 setProperty(v);
239 }
240
241 /**
242 * Set zoned integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800243 *
Steve Paik66481982015-10-27 15:22:38 -0700244 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
245 */
246 public void setZonedIntProperty(int property, int zone, int value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700247 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700248 VehiclePropValue v = VehiclePropValueUtil.createZonedIntValue(property, zone, value, 0);
249 setProperty(v);
250 }
251
252 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800253 * Set zoned int vector type property. Length of passed values should match with vector length.
254 */
255 public void setZonedIntVectorProperty(int property, int zone, int[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700256 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800257 VehiclePropValue v = VehiclePropValueUtil
258 .createZonedIntVectorValue(property, zone, values, 0);
259 setProperty(v);
260 }
261
262 /**
263 * Set zoned float vector type property. Length of passed values should match with vector
264 * length.
265 */
266 public void setZonedFloatVectorProperty(int property, int zone, float[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700267 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800268 VehiclePropValue v = VehiclePropValueUtil
269 .createZonedFloatVectorValue(property, zone, values, 0);
270 setProperty(v);
271 }
272
273 /**
keunyoung5c7cb262015-10-19 10:47:45 -0700274 * Get property. This can be used for a property which does not require any other data.
keunyoung5c7cb262015-10-19 10:47:45 -0700275 */
Keun-young Parkba485482016-03-24 13:24:31 -0700276 public VehiclePropValue getProperty(int property) throws IllegalArgumentException,
277 ServiceSpecificException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700278 int valueType = VehicleNetworkConsts.getVehicleValueType(property);
Pavel Maltsev169b7a62016-01-26 15:56:07 -0800279 if (valueType == 0) {
280 throw new IllegalArgumentException("Data type is unknown for property: " + property);
281 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700282 VehiclePropValue value = VehiclePropValueUtil.createBuilder(property, valueType, 0).build();
283 return getProperty(value);
284 }
285
keunyoung5c7cb262015-10-19 10:47:45 -0700286 /**
287 * Generic get method for any type of property. Some property may require setting data portion
288 * as get may return different result depending on the data set.
keunyoung5c7cb262015-10-19 10:47:45 -0700289 */
Keun-young Parkba485482016-03-24 13:24:31 -0700290 public VehiclePropValue getProperty(VehiclePropValue value) throws IllegalArgumentException,
291 ServiceSpecificException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700292 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
keunyounge18e25d2015-08-28 15:57:19 -0700293 try {
keunyoung7d74e6d2015-10-14 15:43:10 -0700294 VehiclePropValueParcelable resParcelable = mService.getProperty(parcelable);
295 if (resParcelable != null) {
296 return resParcelable.value;
keunyounge18e25d2015-08-28 15:57:19 -0700297 }
298 } catch (RemoteException e) {
299 handleRemoteException(e);
300 }
301 return null;
302 }
303
keunyoung5c7cb262015-10-19 10:47:45 -0700304 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800305 * Get int type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700306 */
Keun-young Parkba485482016-03-24 13:24:31 -0700307 public int getIntProperty(int property) throws IllegalArgumentException,
308 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800309 VehiclePropValue v = getProperty(
310 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
keunyoungd32f4e62015-09-21 11:33:06 -0700311 if (v.getInt32ValuesCount() != 1) {
312 throw new IllegalStateException();
313 }
314 return v.getInt32Values(0);
315 }
316
keunyoung5c7cb262015-10-19 10:47:45 -0700317 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800318 * Get zoned int type property.
319 */
Keun-young Parkba485482016-03-24 13:24:31 -0700320 public int getZonedIntProperty(int property, int zone) throws IllegalArgumentException,
321 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800322 VehiclePropValue v = getProperty(
323 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800324 if (v.getInt32ValuesCount() != 1) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800325 throw new IllegalStateException();
326 }
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800327 return v.getInt32Values(0);
Pavel Maltseve8f75372016-01-26 10:26:04 -0800328 }
329
330 /**
331 * Get int vector type property. Length of values should match vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700332 */
Keun-young Parkba485482016-03-24 13:24:31 -0700333 public int[] getIntVectorProperty(int property) throws IllegalArgumentException,
334 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800335 VehiclePropValue v = getProperty(
336 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
337 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
338 return toIntArray(v.getInt32ValuesList());
339 }
340
341 /**
342 * Get zoned int vector type property. Length of values should match vector length.
343 */
344 public int[] getZonedIntVectorProperty(int property, int zone)
Keun-young Parkba485482016-03-24 13:24:31 -0700345 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800346 VehiclePropValue v = getProperty(
347 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800348 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
349 return toIntArray(v.getInt32ValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700350 }
351
keunyoung5c7cb262015-10-19 10:47:45 -0700352 /**
353 * Get float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700354 */
Keun-young Parkba485482016-03-24 13:24:31 -0700355 public float getFloatProperty(int property) throws IllegalArgumentException,
356 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800357 VehiclePropValue v = getProperty(
358 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
keunyoungd32f4e62015-09-21 11:33:06 -0700359 if (v.getFloatValuesCount() != 1) {
360 throw new IllegalStateException();
361 }
362 return v.getFloatValues(0);
363 }
364
keunyoung5c7cb262015-10-19 10:47:45 -0700365 /**
366 * Get float vector type property. Length of values should match vector's length.
keunyoung5c7cb262015-10-19 10:47:45 -0700367 */
Keun-young Parkba485482016-03-24 13:24:31 -0700368 public float[] getFloatVectorProperty(int property) throws IllegalArgumentException,
369 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800370 VehiclePropValue v = getProperty(
371 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
372 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
373 return toFloatArray(v.getFloatValuesList());
374 }
375
376 /**
377 * Get zoned float vector type property. Length of values should match vector's length.
378 */
379 public float[] getZonedFloatVectorProperty(int property, int zone)
Keun-young Parkba485482016-03-24 13:24:31 -0700380 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800381 VehiclePropValue v = getProperty(property, zone,
382 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800383 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
384 return toFloatArray(v.getFloatValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700385 }
386
keunyoung5c7cb262015-10-19 10:47:45 -0700387 /**
388 * Get long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700389 */
Keun-young Parkba485482016-03-24 13:24:31 -0700390 public long getLongProperty(int property) throws IllegalArgumentException,
391 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800392 VehiclePropValue v = getProperty(
393 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT64);
keunyoungfe30ba02015-09-17 17:56:35 -0700394 return v.getInt64Value();
395 }
396
keunyoung5c7cb262015-10-19 10:47:45 -0700397 /**
398 * Get string type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700399 */
keunyoungfe30ba02015-09-17 17:56:35 -0700400 //TODO check UTF8 to java string conversion
Keun-young Parkba485482016-03-24 13:24:31 -0700401 public String getStringProperty(int property) throws IllegalArgumentException,
402 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800403 VehiclePropValue v = getProperty(
404 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_STRING);
keunyoungfe30ba02015-09-17 17:56:35 -0700405 return v.getStringValue();
406 }
407
keunyoung5c7cb262015-10-19 10:47:45 -0700408 /**
409 * Subscribe given property with given sample rate.
keunyoung5c7cb262015-10-19 10:47:45 -0700410 */
411 public void subscribe(int property, float sampleRate) throws IllegalArgumentException {
Keun-young Park0727f952015-12-21 14:30:07 -0800412 subscribe(property, sampleRate, 0);
413 }
414
415 /**
416 * Subscribe given property with given sample rate.
Keun-young Park0727f952015-12-21 14:30:07 -0800417 */
418 public void subscribe(int property, float sampleRate, int zones)
419 throws IllegalArgumentException {
keunyounge18e25d2015-08-28 15:57:19 -0700420 try {
Keun-young Park0727f952015-12-21 14:30:07 -0800421 mService.subscribe(mVehicleNetworkListener, property, sampleRate, zones);
keunyounge18e25d2015-08-28 15:57:19 -0700422 } catch (RemoteException e) {
423 handleRemoteException(e);
424 }
keunyounge18e25d2015-08-28 15:57:19 -0700425 }
426
keunyoung5c7cb262015-10-19 10:47:45 -0700427 /**
428 * Stop subscribing the property.
keunyoung5c7cb262015-10-19 10:47:45 -0700429 */
keunyounge18e25d2015-08-28 15:57:19 -0700430 public void unsubscribe(int property) {
431 try {
432 mService.unsubscribe(mVehicleNetworkListener, property);
433 } catch (RemoteException e) {
434 handleRemoteException(e);
435 }
436 }
437
keunyoung5c7cb262015-10-19 10:47:45 -0700438 /**
439 * Inject given value to all clients subscribing the property. This is for testing.
keunyoung5c7cb262015-10-19 10:47:45 -0700440 */
keunyoung1ab8e182015-09-24 09:25:22 -0700441 public synchronized void injectEvent(VehiclePropValue value) {
442 try {
443 mService.injectEvent(new VehiclePropValueParcelable(value));
444 } catch (RemoteException e) {
445 handleRemoteException(e);
446 }
447 }
448
keunyoung5c7cb262015-10-19 10:47:45 -0700449 /**
450 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700451 */
keunyoung1ab8e182015-09-24 09:25:22 -0700452 public synchronized void startMocking(VehicleNetworkHalMock mock) {
453 mHalMock = mock;
454 mHalMockImpl = new IVehicleNetworkHalMockImpl(this);
455 try {
456 mService.startMocking(mHalMockImpl);
457 } catch (RemoteException e) {
458 handleRemoteException(e);
459 }
460 }
461
keunyoung5c7cb262015-10-19 10:47:45 -0700462 /**
463 * Stop mocking of vehicle HAL. For testing only.
464 */
keunyoung1ab8e182015-09-24 09:25:22 -0700465 public synchronized void stopMocking() {
Keun-young Park28dd4702015-11-19 18:06:04 -0800466 if (mHalMockImpl == null) {
467 return;
468 }
keunyoung1ab8e182015-09-24 09:25:22 -0700469 try {
470 mService.stopMocking(mHalMockImpl);
471 } catch (RemoteException e) {
472 handleRemoteException(e);
473 } finally {
474 mHalMock = null;
475 mHalMockImpl = null;
476 }
477 }
478
keunyoung5c7cb262015-10-19 10:47:45 -0700479 /**
480 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700481 */
keunyoung1ab8e182015-09-24 09:25:22 -0700482 public synchronized void startMocking(IVehicleNetworkHalMock mock) {
483 mHalMock = null;
484 mHalMockImpl = mock;
485 try {
486 mService.startMocking(mHalMockImpl);
487 } catch (RemoteException e) {
488 handleRemoteException(e);
489 }
490 }
491
keunyoung5c7cb262015-10-19 10:47:45 -0700492 /**
493 * Stop mocking of vehicle HAL. For testing only.
494 */
keunyoung1ab8e182015-09-24 09:25:22 -0700495 public synchronized void stopMocking(IVehicleNetworkHalMock mock) {
496 if (mock.asBinder() != mHalMockImpl.asBinder()) {
497 return;
498 }
499 try {
500 mService.stopMocking(mHalMockImpl);
501 } catch (RemoteException e) {
502 handleRemoteException(e);
503 } finally {
504 mHalMock = null;
505 mHalMockImpl = null;
506 }
507 }
508
Keun-young Park28dd4702015-11-19 18:06:04 -0800509 public synchronized void injectHalError(int errorCode, int property, int operation) {
510 try {
511 mService.injectHalError(errorCode, property, operation);
512 } catch (RemoteException e) {
513 handleRemoteException(e);
514 }
515 }
516
517 public synchronized void startErrorListening() {
518 try {
519 mService.startErrorListening(mVehicleNetworkListener);
520 } catch (RemoteException e) {
521 handleRemoteException(e);
522 }
523 }
524
525 public synchronized void stopErrorListening() {
526 try {
527 mService.stopErrorListening(mVehicleNetworkListener);
528 } catch (RemoteException e) {
529 handleRemoteException(e);
530 }
531 }
532
533 public synchronized void startHalRestartMonitoring() {
534 try {
535 mService.startHalRestartMonitoring(mVehicleNetworkListener);
536 } catch (RemoteException e) {
537 handleRemoteException(e);
538 }
539 }
540
541 public synchronized void stopHalRestartMonitoring() {
542 try {
543 mService.stopHalRestartMonitoring(mVehicleNetworkListener);
544 } catch (RemoteException e) {
545 handleRemoteException(e);
546 }
547 }
548
keunyoung1ab8e182015-09-24 09:25:22 -0700549 private synchronized VehicleNetworkHalMock getHalMock() {
550 return mHalMock;
551 }
552
keunyounge18e25d2015-08-28 15:57:19 -0700553 private void handleRemoteException(RemoteException e) {
554 throw new RuntimeException("Vehicle network service not working ", e);
555 }
556
557 private void handleVehicleNetworkEvents(VehiclePropValues values) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800558 mListener.onVehicleNetworkEvents(values);
keunyounge18e25d2015-08-28 15:57:19 -0700559 }
560
Keun-young Park28dd4702015-11-19 18:06:04 -0800561 private void handleHalError(int errorCode, int property, int operation) {
562 mListener.onHalError(errorCode, property, operation);
563 }
564
565 private void handleHalRestart(boolean inMocking) {
566 mListener.onHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700567 }
568
569 private class EventHandler extends Handler {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800570
keunyounge18e25d2015-08-28 15:57:19 -0700571 private static final int MSG_EVENTS = 0;
Keun-young Park28dd4702015-11-19 18:06:04 -0800572 private static final int MSG_HAL_ERROR = 1;
573 private static final int MSG_HAL_RESTART = 2;
keunyounge18e25d2015-08-28 15:57:19 -0700574
575 private EventHandler(Looper looper) {
576 super(looper);
577 }
578
579 private void notifyEvents(VehiclePropValues values) {
580 Message msg = obtainMessage(MSG_EVENTS, values);
581 sendMessage(msg);
582 }
583
Keun-young Park28dd4702015-11-19 18:06:04 -0800584 private void notifyHalError(int errorCode, int property, int operation) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800585 Message msg = obtainMessage(MSG_HAL_ERROR, errorCode, property, operation);
Keun-young Park28dd4702015-11-19 18:06:04 -0800586 sendMessage(msg);
587 }
588
589 private void notifyHalRestart(boolean inMocking) {
590 Message msg = obtainMessage(MSG_HAL_RESTART, inMocking ? 1 : 0, 0);
591 sendMessage(msg);
592 }
593
keunyounge18e25d2015-08-28 15:57:19 -0700594 @Override
595 public void handleMessage(Message msg) {
596 switch (msg.what) {
597 case MSG_EVENTS:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800598 handleVehicleNetworkEvents((VehiclePropValues) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800599 break;
600 case MSG_HAL_ERROR:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800601 handleHalError(msg.arg1, msg.arg2, (Integer) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800602 break;
603 case MSG_HAL_RESTART:
604 handleHalRestart(msg.arg1 == 1);
keunyounge18e25d2015-08-28 15:57:19 -0700605 break;
606 default:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800607 Log.w(TAG, "Unknown message:" + msg.what, new RuntimeException());
keunyounge18e25d2015-08-28 15:57:19 -0700608 break;
609 }
610 }
611 }
612
613 private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800614
keunyounge18e25d2015-08-28 15:57:19 -0700615 private final WeakReference<VehicleNetwork> mVehicleNetwork;
616
617 private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800618 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyounge18e25d2015-08-28 15:57:19 -0700619 }
620
621 @Override
622 public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) {
623 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
624 if (vehicleNetwork != null) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800625 vehicleNetwork.mEventHandler.notifyEvents(values.values);
626 }
627 }
628
629 @Override
630 public void onHalError(int errorCode, int property, int operation) {
631 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
632 if (vehicleNetwork != null) {
633 vehicleNetwork.mEventHandler.notifyHalError(errorCode, property, operation);
634 }
635 }
636
637 @Override
638 public void onHalRestart(boolean inMocking) {
639 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
640 if (vehicleNetwork != null) {
641 vehicleNetwork.mEventHandler.notifyHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700642 }
643 }
644 }
keunyoung1ab8e182015-09-24 09:25:22 -0700645
646 private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub {
647 private final WeakReference<VehicleNetwork> mVehicleNetwork;
648
649 private IVehicleNetworkHalMockImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800650 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyoung1ab8e182015-09-24 09:25:22 -0700651 }
652
653 @Override
654 public VehiclePropConfigsParcelable onListProperties() {
655 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
656 if (vehicleNetwork == null) {
657 return null;
658 }
659 VehiclePropConfigs configs = vehicleNetwork.getHalMock().onListProperties();
660 return new VehiclePropConfigsParcelable(configs);
661 }
662
663 @Override
664 public void onPropertySet(VehiclePropValueParcelable value) {
665 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
666 if (vehicleNetwork == null) {
667 return;
668 }
669 vehicleNetwork.getHalMock().onPropertySet(value.value);
670 }
671
672 @Override
keunyoung7d74e6d2015-10-14 15:43:10 -0700673 public VehiclePropValueParcelable onPropertyGet(VehiclePropValueParcelable value) {
keunyoung1ab8e182015-09-24 09:25:22 -0700674 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
675 if (vehicleNetwork == null) {
676 return null;
677 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700678 VehiclePropValue resValue = vehicleNetwork.getHalMock().onPropertyGet(value.value);
679 return new VehiclePropValueParcelable(resValue);
keunyoung1ab8e182015-09-24 09:25:22 -0700680 }
681
682 @Override
Keun-young Park0727f952015-12-21 14:30:07 -0800683 public void onPropertySubscribe(int property, float sampleRate, int zones) {
keunyoung1ab8e182015-09-24 09:25:22 -0700684 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
685 if (vehicleNetwork == null) {
686 return;
687 }
Keun-young Park0727f952015-12-21 14:30:07 -0800688 vehicleNetwork.getHalMock().onPropertySubscribe(property, sampleRate, zones);
keunyoung1ab8e182015-09-24 09:25:22 -0700689 }
690
691 @Override
692 public void onPropertyUnsubscribe(int property) {
693 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
694 if (vehicleNetwork == null) {
695 return;
696 }
697 vehicleNetwork.getHalMock().onPropertyUnsubscribe(property);
698 }
699 }
Pavel Maltseve8f75372016-01-26 10:26:04 -0800700
701 private VehiclePropValue getProperty(int property, int zone, int customPropetyDataType) {
702 boolean isCustom = isCustomProperty(property);
703 int valueType = isCustom
704 ? customPropetyDataType
705 : VehicleNetworkConsts.getVehicleValueType(property);
706
707 VehiclePropValue.Builder valuePrototypeBuilder =
708 VehiclePropValueUtil.createBuilder(property, valueType, 0);
709
710 if (zone != NO_ZONE) {
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800711 valuePrototypeBuilder.setZone(zone);
Pavel Maltseve8f75372016-01-26 10:26:04 -0800712 }
713
714 VehiclePropValue v = getProperty(valuePrototypeBuilder.build());
715 if (v == null) {
716 // if property is invalid, IllegalArgumentException should have been thrown
717 // from getProperty.
718 throw new IllegalStateException();
719 }
720
721 if (!isCustom && v.getValueType() != valueType) {
Keun-young Park1488ef22016-02-25 14:00:54 -0800722 throw new IllegalArgumentException(
723 "Unexpected type for property 0x" + Integer.toHexString(property) +
724 " got:0x" + Integer.toHexString(v.getValueType())
725 + ", expecting:0x" + Integer.toHexString(valueType));
Pavel Maltseve8f75372016-01-26 10:26:04 -0800726 }
727 return v;
728 }
729
730 private void assertVectorLength(int actual, int property, int valueType) {
731 int expectedLen = getVectorLength(valueType);
732 if (expectedLen != actual) {
733 throw new IllegalStateException("Invalid array size for property: " + property
734 + ". Expected: " + expectedLen
735 + ", actual: " + actual);
736 }
737 }
keunyounge18e25d2015-08-28 15:57:19 -0700738}