blob: 675870a81704aebb28dc14b1877fdd833d38a015 [file] [log] [blame]
keunyoungcc449f72015-08-12 10:46:27 -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 */
16
17package com.android.car.hal;
18
19import android.support.car.CarSensorEvent;
20import android.support.car.CarSensorManager;
21import android.util.Log;
22import android.util.SparseArray;
23
24import com.android.car.CarLog;
25import com.android.car.CarSensorEventFactory;
keunyoungfe30ba02015-09-17 17:56:35 -070026import com.android.car.vehiclenetwork.VehicleNetworkConsts;
27import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropAccess;
28import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropChangeMode;
29import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
30import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
keunyoungcc449f72015-08-12 10:46:27 -070031
32import java.io.PrintWriter;
33import java.util.LinkedList;
34import java.util.List;
35
36/**
37 * Sensor HAL implementation for physical sensors in car.
38 */
39public class SensorHalService extends SensorHalServiceBase {
40
41 private static final boolean DBG_EVENTS = true;
42
43 private static final int SENSOR_TYPE_INVALD = -1;
44
45 private final VehicleHal mHal;
46 private boolean mIsReady = false;
47 private SensorHalServiceBase.SensorListener mSensorListener;
keunyoungfe30ba02015-09-17 17:56:35 -070048 private final SparseArray<VehiclePropConfig> mSensorToHalProperty =
49 new SparseArray<VehiclePropConfig>();
keunyoungcc449f72015-08-12 10:46:27 -070050
51 public SensorHalService(VehicleHal hal) {
52 mHal = hal;
53 }
54
55 @Override
56 public synchronized void init() {
57 //TODO
58 mIsReady = true;
59 }
60
61 @Override
keunyoungfe30ba02015-09-17 17:56:35 -070062 public synchronized List<VehiclePropConfig> takeSupportedProperties(
63 List<VehiclePropConfig> allProperties) {
64 LinkedList<VehiclePropConfig> supportedProperties = new LinkedList<VehiclePropConfig>();
65 for (VehiclePropConfig halProperty : allProperties) {
66 int sensor = getSensorTypeFromHalProperty(halProperty.getProp());
keunyoungcc449f72015-08-12 10:46:27 -070067 if (sensor != SENSOR_TYPE_INVALD &&
keunyoungfe30ba02015-09-17 17:56:35 -070068 halProperty.getChangeMode() !=
69 VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_STATIC &&
70 (halProperty.getAccess() == VehiclePropAccess.VEHICLE_PROP_ACCESS_READ
71 || halProperty.getAccess() ==
72 VehiclePropAccess.VEHICLE_PROP_ACCESS_WRITE)) {
keunyoungcc449f72015-08-12 10:46:27 -070073 supportedProperties.add(halProperty);
74 mSensorToHalProperty.append(sensor, halProperty);
75 }
76 }
77 return supportedProperties;
78 }
79
80 @Override
81 public synchronized void release() {
82 mSensorToHalProperty.clear();
83 mIsReady = false;
84 }
85
keunyoungfe30ba02015-09-17 17:56:35 -070086 // should be used only insidehandleHalEvents.
87 private final LinkedList<CarSensorEvent> mEventsToDispatch = new LinkedList<CarSensorEvent>();
keunyoungcc449f72015-08-12 10:46:27 -070088 @Override
keunyoungfe30ba02015-09-17 17:56:35 -070089 public void handleHalEvents(List<VehiclePropValue> values) {
90 for (VehiclePropValue v : values) {
91 CarSensorEvent event = createCarSensorEvent(v);
92 if (event != null) {
93 mEventsToDispatch.add(event);
94 }
keunyoungcc449f72015-08-12 10:46:27 -070095 }
keunyoungfe30ba02015-09-17 17:56:35 -070096 SensorHalServiceBase.SensorListener sensorListener = null;
97 synchronized (this) {
98 sensorListener = mSensorListener;
keunyoungcc449f72015-08-12 10:46:27 -070099 }
keunyoungfe30ba02015-09-17 17:56:35 -0700100 if (sensorListener != null) {
101 sensorListener.onSensorEvents(mEventsToDispatch);
102 }
103 mEventsToDispatch.clear();
104 }
105
106 private CarSensorEvent createCarSensorEvent(VehiclePropValue v) {
107 int property = v.getProp();
keunyoungcc449f72015-08-12 10:46:27 -0700108 int sensorType = getSensorTypeFromHalProperty(property);
109 if (sensorType == SENSOR_TYPE_INVALD) {
110 throw new RuntimeException("handleBooleanHalEvent no sensor defined for property " +
111 property);
112 }
keunyoungcc449f72015-08-12 10:46:27 -0700113 switch (property) {
keunyoungfe30ba02015-09-17 17:56:35 -0700114 // boolean
115 case VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE:
116 case VehicleNetworkConsts.VEHICLE_PROPERTY_PARKING_BRAKE_ON: {
117 if (DBG_EVENTS) {
118 Log.i(CarLog.TAG_SENSOR, "boolean event, property:" +
119 Integer.toHexString(property) + " value:" + v.getInt32Value());
120 }
121 return CarSensorEventFactory.createBooleanEvent(sensorType, v.getTimestamp(),
122 v.getInt32Value() == 1);
123 }
124 // int
125 case VehicleNetworkConsts.VEHICLE_PROPERTY_GEAR_SELECTION:
126 case VehicleNetworkConsts.VEHICLE_PROPERTY_DRIVING_STATUS: {
127 if (DBG_EVENTS) {
128 Log.i(CarLog.TAG_SENSOR, "int event, property:" +
129 Integer.toHexString(property) + " value:" + v.getInt32Value());
130 }
131 return CarSensorEventFactory.createIntEvent(sensorType, v.getTimestamp(),
132 v.getInt32Value());
133 }
134 // float
135 case VehicleNetworkConsts.VEHICLE_PROPERTY_PERF_VEHICLE_SPEED: {
136 if (DBG_EVENTS) {
137 Log.i(CarLog.TAG_SENSOR, "float event, property:" +
138 Integer.toHexString(property) + " value:" + v.getFloatValue());
139 }
140 return CarSensorEventFactory.createFloatEvent(sensorType, v.getTimestamp(),
141 v.getFloatValue());
142 }
keunyoungcc449f72015-08-12 10:46:27 -0700143 }
keunyoungfe30ba02015-09-17 17:56:35 -0700144 return null;
keunyoungcc449f72015-08-12 10:46:27 -0700145 }
146
147 @Override
148 public synchronized void registerSensorListener(SensorHalServiceBase.SensorListener listener) {
149 mSensorListener = listener;
150 if (mIsReady) {
151 listener.onSensorHalReady(this);
152 }
153 }
154
155 @Override
156 public synchronized boolean isReady() {
157 return mIsReady;
158 }
159
160 @Override
161 public synchronized int[] getSupportedSensors() {
162 int[] supportedSensors = new int[mSensorToHalProperty.size()];
163 for (int i = 0; i < supportedSensors.length; i++) {
164 supportedSensors[i] = mSensorToHalProperty.keyAt(i);
165 }
166 return supportedSensors;
167 }
168
169 @Override
170 public synchronized boolean requestSensorStart(int sensorType, int rate) {
keunyoungfe30ba02015-09-17 17:56:35 -0700171 VehiclePropConfig config = mSensorToHalProperty.get(sensorType);
172 if (config == null) {
keunyoungcc449f72015-08-12 10:46:27 -0700173 return false;
174 }
175 //TODO calculate sampling rate properly
keunyoungfe30ba02015-09-17 17:56:35 -0700176 mHal.subscribeProperty(this, config, fixSamplingRateForProperty(config, rate));
177 return true;
keunyoungcc449f72015-08-12 10:46:27 -0700178 }
179
keunyoungfe30ba02015-09-17 17:56:35 -0700180 private float fixSamplingRateForProperty(VehiclePropConfig prop, int carSensorManagerRate) {
181 if (prop.getChangeMode() == VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_ON_CHANGE) {
keunyoungcc449f72015-08-12 10:46:27 -0700182 return 0;
183 }
184 float rate = 1.0f;
185 switch (carSensorManagerRate) {
186 case CarSensorManager.SENSOR_RATE_FASTEST:
187 case CarSensorManager.SENSOR_RATE_FAST:
188 rate = 10f;
189 break;
190 case CarSensorManager.SENSOR_RATE_UI:
191 rate = 5f;
192 break;
193 default: // fall back to default.
194 break;
195 }
keunyoungfe30ba02015-09-17 17:56:35 -0700196 if (rate > prop.getSampleRateMax()) {
197 rate = prop.getSampleRateMax();
keunyoungcc449f72015-08-12 10:46:27 -0700198 }
keunyoungfe30ba02015-09-17 17:56:35 -0700199 if (rate < prop.getSampleRateMin()) {
200 rate = prop.getSampleRateMin();
keunyoungcc449f72015-08-12 10:46:27 -0700201 }
202 return rate;
203 }
204
205 @Override
206 public synchronized void requestSensorStop(int sensorType) {
keunyoungfe30ba02015-09-17 17:56:35 -0700207 VehiclePropConfig config = mSensorToHalProperty.get(sensorType);
208 if (config == null) {
keunyoungcc449f72015-08-12 10:46:27 -0700209 return;
210 }
keunyoungfe30ba02015-09-17 17:56:35 -0700211 mHal.unsubscribeProperty(this, config);
keunyoungcc449f72015-08-12 10:46:27 -0700212 }
213
214 /**
215 * Covert hal property to sensor type. This is also used to check if specific property
216 * is supported by sensor hal or not.
217 * @param halPropertyType
218 * @return
219 */
220 static int getSensorTypeFromHalProperty(int halPropertyType) {
221 switch (halPropertyType) {
keunyoungfe30ba02015-09-17 17:56:35 -0700222 case VehicleNetworkConsts.VEHICLE_PROPERTY_PERF_VEHICLE_SPEED:
keunyoungcc449f72015-08-12 10:46:27 -0700223 return CarSensorManager.SENSOR_TYPE_CAR_SPEED;
keunyoungfe30ba02015-09-17 17:56:35 -0700224 case VehicleNetworkConsts.VEHICLE_PROPERTY_GEAR_SELECTION:
keunyoungcc449f72015-08-12 10:46:27 -0700225 return CarSensorManager.SENSOR_TYPE_GEAR;
keunyoungfe30ba02015-09-17 17:56:35 -0700226 case VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE:
keunyoungcc449f72015-08-12 10:46:27 -0700227 return CarSensorManager.SENSOR_TYPE_NIGHT;
keunyoungfe30ba02015-09-17 17:56:35 -0700228 case VehicleNetworkConsts.VEHICLE_PROPERTY_PARKING_BRAKE_ON:
keunyoungcc449f72015-08-12 10:46:27 -0700229 return CarSensorManager.SENSOR_TYPE_PARKING_BRAKE;
keunyoungfe30ba02015-09-17 17:56:35 -0700230 case VehicleNetworkConsts.VEHICLE_PROPERTY_DRIVING_STATUS:
keunyoungcc449f72015-08-12 10:46:27 -0700231 return CarSensorManager.SENSOR_TYPE_DRIVING_STATUS;
232 default:
233 Log.e(CarLog.TAG_SENSOR, "unknown sensor property from HAL " + halPropertyType);
234 return SENSOR_TYPE_INVALD;
235 }
236 }
237
238 @Override
239 public void dump(PrintWriter writer) {
keunyounga3b28d82015-08-25 13:05:15 -0700240 writer.println("*Sensor HAL*");
241 writer.println("**Supported properties**");
keunyoungcc449f72015-08-12 10:46:27 -0700242 for (int i = 0; i < mSensorToHalProperty.size(); i++) {
243 writer.println(mSensorToHalProperty.valueAt(i).toString());
244 }
245 }
246}