blob: 471c2c35036481224e0fb594bdbb68fd7ef1effd [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
Pavel Maltsevb0324b42016-09-27 21:00:41 -070023import android.annotation.IntDef;
keunyounge18e25d2015-08-28 15:57:19 -070024import android.os.Handler;
25import android.os.Looper;
26import android.os.Message;
27import android.os.RemoteException;
28import android.os.ServiceManager;
Keun-young Parkba485482016-03-24 13:24:31 -070029import android.os.ServiceSpecificException;
keunyounge18e25d2015-08-28 15:57:19 -070030import android.util.Log;
31
keunyoungd32f4e62015-09-21 11:33:06 -070032import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
keunyounge18e25d2015-08-28 15:57:19 -070033import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
34import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
35import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValues;
keunyoung1ab8e182015-09-24 09:25:22 -070036import com.android.internal.annotations.GuardedBy;
keunyounge18e25d2015-08-28 15:57:19 -070037
Pavel Maltsevb0324b42016-09-27 21:00:41 -070038import java.lang.annotation.Retention;
39import java.lang.annotation.RetentionPolicy;
keunyounge18e25d2015-08-28 15:57:19 -070040import java.lang.ref.WeakReference;
41
42/**
43 * System API to access Vehicle network. This is only for system services and applications should
keunyoung15882e52015-09-16 16:57:58 -070044 * not use this. All APIs will fail with security error if normal app tries this.
keunyounge18e25d2015-08-28 15:57:19 -070045 */
46public class VehicleNetwork {
keunyoung1ab8e182015-09-24 09:25:22 -070047 /**
48 * Listener for VNS events.
49 */
keunyounge18e25d2015-08-28 15:57:19 -070050 public interface VehicleNetworkListener {
keunyoung1ab8e182015-09-24 09:25:22 -070051 /**
52 * Notify HAL events. This requires subscribing the property
53 */
keunyounge18e25d2015-08-28 15:57:19 -070054 void onVehicleNetworkEvents(VehiclePropValues values);
Keun-young Park28dd4702015-11-19 18:06:04 -080055 void onHalError(int errorCode, int property, int operation);
56 void onHalRestart(boolean inMocking);
Pavel Maltsevb0324b42016-09-27 21:00:41 -070057 void onPropertySet(VehiclePropValue value);
keunyounge18e25d2015-08-28 15:57:19 -070058 }
59
keunyoung1ab8e182015-09-24 09:25:22 -070060 public interface VehicleNetworkHalMock {
61 VehiclePropConfigs onListProperties();
62 void onPropertySet(VehiclePropValue value);
Keun-young Park28dd4702015-11-19 18:06:04 -080063 VehiclePropValue onPropertyGet(VehiclePropValue value);
Keun-young Park0727f952015-12-21 14:30:07 -080064 void onPropertySubscribe(int property, float sampleRate, int zones);
keunyoung1ab8e182015-09-24 09:25:22 -070065 void onPropertyUnsubscribe(int property);
66 }
67
Pavel Maltsevb0324b42016-09-27 21:00:41 -070068 /**
69 * Flags to be used in #subscribe(int, float, int, int).
70 */
71 @Retention(RetentionPolicy.SOURCE)
72 @IntDef({
73 SubscribeFlags.HAL_EVENT,
74 SubscribeFlags.SET_CALL,
75 SubscribeFlags.DEFAULT,
76 })
77 public @interface SubscribeFlags {
78 int HAL_EVENT = 0x1;
79 int SET_CALL = 0x2;
80 int DEFAULT = HAL_EVENT;
81 }
82
keunyounge18e25d2015-08-28 15:57:19 -070083 private static final String TAG = VehicleNetwork.class.getSimpleName();
84
85 private final IVehicleNetwork mService;
86 private final VehicleNetworkListener mListener;
87 private final IVehicleNetworkListenerImpl mVehicleNetworkListener;
88 private final EventHandler mEventHandler;
89
keunyoung1ab8e182015-09-24 09:25:22 -070090 @GuardedBy("this")
91 private VehicleNetworkHalMock mHalMock;
92 private IVehicleNetworkHalMock mHalMockImpl;
93
keunyoung217ca352015-11-17 14:45:38 -080094 private static final int VNS_CONNECT_MAX_RETRY = 10;
95 private static final long VNS_RETRY_WAIT_TIME_MS = 1000;
Pavel Maltseve8f75372016-01-26 10:26:04 -080096 private static final int NO_ZONE = -1;
keunyoung217ca352015-11-17 14:45:38 -080097
keunyoung5c7cb262015-10-19 10:47:45 -070098 /**
99 * Factory method to create VehicleNetwork
Pavel Maltseve8f75372016-01-26 10:26:04 -0800100 *
keunyoung5c7cb262015-10-19 10:47:45 -0700101 * @param listener listener for listening events
102 * @param looper Looper to dispatch listener events
keunyoung5c7cb262015-10-19 10:47:45 -0700103 */
keunyoung15882e52015-09-16 16:57:58 -0700104 public static VehicleNetwork createVehicleNetwork(VehicleNetworkListener listener,
105 Looper looper) {
keunyoung217ca352015-11-17 14:45:38 -0800106 int retryCount = 0;
107 IVehicleNetwork service = null;
Keun-young Parke52e8f22016-08-15 09:29:14 -0700108 while (true) {
keunyoung217ca352015-11-17 14:45:38 -0800109 service = IVehicleNetwork.Stub.asInterface(ServiceManager.getService(
110 IVehicleNetwork.class.getCanonicalName()));
Keun-young Parke52e8f22016-08-15 09:29:14 -0700111 if (service != null) {
112 break;
113 }
keunyoung217ca352015-11-17 14:45:38 -0800114 retryCount++;
115 if (retryCount > VNS_CONNECT_MAX_RETRY) {
116 break;
117 }
118 try {
119 Thread.sleep(VNS_RETRY_WAIT_TIME_MS);
120 } catch (InterruptedException e) {
121 //ignore
122 }
123 }
keunyounge18e25d2015-08-28 15:57:19 -0700124 if (service == null) {
keunyoung15882e52015-09-16 16:57:58 -0700125 throw new RuntimeException("Vehicle network service not available:" +
126 IVehicleNetwork.class.getCanonicalName());
keunyounge18e25d2015-08-28 15:57:19 -0700127 }
128 return new VehicleNetwork(service, listener, looper);
129 }
130
131 private VehicleNetwork(IVehicleNetwork service, VehicleNetworkListener listener,
132 Looper looper) {
133 mService = service;
134 mListener = listener;
135 mEventHandler = new EventHandler(looper);
136 mVehicleNetworkListener = new IVehicleNetworkListenerImpl(this);
137 }
138
keunyoung5c7cb262015-10-19 10:47:45 -0700139 /**
140 * List all properties from vehicle HAL
Pavel Maltseve8f75372016-01-26 10:26:04 -0800141 *
keunyoung5c7cb262015-10-19 10:47:45 -0700142 * @return all properties
143 */
keunyoung15882e52015-09-16 16:57:58 -0700144 public VehiclePropConfigs listProperties() {
145 return listProperties(0 /* all */);
146 }
147
keunyoung5c7cb262015-10-19 10:47:45 -0700148 /**
149 * Return configuration information of single property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800150 *
151 * @param property vehicle property number defined in {@link VehicleNetworkConsts}. 0 has has
152 * special meaning of list all properties.
keunyoung5c7cb262015-10-19 10:47:45 -0700153 * @return null if given property does not exist.
154 */
keunyounge18e25d2015-08-28 15:57:19 -0700155 public VehiclePropConfigs listProperties(int property) {
156 try {
157 VehiclePropConfigsParcelable parcelable = mService.listProperties(property);
158 if (parcelable != null) {
159 return parcelable.configs;
160 }
161 } catch (RemoteException e) {
162 handleRemoteException(e);
163 }
164 return null;
165 }
166
keunyoung5c7cb262015-10-19 10:47:45 -0700167 /**
168 * Set property which will lead into writing the value to vehicle HAL.
Pavel Maltseve8f75372016-01-26 10:26:04 -0800169 *
170 * @throws IllegalArgumentException If value set has wrong value like wrong valueType, wrong
171 * data, and etc.
keunyoung5c7cb262015-10-19 10:47:45 -0700172 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700173 public void setProperty(VehiclePropValue value)
174 throws IllegalArgumentException, ServiceSpecificException {
keunyounge18e25d2015-08-28 15:57:19 -0700175 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
176 try {
keunyoung15882e52015-09-16 16:57:58 -0700177 mService.setProperty(parcelable);
keunyounge18e25d2015-08-28 15:57:19 -0700178 } catch (RemoteException e) {
179 handleRemoteException(e);
180 }
keunyounge18e25d2015-08-28 15:57:19 -0700181 }
182
keunyoung5c7cb262015-10-19 10:47:45 -0700183 /**
184 * Set integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800185 *
keunyoung5c7cb262015-10-19 10:47:45 -0700186 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
187 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700188 public void setIntProperty(int property, int value)
189 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700190 VehiclePropValue v = VehiclePropValueUtil.createIntValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700191 setProperty(v);
192 }
193
keunyoung5c7cb262015-10-19 10:47:45 -0700194 /**
195 * Set int vector type property. Length of passed values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700196 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700197 public void setIntVectorProperty(int property, int[] values)
198 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700199 VehiclePropValue v = VehiclePropValueUtil.createIntVectorValue(property, values, 0);
200 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700201 }
202
keunyoung5c7cb262015-10-19 10:47:45 -0700203 /**
204 * Set long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700205 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700206 public void setLongProperty(int property, long value)
207 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700208 VehiclePropValue v = VehiclePropValueUtil.createLongValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700209 setProperty(v);
210 }
211
keunyoung5c7cb262015-10-19 10:47:45 -0700212 /**
213 * Set float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700214 */
Keun-young Parke78bf532016-04-25 18:59:22 -0700215 public void setFloatProperty(int property, float value)
216 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700217 VehiclePropValue v = VehiclePropValueUtil.createFloatValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700218 setProperty(v);
219 }
220
keunyoung5c7cb262015-10-19 10:47:45 -0700221 /**
222 * Set float vector type property. Length of values should match with vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700223 */
224 public void setFloatVectorProperty(int property, float[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700225 throws IllegalArgumentException, ServiceSpecificException {
keunyoung1ab8e182015-09-24 09:25:22 -0700226 VehiclePropValue v = VehiclePropValueUtil.createFloatVectorValue(property, values, 0);
227 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700228 }
229
keunyoung5c7cb262015-10-19 10:47:45 -0700230 /**
Steve Paik66481982015-10-27 15:22:38 -0700231 * Set zoned boolean type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800232 *
233 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
234 */
235 public void setBooleanProperty(int property, boolean value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700236 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800237 VehiclePropValue v = VehiclePropValueUtil.createBooleanValue(property, value, 0);
238 setProperty(v);
239 }
240
Keun-young Park4c6834a2016-06-28 12:58:23 -0700241 public void setStringProperty(int property, String value)
242 throws IllegalArgumentException, ServiceSpecificException {
243 VehiclePropValue v = VehiclePropValueUtil.createStringValue(property, value, 0);
244 setProperty(v);
245 }
246
Pavel Maltseve8f75372016-01-26 10:26:04 -0800247 /**
248 * Set zoned boolean type property
249 *
Steve Paik66481982015-10-27 15:22:38 -0700250 * @throws IllegalArgumentException For type mismatch (=the property is not boolean type)
251 */
252 public void setZonedBooleanProperty(int property, int zone, boolean value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700253 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700254 VehiclePropValue v = VehiclePropValueUtil.createZonedBooleanValue(property, zone, value, 0);
255 setProperty(v);
256 }
257
258 /**
259 * Set zoned float type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800260 *
Steve Paik66481982015-10-27 15:22:38 -0700261 * @throws IllegalArgumentException For type mismatch (=the property is not float type)
262 */
263 public void setZonedFloatProperty(int property, int zone, float value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700264 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700265 VehiclePropValue v = VehiclePropValueUtil.createZonedFloatValue(property, zone, value, 0);
266 setProperty(v);
267 }
268
269 /**
270 * Set zoned integer type property
Pavel Maltseve8f75372016-01-26 10:26:04 -0800271 *
Steve Paik66481982015-10-27 15:22:38 -0700272 * @throws IllegalArgumentException For type mismatch (=the property is not int type)
273 */
274 public void setZonedIntProperty(int property, int zone, int value)
Keun-young Parke78bf532016-04-25 18:59:22 -0700275 throws IllegalArgumentException, ServiceSpecificException {
Steve Paik66481982015-10-27 15:22:38 -0700276 VehiclePropValue v = VehiclePropValueUtil.createZonedIntValue(property, zone, value, 0);
277 setProperty(v);
278 }
279
280 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800281 * Set zoned int vector type property. Length of passed values should match with vector length.
282 */
283 public void setZonedIntVectorProperty(int property, int zone, int[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700284 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800285 VehiclePropValue v = VehiclePropValueUtil
286 .createZonedIntVectorValue(property, zone, values, 0);
287 setProperty(v);
288 }
289
290 /**
291 * Set zoned float vector type property. Length of passed values should match with vector
292 * length.
293 */
294 public void setZonedFloatVectorProperty(int property, int zone, float[] values)
Keun-young Parke78bf532016-04-25 18:59:22 -0700295 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800296 VehiclePropValue v = VehiclePropValueUtil
297 .createZonedFloatVectorValue(property, zone, values, 0);
298 setProperty(v);
299 }
300
301 /**
keunyoung5c7cb262015-10-19 10:47:45 -0700302 * Get property. This can be used for a property which does not require any other data.
keunyoung5c7cb262015-10-19 10:47:45 -0700303 */
Keun-young Parkba485482016-03-24 13:24:31 -0700304 public VehiclePropValue getProperty(int property) throws IllegalArgumentException,
305 ServiceSpecificException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700306 int valueType = VehicleNetworkConsts.getVehicleValueType(property);
Pavel Maltsev169b7a62016-01-26 15:56:07 -0800307 if (valueType == 0) {
308 throw new IllegalArgumentException("Data type is unknown for property: " + property);
309 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700310 VehiclePropValue value = VehiclePropValueUtil.createBuilder(property, valueType, 0).build();
311 return getProperty(value);
312 }
313
keunyoung5c7cb262015-10-19 10:47:45 -0700314 /**
315 * Generic get method for any type of property. Some property may require setting data portion
316 * as get may return different result depending on the data set.
keunyoung5c7cb262015-10-19 10:47:45 -0700317 */
Keun-young Parkba485482016-03-24 13:24:31 -0700318 public VehiclePropValue getProperty(VehiclePropValue value) throws IllegalArgumentException,
319 ServiceSpecificException {
keunyoung7d74e6d2015-10-14 15:43:10 -0700320 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
keunyounge18e25d2015-08-28 15:57:19 -0700321 try {
keunyoung7d74e6d2015-10-14 15:43:10 -0700322 VehiclePropValueParcelable resParcelable = mService.getProperty(parcelable);
323 if (resParcelable != null) {
324 return resParcelable.value;
keunyounge18e25d2015-08-28 15:57:19 -0700325 }
326 } catch (RemoteException e) {
327 handleRemoteException(e);
328 }
329 return null;
330 }
331
keunyoung5c7cb262015-10-19 10:47:45 -0700332 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800333 * Get int type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700334 */
Keun-young Parkba485482016-03-24 13:24:31 -0700335 public int getIntProperty(int property) throws IllegalArgumentException,
336 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800337 VehiclePropValue v = getProperty(
338 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
keunyoungd32f4e62015-09-21 11:33:06 -0700339 if (v.getInt32ValuesCount() != 1) {
340 throw new IllegalStateException();
341 }
342 return v.getInt32Values(0);
343 }
344
keunyoung5c7cb262015-10-19 10:47:45 -0700345 /**
Pavel Maltseve8f75372016-01-26 10:26:04 -0800346 * Get zoned int type property.
347 */
Keun-young Parkba485482016-03-24 13:24:31 -0700348 public int getZonedIntProperty(int property, int zone) throws IllegalArgumentException,
349 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800350 VehiclePropValue v = getProperty(
351 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800352 if (v.getInt32ValuesCount() != 1) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800353 throw new IllegalStateException();
354 }
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800355 return v.getInt32Values(0);
Pavel Maltseve8f75372016-01-26 10:26:04 -0800356 }
357
358 /**
359 * Get int vector type property. Length of values should match vector length.
keunyoung5c7cb262015-10-19 10:47:45 -0700360 */
Keun-young Parkba485482016-03-24 13:24:31 -0700361 public int[] getIntVectorProperty(int property) throws IllegalArgumentException,
362 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800363 VehiclePropValue v = getProperty(
364 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT32);
365 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
366 return toIntArray(v.getInt32ValuesList());
367 }
368
369 /**
370 * Get zoned int vector type property. Length of values should match vector length.
371 */
372 public int[] getZonedIntVectorProperty(int property, int zone)
Keun-young Parkba485482016-03-24 13:24:31 -0700373 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800374 VehiclePropValue v = getProperty(
375 property, zone, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800376 assertVectorLength(v.getInt32ValuesCount(), property, v.getValueType());
377 return toIntArray(v.getInt32ValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700378 }
379
keunyoung5c7cb262015-10-19 10:47:45 -0700380 /**
381 * Get float type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700382 */
Keun-young Parkba485482016-03-24 13:24:31 -0700383 public float getFloatProperty(int property) throws IllegalArgumentException,
384 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800385 VehiclePropValue v = getProperty(
386 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
keunyoungd32f4e62015-09-21 11:33:06 -0700387 if (v.getFloatValuesCount() != 1) {
388 throw new IllegalStateException();
389 }
390 return v.getFloatValues(0);
391 }
392
keunyoung5c7cb262015-10-19 10:47:45 -0700393 /**
394 * Get float vector type property. Length of values should match vector's length.
keunyoung5c7cb262015-10-19 10:47:45 -0700395 */
Keun-young Parkba485482016-03-24 13:24:31 -0700396 public float[] getFloatVectorProperty(int property) throws IllegalArgumentException,
397 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800398 VehiclePropValue v = getProperty(
399 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT);
400 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
401 return toFloatArray(v.getFloatValuesList());
402 }
403
404 /**
405 * Get zoned float vector type property. Length of values should match vector's length.
406 */
407 public float[] getZonedFloatVectorProperty(int property, int zone)
Keun-young Parkba485482016-03-24 13:24:31 -0700408 throws IllegalArgumentException, ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800409 VehiclePropValue v = getProperty(property, zone,
410 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT);
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800411 assertVectorLength(v.getFloatValuesCount(), property, v.getValueType());
412 return toFloatArray(v.getFloatValuesList());
keunyoungfe30ba02015-09-17 17:56:35 -0700413 }
414
keunyoung5c7cb262015-10-19 10:47:45 -0700415 /**
416 * Get long type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700417 */
Keun-young Parkba485482016-03-24 13:24:31 -0700418 public long getLongProperty(int property) throws IllegalArgumentException,
419 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800420 VehiclePropValue v = getProperty(
421 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_INT64);
keunyoungfe30ba02015-09-17 17:56:35 -0700422 return v.getInt64Value();
423 }
424
keunyoung5c7cb262015-10-19 10:47:45 -0700425 /**
426 * Get string type property.
keunyoung5c7cb262015-10-19 10:47:45 -0700427 */
keunyoungfe30ba02015-09-17 17:56:35 -0700428 //TODO check UTF8 to java string conversion
Keun-young Parkba485482016-03-24 13:24:31 -0700429 public String getStringProperty(int property) throws IllegalArgumentException,
430 ServiceSpecificException {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800431 VehiclePropValue v = getProperty(
432 property, NO_ZONE, VehicleValueType.VEHICLE_VALUE_TYPE_STRING);
keunyoungfe30ba02015-09-17 17:56:35 -0700433 return v.getStringValue();
434 }
435
keunyoung5c7cb262015-10-19 10:47:45 -0700436 /**
437 * Subscribe given property with given sample rate.
keunyoung5c7cb262015-10-19 10:47:45 -0700438 */
439 public void subscribe(int property, float sampleRate) throws IllegalArgumentException {
Keun-young Park0727f952015-12-21 14:30:07 -0800440 subscribe(property, sampleRate, 0);
441 }
442
443 /**
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700444 * Subscribe given property with given sample rate and zones.
Keun-young Park0727f952015-12-21 14:30:07 -0800445 */
446 public void subscribe(int property, float sampleRate, int zones)
447 throws IllegalArgumentException {
keunyounge18e25d2015-08-28 15:57:19 -0700448 try {
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700449 mService.subscribe(mVehicleNetworkListener, property, sampleRate, zones,
450 SubscribeFlags.DEFAULT);
451 } catch (RemoteException e) {
452 handleRemoteException(e);
453 }
454 }
455
456 /**
457 * Subscribe given property with given sample rate, zones and flags.
458 */
459 @SuppressWarnings("ResourceType")
460 public void subscribe(int property, float sampleRate, int zones, @SubscribeFlags int flags)
461 throws IllegalArgumentException {
462 try {
463 mService.subscribe(mVehicleNetworkListener, property, sampleRate, zones, flags);
keunyounge18e25d2015-08-28 15:57:19 -0700464 } catch (RemoteException e) {
465 handleRemoteException(e);
466 }
keunyounge18e25d2015-08-28 15:57:19 -0700467 }
468
keunyoung5c7cb262015-10-19 10:47:45 -0700469 /**
470 * Stop subscribing the property.
keunyoung5c7cb262015-10-19 10:47:45 -0700471 */
keunyounge18e25d2015-08-28 15:57:19 -0700472 public void unsubscribe(int property) {
473 try {
474 mService.unsubscribe(mVehicleNetworkListener, property);
475 } catch (RemoteException e) {
476 handleRemoteException(e);
477 }
478 }
479
keunyoung5c7cb262015-10-19 10:47:45 -0700480 /**
481 * Inject given value to all clients subscribing the property. This is for testing.
keunyoung5c7cb262015-10-19 10:47:45 -0700482 */
keunyoung1ab8e182015-09-24 09:25:22 -0700483 public synchronized void injectEvent(VehiclePropValue value) {
484 try {
485 mService.injectEvent(new VehiclePropValueParcelable(value));
486 } catch (RemoteException e) {
487 handleRemoteException(e);
488 }
489 }
490
keunyoung5c7cb262015-10-19 10:47:45 -0700491 /**
492 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700493 */
keunyoung1ab8e182015-09-24 09:25:22 -0700494 public synchronized void startMocking(VehicleNetworkHalMock mock) {
495 mHalMock = mock;
496 mHalMockImpl = new IVehicleNetworkHalMockImpl(this);
497 try {
498 mService.startMocking(mHalMockImpl);
499 } catch (RemoteException e) {
500 handleRemoteException(e);
501 }
502 }
503
keunyoung5c7cb262015-10-19 10:47:45 -0700504 /**
505 * Stop mocking of vehicle HAL. For testing only.
506 */
keunyoung1ab8e182015-09-24 09:25:22 -0700507 public synchronized void stopMocking() {
Keun-young Park28dd4702015-11-19 18:06:04 -0800508 if (mHalMockImpl == null) {
509 return;
510 }
keunyoung1ab8e182015-09-24 09:25:22 -0700511 try {
512 mService.stopMocking(mHalMockImpl);
513 } catch (RemoteException e) {
514 handleRemoteException(e);
515 } finally {
516 mHalMock = null;
517 mHalMockImpl = null;
518 }
519 }
520
keunyoung5c7cb262015-10-19 10:47:45 -0700521 /**
522 * Start mocking of vehicle HAL. For testing only.
keunyoung5c7cb262015-10-19 10:47:45 -0700523 */
keunyoung1ab8e182015-09-24 09:25:22 -0700524 public synchronized void startMocking(IVehicleNetworkHalMock mock) {
525 mHalMock = null;
526 mHalMockImpl = mock;
527 try {
528 mService.startMocking(mHalMockImpl);
529 } catch (RemoteException e) {
530 handleRemoteException(e);
531 }
532 }
533
keunyoung5c7cb262015-10-19 10:47:45 -0700534 /**
535 * Stop mocking of vehicle HAL. For testing only.
536 */
keunyoung1ab8e182015-09-24 09:25:22 -0700537 public synchronized void stopMocking(IVehicleNetworkHalMock mock) {
538 if (mock.asBinder() != mHalMockImpl.asBinder()) {
539 return;
540 }
541 try {
542 mService.stopMocking(mHalMockImpl);
543 } catch (RemoteException e) {
544 handleRemoteException(e);
545 } finally {
546 mHalMock = null;
547 mHalMockImpl = null;
548 }
549 }
550
Keun-young Park28dd4702015-11-19 18:06:04 -0800551 public synchronized void injectHalError(int errorCode, int property, int operation) {
552 try {
553 mService.injectHalError(errorCode, property, operation);
554 } catch (RemoteException e) {
555 handleRemoteException(e);
556 }
557 }
558
559 public synchronized void startErrorListening() {
560 try {
561 mService.startErrorListening(mVehicleNetworkListener);
562 } catch (RemoteException e) {
563 handleRemoteException(e);
564 }
565 }
566
567 public synchronized void stopErrorListening() {
568 try {
569 mService.stopErrorListening(mVehicleNetworkListener);
570 } catch (RemoteException e) {
571 handleRemoteException(e);
572 }
573 }
574
575 public synchronized void startHalRestartMonitoring() {
576 try {
577 mService.startHalRestartMonitoring(mVehicleNetworkListener);
578 } catch (RemoteException e) {
579 handleRemoteException(e);
580 }
581 }
582
583 public synchronized void stopHalRestartMonitoring() {
584 try {
585 mService.stopHalRestartMonitoring(mVehicleNetworkListener);
586 } catch (RemoteException e) {
587 handleRemoteException(e);
588 }
589 }
590
keunyoung1ab8e182015-09-24 09:25:22 -0700591 private synchronized VehicleNetworkHalMock getHalMock() {
592 return mHalMock;
593 }
594
keunyounge18e25d2015-08-28 15:57:19 -0700595 private void handleRemoteException(RemoteException e) {
596 throw new RuntimeException("Vehicle network service not working ", e);
597 }
598
599 private void handleVehicleNetworkEvents(VehiclePropValues values) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800600 mListener.onVehicleNetworkEvents(values);
keunyounge18e25d2015-08-28 15:57:19 -0700601 }
602
Keun-young Park28dd4702015-11-19 18:06:04 -0800603 private void handleHalError(int errorCode, int property, int operation) {
604 mListener.onHalError(errorCode, property, operation);
605 }
606
607 private void handleHalRestart(boolean inMocking) {
608 mListener.onHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700609 }
610
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700611 private void handleOnPropertySet(VehiclePropValue value) {
612 mListener.onPropertySet(value);
613 }
614
keunyounge18e25d2015-08-28 15:57:19 -0700615 private class EventHandler extends Handler {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800616
keunyounge18e25d2015-08-28 15:57:19 -0700617 private static final int MSG_EVENTS = 0;
Keun-young Park28dd4702015-11-19 18:06:04 -0800618 private static final int MSG_HAL_ERROR = 1;
619 private static final int MSG_HAL_RESTART = 2;
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700620 private static final int MSG_ON_PROPERTY_SET = 3;
keunyounge18e25d2015-08-28 15:57:19 -0700621
622 private EventHandler(Looper looper) {
623 super(looper);
624 }
625
626 private void notifyEvents(VehiclePropValues values) {
627 Message msg = obtainMessage(MSG_EVENTS, values);
628 sendMessage(msg);
629 }
630
Keun-young Park28dd4702015-11-19 18:06:04 -0800631 private void notifyHalError(int errorCode, int property, int operation) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800632 Message msg = obtainMessage(MSG_HAL_ERROR, errorCode, property, operation);
Keun-young Park28dd4702015-11-19 18:06:04 -0800633 sendMessage(msg);
634 }
635
636 private void notifyHalRestart(boolean inMocking) {
637 Message msg = obtainMessage(MSG_HAL_RESTART, inMocking ? 1 : 0, 0);
638 sendMessage(msg);
639 }
640
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700641 private void notifyPropertySet(VehiclePropValue value) {
642 Message msg = obtainMessage(MSG_ON_PROPERTY_SET, value);
643 sendMessage(msg);
644 }
645
keunyounge18e25d2015-08-28 15:57:19 -0700646 @Override
647 public void handleMessage(Message msg) {
648 switch (msg.what) {
649 case MSG_EVENTS:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800650 handleVehicleNetworkEvents((VehiclePropValues) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800651 break;
652 case MSG_HAL_ERROR:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800653 handleHalError(msg.arg1, msg.arg2, (Integer) msg.obj);
Keun-young Park28dd4702015-11-19 18:06:04 -0800654 break;
655 case MSG_HAL_RESTART:
656 handleHalRestart(msg.arg1 == 1);
keunyounge18e25d2015-08-28 15:57:19 -0700657 break;
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700658 case MSG_ON_PROPERTY_SET:
659 handleOnPropertySet((VehiclePropValue) msg.obj);
keunyounge18e25d2015-08-28 15:57:19 -0700660 default:
Pavel Maltseve8f75372016-01-26 10:26:04 -0800661 Log.w(TAG, "Unknown message:" + msg.what, new RuntimeException());
keunyounge18e25d2015-08-28 15:57:19 -0700662 break;
663 }
664 }
665 }
666
667 private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800668
keunyounge18e25d2015-08-28 15:57:19 -0700669 private final WeakReference<VehicleNetwork> mVehicleNetwork;
670
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700671 private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNetwork) {
672 mVehicleNetwork = new WeakReference<>(vehicleNetwork);
keunyounge18e25d2015-08-28 15:57:19 -0700673 }
674
675 @Override
676 public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) {
677 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
678 if (vehicleNetwork != null) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800679 vehicleNetwork.mEventHandler.notifyEvents(values.values);
680 }
681 }
682
683 @Override
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700684 public void onPropertySet(VehiclePropValueParcelable value) {
685 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
686 if (vehicleNetwork != null) {
687 vehicleNetwork.mEventHandler.notifyPropertySet(value.value);
688 }
689 }
690
691 @Override
Keun-young Park28dd4702015-11-19 18:06:04 -0800692 public void onHalError(int errorCode, int property, int operation) {
693 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
694 if (vehicleNetwork != null) {
695 vehicleNetwork.mEventHandler.notifyHalError(errorCode, property, operation);
696 }
697 }
698
699 @Override
700 public void onHalRestart(boolean inMocking) {
701 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
702 if (vehicleNetwork != null) {
703 vehicleNetwork.mEventHandler.notifyHalRestart(inMocking);
keunyounge18e25d2015-08-28 15:57:19 -0700704 }
705 }
706 }
keunyoung1ab8e182015-09-24 09:25:22 -0700707
708 private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub {
709 private final WeakReference<VehicleNetwork> mVehicleNetwork;
710
711 private IVehicleNetworkHalMockImpl(VehicleNetwork vehicleNewotk) {
Pavel Maltseve8f75372016-01-26 10:26:04 -0800712 mVehicleNetwork = new WeakReference<>(vehicleNewotk);
keunyoung1ab8e182015-09-24 09:25:22 -0700713 }
714
715 @Override
716 public VehiclePropConfigsParcelable onListProperties() {
717 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
718 if (vehicleNetwork == null) {
719 return null;
720 }
721 VehiclePropConfigs configs = vehicleNetwork.getHalMock().onListProperties();
722 return new VehiclePropConfigsParcelable(configs);
723 }
724
725 @Override
726 public void onPropertySet(VehiclePropValueParcelable value) {
727 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
728 if (vehicleNetwork == null) {
729 return;
730 }
731 vehicleNetwork.getHalMock().onPropertySet(value.value);
732 }
733
734 @Override
keunyoung7d74e6d2015-10-14 15:43:10 -0700735 public VehiclePropValueParcelable onPropertyGet(VehiclePropValueParcelable value) {
keunyoung1ab8e182015-09-24 09:25:22 -0700736 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
737 if (vehicleNetwork == null) {
738 return null;
739 }
keunyoung7d74e6d2015-10-14 15:43:10 -0700740 VehiclePropValue resValue = vehicleNetwork.getHalMock().onPropertyGet(value.value);
741 return new VehiclePropValueParcelable(resValue);
keunyoung1ab8e182015-09-24 09:25:22 -0700742 }
743
744 @Override
Keun-young Park0727f952015-12-21 14:30:07 -0800745 public void onPropertySubscribe(int property, float sampleRate, int zones) {
keunyoung1ab8e182015-09-24 09:25:22 -0700746 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
747 if (vehicleNetwork == null) {
748 return;
749 }
Keun-young Park0727f952015-12-21 14:30:07 -0800750 vehicleNetwork.getHalMock().onPropertySubscribe(property, sampleRate, zones);
keunyoung1ab8e182015-09-24 09:25:22 -0700751 }
752
753 @Override
754 public void onPropertyUnsubscribe(int property) {
755 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
756 if (vehicleNetwork == null) {
757 return;
758 }
759 vehicleNetwork.getHalMock().onPropertyUnsubscribe(property);
760 }
761 }
Pavel Maltseve8f75372016-01-26 10:26:04 -0800762
763 private VehiclePropValue getProperty(int property, int zone, int customPropetyDataType) {
764 boolean isCustom = isCustomProperty(property);
765 int valueType = isCustom
766 ? customPropetyDataType
767 : VehicleNetworkConsts.getVehicleValueType(property);
768
769 VehiclePropValue.Builder valuePrototypeBuilder =
770 VehiclePropValueUtil.createBuilder(property, valueType, 0);
771
772 if (zone != NO_ZONE) {
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800773 valuePrototypeBuilder.setZone(zone);
Pavel Maltseve8f75372016-01-26 10:26:04 -0800774 }
775
776 VehiclePropValue v = getProperty(valuePrototypeBuilder.build());
777 if (v == null) {
778 // if property is invalid, IllegalArgumentException should have been thrown
779 // from getProperty.
780 throw new IllegalStateException();
781 }
782
783 if (!isCustom && v.getValueType() != valueType) {
Keun-young Park1488ef22016-02-25 14:00:54 -0800784 throw new IllegalArgumentException(
785 "Unexpected type for property 0x" + Integer.toHexString(property) +
786 " got:0x" + Integer.toHexString(v.getValueType())
787 + ", expecting:0x" + Integer.toHexString(valueType));
Pavel Maltseve8f75372016-01-26 10:26:04 -0800788 }
789 return v;
790 }
791
792 private void assertVectorLength(int actual, int property, int valueType) {
793 int expectedLen = getVectorLength(valueType);
794 if (expectedLen != actual) {
795 throw new IllegalStateException("Invalid array size for property: " + property
796 + ". Expected: " + expectedLen
797 + ", actual: " + actual);
798 }
799 }
keunyounge18e25d2015-08-28 15:57:19 -0700800}