blob: 7514c8c40965c9c9e7107125c5509dbf6668cf0f [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;
30
31import java.lang.ref.WeakReference;
32
33/**
34 * System API to access Vehicle network. This is only for system services and applications should
keunyoung15882e52015-09-16 16:57:58 -070035 * not use this. All APIs will fail with security error if normal app tries this.
keunyounge18e25d2015-08-28 15:57:19 -070036 */
37public class VehicleNetwork {
38 public interface VehicleNetworkListener {
39 void onVehicleNetworkEvents(VehiclePropValues values);
40 }
41
keunyounge18e25d2015-08-28 15:57:19 -070042 private static final String TAG = VehicleNetwork.class.getSimpleName();
43
44 private final IVehicleNetwork mService;
45 private final VehicleNetworkListener mListener;
46 private final IVehicleNetworkListenerImpl mVehicleNetworkListener;
47 private final EventHandler mEventHandler;
48
keunyoung15882e52015-09-16 16:57:58 -070049 public static VehicleNetwork createVehicleNetwork(VehicleNetworkListener listener,
50 Looper looper) {
keunyounge18e25d2015-08-28 15:57:19 -070051 IVehicleNetwork service = IVehicleNetwork.Stub.asInterface(ServiceManager.getService(
52 IVehicleNetwork.class.getCanonicalName()));
53 if (service == null) {
keunyoung15882e52015-09-16 16:57:58 -070054 throw new RuntimeException("Vehicle network service not available:" +
55 IVehicleNetwork.class.getCanonicalName());
keunyounge18e25d2015-08-28 15:57:19 -070056 }
57 return new VehicleNetwork(service, listener, looper);
58 }
59
60 private VehicleNetwork(IVehicleNetwork service, VehicleNetworkListener listener,
61 Looper looper) {
62 mService = service;
63 mListener = listener;
64 mEventHandler = new EventHandler(looper);
65 mVehicleNetworkListener = new IVehicleNetworkListenerImpl(this);
66 }
67
keunyoung15882e52015-09-16 16:57:58 -070068 public VehiclePropConfigs listProperties() {
69 return listProperties(0 /* all */);
70 }
71
keunyounge18e25d2015-08-28 15:57:19 -070072 public VehiclePropConfigs listProperties(int property) {
73 try {
74 VehiclePropConfigsParcelable parcelable = mService.listProperties(property);
75 if (parcelable != null) {
76 return parcelable.configs;
77 }
78 } catch (RemoteException e) {
79 handleRemoteException(e);
80 }
81 return null;
82 }
83
keunyoung15882e52015-09-16 16:57:58 -070084 public void setProperty(VehiclePropValue value) {
keunyounge18e25d2015-08-28 15:57:19 -070085 VehiclePropValueParcelable parcelable = new VehiclePropValueParcelable(value);
86 try {
keunyoung15882e52015-09-16 16:57:58 -070087 mService.setProperty(parcelable);
keunyounge18e25d2015-08-28 15:57:19 -070088 } catch (RemoteException e) {
89 handleRemoteException(e);
90 }
keunyounge18e25d2015-08-28 15:57:19 -070091 }
92
keunyoungfe30ba02015-09-17 17:56:35 -070093 public void setIntProperty(int property, int value) {
94 VehiclePropValue v = VehiclePropValue.newBuilder().
95 setProp(property).
keunyoungd32f4e62015-09-21 11:33:06 -070096 setValueType(VehicleValueType.VEHICLE_VALUE_TYPE_INT32).
97 addInt32Values(value).
keunyoungfe30ba02015-09-17 17:56:35 -070098 build();
99 setProperty(v);
100 }
101
keunyoungd32f4e62015-09-21 11:33:06 -0700102 public void setIntVectorProperty(int property, int[] values) {
103 int len = values.length;
104 VehiclePropValue.Builder builder = VehiclePropValue.newBuilder().
105 setProp(property).
106 setValueType(VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2 + len - 2);
107 for (int v : values) {
108 builder.addInt32Values(v);
109 }
110 setProperty(builder.build());
111 }
112
keunyoungfe30ba02015-09-17 17:56:35 -0700113 public void setLongProperty(int property, long value) {
114 VehiclePropValue v = VehiclePropValue.newBuilder().
115 setProp(property).
keunyoungd32f4e62015-09-21 11:33:06 -0700116 setValueType(VehicleValueType.VEHICLE_VALUE_TYPE_INT64).
keunyoungfe30ba02015-09-17 17:56:35 -0700117 setInt64Value(value).
118 build();
119 setProperty(v);
120 }
121
keunyoungd32f4e62015-09-21 11:33:06 -0700122 public void setFloatProperty(int property, float value) {
keunyoungfe30ba02015-09-17 17:56:35 -0700123 VehiclePropValue v = VehiclePropValue.newBuilder().
124 setProp(property).
keunyoungd32f4e62015-09-21 11:33:06 -0700125 setValueType(VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT).
126 addFloatValues(value).
keunyoungfe30ba02015-09-17 17:56:35 -0700127 build();
128 setProperty(v);
129 }
130
keunyoungd32f4e62015-09-21 11:33:06 -0700131 public void setFloatVectorProperty(int property, float[] values) {
132 int len = values.length;
133 VehiclePropValue.Builder builder = VehiclePropValue.newBuilder().
134 setProp(property).
135 setValueType(VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2 + len - 2);
136 for (float v : values) {
137 builder.addFloatValues(v);
138 }
139 setProperty(builder.build());
140 }
141
keunyounge18e25d2015-08-28 15:57:19 -0700142 public VehiclePropValue getProperty(int property) {
143 try {
144 VehiclePropValueParcelable parcelable = mService.getProperty(property);
145 if (parcelable != null) {
146 return parcelable.value;
147 }
148 } catch (RemoteException e) {
149 handleRemoteException(e);
150 }
151 return null;
152 }
153
keunyoungfe30ba02015-09-17 17:56:35 -0700154 public int getIntProperty(int property) {
155 VehiclePropValue v = getProperty(property);
156 if (v == null) {
keunyoungd32f4e62015-09-21 11:33:06 -0700157 // if property is invalid, IllegalArgumentException should have been thrown
158 // from getProperty.
keunyoungfe30ba02015-09-17 17:56:35 -0700159 throw new IllegalStateException();
160 }
keunyoungd32f4e62015-09-21 11:33:06 -0700161 if (v.getValueType() != VehicleValueType.VEHICLE_VALUE_TYPE_INT32) {
keunyoungfe30ba02015-09-17 17:56:35 -0700162 throw new IllegalArgumentException();
163 }
keunyoungd32f4e62015-09-21 11:33:06 -0700164 if (v.getInt32ValuesCount() != 1) {
165 throw new IllegalStateException();
166 }
167 return v.getInt32Values(0);
168 }
169
170 public void getIntVectorProperty(int property, int[] values) {
171 VehiclePropValue v = getProperty(property);
172 if (v == null) {
173 // if property is invalid, IllegalArgumentException should have been thrown
174 // from getProperty.
175 throw new IllegalStateException();
176 }
177 switch (v.getValueType()) {
178 case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2:
179 case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC3:
180 case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4:
181 if (values.length !=
182 (v.getValueType() - VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2 + 2)) {
183 throw new IllegalArgumentException("wrong array length");
184 }
185 break;
186 default:
187 throw new IllegalArgumentException();
188 }
189 if (v.getInt32ValuesCount() != values.length) {
190 throw new IllegalStateException();
191 }
192 for (int i = 0; i < values.length; i++) {
193 values[i] = v.getInt32Values(i);
194 }
keunyoungfe30ba02015-09-17 17:56:35 -0700195 }
196
197 public float getFloatProperty(int property) {
198 VehiclePropValue v = getProperty(property);
199 if (v == null) {
200 throw new IllegalStateException();
201 }
keunyoungd32f4e62015-09-21 11:33:06 -0700202 if (v.getValueType() != VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT) {
keunyoungfe30ba02015-09-17 17:56:35 -0700203 throw new IllegalArgumentException();
204 }
keunyoungd32f4e62015-09-21 11:33:06 -0700205 if (v.getFloatValuesCount() != 1) {
206 throw new IllegalStateException();
207 }
208 return v.getFloatValues(0);
209 }
210
211 public void getFloatVectorProperty(int property, float[] values) {
212 VehiclePropValue v = getProperty(property);
213 if (v == null) {
214 // if property is invalid, IllegalArgumentException should have been thrown
215 // from getProperty.
216 throw new IllegalStateException();
217 }
218 switch (v.getValueType()) {
219 case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2:
220 case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC3:
221 case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC4:
222 if (values.length !=
223 (v.getValueType() - VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2 + 2)) {
224 throw new IllegalArgumentException("wrong array length");
225 }
226 break;
227 default:
228 throw new IllegalArgumentException();
229 }
230 if (v.getFloatValuesCount() != values.length) {
231 throw new IllegalStateException();
232 }
233 for (int i = 0; i < values.length; i++) {
234 values[i] = v.getFloatValues(i);
235 }
keunyoungfe30ba02015-09-17 17:56:35 -0700236 }
237
238 public long getLongProperty(int property) {
239 VehiclePropValue v = getProperty(property);
240 if (v == null) {
241 throw new IllegalStateException();
242 }
keunyoungd32f4e62015-09-21 11:33:06 -0700243 if (v.getValueType() != VehicleValueType.VEHICLE_VALUE_TYPE_INT64) {
keunyoungfe30ba02015-09-17 17:56:35 -0700244 throw new IllegalArgumentException();
245 }
246 return v.getInt64Value();
247 }
248
249 //TODO check UTF8 to java string conversion
250 public String getStringProperty(int property) {
251 VehiclePropValue v = getProperty(property);
252 if (v == null) {
253 throw new IllegalStateException();
254 }
keunyoungd32f4e62015-09-21 11:33:06 -0700255 if (v.getValueType() != VehicleValueType.VEHICLE_VALUE_TYPE_STRING) {
keunyoungfe30ba02015-09-17 17:56:35 -0700256 throw new IllegalArgumentException();
257 }
258 return v.getStringValue();
259 }
260
keunyoung15882e52015-09-16 16:57:58 -0700261 public void subscribe(int property, float sampleRate) {
keunyounge18e25d2015-08-28 15:57:19 -0700262 try {
keunyoung15882e52015-09-16 16:57:58 -0700263 mService.subscribe(mVehicleNetworkListener, property, sampleRate);
keunyounge18e25d2015-08-28 15:57:19 -0700264 } catch (RemoteException e) {
265 handleRemoteException(e);
266 }
keunyounge18e25d2015-08-28 15:57:19 -0700267 }
268
269 public void unsubscribe(int property) {
270 try {
271 mService.unsubscribe(mVehicleNetworkListener, property);
272 } catch (RemoteException e) {
273 handleRemoteException(e);
274 }
275 }
276
277 private void handleRemoteException(RemoteException e) {
278 throw new RuntimeException("Vehicle network service not working ", e);
279 }
280
281 private void handleVehicleNetworkEvents(VehiclePropValues values) {
282 mEventHandler.notifyEvents(values);
283 }
284
285 private void doHandleVehicleNetworkEvents(VehiclePropValues values) {
286 mListener.onVehicleNetworkEvents(values);
287 }
288
289 private class EventHandler extends Handler {
290 private static final int MSG_EVENTS = 0;
291
292 private EventHandler(Looper looper) {
293 super(looper);
294 }
295
296 private void notifyEvents(VehiclePropValues values) {
297 Message msg = obtainMessage(MSG_EVENTS, values);
298 sendMessage(msg);
299 }
300
301 @Override
302 public void handleMessage(Message msg) {
303 switch (msg.what) {
304 case MSG_EVENTS:
305 doHandleVehicleNetworkEvents((VehiclePropValues)msg.obj);
306 break;
307 default:
308 Log.w(TAG, "unown message:" + msg.what, new RuntimeException());
309 break;
310 }
311 }
312 }
313
314 private static class IVehicleNetworkListenerImpl extends IVehicleNetworkListener.Stub {
315 private final WeakReference<VehicleNetwork> mVehicleNetwork;
316
317 private IVehicleNetworkListenerImpl(VehicleNetwork vehicleNewotk) {
318 mVehicleNetwork = new WeakReference<VehicleNetwork>(vehicleNewotk);
319 }
320
321 @Override
322 public void onVehicleNetworkEvents(VehiclePropValuesParcelable values) {
323 VehicleNetwork vehicleNetwork = mVehicleNetwork.get();
324 if (vehicleNetwork != null) {
325 vehicleNetwork.handleVehicleNetworkEvents(values.values);
326 }
327 }
328 }
329}