blob: b9cd8704d1fb228f5661f88d0e8806f2a83b5be9 [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
18import android.annotation.Nullable;
19import android.os.Handler;
20import android.os.Looper;
21import android.os.Message;
22import android.os.RemoteException;
23import android.os.ServiceManager;
24import android.util.Log;
25
keunyoungd32f4e62015-09-21 11:33:06 -070026import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
keunyounge18e25d2015-08-28 15:57:19 -070027import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
28import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
29import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValues;
keunyoung1ab8e182015-09-24 09:25:22 -070030import com.android.internal.annotations.GuardedBy;
keunyounge18e25d2015-08-28 15:57:19 -070031
32import java.lang.ref.WeakReference;
33
34/**
35 * System API to access Vehicle network. This is only for system services and applications should
keunyoung15882e52015-09-16 16:57:58 -070036 * not use this. All APIs will fail with security error if normal app tries this.
keunyounge18e25d2015-08-28 15:57:19 -070037 */
38public class VehicleNetwork {
keunyoung1ab8e182015-09-24 09:25:22 -070039 /**
40 * Listener for VNS events.
41 */
keunyounge18e25d2015-08-28 15:57:19 -070042 public interface VehicleNetworkListener {
keunyoung1ab8e182015-09-24 09:25:22 -070043 /**
44 * Notify HAL events. This requires subscribing the property
45 */
keunyounge18e25d2015-08-28 15:57:19 -070046 void onVehicleNetworkEvents(VehiclePropValues values);
47 }
48
keunyoung1ab8e182015-09-24 09:25:22 -070049 public interface VehicleNetworkHalMock {
50 VehiclePropConfigs onListProperties();
51 void onPropertySet(VehiclePropValue value);
52 VehiclePropValue onPropertyGet(int property);
53 void onPropertySubscribe(int property, int sampleRate);
54 void onPropertyUnsubscribe(int property);
55 }
56
keunyounge18e25d2015-08-28 15:57:19 -070057 private static final String TAG = VehicleNetwork.class.getSimpleName();
58
59 private final IVehicleNetwork mService;
60 private final VehicleNetworkListener mListener;
61 private final IVehicleNetworkListenerImpl mVehicleNetworkListener;
62 private final EventHandler mEventHandler;
63
keunyoung1ab8e182015-09-24 09:25:22 -070064 @GuardedBy("this")
65 private VehicleNetworkHalMock mHalMock;
66 private IVehicleNetworkHalMock mHalMockImpl;
67
keunyoung15882e52015-09-16 16:57:58 -070068 public static VehicleNetwork createVehicleNetwork(VehicleNetworkListener listener,
69 Looper looper) {
keunyounge18e25d2015-08-28 15:57:19 -070070 IVehicleNetwork service = IVehicleNetwork.Stub.asInterface(ServiceManager.getService(
71 IVehicleNetwork.class.getCanonicalName()));
72 if (service == null) {
keunyoung15882e52015-09-16 16:57:58 -070073 throw new RuntimeException("Vehicle network service not available:" +
74 IVehicleNetwork.class.getCanonicalName());
keunyounge18e25d2015-08-28 15:57:19 -070075 }
76 return new VehicleNetwork(service, listener, looper);
77 }
78
79 private VehicleNetwork(IVehicleNetwork service, VehicleNetworkListener listener,
80 Looper looper) {
81 mService = service;
82 mListener = listener;
83 mEventHandler = new EventHandler(looper);
84 mVehicleNetworkListener = new IVehicleNetworkListenerImpl(this);
85 }
86
keunyoung15882e52015-09-16 16:57:58 -070087 public VehiclePropConfigs listProperties() {
88 return listProperties(0 /* all */);
89 }
90
keunyounge18e25d2015-08-28 15:57:19 -070091 public VehiclePropConfigs listProperties(int property) {
92 try {
93 VehiclePropConfigsParcelable parcelable = mService.listProperties(property);
94 if (parcelable != null) {
95 return parcelable.configs;
96 }
97 } catch (RemoteException e) {
98 handleRemoteException(e);
99 }
100 return null;
101 }
102
keunyoung15882e52015-09-16 16:57:58 -0700103 public void setProperty(VehiclePropValue value) {
keunyounge18e25d2015-08-28 15:57:19 -0700104 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
105 try {
keunyoung15882e52015-09-16 16:57:58 -0700106 mService.setProperty(parcelable);
keunyounge18e25d2015-08-28 15:57:19 -0700107 } catch (RemoteException e) {
108 handleRemoteException(e);
109 }
keunyounge18e25d2015-08-28 15:57:19 -0700110 }
111
keunyoungfe30ba02015-09-17 17:56:35 -0700112 public void setIntProperty(int property, int value) {
keunyoung1ab8e182015-09-24 09:25:22 -0700113 VehiclePropValue v = VehiclePropValueUtil.createIntValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700114 setProperty(v);
115 }
116
keunyoungd32f4e62015-09-21 11:33:06 -0700117 public void setIntVectorProperty(int property, int[] values) {
keunyoung1ab8e182015-09-24 09:25:22 -0700118 VehiclePropValue v = VehiclePropValueUtil.createIntVectorValue(property, values, 0);
119 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700120 }
121
keunyoungfe30ba02015-09-17 17:56:35 -0700122 public void setLongProperty(int property, long value) {
keunyoung1ab8e182015-09-24 09:25:22 -0700123 VehiclePropValue v = VehiclePropValueUtil.createLongValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700124 setProperty(v);
125 }
126
keunyoungd32f4e62015-09-21 11:33:06 -0700127 public void setFloatProperty(int property, float value) {
keunyoung1ab8e182015-09-24 09:25:22 -0700128 VehiclePropValue v = VehiclePropValueUtil.createFloatValue(property, value, 0);
keunyoungfe30ba02015-09-17 17:56:35 -0700129 setProperty(v);
130 }
131
keunyoungd32f4e62015-09-21 11:33:06 -0700132 public void setFloatVectorProperty(int property, float[] values) {
keunyoung1ab8e182015-09-24 09:25:22 -0700133 VehiclePropValue v = VehiclePropValueUtil.createFloatVectorValue(property, values, 0);
134 setProperty(v);
keunyoungd32f4e62015-09-21 11:33:06 -0700135 }
136
keunyounge18e25d2015-08-28 15:57:19 -0700137 public VehiclePropValue getProperty(int property) {
138 try {
139 VehiclePropValueParcelable parcelable = mService.getProperty(property);
140 if (parcelable != null) {
141 return parcelable.value;
142 }
143 } catch (RemoteException e) {
144 handleRemoteException(e);
145 }
146 return null;
147 }
148
keunyoungfe30ba02015-09-17 17:56:35 -0700149 public int getIntProperty(int property) {
150 VehiclePropValue v = getProperty(property);
151 if (v == null) {
keunyoungd32f4e62015-09-21 11:33:06 -0700152 // if property is invalid, IllegalArgumentException should have been thrown
153 // from getProperty.
keunyoungfe30ba02015-09-17 17:56:35 -0700154 throw new IllegalStateException();
155 }
keunyoungd32f4e62015-09-21 11:33:06 -0700156 if (v.getValueType() != VehicleValueType.VEHICLE_VALUE_TYPE_INT32) {
keunyoungfe30ba02015-09-17 17:56:35 -0700157 throw new IllegalArgumentException();
158 }
keunyoungd32f4e62015-09-21 11:33:06 -0700159 if (v.getInt32ValuesCount() != 1) {
160 throw new IllegalStateException();
161 }
162 return v.getInt32Values(0);
163 }
164
165 public void getIntVectorProperty(int property, int[] values) {
166 VehiclePropValue v = getProperty(property);
167 if (v == null) {
168 // if property is invalid, IllegalArgumentException should have been thrown
169 // from getProperty.
170 throw new IllegalStateException();
171 }
172 switch (v.getValueType()) {
173 case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2:
174 case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC3:
175 case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4:
176 if (values.length !=
177 (v.getValueType() - VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2 + 2)) {
178 throw new IllegalArgumentException("wrong array length");
179 }
180 break;
181 default:
182 throw new IllegalArgumentException();
183 }
184 if (v.getInt32ValuesCount() != values.length) {
185 throw new IllegalStateException();
186 }
187 for (int i = 0; i < values.length; i++) {
188 values[i] = v.getInt32Values(i);
189 }
keunyoungfe30ba02015-09-17 17:56:35 -0700190 }
191
192 public float getFloatProperty(int property) {
193 VehiclePropValue v = getProperty(property);
194 if (v == null) {
195 throw new IllegalStateException();
196 }
keunyoungd32f4e62015-09-21 11:33:06 -0700197 if (v.getValueType() != VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT) {
keunyoungfe30ba02015-09-17 17:56:35 -0700198 throw new IllegalArgumentException();
199 }
keunyoungd32f4e62015-09-21 11:33:06 -0700200 if (v.getFloatValuesCount() != 1) {
201 throw new IllegalStateException();
202 }
203 return v.getFloatValues(0);
204 }
205
206 public void getFloatVectorProperty(int property, float[] values) {
207 VehiclePropValue v = getProperty(property);
208 if (v == null) {
209 // if property is invalid, IllegalArgumentException should have been thrown
210 // from getProperty.
211 throw new IllegalStateException();
212 }
213 switch (v.getValueType()) {
214 case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2:
215 case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC3:
216 case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC4:
217 if (values.length !=
218 (v.getValueType() - VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2 + 2)) {
219 throw new IllegalArgumentException("wrong array length");
220 }
221 break;
222 default:
223 throw new IllegalArgumentException();
224 }
225 if (v.getFloatValuesCount() != values.length) {
226 throw new IllegalStateException();
227 }
228 for (int i = 0; i < values.length; i++) {
229 values[i] = v.getFloatValues(i);
230 }
keunyoungfe30ba02015-09-17 17:56:35 -0700231 }
232
233 public long getLongProperty(int property) {
234 VehiclePropValue v = getProperty(property);
235 if (v == null) {
236 throw new IllegalStateException();
237 }
keunyoungd32f4e62015-09-21 11:33:06 -0700238 if (v.getValueType() != VehicleValueType.VEHICLE_VALUE_TYPE_INT64) {
keunyoungfe30ba02015-09-17 17:56:35 -0700239 throw new IllegalArgumentException();
240 }
241 return v.getInt64Value();
242 }
243
244 //TODO check UTF8 to java string conversion
245 public String getStringProperty(int property) {
246 VehiclePropValue v = getProperty(property);
247 if (v == null) {
248 throw new IllegalStateException();
249 }
keunyoungd32f4e62015-09-21 11:33:06 -0700250 if (v.getValueType() != VehicleValueType.VEHICLE_VALUE_TYPE_STRING) {
keunyoungfe30ba02015-09-17 17:56:35 -0700251 throw new IllegalArgumentException();
252 }
253 return v.getStringValue();
254 }
255
keunyoung15882e52015-09-16 16:57:58 -0700256 public void subscribe(int property, float sampleRate) {
keunyounge18e25d2015-08-28 15:57:19 -0700257 try {
keunyoung15882e52015-09-16 16:57:58 -0700258 mService.subscribe(mVehicleNetworkListener, property, sampleRate);
keunyounge18e25d2015-08-28 15:57:19 -0700259 } catch (RemoteException e) {
260 handleRemoteException(e);
261 }
keunyounge18e25d2015-08-28 15:57:19 -0700262 }
263
264 public void unsubscribe(int property) {
265 try {
266 mService.unsubscribe(mVehicleNetworkListener, property);
267 } catch (RemoteException e) {
268 handleRemoteException(e);
269 }
270 }
271
keunyoung1ab8e182015-09-24 09:25:22 -0700272 public synchronized void injectEvent(VehiclePropValue value) {
273 try {
274 mService.injectEvent(new VehiclePropValueParcelable(value));
275 } catch (RemoteException e) {
276 handleRemoteException(e);
277 }
278 }
279
280 public synchronized void startMocking(VehicleNetworkHalMock mock) {
281 mHalMock = mock;
282 mHalMockImpl = new IVehicleNetworkHalMockImpl(this);
283 try {
284 mService.startMocking(mHalMockImpl);
285 } catch (RemoteException e) {
286 handleRemoteException(e);
287 }
288 }
289
290 public synchronized void stopMocking() {
291 try {
292 mService.stopMocking(mHalMockImpl);
293 } catch (RemoteException e) {
294 handleRemoteException(e);
295 } finally {
296 mHalMock = null;
297 mHalMockImpl = null;
298 }
299 }
300
301 public synchronized void startMocking(IVehicleNetworkHalMock mock) {
302 mHalMock = null;
303 mHalMockImpl = mock;
304 try {
305 mService.startMocking(mHalMockImpl);
306 } catch (RemoteException e) {
307 handleRemoteException(e);
308 }
309 }
310
311 public synchronized void stopMocking(IVehicleNetworkHalMock mock) {
312 if (mock.asBinder() != mHalMockImpl.asBinder()) {
313 return;
314 }
315 try {
316 mService.stopMocking(mHalMockImpl);
317 } catch (RemoteException e) {
318 handleRemoteException(e);
319 } finally {
320 mHalMock = null;
321 mHalMockImpl = null;
322 }
323 }
324
325 private synchronized VehicleNetworkHalMock getHalMock() {
326 return mHalMock;
327 }
328
keunyounge18e25d2015-08-28 15:57:19 -0700329 private void handleRemoteException(RemoteException e) {
330 throw new RuntimeException("Vehicle network service not working ", e);
331 }
332
333 private void handleVehicleNetworkEvents(VehiclePropValues values) {
334 mEventHandler.notifyEvents(values);
335 }
336
337 private void doHandleVehicleNetworkEvents(VehiclePropValues values) {
338 mListener.onVehicleNetworkEvents(values);
339 }
340
341 private class EventHandler extends Handler {
342 private static final int MSG_EVENTS = 0;
343
344 private EventHandler(Looper looper) {
345 super(looper);
346 }
347
348 private void notifyEvents(VehiclePropValues values) {
349 Message msg = obtainMessage(MSG_EVENTS, values);
350 sendMessage(msg);
351 }
352
353 @Override
354 public void handleMessage(Message msg) {
355 switch (msg.what) {
356 case MSG_EVENTS:
357 doHandleVehicleNetworkEvents((VehiclePropValues)msg.obj);
358 break;
359 default:
360 Log.w(TAG, "unown message:" + msg.what, new RuntimeException());
361 break;
362 }
363 }
364 }
365
366 private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub {
367 private final WeakReference<VehicleNetwork> mVehicleNetwork;
368
369 private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNewotk) {
370 mVehicleNetwork = new WeakReference<VehicleNetwork>(vehicleNewotk);
371 }
372
373 @Override
374 public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) {
375 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
376 if (vehicleNetwork != null) {
377 vehicleNetwork.handleVehicleNetworkEvents(values.values);
378 }
379 }
380 }
keunyoung1ab8e182015-09-24 09:25:22 -0700381
382 private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub {
383 private final WeakReference<VehicleNetwork> mVehicleNetwork;
384
385 private IVehicleNetworkHalMockImpl(VehicleNetwork vehicleNewotk) {
386 mVehicleNetwork = new WeakReference<VehicleNetwork>(vehicleNewotk);
387 }
388
389 @Override
390 public VehiclePropConfigsParcelable onListProperties() {
391 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
392 if (vehicleNetwork == null) {
393 return null;
394 }
395 VehiclePropConfigs configs = vehicleNetwork.getHalMock().onListProperties();
396 return new VehiclePropConfigsParcelable(configs);
397 }
398
399 @Override
400 public void onPropertySet(VehiclePropValueParcelable value) {
401 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
402 if (vehicleNetwork == null) {
403 return;
404 }
405 vehicleNetwork.getHalMock().onPropertySet(value.value);
406 }
407
408 @Override
409 public VehiclePropValueParcelable onPropertyGet(int property) {
410 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
411 if (vehicleNetwork == null) {
412 return null;
413 }
414 VehiclePropValue value = vehicleNetwork.getHalMock().onPropertyGet(property);
415 return new VehiclePropValueParcelable(value);
416 }
417
418 @Override
419 public void onPropertySubscribe(int property, int sampleRate) {
420 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
421 if (vehicleNetwork == null) {
422 return;
423 }
424 vehicleNetwork.getHalMock().onPropertySubscribe(property, sampleRate);
425 }
426
427 @Override
428 public void onPropertyUnsubscribe(int property) {
429 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
430 if (vehicleNetwork == null) {
431 return;
432 }
433 vehicleNetwork.getHalMock().onPropertyUnsubscribe(property);
434 }
435 }
keunyounge18e25d2015-08-28 15:57:19 -0700436}