1 /* 2 * Copyright (C) 2018 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 android.car.cluster.sensors; 17 18 import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL; 19 20 import android.car.VehiclePropertyIds; 21 import android.car.VehiclePropertyType; 22 import android.car.hardware.CarPropertyValue; 23 import android.car.hardware.CarSensorEvent; 24 25 import java.util.ArrayList; 26 import java.util.HashMap; 27 import java.util.List; 28 import java.util.Map; 29 import java.util.Set; 30 import java.util.function.Function; 31 32 /** 33 * The collection of all sensors supported by this application. 34 */ 35 public class Sensors { 36 private static Sensors sInstance; 37 private static List<Sensor<?>> sSensors = new ArrayList<>(); 38 private Map<Integer, List<Sensor<?>>> mSensorsByPropertyId = new HashMap<>(); 39 40 /** Possible values of the {@link #SENSOR_GEAR} sensor */ 41 public enum Gear { 42 NEUTRAL, 43 REVERSE, 44 DRIVE, 45 PARK, 46 } 47 48 /** Fuel of the car, measured in millimeters */ 49 public static final Sensor<Float> SENSOR_FUEL = registerSensor( 50 "Fuel", VehiclePropertyIds.FUEL_LEVEL, VEHICLE_AREA_TYPE_GLOBAL, 51 VehiclePropertyType.FLOAT, 52 value -> (Float) value.getValue()); 53 /** Fuel capacity of the car, measured in millimeters */ 54 public static final Sensor<Float> SENSOR_FUEL_CAPACITY = registerSensor( 55 "Fuel Capacity", VehiclePropertyIds.INFO_FUEL_CAPACITY, VEHICLE_AREA_TYPE_GLOBAL, 56 VehiclePropertyType.FLOAT, 57 value -> (Float) value.getValue()); 58 /** RPMs */ 59 public static final Sensor<Float> SENSOR_RPM = registerSensor( 60 "RPM", VehiclePropertyIds.ENGINE_RPM, VEHICLE_AREA_TYPE_GLOBAL, 61 VehiclePropertyType.FLOAT, 62 value -> (Float) value.getValue()); 63 /** Fuel range in meters */ 64 public static final Sensor<Float> SENSOR_FUEL_RANGE = registerSensor( 65 "Fuel Range", VehiclePropertyIds.RANGE_REMAINING, VEHICLE_AREA_TYPE_GLOBAL, 66 VehiclePropertyType.FLOAT, 67 value -> (Float) value.getValue()); 68 /** Speed in meters per second */ 69 public static final Sensor<Float> SENSOR_SPEED = registerSensor( 70 "Speed", VehiclePropertyIds.PERF_VEHICLE_SPEED, VEHICLE_AREA_TYPE_GLOBAL, 71 VehiclePropertyType.FLOAT, 72 value -> (Float) value.getValue()); 73 /** Current gear of the car */ 74 public static final Sensor<Gear> SENSOR_GEAR = registerSensor( 75 "Gear", VehiclePropertyIds.GEAR_SELECTION, VEHICLE_AREA_TYPE_GLOBAL, 76 VehiclePropertyType.INT32, 77 value -> { 78 Integer gear = (Integer) value.getValue(); 79 if ((gear & CarSensorEvent.GEAR_REVERSE) != 0) { 80 return Gear.REVERSE; 81 } else if ((gear & CarSensorEvent.GEAR_NEUTRAL) != 0) { 82 return Gear.NEUTRAL; 83 } else if ((gear & CarSensorEvent.GEAR_DRIVE) != 0) { 84 return Gear.DRIVE; 85 } else if ((gear & CarSensorEvent.GEAR_PARK) != 0) { 86 return Gear.PARK; 87 } else { 88 return null; 89 } 90 }); 91 registerSensor(String propertyName, int propertyId, int areaId, int expectedPropertyType, Function<CarPropertyValue<?>, T> adapter)92 private static <T> Sensor<T> registerSensor(String propertyName, int propertyId, int areaId, 93 int expectedPropertyType, Function<CarPropertyValue<?>, T> adapter) { 94 Sensor<T> sensor = new Sensor<>(propertyName, propertyId, areaId, expectedPropertyType, 95 adapter); 96 sSensors.add(sensor); 97 return sensor; 98 } 99 100 /** 101 * Obtains the singleton instance of this class 102 */ getInstance()103 public static Sensors getInstance() { 104 if (sInstance == null) { 105 sInstance = new Sensors(); 106 } 107 return sInstance; 108 } 109 Sensors()110 private Sensors() { 111 initializeSensorsMap(); 112 } 113 initializeSensorsMap()114 private void initializeSensorsMap() { 115 for (Sensor<?> sensorId : getSensors()) { 116 mSensorsByPropertyId 117 .computeIfAbsent(sensorId.mPropertyId, (id) -> new ArrayList<>()) 118 .add(sensorId); 119 } 120 } 121 122 /** 123 * Returns all sensors. 124 */ getSensors()125 public List<Sensor<?>> getSensors() { 126 return sSensors; 127 } 128 129 /** 130 * Returns all sensors associated to the given VHAL property id. 131 */ getSensorsForPropertyId(int propertyId)132 public List<Sensor<?>> getSensorsForPropertyId(int propertyId) { 133 return mSensorsByPropertyId.get(propertyId); 134 } 135 136 /** 137 * Returns all property ids we care about. 138 */ getPropertyIds()139 public Set<Integer> getPropertyIds() { 140 return mSensorsByPropertyId.keySet(); 141 } 142 } 143