blob: 6724247fe27be4ef4425f63ab3e6b4b2e8ceebf2 [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;
Keun-young Parke52e8f22016-08-15 09:29:14 -070089 while (true) {
keunyoung217ca352015-11-17 14:45:38 -080090 service = IVehicleNetwork.Stub.asInterface(ServiceManager.getService(
91 IVehicleNetwork.class.getCanonicalName()));
Keun-young Parke52e8f22016-08-15 09:29:14 -070092 if (service != null) {
93 break;
94 }
keunyoung217ca352015-11-17 14:45:38 -080095 retryCount++;
96 if (retryCount > VNS_CONNECT_MAX_RETRY) {
97 break;
98 }
99 try {
100 Thread.sleep(VNS_RETRY_WAIT_TIME_MS);
101 } catch (InterruptedException e) {
102 //ignore
103 }
104 }
keunyounge18e25d2015-08-28 15:57:19 -0700105 if (service == null) {
keunyoung15882e52015-09-16 16:57:58 -0700106 throw new RuntimeException("Vehicle network service not available:" +
107 IVehicleNetwork.class.getCanonicalName());
keunyounge18e25d2015-08-28 15:57:19 -0700108 }
109 return new VehicleNetwork(service, listener, looper);
110 }
111
112 private VehicleNetwork(IVehicleNetwork service, VehicleNetworkListener listener,
113 Looper looper) {
114 mService = service;
115 mListener = listener;
116 mEventHandler = new EventHandler(looper);
117 mVehicleNetworkListener = new IVehicleNetworkListenerImpl(this);
118 }
119
keunyoung5c7cb262015-10-19 10:47:45 -0700120 /**
121 * List all properties from vehicle HAL
Pavel Maltseve8f75372016-01-26 10:26:04 -0800122 *
keunyoung5c7cb262015-10-19 10:47:45 -0700123 * @return all properties
124 */
keunyoung15882e52015-09-16 16:57:58 -0700125 public VehiclePropConfigs listProperties() {
126 return listProperties(0 /* all */);
127 }
128
keunyoung5c7cb262015-10-19 10:47:45 -0700129 /**
130 * Return configuration information of single property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800131 *
132 * @param property vehicle property number defined in {@link VehicleNetworkConsts}. 0 has has
133 * special meaning of list all properties.
keunyoung5c7cb262015-10-19 10:47:45 -0700134 * @return null if given property does not exist.
135 */
keunyounge18e25d2015-08-28 15:57:19 -0700136 public VehiclePropConfigs listProperties(int property) {
137 try {
138 VehiclePropConfigsParcelable parcelable = mService.listProperties(property);
139 if (parcelable != null) {
140 return parcelable.configs;
141 }
142 } catch (RemoteException e) {
143 handleRemoteException(e);
144 }
145 return null;
146 }
147
keunyoung5c7cb262015-10-19 10:47:45 -0700148 /**
149 * Set property which will lead into writing the value to vehicle HAL.
Pavel Maltseve8f75372016-01-26 10:26:04 -0800150 *
151 * @throws IllegalArgumentException If value set has wrong value like wrong valueType, wrong
152 * data, and etc.
keunyoung5c7cb262015-10-19 10:47:45 -0700153 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700154 public void setProperty(VehiclePropValue value)
155 throws IllegalArgumentException, ServiceSpecificException {
keunyounge18e25d2015-08-28 15:57:19 -0700156 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
157 try {
keunyoung15882e52015-09-16 16:57:58 -0700158 mService.setProperty(parcelable);
keunyounge18e25d2015-08-28 15:57:19 -0700159 } catch (RemoteException e) {
160 handleRemoteException(e);
161 }
keunyounge18e25d2015-08-28 15:57:19 -0700162 }
163
keunyoung5c7cb262015-10-19 10:47:45 -0700164 /**
165 * Set integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800166 *
keunyoung5c7cb262015-10-19 10:47:45 -0700167 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
168 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700169 public void setIntProperty(int property, int value)
170 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700171 VehiclePropValue v = VehiclePropValueUtil.createIntValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700172 setProperty(v);
173 }
174
keunyoung5c7cb262015-10-19 10:47:45 -0700175 /**
176 * Set int vector type property. Length of passed values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700177 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700178 public void setIntVectorProperty(int property, int[] values)
179 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700180 VehiclePropValue v = VehiclePropValueUtil.createIntVectorValue(property, values, 0);
181 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700182 }
183
keunyoung5c7cb262015-10-19 10:47:45 -0700184 /**
185 * Set long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700186 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700187 public void setLongProperty(int property, long value)
188 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700189 VehiclePropValue v = VehiclePropValueUtil.createLongValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700190 setProperty(v);
191 }
192
keunyoung5c7cb262015-10-19 10:47:45 -0700193 /**
194 * Set float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700195 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700196 public void setFloatProperty(int property, float value)
197 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700198 VehiclePropValue v = VehiclePropValueUtil.createFloatValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700199 setProperty(v);
200 }
201
keunyoung5c7cb262015-10-19 10:47:45 -0700202 /**
203 * Set float vector type property. Length of values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700204 */
205 public void setFloatVectorProperty(int property, float[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700206 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700207 VehiclePropValue v = VehiclePropValueUtil.createFloatVectorValue(property, values, 0);
208 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700209 }
210
keunyoung5c7cb262015-10-19 10:47:45 -0700211 /**
Steve Paik66481982015-10-27 15:22:38 -0700212 * Set zoned boolean type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800213 *
214 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
215 */
216 public void setBooleanProperty(int property, boolean value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700217 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800218 VehiclePropValue v = VehiclePropValueUtil.createBooleanValue(property, value, 0);
219 setProperty(v);
220 }
221
Keun-young Park4c6834a2016-06-28 12:58:23 -0700222 public void setStringProperty(int property, String value)
223 throws IllegalArgumentException, ServiceSpecificException {
224 VehiclePropValue v = VehiclePropValueUtil.createStringValue(property, value, 0);
225 setProperty(v);
226 }
227
Pavel Maltseve8f75372016-01-26 10:26:04 -0800228 /**
229 * Set zoned boolean type property
230 *
Steve Paik66481982015-10-27 15:22:38 -0700231 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
232 */
233 public void setZonedBooleanProperty(int property, int zone, boolean value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700234 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700235 VehiclePropValue v = VehiclePropValueUtil.createZonedBooleanValue(property, zone, value, 0);
236 setProperty(v);
237 }
238
239 /**
240 * Set zoned float type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800241 *
Steve Paik66481982015-10-27 15:22:38 -0700242 * @throws IllegalArgumentException For type mismatch (=the property is not float type)
243 */
244 public void setZonedFloatProperty(int property, int zone, float value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700245 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700246 VehiclePropValue v = VehiclePropValueUtil.createZonedFloatValue(property, zone, value, 0);
247 setProperty(v);
248 }
249
250 /**
251 * Set zoned integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800252 *
Steve Paik66481982015-10-27 15:22:38 -0700253 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
254 */
255 public void setZonedIntProperty(int property, int zone, int value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700256 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700257 VehiclePropValue v = VehiclePropValueUtil.createZonedIntValue(property, zone, value, 0);
258 setProperty(v);
259 }
260
261 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800262 * Set zoned int vector type property. Length of passed values should match with vector length.
263 */
264 public void setZonedIntVectorProperty(int property, int zone, int[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700265 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800266 VehiclePropValue v = VehiclePropValueUtil
267 .createZonedIntVectorValue(property, zone, values, 0);
268 setProperty(v);
269 }
270
271 /**
272 * Set zoned float vector type property. Length of passed values should match with vector
273 * length.
274 */
275 public void setZonedFloatVectorProperty(int property, int zone, float[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700276 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800277 VehiclePropValue v = VehiclePropValueUtil
278 .createZonedFloatVectorValue(property, zone, values, 0);
279 setProperty(v);
280 }
281
282 /**
keunyoung5c7cb262015-10-19 10:47:45 -0700283 * Get property. This can be used for a property which does not require any other data.
keunyoung5c7cb262015-10-19 10:47:45 -0700284 */
Keun-young Parkba485482016-03-24 13:24:31 -0700285 public VehiclePropValue getProperty(int property) throws IllegalArgumentException,
286 ServiceSpecificException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700287 int valueType = VehicleNetworkConsts.getVehicleValueType(property);
Pavel Maltsev169b7a62016-01-26 15:56:07 -0800288 if (valueType == 0) {
289 throw new IllegalArgumentException("Data type is unknown for property: " + property);
290 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700291 VehiclePropValue value = VehiclePropValueUtil.createBuilder(property, valueType, 0).build();
292 return getProperty(value);
293 }
294
keunyoung5c7cb262015-10-19 10:47:45 -0700295 /**
296 * Generic get method for any type of property. Some property may require setting data portion
297 * as get may return different result depending on the data set.
keunyoung5c7cb262015-10-19 10:47:45 -0700298 */
Keun-young Parkba485482016-03-24 13:24:31 -0700299 public VehiclePropValue getProperty(VehiclePropValue value) throws IllegalArgumentException,
300 ServiceSpecificException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700301 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
keunyounge18e25d2015-08-28 15:57:19 -0700302 try {
keunyoung7d74e6d2015-10-14 15:43:10 -0700303 VehiclePropValueParcelable resParcelable = mService.getProperty(parcelable);
304 if (resParcelable != null) {
305 return resParcelable.value;
keunyounge18e25d2015-08-28 15:57:19 -0700306 }
307 } catch (RemoteException e) {
308 handleRemoteException(e);
309 }
310 return null;
311 }
312
keunyoung5c7cb262015-10-19 10:47:45 -0700313 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800314 * Get int type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700315 */
Keun-young Parkba485482016-03-24 13:24:31 -0700316 public int getIntProperty(int property) throws IllegalArgumentException,
317 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800318 VehiclePropValue v = getProperty(
319 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
keunyoungd32f4e62015-09-21 11:33:06 -0700320 if (v.getInt32ValuesCount() != 1) {
321 throw new IllegalStateException();
322 }
323 return v.getInt32Values(0);
324 }
325
keunyoung5c7cb262015-10-19 10:47:45 -0700326 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800327 * Get zoned int type property.
328 */
Keun-young Parkba485482016-03-24 13:24:31 -0700329 public int getZonedIntProperty(int property, int zone) throws IllegalArgumentException,
330 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800331 VehiclePropValue v = getProperty(
332 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800333 if (v.getInt32ValuesCount() != 1) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800334 throw new IllegalStateException();
335 }
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800336 return v.getInt32Values(0);
Pavel Maltseve8f75372016-01-26 10:26:04 -0800337 }
338
339 /**
340 * Get int vector type property. Length of values should match vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700341 */
Keun-young Parkba485482016-03-24 13:24:31 -0700342 public int[] getIntVectorProperty(int property) throws IllegalArgumentException,
343 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800344 VehiclePropValue v = getProperty(
345 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
346 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
347 return toIntArray(v.getInt32ValuesList());
348 }
349
350 /**
351 * Get zoned int vector type property. Length of values should match vector length.
352 */
353 public int[] getZonedIntVectorProperty(int property, int zone)
Keun-young Parkba485482016-03-24 13:24:31 -0700354 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800355 VehiclePropValue v = getProperty(
356 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800357 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
358 return toIntArray(v.getInt32ValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700359 }
360
keunyoung5c7cb262015-10-19 10:47:45 -0700361 /**
362 * Get float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700363 */
Keun-young Parkba485482016-03-24 13:24:31 -0700364 public float getFloatProperty(int property) throws IllegalArgumentException,
365 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800366 VehiclePropValue v = getProperty(
367 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
keunyoungd32f4e62015-09-21 11:33:06 -0700368 if (v.getFloatValuesCount() != 1) {
369 throw new IllegalStateException();
370 }
371 return v.getFloatValues(0);
372 }
373
keunyoung5c7cb262015-10-19 10:47:45 -0700374 /**
375 * Get float vector type property. Length of values should match vector's length.
keunyoung5c7cb262015-10-19 10:47:45 -0700376 */
Keun-young Parkba485482016-03-24 13:24:31 -0700377 public float[] getFloatVectorProperty(int property) throws IllegalArgumentException,
378 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800379 VehiclePropValue v = getProperty(
380 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
381 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
382 return toFloatArray(v.getFloatValuesList());
383 }
384
385 /**
386 * Get zoned float vector type property. Length of values should match vector's length.
387 */
388 public float[] getZonedFloatVectorProperty(int property, int zone)
Keun-young Parkba485482016-03-24 13:24:31 -0700389 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800390 VehiclePropValue v = getProperty(property, zone,
391 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800392 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
393 return toFloatArray(v.getFloatValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700394 }
395
keunyoung5c7cb262015-10-19 10:47:45 -0700396 /**
397 * Get long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700398 */
Keun-young Parkba485482016-03-24 13:24:31 -0700399 public long getLongProperty(int property) throws IllegalArgumentException,
400 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800401 VehiclePropValue v = getProperty(
402 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT64);
keunyoungfe30ba02015-09-17 17:56:35 -0700403 return v.getInt64Value();
404 }
405
keunyoung5c7cb262015-10-19 10:47:45 -0700406 /**
407 * Get string type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700408 */
keunyoungfe30ba02015-09-17 17:56:35 -0700409 //TODO check UTF8 to java string conversion
Keun-young Parkba485482016-03-24 13:24:31 -0700410 public String getStringProperty(int property) throws IllegalArgumentException,
411 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800412 VehiclePropValue v = getProperty(
413 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_STRING);
keunyoungfe30ba02015-09-17 17:56:35 -0700414 return v.getStringValue();
415 }
416
keunyoung5c7cb262015-10-19 10:47:45 -0700417 /**
418 * Subscribe given property with given sample rate.
keunyoung5c7cb262015-10-19 10:47:45 -0700419 */
420 public void subscribe(int property, float sampleRate) throws IllegalArgumentException {
Keun-young Park0727f952015-12-21 14:30:07 -0800421 subscribe(property, sampleRate, 0);
422 }
423
424 /**
425 * Subscribe given property with given sample rate.
Keun-young Park0727f952015-12-21 14:30:07 -0800426 */
427 public void subscribe(int property, float sampleRate, int zones)
428 throws IllegalArgumentException {
keunyounge18e25d2015-08-28 15:57:19 -0700429 try {
Keun-young Park0727f952015-12-21 14:30:07 -0800430 mService.subscribe(mVehicleNetworkListener, property, sampleRate, zones);
keunyounge18e25d2015-08-28 15:57:19 -0700431 } catch (RemoteException e) {
432 handleRemoteException(e);
433 }
keunyounge18e25d2015-08-28 15:57:19 -0700434 }
435
keunyoung5c7cb262015-10-19 10:47:45 -0700436 /**
437 * Stop subscribing the property.
keunyoung5c7cb262015-10-19 10:47:45 -0700438 */
keunyounge18e25d2015-08-28 15:57:19 -0700439 public void unsubscribe(int property) {
440 try {
441 mService.unsubscribe(mVehicleNetworkListener, property);
442 } catch (RemoteException e) {
443 handleRemoteException(e);
444 }
445 }
446
keunyoung5c7cb262015-10-19 10:47:45 -0700447 /**
448 * Inject given value to all clients subscribing the property. This is for testing.
keunyoung5c7cb262015-10-19 10:47:45 -0700449 */
keunyoung1ab8e182015-09-24 09:25:22 -0700450 public synchronized void injectEvent(VehiclePropValue value) {
451 try {
452 mService.injectEvent(new VehiclePropValueParcelable(value));
453 } catch (RemoteException e) {
454 handleRemoteException(e);
455 }
456 }
457
keunyoung5c7cb262015-10-19 10:47:45 -0700458 /**
459 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700460 */
keunyoung1ab8e182015-09-24 09:25:22 -0700461 public synchronized void startMocking(VehicleNetworkHalMock mock) {
462 mHalMock = mock;
463 mHalMockImpl = new IVehicleNetworkHalMockImpl(this);
464 try {
465 mService.startMocking(mHalMockImpl);
466 } catch (RemoteException e) {
467 handleRemoteException(e);
468 }
469 }
470
keunyoung5c7cb262015-10-19 10:47:45 -0700471 /**
472 * Stop mocking of vehicle HAL. For testing only.
473 */
keunyoung1ab8e182015-09-24 09:25:22 -0700474 public synchronized void stopMocking() {
Keun-young Park28dd4702015-11-19 18:06:04 -0800475 if (mHalMockImpl == null) {
476 return;
477 }
keunyoung1ab8e182015-09-24 09:25:22 -0700478 try {
479 mService.stopMocking(mHalMockImpl);
480 } catch (RemoteException e) {
481 handleRemoteException(e);
482 } finally {
483 mHalMock = null;
484 mHalMockImpl = null;
485 }
486 }
487
keunyoung5c7cb262015-10-19 10:47:45 -0700488 /**
489 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700490 */
keunyoung1ab8e182015-09-24 09:25:22 -0700491 public synchronized void startMocking(IVehicleNetworkHalMock mock) {
492 mHalMock = null;
493 mHalMockImpl = mock;
494 try {
495 mService.startMocking(mHalMockImpl);
496 } catch (RemoteException e) {
497 handleRemoteException(e);
498 }
499 }
500
keunyoung5c7cb262015-10-19 10:47:45 -0700501 /**
502 * Stop mocking of vehicle HAL. For testing only.
503 */
keunyoung1ab8e182015-09-24 09:25:22 -0700504 public synchronized void stopMocking(IVehicleNetworkHalMock mock) {
505 if (mock.asBinder() != mHalMockImpl.asBinder()) {
506 return;
507 }
508 try {
509 mService.stopMocking(mHalMockImpl);
510 } catch (RemoteException e) {
511 handleRemoteException(e);
512 } finally {
513 mHalMock = null;
514 mHalMockImpl = null;
515 }
516 }
517
Keun-young Park28dd4702015-11-19 18:06:04 -0800518 public synchronized void injectHalError(int errorCode, int property, int operation) {
519 try {
520 mService.injectHalError(errorCode, property, operation);
521 } catch (RemoteException e) {
522 handleRemoteException(e);
523 }
524 }
525
526 public synchronized void startErrorListening() {
527 try {
528 mService.startErrorListening(mVehicleNetworkListener);
529 } catch (RemoteException e) {
530 handleRemoteException(e);
531 }
532 }
533
534 public synchronized void stopErrorListening() {
535 try {
536 mService.stopErrorListening(mVehicleNetworkListener);
537 } catch (RemoteException e) {
538 handleRemoteException(e);
539 }
540 }
541
542 public synchronized void startHalRestartMonitoring() {
543 try {
544 mService.startHalRestartMonitoring(mVehicleNetworkListener);
545 } catch (RemoteException e) {
546 handleRemoteException(e);
547 }
548 }
549
550 public synchronized void stopHalRestartMonitoring() {
551 try {
552 mService.stopHalRestartMonitoring(mVehicleNetworkListener);
553 } catch (RemoteException e) {
554 handleRemoteException(e);
555 }
556 }
557
keunyoung1ab8e182015-09-24 09:25:22 -0700558 private synchronized VehicleNetworkHalMock getHalMock() {
559 return mHalMock;
560 }
561
keunyounge18e25d2015-08-28 15:57:19 -0700562 private void handleRemoteException(RemoteException e) {
563 throw new RuntimeException("Vehicle network service not working ", e);
564 }
565
566 private void handleVehicleNetworkEvents(VehiclePropValues values) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800567 mListener.onVehicleNetworkEvents(values);
keunyounge18e25d2015-08-28 15:57:19 -0700568 }
569
Keun-young Park28dd4702015-11-19 18:06:04 -0800570 private void handleHalError(int errorCode, int property, int operation) {
571 mListener.onHalError(errorCode, property, operation);
572 }
573
574 private void handleHalRestart(boolean inMocking) {
575 mListener.onHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700576 }
577
578 private class EventHandler extends Handler {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800579
keunyounge18e25d2015-08-28 15:57:19 -0700580 private static final int MSG_EVENTS = 0;
Keun-young Park28dd4702015-11-19 18:06:04 -0800581 private static final int MSG_HAL_ERROR = 1;
582 private static final int MSG_HAL_RESTART = 2;
keunyounge18e25d2015-08-28 15:57:19 -0700583
584 private EventHandler(Looper looper) {
585 super(looper);
586 }
587
588 private void notifyEvents(VehiclePropValues values) {
589 Message msg = obtainMessage(MSG_EVENTS, values);
590 sendMessage(msg);
591 }
592
Keun-young Park28dd4702015-11-19 18:06:04 -0800593 private void notifyHalError(int errorCode, int property, int operation) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800594 Message msg = obtainMessage(MSG_HAL_ERROR, errorCode, property, operation);
Keun-young Park28dd4702015-11-19 18:06:04 -0800595 sendMessage(msg);
596 }
597
598 private void notifyHalRestart(boolean inMocking) {
599 Message msg = obtainMessage(MSG_HAL_RESTART, inMocking ? 1 : 0, 0);
600 sendMessage(msg);
601 }
602
keunyounge18e25d2015-08-28 15:57:19 -0700603 @Override
604 public void handleMessage(Message msg) {
605 switch (msg.what) {
606 case MSG_EVENTS:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800607 handleVehicleNetworkEvents((VehiclePropValues) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800608 break;
609 case MSG_HAL_ERROR:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800610 handleHalError(msg.arg1, msg.arg2, (Integer) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800611 break;
612 case MSG_HAL_RESTART:
613 handleHalRestart(msg.arg1 == 1);
keunyounge18e25d2015-08-28 15:57:19 -0700614 break;
615 default:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800616 Log.w(TAG, "Unknown message:" + msg.what, new RuntimeException());
keunyounge18e25d2015-08-28 15:57:19 -0700617 break;
618 }
619 }
620 }
621
622 private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800623
keunyounge18e25d2015-08-28 15:57:19 -0700624 private final WeakReference<VehicleNetwork> mVehicleNetwork;
625
626 private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800627 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyounge18e25d2015-08-28 15:57:19 -0700628 }
629
630 @Override
631 public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) {
632 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
633 if (vehicleNetwork != null) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800634 vehicleNetwork.mEventHandler.notifyEvents(values.values);
635 }
636 }
637
638 @Override
639 public void onHalError(int errorCode, int property, int operation) {
640 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
641 if (vehicleNetwork != null) {
642 vehicleNetwork.mEventHandler.notifyHalError(errorCode, property, operation);
643 }
644 }
645
646 @Override
647 public void onHalRestart(boolean inMocking) {
648 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
649 if (vehicleNetwork != null) {
650 vehicleNetwork.mEventHandler.notifyHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700651 }
652 }
653 }
keunyoung1ab8e182015-09-24 09:25:22 -0700654
655 private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub {
656 private final WeakReference<VehicleNetwork> mVehicleNetwork;
657
658 private IVehicleNetworkHalMockImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800659 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyoung1ab8e182015-09-24 09:25:22 -0700660 }
661
662 @Override
663 public VehiclePropConfigsParcelable onListProperties() {
664 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
665 if (vehicleNetwork == null) {
666 return null;
667 }
668 VehiclePropConfigs configs = vehicleNetwork.getHalMock().onListProperties();
669 return new VehiclePropConfigsParcelable(configs);
670 }
671
672 @Override
673 public void onPropertySet(VehiclePropValueParcelable value) {
674 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
675 if (vehicleNetwork == null) {
676 return;
677 }
678 vehicleNetwork.getHalMock().onPropertySet(value.value);
679 }
680
681 @Override
keunyoung7d74e6d2015-10-14 15:43:10 -0700682 public VehiclePropValueParcelable onPropertyGet(VehiclePropValueParcelable value) {
keunyoung1ab8e182015-09-24 09:25:22 -0700683 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
684 if (vehicleNetwork == null) {
685 return null;
686 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700687 VehiclePropValue resValue = vehicleNetwork.getHalMock().onPropertyGet(value.value);
688 return new VehiclePropValueParcelable(resValue);
keunyoung1ab8e182015-09-24 09:25:22 -0700689 }
690
691 @Override
Keun-young Park0727f952015-12-21 14:30:07 -0800692 public void onPropertySubscribe(int property, float sampleRate, int zones) {
keunyoung1ab8e182015-09-24 09:25:22 -0700693 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
694 if (vehicleNetwork == null) {
695 return;
696 }
Keun-young Park0727f952015-12-21 14:30:07 -0800697 vehicleNetwork.getHalMock().onPropertySubscribe(property, sampleRate, zones);
keunyoung1ab8e182015-09-24 09:25:22 -0700698 }
699
700 @Override
701 public void onPropertyUnsubscribe(int property) {
702 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
703 if (vehicleNetwork == null) {
704 return;
705 }
706 vehicleNetwork.getHalMock().onPropertyUnsubscribe(property);
707 }
708 }
Pavel Maltseve8f75372016-01-26 10:26:04 -0800709
710 private VehiclePropValue getProperty(int property, int zone, int customPropetyDataType) {
711 boolean isCustom = isCustomProperty(property);
712 int valueType = isCustom
713 ? customPropetyDataType
714 : VehicleNetworkConsts.getVehicleValueType(property);
715
716 VehiclePropValue.Builder valuePrototypeBuilder =
717 VehiclePropValueUtil.createBuilder(property, valueType, 0);
718
719 if (zone != NO_ZONE) {
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800720 valuePrototypeBuilder.setZone(zone);
Pavel Maltseve8f75372016-01-26 10:26:04 -0800721 }
722
723 VehiclePropValue v = getProperty(valuePrototypeBuilder.build());
724 if (v == null) {
725 // if property is invalid, IllegalArgumentException should have been thrown
726 // from getProperty.
727 throw new IllegalStateException();
728 }
729
730 if (!isCustom && v.getValueType() != valueType) {
Keun-young Park1488ef22016-02-25 14:00:54 -0800731 throw new IllegalArgumentException(
732 "Unexpected type for property 0x" + Integer.toHexString(property) +
733 " got:0x" + Integer.toHexString(v.getValueType())
734 + ", expecting:0x" + Integer.toHexString(valueType));
Pavel Maltseve8f75372016-01-26 10:26:04 -0800735 }
736 return v;
737 }
738
739 private void assertVectorLength(int actual, int property, int valueType) {
740 int expectedLen = getVectorLength(valueType);
741 if (expectedLen != actual) {
742 throw new IllegalStateException("Invalid array size for property: " + property
743 + ". Expected: " + expectedLen
744 + ", actual: " + actual);
745 }
746 }
keunyounge18e25d2015-08-28 15:57:19 -0700747}