blob: 3ac50402a3c7bdcfe2a2a8cc998efd2954318902 [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;
keunyoung1ab8e182015-09-24 09:25:22 -070034import com.android.internal.annotations.GuardedBy;
keunyounge18e25d2015-08-28 15:57:19 -070035
36import java.lang.ref.WeakReference;
37
38/**
39 * System API to access Vehicle network. This is only for system services and applications should
keunyoung15882e52015-09-16 16:57:58 -070040 * not use this. All APIs will fail with security error if normal app tries this.
keunyounge18e25d2015-08-28 15:57:19 -070041 */
42public class VehicleNetwork {
keunyoung1ab8e182015-09-24 09:25:22 -070043 /**
44 * Listener for VNS events.
45 */
keunyounge18e25d2015-08-28 15:57:19 -070046 public interface VehicleNetworkListener {
keunyoung1ab8e182015-09-24 09:25:22 -070047 /**
48 * Notify HAL events. This requires subscribing the property
49 */
keunyounge18e25d2015-08-28 15:57:19 -070050 void onVehicleNetworkEvents(VehiclePropValues values);
Keun-young Park28dd4702015-11-19 18:06:04 -080051 void onHalError(int errorCode, int property, int operation);
52 void onHalRestart(boolean inMocking);
keunyounge18e25d2015-08-28 15:57:19 -070053 }
54
keunyoung1ab8e182015-09-24 09:25:22 -070055 public interface VehicleNetworkHalMock {
56 VehiclePropConfigs onListProperties();
57 void onPropertySet(VehiclePropValue value);
Keun-young Park28dd4702015-11-19 18:06:04 -080058 VehiclePropValue onPropertyGet(VehiclePropValue value);
Keun-young Park0727f952015-12-21 14:30:07 -080059 void onPropertySubscribe(int property, float sampleRate, int zones);
keunyoung1ab8e182015-09-24 09:25:22 -070060 void onPropertyUnsubscribe(int property);
61 }
62
keunyounge18e25d2015-08-28 15:57:19 -070063 private static final String TAG = VehicleNetwork.class.getSimpleName();
64
65 private final IVehicleNetwork mService;
66 private final VehicleNetworkListener mListener;
67 private final IVehicleNetworkListenerImpl mVehicleNetworkListener;
68 private final EventHandler mEventHandler;
69
keunyoung1ab8e182015-09-24 09:25:22 -070070 @GuardedBy("this")
71 private VehicleNetworkHalMock mHalMock;
72 private IVehicleNetworkHalMock mHalMockImpl;
73
keunyoung217ca352015-11-17 14:45:38 -080074 private static final int VNS_CONNECT_MAX_RETRY = 10;
75 private static final long VNS_RETRY_WAIT_TIME_MS = 1000;
Pavel Maltseve8f75372016-01-26 10:26:04 -080076 private static final int NO_ZONE = -1;
keunyoung217ca352015-11-17 14:45:38 -080077
keunyoung5c7cb262015-10-19 10:47:45 -070078 /**
79 * Factory method to create VehicleNetwork
Pavel Maltseve8f75372016-01-26 10:26:04 -080080 *
keunyoung5c7cb262015-10-19 10:47:45 -070081 * @param listener listener for listening events
82 * @param looper Looper to dispatch listener events
keunyoung5c7cb262015-10-19 10:47:45 -070083 */
keunyoung15882e52015-09-16 16:57:58 -070084 public static VehicleNetwork createVehicleNetwork(VehicleNetworkListener listener,
85 Looper looper) {
keunyoung217ca352015-11-17 14:45:38 -080086 int retryCount = 0;
87 IVehicleNetwork service = null;
88 while (service == null) {
89 service = IVehicleNetwork.Stub.asInterface(ServiceManager.getService(
90 IVehicleNetwork.class.getCanonicalName()));
91 retryCount++;
92 if (retryCount > VNS_CONNECT_MAX_RETRY) {
93 break;
94 }
95 try {
96 Thread.sleep(VNS_RETRY_WAIT_TIME_MS);
97 } catch (InterruptedException e) {
98 //ignore
99 }
100 }
keunyounge18e25d2015-08-28 15:57:19 -0700101 if (service == null) {
keunyoung15882e52015-09-16 16:57:58 -0700102 throw new RuntimeException("Vehicle network service not available:" +
103 IVehicleNetwork.class.getCanonicalName());
keunyounge18e25d2015-08-28 15:57:19 -0700104 }
105 return new VehicleNetwork(service, listener, looper);
106 }
107
108 private VehicleNetwork(IVehicleNetwork service, VehicleNetworkListener listener,
109 Looper looper) {
110 mService = service;
111 mListener = listener;
112 mEventHandler = new EventHandler(looper);
113 mVehicleNetworkListener = new IVehicleNetworkListenerImpl(this);
114 }
115
keunyoung5c7cb262015-10-19 10:47:45 -0700116 /**
117 * List all properties from vehicle HAL
Pavel Maltseve8f75372016-01-26 10:26:04 -0800118 *
keunyoung5c7cb262015-10-19 10:47:45 -0700119 * @return all properties
120 */
keunyoung15882e52015-09-16 16:57:58 -0700121 public VehiclePropConfigs listProperties() {
122 return listProperties(0 /* all */);
123 }
124
keunyoung5c7cb262015-10-19 10:47:45 -0700125 /**
126 * Return configuration information of single property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800127 *
128 * @param property vehicle property number defined in {@link VehicleNetworkConsts}. 0 has has
129 * special meaning of list all properties.
keunyoung5c7cb262015-10-19 10:47:45 -0700130 * @return null if given property does not exist.
131 */
keunyounge18e25d2015-08-28 15:57:19 -0700132 public VehiclePropConfigs listProperties(int property) {
133 try {
134 VehiclePropConfigsParcelable parcelable = mService.listProperties(property);
135 if (parcelable != null) {
136 return parcelable.configs;
137 }
138 } catch (RemoteException e) {
139 handleRemoteException(e);
140 }
141 return null;
142 }
143
keunyoung5c7cb262015-10-19 10:47:45 -0700144 /**
145 * Set property which will lead into writing the value to vehicle HAL.
Pavel Maltseve8f75372016-01-26 10:26:04 -0800146 *
147 * @throws IllegalArgumentException If value set has wrong value like wrong valueType, wrong
148 * data, and etc.
keunyoung5c7cb262015-10-19 10:47:45 -0700149 */
150 public void setProperty(VehiclePropValue value) throws IllegalArgumentException {
keunyounge18e25d2015-08-28 15:57:19 -0700151 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
152 try {
keunyoung15882e52015-09-16 16:57:58 -0700153 mService.setProperty(parcelable);
keunyounge18e25d2015-08-28 15:57:19 -0700154 } catch (RemoteException e) {
155 handleRemoteException(e);
156 }
keunyounge18e25d2015-08-28 15:57:19 -0700157 }
158
keunyoung5c7cb262015-10-19 10:47:45 -0700159 /**
160 * Set integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800161 *
keunyoung5c7cb262015-10-19 10:47:45 -0700162 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
163 */
164 public void setIntProperty(int property, int value) throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700165 VehiclePropValue v = VehiclePropValueUtil.createIntValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700166 setProperty(v);
167 }
168
keunyoung5c7cb262015-10-19 10:47:45 -0700169 /**
170 * Set int vector type property. Length of passed values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700171 */
172 public void setIntVectorProperty(int property, int[] values) throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700173 VehiclePropValue v = VehiclePropValueUtil.createIntVectorValue(property, values, 0);
174 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700175 }
176
keunyoung5c7cb262015-10-19 10:47:45 -0700177 /**
178 * Set long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700179 */
180 public void setLongProperty(int property, long value) throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700181 VehiclePropValue v = VehiclePropValueUtil.createLongValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700182 setProperty(v);
183 }
184
keunyoung5c7cb262015-10-19 10:47:45 -0700185 /**
186 * Set float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700187 */
188 public void setFloatProperty(int property, float value) throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700189 VehiclePropValue v = VehiclePropValueUtil.createFloatValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700190 setProperty(v);
191 }
192
keunyoung5c7cb262015-10-19 10:47:45 -0700193 /**
194 * Set float vector type property. Length of values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700195 */
196 public void setFloatVectorProperty(int property, float[] values)
197 throws IllegalArgumentException {
keunyoung1ab8e182015-09-24 09:25:22 -0700198 VehiclePropValue v = VehiclePropValueUtil.createFloatVectorValue(property, values, 0);
199 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700200 }
201
keunyoung5c7cb262015-10-19 10:47:45 -0700202 /**
Steve Paik66481982015-10-27 15:22:38 -0700203 * Set zoned boolean type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800204 *
205 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
206 */
207 public void setBooleanProperty(int property, boolean value)
208 throws IllegalArgumentException {
209 VehiclePropValue v = VehiclePropValueUtil.createBooleanValue(property, value, 0);
210 setProperty(v);
211 }
212
213 /**
214 * Set zoned boolean type property
215 *
Steve Paik66481982015-10-27 15:22:38 -0700216 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
217 */
218 public void setZonedBooleanProperty(int property, int zone, boolean value)
219 throws IllegalArgumentException {
220 VehiclePropValue v = VehiclePropValueUtil.createZonedBooleanValue(property, zone, value, 0);
221 setProperty(v);
222 }
223
224 /**
225 * Set zoned float type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800226 *
Steve Paik66481982015-10-27 15:22:38 -0700227 * @throws IllegalArgumentException For type mismatch (=the property is not float type)
228 */
229 public void setZonedFloatProperty(int property, int zone, float value)
230 throws IllegalArgumentException {
231 VehiclePropValue v = VehiclePropValueUtil.createZonedFloatValue(property, zone, value, 0);
232 setProperty(v);
233 }
234
235 /**
236 * Set zoned integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800237 *
Steve Paik66481982015-10-27 15:22:38 -0700238 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
239 */
240 public void setZonedIntProperty(int property, int zone, int value)
241 throws IllegalArgumentException {
242 VehiclePropValue v = VehiclePropValueUtil.createZonedIntValue(property, zone, value, 0);
243 setProperty(v);
244 }
245
246 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800247 * Set zoned int vector type property. Length of passed values should match with vector length.
248 */
249 public void setZonedIntVectorProperty(int property, int zone, int[] values)
250 throws IllegalArgumentException {
251 VehiclePropValue v = VehiclePropValueUtil
252 .createZonedIntVectorValue(property, zone, values, 0);
253 setProperty(v);
254 }
255
256 /**
257 * Set zoned float vector type property. Length of passed values should match with vector
258 * length.
259 */
260 public void setZonedFloatVectorProperty(int property, int zone, float[] values)
261 throws IllegalArgumentException {
262 VehiclePropValue v = VehiclePropValueUtil
263 .createZonedFloatVectorValue(property, zone, values, 0);
264 setProperty(v);
265 }
266
267 /**
keunyoung5c7cb262015-10-19 10:47:45 -0700268 * Get property. This can be used for a property which does not require any other data.
keunyoung5c7cb262015-10-19 10:47:45 -0700269 */
270 public VehiclePropValue getProperty(int property) throws IllegalArgumentException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700271 int valueType = VehicleNetworkConsts.getVehicleValueType(property);
Pavel Maltsev169b7a62016-01-26 15:56:07 -0800272 if (valueType == 0) {
273 throw new IllegalArgumentException("Data type is unknown for property: " + property);
274 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700275 VehiclePropValue value = VehiclePropValueUtil.createBuilder(property, valueType, 0).build();
276 return getProperty(value);
277 }
278
keunyoung5c7cb262015-10-19 10:47:45 -0700279 /**
280 * Generic get method for any type of property. Some property may require setting data portion
281 * as get may return different result depending on the data set.
keunyoung5c7cb262015-10-19 10:47:45 -0700282 */
283 public VehiclePropValue getProperty(VehiclePropValue value) throws IllegalArgumentException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700284 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
keunyounge18e25d2015-08-28 15:57:19 -0700285 try {
keunyoung7d74e6d2015-10-14 15:43:10 -0700286 VehiclePropValueParcelable resParcelable = mService.getProperty(parcelable);
287 if (resParcelable != null) {
288 return resParcelable.value;
keunyounge18e25d2015-08-28 15:57:19 -0700289 }
290 } catch (RemoteException e) {
291 handleRemoteException(e);
292 }
293 return null;
294 }
295
keunyoung5c7cb262015-10-19 10:47:45 -0700296 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800297 * Get int type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700298 */
299 public int getIntProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800300 VehiclePropValue v = getProperty(
301 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
keunyoungd32f4e62015-09-21 11:33:06 -0700302 if (v.getInt32ValuesCount() != 1) {
303 throw new IllegalStateException();
304 }
305 return v.getInt32Values(0);
306 }
307
keunyoung5c7cb262015-10-19 10:47:45 -0700308 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800309 * Get zoned int type property.
310 */
311 public int getZonedIntProperty(int property, int zone) throws IllegalArgumentException {
312 VehiclePropValue v = getProperty(
313 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800314 if (v.getInt32ValuesCount() != 1) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800315 throw new IllegalStateException();
316 }
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800317 return v.getInt32Values(0);
Pavel Maltseve8f75372016-01-26 10:26:04 -0800318 }
319
320 /**
321 * Get int vector type property. Length of values should match vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700322 */
keunyoung4b0212c2015-10-29 17:11:57 -0700323 public int[] getIntVectorProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800324 VehiclePropValue v = getProperty(
325 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
326 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
327 return toIntArray(v.getInt32ValuesList());
328 }
329
330 /**
331 * Get zoned int vector type property. Length of values should match vector length.
332 */
333 public int[] getZonedIntVectorProperty(int property, int zone)
334 throws IllegalArgumentException {
335 VehiclePropValue v = getProperty(
336 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800337 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
338 return toIntArray(v.getInt32ValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700339 }
340
keunyoung5c7cb262015-10-19 10:47:45 -0700341 /**
342 * Get float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700343 */
344 public float getFloatProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800345 VehiclePropValue v = getProperty(
346 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
keunyoungd32f4e62015-09-21 11:33:06 -0700347 if (v.getFloatValuesCount() != 1) {
348 throw new IllegalStateException();
349 }
350 return v.getFloatValues(0);
351 }
352
keunyoung5c7cb262015-10-19 10:47:45 -0700353 /**
354 * Get float vector type property. Length of values should match vector's length.
keunyoung5c7cb262015-10-19 10:47:45 -0700355 */
Pavel Maltseve8f75372016-01-26 10:26:04 -0800356 public float[] getFloatVectorProperty(int property) throws IllegalArgumentException {
357 VehiclePropValue v = getProperty(
358 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
359 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
360 return toFloatArray(v.getFloatValuesList());
361 }
362
363 /**
364 * Get zoned float vector type property. Length of values should match vector's length.
365 */
366 public float[] getZonedFloatVectorProperty(int property, int zone)
keunyoung5c7cb262015-10-19 10:47:45 -0700367 throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800368 VehiclePropValue v = getProperty(property, zone,
369 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800370 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
371 return toFloatArray(v.getFloatValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700372 }
373
keunyoung5c7cb262015-10-19 10:47:45 -0700374 /**
375 * Get long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700376 */
377 public long getLongProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800378 VehiclePropValue v = getProperty(
379 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT64);
keunyoungfe30ba02015-09-17 17:56:35 -0700380 return v.getInt64Value();
381 }
382
keunyoung5c7cb262015-10-19 10:47:45 -0700383 /**
384 * Get string type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700385 */
keunyoungfe30ba02015-09-17 17:56:35 -0700386 //TODO check UTF8 to java string conversion
keunyoung5c7cb262015-10-19 10:47:45 -0700387 public String getStringProperty(int property) throws IllegalArgumentException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800388 VehiclePropValue v = getProperty(
389 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_STRING);
keunyoungfe30ba02015-09-17 17:56:35 -0700390 return v.getStringValue();
391 }
392
keunyoung5c7cb262015-10-19 10:47:45 -0700393 /**
394 * Subscribe given property with given sample rate.
keunyoung5c7cb262015-10-19 10:47:45 -0700395 */
396 public void subscribe(int property, float sampleRate) throws IllegalArgumentException {
Keun-young Park0727f952015-12-21 14:30:07 -0800397 subscribe(property, sampleRate, 0);
398 }
399
400 /**
401 * Subscribe given property with given sample rate.
Keun-young Park0727f952015-12-21 14:30:07 -0800402 */
403 public void subscribe(int property, float sampleRate, int zones)
404 throws IllegalArgumentException {
keunyounge18e25d2015-08-28 15:57:19 -0700405 try {
Keun-young Park0727f952015-12-21 14:30:07 -0800406 mService.subscribe(mVehicleNetworkListener, property, sampleRate, zones);
keunyounge18e25d2015-08-28 15:57:19 -0700407 } catch (RemoteException e) {
408 handleRemoteException(e);
409 }
keunyounge18e25d2015-08-28 15:57:19 -0700410 }
411
keunyoung5c7cb262015-10-19 10:47:45 -0700412 /**
413 * Stop subscribing the property.
keunyoung5c7cb262015-10-19 10:47:45 -0700414 */
keunyounge18e25d2015-08-28 15:57:19 -0700415 public void unsubscribe(int property) {
416 try {
417 mService.unsubscribe(mVehicleNetworkListener, property);
418 } catch (RemoteException e) {
419 handleRemoteException(e);
420 }
421 }
422
keunyoung5c7cb262015-10-19 10:47:45 -0700423 /**
424 * Inject given value to all clients subscribing the property. This is for testing.
keunyoung5c7cb262015-10-19 10:47:45 -0700425 */
keunyoung1ab8e182015-09-24 09:25:22 -0700426 public synchronized void injectEvent(VehiclePropValue value) {
427 try {
428 mService.injectEvent(new VehiclePropValueParcelable(value));
429 } catch (RemoteException e) {
430 handleRemoteException(e);
431 }
432 }
433
keunyoung5c7cb262015-10-19 10:47:45 -0700434 /**
435 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700436 */
keunyoung1ab8e182015-09-24 09:25:22 -0700437 public synchronized void startMocking(VehicleNetworkHalMock mock) {
438 mHalMock = mock;
439 mHalMockImpl = new IVehicleNetworkHalMockImpl(this);
440 try {
441 mService.startMocking(mHalMockImpl);
442 } catch (RemoteException e) {
443 handleRemoteException(e);
444 }
445 }
446
keunyoung5c7cb262015-10-19 10:47:45 -0700447 /**
448 * Stop mocking of vehicle HAL. For testing only.
449 */
keunyoung1ab8e182015-09-24 09:25:22 -0700450 public synchronized void stopMocking() {
Keun-young Park28dd4702015-11-19 18:06:04 -0800451 if (mHalMockImpl == null) {
452 return;
453 }
keunyoung1ab8e182015-09-24 09:25:22 -0700454 try {
455 mService.stopMocking(mHalMockImpl);
456 } catch (RemoteException e) {
457 handleRemoteException(e);
458 } finally {
459 mHalMock = null;
460 mHalMockImpl = null;
461 }
462 }
463
keunyoung5c7cb262015-10-19 10:47:45 -0700464 /**
465 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700466 */
keunyoung1ab8e182015-09-24 09:25:22 -0700467 public synchronized void startMocking(IVehicleNetworkHalMock mock) {
468 mHalMock = null;
469 mHalMockImpl = mock;
470 try {
471 mService.startMocking(mHalMockImpl);
472 } catch (RemoteException e) {
473 handleRemoteException(e);
474 }
475 }
476
keunyoung5c7cb262015-10-19 10:47:45 -0700477 /**
478 * Stop mocking of vehicle HAL. For testing only.
479 */
keunyoung1ab8e182015-09-24 09:25:22 -0700480 public synchronized void stopMocking(IVehicleNetworkHalMock mock) {
481 if (mock.asBinder() != mHalMockImpl.asBinder()) {
482 return;
483 }
484 try {
485 mService.stopMocking(mHalMockImpl);
486 } catch (RemoteException e) {
487 handleRemoteException(e);
488 } finally {
489 mHalMock = null;
490 mHalMockImpl = null;
491 }
492 }
493
Keun-young Park28dd4702015-11-19 18:06:04 -0800494 public synchronized void injectHalError(int errorCode, int property, int operation) {
495 try {
496 mService.injectHalError(errorCode, property, operation);
497 } catch (RemoteException e) {
498 handleRemoteException(e);
499 }
500 }
501
502 public synchronized void startErrorListening() {
503 try {
504 mService.startErrorListening(mVehicleNetworkListener);
505 } catch (RemoteException e) {
506 handleRemoteException(e);
507 }
508 }
509
510 public synchronized void stopErrorListening() {
511 try {
512 mService.stopErrorListening(mVehicleNetworkListener);
513 } catch (RemoteException e) {
514 handleRemoteException(e);
515 }
516 }
517
518 public synchronized void startHalRestartMonitoring() {
519 try {
520 mService.startHalRestartMonitoring(mVehicleNetworkListener);
521 } catch (RemoteException e) {
522 handleRemoteException(e);
523 }
524 }
525
526 public synchronized void stopHalRestartMonitoring() {
527 try {
528 mService.stopHalRestartMonitoring(mVehicleNetworkListener);
529 } catch (RemoteException e) {
530 handleRemoteException(e);
531 }
532 }
533
keunyoung1ab8e182015-09-24 09:25:22 -0700534 private synchronized VehicleNetworkHalMock getHalMock() {
535 return mHalMock;
536 }
537
keunyounge18e25d2015-08-28 15:57:19 -0700538 private void handleRemoteException(RemoteException e) {
539 throw new RuntimeException("Vehicle network service not working ", e);
540 }
541
542 private void handleVehicleNetworkEvents(VehiclePropValues values) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800543 mListener.onVehicleNetworkEvents(values);
keunyounge18e25d2015-08-28 15:57:19 -0700544 }
545
Keun-young Park28dd4702015-11-19 18:06:04 -0800546 private void handleHalError(int errorCode, int property, int operation) {
547 mListener.onHalError(errorCode, property, operation);
548 }
549
550 private void handleHalRestart(boolean inMocking) {
551 mListener.onHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700552 }
553
554 private class EventHandler extends Handler {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800555
keunyounge18e25d2015-08-28 15:57:19 -0700556 private static final int MSG_EVENTS = 0;
Keun-young Park28dd4702015-11-19 18:06:04 -0800557 private static final int MSG_HAL_ERROR = 1;
558 private static final int MSG_HAL_RESTART = 2;
keunyounge18e25d2015-08-28 15:57:19 -0700559
560 private EventHandler(Looper looper) {
561 super(looper);
562 }
563
564 private void notifyEvents(VehiclePropValues values) {
565 Message msg = obtainMessage(MSG_EVENTS, values);
566 sendMessage(msg);
567 }
568
Keun-young Park28dd4702015-11-19 18:06:04 -0800569 private void notifyHalError(int errorCode, int property, int operation) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800570 Message msg = obtainMessage(MSG_HAL_ERROR, errorCode, property, operation);
Keun-young Park28dd4702015-11-19 18:06:04 -0800571 sendMessage(msg);
572 }
573
574 private void notifyHalRestart(boolean inMocking) {
575 Message msg = obtainMessage(MSG_HAL_RESTART, inMocking ? 1 : 0, 0);
576 sendMessage(msg);
577 }
578
keunyounge18e25d2015-08-28 15:57:19 -0700579 @Override
580 public void handleMessage(Message msg) {
581 switch (msg.what) {
582 case MSG_EVENTS:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800583 handleVehicleNetworkEvents((VehiclePropValues) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800584 break;
585 case MSG_HAL_ERROR:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800586 handleHalError(msg.arg1, msg.arg2, (Integer) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800587 break;
588 case MSG_HAL_RESTART:
589 handleHalRestart(msg.arg1 == 1);
keunyounge18e25d2015-08-28 15:57:19 -0700590 break;
591 default:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800592 Log.w(TAG, "Unknown message:" + msg.what, new RuntimeException());
keunyounge18e25d2015-08-28 15:57:19 -0700593 break;
594 }
595 }
596 }
597
598 private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800599
keunyounge18e25d2015-08-28 15:57:19 -0700600 private final WeakReference<VehicleNetwork> mVehicleNetwork;
601
602 private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800603 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyounge18e25d2015-08-28 15:57:19 -0700604 }
605
606 @Override
607 public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) {
608 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
609 if (vehicleNetwork != null) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800610 vehicleNetwork.mEventHandler.notifyEvents(values.values);
611 }
612 }
613
614 @Override
615 public void onHalError(int errorCode, int property, int operation) {
616 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
617 if (vehicleNetwork != null) {
618 vehicleNetwork.mEventHandler.notifyHalError(errorCode, property, operation);
619 }
620 }
621
622 @Override
623 public void onHalRestart(boolean inMocking) {
624 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
625 if (vehicleNetwork != null) {
626 vehicleNetwork.mEventHandler.notifyHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700627 }
628 }
629 }
keunyoung1ab8e182015-09-24 09:25:22 -0700630
631 private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub {
632 private final WeakReference<VehicleNetwork> mVehicleNetwork;
633
634 private IVehicleNetworkHalMockImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800635 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyoung1ab8e182015-09-24 09:25:22 -0700636 }
637
638 @Override
639 public VehiclePropConfigsParcelable onListProperties() {
640 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
641 if (vehicleNetwork == null) {
642 return null;
643 }
644 VehiclePropConfigs configs = vehicleNetwork.getHalMock().onListProperties();
645 return new VehiclePropConfigsParcelable(configs);
646 }
647
648 @Override
649 public void onPropertySet(VehiclePropValueParcelable value) {
650 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
651 if (vehicleNetwork == null) {
652 return;
653 }
654 vehicleNetwork.getHalMock().onPropertySet(value.value);
655 }
656
657 @Override
keunyoung7d74e6d2015-10-14 15:43:10 -0700658 public VehiclePropValueParcelable onPropertyGet(VehiclePropValueParcelable value) {
keunyoung1ab8e182015-09-24 09:25:22 -0700659 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
660 if (vehicleNetwork == null) {
661 return null;
662 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700663 VehiclePropValue resValue = vehicleNetwork.getHalMock().onPropertyGet(value.value);
664 return new VehiclePropValueParcelable(resValue);
keunyoung1ab8e182015-09-24 09:25:22 -0700665 }
666
667 @Override
Keun-young Park0727f952015-12-21 14:30:07 -0800668 public void onPropertySubscribe(int property, float sampleRate, int zones) {
keunyoung1ab8e182015-09-24 09:25:22 -0700669 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
670 if (vehicleNetwork == null) {
671 return;
672 }
Keun-young Park0727f952015-12-21 14:30:07 -0800673 vehicleNetwork.getHalMock().onPropertySubscribe(property, sampleRate, zones);
keunyoung1ab8e182015-09-24 09:25:22 -0700674 }
675
676 @Override
677 public void onPropertyUnsubscribe(int property) {
678 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
679 if (vehicleNetwork == null) {
680 return;
681 }
682 vehicleNetwork.getHalMock().onPropertyUnsubscribe(property);
683 }
684 }
Pavel Maltseve8f75372016-01-26 10:26:04 -0800685
686 private VehiclePropValue getProperty(int property, int zone, int customPropetyDataType) {
687 boolean isCustom = isCustomProperty(property);
688 int valueType = isCustom
689 ? customPropetyDataType
690 : VehicleNetworkConsts.getVehicleValueType(property);
691
692 VehiclePropValue.Builder valuePrototypeBuilder =
693 VehiclePropValueUtil.createBuilder(property, valueType, 0);
694
695 if (zone != NO_ZONE) {
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800696 valuePrototypeBuilder.setZone(zone);
Pavel Maltseve8f75372016-01-26 10:26:04 -0800697 }
698
699 VehiclePropValue v = getProperty(valuePrototypeBuilder.build());
700 if (v == null) {
701 // if property is invalid, IllegalArgumentException should have been thrown
702 // from getProperty.
703 throw new IllegalStateException();
704 }
705
706 if (!isCustom && v.getValueType() != valueType) {
Keun-young Park1488ef22016-02-25 14:00:54 -0800707 throw new IllegalArgumentException(
708 "Unexpected type for property 0x" + Integer.toHexString(property) +
709 " got:0x" + Integer.toHexString(v.getValueType())
710 + ", expecting:0x" + Integer.toHexString(valueType));
Pavel Maltseve8f75372016-01-26 10:26:04 -0800711 }
712 return v;
713 }
714
715 private void assertVectorLength(int actual, int property, int valueType) {
716 int expectedLen = getVectorLength(valueType);
717 if (expectedLen != actual) {
718 throw new IllegalStateException("Invalid array size for property: " + property
719 + ". Expected: " + expectedLen
720 + ", actual: " + actual);
721 }
722 }
keunyounge18e25d2015-08-28 15:57:19 -0700723}