blob: 79fd62650e37fc6dc14ca5b5037fde5e2c9b58ba [file] [log] [blame]
Steve Paik461ecc62016-06-08 15:28:32 -07001/*
2 * Copyright (C) 2016 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.hal;
17
18import static com.android.car.hal.CarPropertyUtils.toCarPropertyValue;
19import static com.android.car.hal.CarPropertyUtils.toVehiclePropValue;
20import static java.lang.Integer.toHexString;
21
22import android.car.hardware.CarPropertyConfig;
23import android.car.hardware.CarPropertyValue;
24import android.car.hardware.property.CarPropertyEvent;
25import android.os.ServiceSpecificException;
26import android.util.Log;
27import android.util.SparseIntArray;
28
29import com.android.car.CarLog;
30import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
31import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
Pavel Maltsev634e1ff2016-07-14 15:41:26 -070032import com.android.internal.annotations.GuardedBy;
Steve Paik461ecc62016-06-08 15:28:32 -070033
34import java.io.PrintWriter;
35import java.util.ArrayList;
36import java.util.LinkedList;
37import java.util.List;
38import java.util.concurrent.ConcurrentHashMap;
39
40/**
41 * Common interface for HAL services that send Vehicle Properties back and forth via ICarProperty.
42 * Services that communicate by passing vehicle properties back and forth via ICarProperty should
43 * extend this class.
44 */
45public abstract class PropertyHalServiceBase extends HalServiceBase {
46 private final boolean mDbg;
47 private final SparseIntArray mHalPropToValueType = new SparseIntArray();
Steve Paik461ecc62016-06-08 15:28:32 -070048 private final ConcurrentHashMap<Integer, CarPropertyConfig<?>> mProps =
49 new ConcurrentHashMap<>();
50 private final String mTag;
51 private final VehicleHal mVehicleHal;
52
Pavel Maltsev634e1ff2016-07-14 15:41:26 -070053 @GuardedBy("mLock")
54 private PropertyHalListener mListener;
55 private final Object mLock = new Object();
56
57 protected final static int NOT_SUPPORTED_PROPERTY = -1;
58
Steve Paik461ecc62016-06-08 15:28:32 -070059 public interface PropertyHalListener {
60 void onPropertyChange(CarPropertyEvent event);
61 void onError(int zone, int property);
62 }
63
Pavel Maltsev634e1ff2016-07-14 15:41:26 -070064 protected PropertyHalServiceBase(VehicleHal vehicleHal, String tag, boolean dbg) {
Steve Paik461ecc62016-06-08 15:28:32 -070065 mVehicleHal = vehicleHal;
66 mTag = "PropertyHalServiceBase." + tag;
67 mDbg = dbg;
68
69 if (mDbg) {
70 Log.d(mTag, "started PropertyHalServiceBase!");
71 }
72 }
73
74 public void setListener(PropertyHalListener listener) {
Pavel Maltsev634e1ff2016-07-14 15:41:26 -070075 synchronized (mLock) {
Steve Paik461ecc62016-06-08 15:28:32 -070076 mListener = listener;
77 }
78 }
79
80 public List<CarPropertyConfig> getPropertyList() {
81 return new ArrayList<>(mProps.values());
82 }
83
84 public CarPropertyValue getProperty(int mgrPropId, int areaId) {
85 int halPropId = managerToHalPropId(mgrPropId);
Pavel Maltsev634e1ff2016-07-14 15:41:26 -070086 if (halPropId == NOT_SUPPORTED_PROPERTY) {
87 throw new IllegalArgumentException("Invalid property Id : 0x" + toHexString(mgrPropId));
88 }
Steve Paik461ecc62016-06-08 15:28:32 -070089
90 VehiclePropValue value = null;
91 try {
92 VehiclePropValue valueRequest = VehiclePropValue.newBuilder()
93 .setProp(halPropId)
94 .setZone(areaId)
95 .setValueType(mHalPropToValueType.get(halPropId))
96 .build();
97
98 value = mVehicleHal.getVehicleNetwork().getProperty(valueRequest);
99 } catch (ServiceSpecificException e) {
100 Log.e(CarLog.TAG_PROPERTY, "get, property not ready 0x" + toHexString(halPropId), e);
101 }
102
103 return value == null ? null : toCarPropertyValue(value, mgrPropId);
104 }
105
106 public void setProperty(CarPropertyValue prop) {
107 int halPropId = managerToHalPropId(prop.getPropertyId());
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700108 if (halPropId == NOT_SUPPORTED_PROPERTY) {
109 throw new IllegalArgumentException("Invalid property Id : 0x"
110 + toHexString(prop.getPropertyId()));
111 }
Steve Paik461ecc62016-06-08 15:28:32 -0700112 VehiclePropValue halProp = toVehiclePropValue(prop, halPropId);
113 try {
114 mVehicleHal.getVehicleNetwork().setProperty(halProp);
115 } catch (ServiceSpecificException e) {
116 Log.e(CarLog.TAG_PROPERTY, "set, property not ready 0x" + toHexString(halPropId), e);
117 throw new RuntimeException(e);
118 }
119 }
120
121 @Override
122 public void init() {
123 if (mDbg) {
124 Log.d(mTag, "init()");
125 }
126 // Subscribe to each of the properties
127 for (Integer prop : mProps.keySet()) {
128 mVehicleHal.subscribeProperty(this, prop, 0);
129 }
130 }
131
132 @Override
133 public void release() {
134 if (mDbg) {
135 Log.d(mTag, "release()");
136 }
137
138 for (Integer prop : mProps.keySet()) {
139 mVehicleHal.unsubscribeProperty(this, prop);
140 }
141
142 // Clear the property list
143 mProps.clear();
144
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700145 synchronized (mLock) {
Steve Paik461ecc62016-06-08 15:28:32 -0700146 mListener = null;
147 }
148 }
149
150 @Override
151 public List<VehiclePropConfig> takeSupportedProperties(
152 List<VehiclePropConfig> allProperties) {
153 List<VehiclePropConfig> taken = new LinkedList<>();
154
155 for (VehiclePropConfig p : allProperties) {
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700156 int mgrPropId = halToManagerPropId(p.getProp());
Steve Paik461ecc62016-06-08 15:28:32 -0700157
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700158 if (mgrPropId == NOT_SUPPORTED_PROPERTY) {
159 continue; // The property is not handled by this HAL.
Steve Paik461ecc62016-06-08 15:28:32 -0700160 }
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700161
Steve Paik461ecc62016-06-08 15:28:32 -0700162 CarPropertyConfig config = CarPropertyUtils.toCarPropertyConfig(p, mgrPropId);
163
164 taken.add(p);
165 mProps.put(p.getProp(), config);
166 mHalPropToValueType.put(p.getProp(), p.getValueType());
167
168 if (mDbg) {
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700169 Log.d(mTag, "takeSupportedProperties: " + toHexString(p.getProp()));
Steve Paik461ecc62016-06-08 15:28:32 -0700170 }
171 }
172 return taken;
173 }
174
175 @Override
176 public void handleHalEvents(List<VehiclePropValue> values) {
177 PropertyHalListener listener;
178 synchronized (this) {
179 listener = mListener;
180 }
181 if (listener != null) {
182 for (VehiclePropValue v : values) {
183 int prop = v.getProp();
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700184 int mgrPropId = halToManagerPropId(prop);
Steve Paik461ecc62016-06-08 15:28:32 -0700185
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700186 if (mgrPropId == NOT_SUPPORTED_PROPERTY) {
187 Log.e(mTag, "Property is not supported: 0x" + toHexString(prop));
Steve Paik461ecc62016-06-08 15:28:32 -0700188 continue;
189 }
190
191 CarPropertyEvent event;
192 CarPropertyValue<?> propVal = toCarPropertyValue(v, mgrPropId);
193 event = new CarPropertyEvent(CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE,
194 propVal);
195
196 listener.onPropertyChange(event);
197 if (mDbg) {
198 Log.d(mTag, "handleHalEvents event: " + event);
199 }
200 }
201 }
202 }
203
204 @Override
205 public void dump(PrintWriter writer) {
206 writer.println(mTag);
207 writer.println(" Properties available:");
208 for (CarPropertyConfig prop : mProps.values()) {
209 writer.println(" " + prop.toString());
210 }
211 }
212
213 /**
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700214 * Converts manager property ID to Vehicle HAL property ID.
215 * If property is not supported, it will return {@link #NOT_SUPPORTED_PROPERTY}.
Steve Paik461ecc62016-06-08 15:28:32 -0700216 */
217 abstract protected int managerToHalPropId(int managerPropId);
218
219 /**
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700220 * Converts Vehicle HAL property ID to manager property ID.
221 * If property is not supported, it will return {@link #NOT_SUPPORTED_PROPERTY}.
Steve Paik461ecc62016-06-08 15:28:32 -0700222 */
223 abstract protected int halToManagerPropId(int halPropId);
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700224
225 /**
226 * Helper class that maintains bi-directional mapping between manager's property
227 * Id (public or system API) and vehicle HAL property Id.
228 *
229 * <p>This class is supposed to be immutable. Use {@link #create(int[])} factory method to
230 * instantiate this class.
231 */
232 static class ManagerToHalPropIdMap {
233 private final SparseIntArray mMap;
234 private final SparseIntArray mInverseMap;
235
236 /**
237 * Creates {@link ManagerToHalPropIdMap} for provided [manager prop Id, hal prop Id] pairs.
238 *
239 * <p> The input array should have an odd number of elements.
240 */
241 static ManagerToHalPropIdMap create(int[] mgrToHalPropIds) {
242 int inputLength = mgrToHalPropIds.length;
243 if (inputLength % 2 != 0) {
244 throw new IllegalArgumentException("Odd number of key-value elements");
245 }
246
247 ManagerToHalPropIdMap biMap = new ManagerToHalPropIdMap(inputLength / 2);
248 for (int i = 0; i < mgrToHalPropIds.length; i += 2) {
249 biMap.put(mgrToHalPropIds[i], mgrToHalPropIds[i + 1]);
250 }
251 return biMap;
252 }
253
254 private ManagerToHalPropIdMap(int initialCapacity) {
255 mMap = new SparseIntArray(initialCapacity);
256 mInverseMap = new SparseIntArray(initialCapacity);
257 }
258
259 private void put(int managerPropId, int halPropId) {
260 mMap.put(managerPropId, halPropId);
261 mInverseMap.put(halPropId, managerPropId);
262 }
263
264 int getHalPropId(int managerPropId) {
265 return mMap.get(managerPropId, NOT_SUPPORTED_PROPERTY);
266 }
267
268 int getManagerPropId(int halPropId) {
269 return mInverseMap.get(halPropId, NOT_SUPPORTED_PROPERTY);
270 }
271 }
Steve Paik461ecc62016-06-08 15:28:32 -0700272}