• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 package com.android.car.hal;
17 
18 import static com.android.car.hal.CarPropertyUtils.toCarPropertyValue;
19 import static com.android.car.hal.CarPropertyUtils.toVehiclePropValue;
20 import static java.lang.Integer.toHexString;
21 
22 import android.annotation.Nullable;
23 import android.car.hardware.CarPropertyConfig;
24 import android.car.hardware.CarPropertyValue;
25 import android.car.hardware.property.CarPropertyEvent;
26 import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig;
27 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
28 import android.util.Log;
29 
30 import com.android.car.CarLog;
31 import com.android.internal.annotations.GuardedBy;
32 
33 import java.io.PrintWriter;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.LinkedList;
37 import java.util.List;
38 import 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  */
45 public abstract class PropertyHalServiceBase extends HalServiceBase {
46     private final boolean mDbg;
47     private final ConcurrentHashMap<Integer, CarPropertyConfig<?>> mProps =
48             new ConcurrentHashMap<>();
49     private final String mTag;
50     private final VehicleHal mVehicleHal;
51 
52     @GuardedBy("mLock")
53     private PropertyHalListener mListener;
54     private final Object mLock = new Object();
55 
56     public interface PropertyHalListener {
onPropertyChange(CarPropertyEvent event)57         void onPropertyChange(CarPropertyEvent event);
onPropertySetError(int property, int area)58         void onPropertySetError(int property, int area);
59     }
60 
PropertyHalServiceBase(VehicleHal vehicleHal, String tag, boolean dbg)61     protected PropertyHalServiceBase(VehicleHal vehicleHal, String tag, boolean dbg) {
62         mVehicleHal = vehicleHal;
63         mTag = "PropertyHalServiceBase." + tag;
64         mDbg = dbg;
65 
66         if (mDbg) {
67             Log.d(mTag, "started PropertyHalServiceBase!");
68         }
69     }
70 
setListener(PropertyHalListener listener)71     public void setListener(PropertyHalListener listener) {
72         synchronized (mLock) {
73             mListener = listener;
74         }
75     }
76 
getPropertyList()77     public List<CarPropertyConfig> getPropertyList() {
78         return new ArrayList<>(mProps.values());
79     }
80 
81     /**
82      * Returns property or null if property is not ready yet.
83      */
84     @Nullable
getProperty(int mgrPropId, int areaId)85     public CarPropertyValue getProperty(int mgrPropId, int areaId) {
86         int halPropId = managerToHalPropId(mgrPropId);
87         if (halPropId == NOT_SUPPORTED_PROPERTY) {
88             throw new IllegalArgumentException("Invalid property Id : 0x" + toHexString(mgrPropId));
89         }
90 
91         VehiclePropValue value = null;
92         try {
93             value = mVehicleHal.get(halPropId, areaId);
94         } catch (PropertyTimeoutException e) {
95             Log.e(CarLog.TAG_PROPERTY, "get, property not ready 0x" + toHexString(halPropId), e);
96         }
97 
98         return value == null ? null : toCarPropertyValue(value, mgrPropId);
99     }
100 
setProperty(CarPropertyValue prop)101     public void setProperty(CarPropertyValue prop) {
102         int halPropId = managerToHalPropId(prop.getPropertyId());
103         if (halPropId == NOT_SUPPORTED_PROPERTY) {
104             throw new IllegalArgumentException("Invalid property Id : 0x"
105                     + toHexString(prop.getPropertyId()));
106         }
107         VehiclePropValue halProp = toVehiclePropValue(prop, halPropId);
108         try {
109             mVehicleHal.set(halProp);
110         } catch (PropertyTimeoutException e) {
111             Log.e(CarLog.TAG_PROPERTY, "set, property not ready 0x" + toHexString(halPropId), e);
112             throw new RuntimeException(e);
113         }
114     }
115 
116     @Override
init()117     public void init() {
118         if (mDbg) {
119             Log.d(mTag, "init()");
120         }
121         // Subscribe to each of the properties
122         for (Integer prop : mProps.keySet()) {
123             mVehicleHal.subscribeProperty(this, prop);
124         }
125     }
126 
127     @Override
release()128     public void release() {
129         if (mDbg) {
130             Log.d(mTag, "release()");
131         }
132 
133         for (Integer prop : mProps.keySet()) {
134             mVehicleHal.unsubscribeProperty(this, prop);
135         }
136 
137         // Clear the property list
138         mProps.clear();
139 
140         synchronized (mLock) {
141             mListener = null;
142         }
143     }
144 
145     @Override
takeSupportedProperties( Collection<VehiclePropConfig> allProperties)146     public Collection<VehiclePropConfig> takeSupportedProperties(
147             Collection<VehiclePropConfig> allProperties) {
148         List<VehiclePropConfig> taken = new LinkedList<>();
149 
150         for (VehiclePropConfig p : allProperties) {
151             int mgrPropId = halToManagerPropId(p.prop);
152 
153             if (mgrPropId == NOT_SUPPORTED_PROPERTY) {
154                 continue;  // The property is not handled by this HAL.
155             }
156 
157             CarPropertyConfig config = CarPropertyUtils.toCarPropertyConfig(p, mgrPropId);
158 
159             taken.add(p);
160             mProps.put(p.prop, config);
161 
162             if (mDbg) {
163                 Log.d(mTag, "takeSupportedProperties: " + toHexString(p.prop));
164             }
165         }
166         return taken;
167     }
168 
169     @Override
handleHalEvents(List<VehiclePropValue> values)170     public void handleHalEvents(List<VehiclePropValue> values) {
171         PropertyHalListener listener;
172         synchronized (mLock) {
173             listener = mListener;
174         }
175         if (listener != null) {
176             for (VehiclePropValue v : values) {
177                 int prop = v.prop;
178                 int mgrPropId = halToManagerPropId(prop);
179 
180                 if (mgrPropId == NOT_SUPPORTED_PROPERTY) {
181                     Log.e(mTag, "Property is not supported: 0x" + toHexString(prop));
182                     continue;
183                 }
184 
185                 CarPropertyEvent event;
186                 CarPropertyValue<?> propVal = toCarPropertyValue(v, mgrPropId);
187                 event = new CarPropertyEvent(CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE,
188                         propVal);
189 
190                 listener.onPropertyChange(event);
191                 if (mDbg) {
192                     Log.d(mTag, "handleHalEvents event: " + event);
193                 }
194             }
195         }
196     }
197 
198     @Override
handlePropertySetError(int property, int area)199     public void handlePropertySetError(int property, int area) {
200         PropertyHalListener listener;
201         synchronized (mLock) {
202             listener = mListener;
203         }
204         if (listener != null) {
205             listener.onPropertySetError(property, area);
206         }
207     }
208 
209     @Override
dump(PrintWriter writer)210     public void dump(PrintWriter writer) {
211         writer.println(mTag);
212         writer.println("  Properties available:");
213         for (CarPropertyConfig prop : mProps.values()) {
214             writer.println("    " + prop.toString());
215         }
216     }
217 
218     /**
219      * Converts manager property ID to Vehicle HAL property ID.
220      * If property is not supported, it will return {@link #NOT_SUPPORTED_PROPERTY}.
221      */
managerToHalPropId(int managerPropId)222     abstract protected int managerToHalPropId(int managerPropId);
223 
224     /**
225      * Converts Vehicle HAL property ID to manager property ID.
226      * If property is not supported, it will return {@link #NOT_SUPPORTED_PROPERTY}.
227      */
halToManagerPropId(int halPropId)228     abstract protected int halToManagerPropId(int halPropId);
229 }
230