1 /* 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 17 package android.car; 18 19 import android.annotation.NonNull; 20 import android.car.annotation.ValueTypeDef; 21 import android.car.hardware.CarPropertyValue; 22 import android.car.hardware.property.CarPropertyManager; 23 import android.car.hardware.property.ICarProperty; 24 import android.os.Bundle; 25 import android.os.IBinder; 26 import android.util.Slog; 27 28 import java.util.Arrays; 29 30 31 /** 32 * Utility to retrieve various static information from car. Each data are grouped as {@link Bundle} 33 * and relevant data can be checked from {@link Bundle} using pre-specified keys. 34 */ 35 public final class CarInfoManager extends CarManagerBase { 36 37 private static final String TAG = CarInfoManager.class.getSimpleName(); 38 39 private final CarPropertyManager mCarPropertyMgr; 40 /** 41 * Key for manufacturer of the car. Passed in basic info Bundle. 42 * @hide 43 */ 44 @ValueTypeDef(type = Integer.class) 45 public static final int BASIC_INFO_KEY_MANUFACTURER = 0x11100101; 46 /** 47 * Key for model name of the car. This information may not necessarily allow distinguishing 48 * different car models as the same name may be used for different cars depending on 49 * manufacturers. Passed in basic info Bundle. 50 * @hide 51 */ 52 @ValueTypeDef(type = Integer.class) 53 public static final int BASIC_INFO_KEY_MODEL = 0x11100102; 54 /** 55 * Key for model year of the car in AD. Passed in basic info Bundle. 56 * @hide 57 */ 58 @ValueTypeDef(type = Integer.class) 59 public static final int BASIC_INFO_KEY_MODEL_YEAR = 0x11400103; 60 /** 61 * Key for unique identifier for the car. This is not VIN, and id is persistent until user 62 * resets it. Passed in basic info Bundle. 63 * @hide 64 */ 65 @ValueTypeDef(type = String.class) 66 public static final String BASIC_INFO_KEY_VEHICLE_ID = "android.car.vehicle-id"; 67 /** 68 * Key for product configuration info. 69 * @hide 70 */ 71 @ValueTypeDef(type = String.class) 72 public static final String INFO_KEY_PRODUCT_CONFIGURATION = "android.car.product-config"; 73 /** 74 * Key for driver seat of the car. 75 * @hide 76 */ 77 @ValueTypeDef(type = Integer.class) 78 public static final int BASIC_INFO_DRIVER_SEAT = 0x1540010a; 79 /** 80 * Key for EV port location of vehicle. 81 * @hide 82 */ 83 @ValueTypeDef(type = Integer.class) 84 public static final int BASIC_INFO_EV_PORT_LOCATION = 0x11400109; 85 /** 86 * Key for fuel door location of vehicle. 87 * @hide 88 */ 89 @ValueTypeDef(type = Integer.class) 90 public static final int BASIC_INFO_FUEL_DOOR_LOCATION = 0x11400108; 91 /** 92 * Key for Fuel Capacity in milliliters. Passed in basic info Bundle. 93 * @hide 94 */ 95 @ValueTypeDef(type = Integer.class) 96 public static final int BASIC_INFO_FUEL_CAPACITY = 0x11600104; 97 /** 98 * Key for Fuel Types. This is an array of fuel types the vehicle supports. 99 * Passed in basic info Bundle. 100 * @hide 101 */ 102 @ValueTypeDef(type = Integer.class) 103 public static final int BASIC_INFO_FUEL_TYPES = 0x11410105; 104 /** 105 * Key for EV Battery Capacity in WH. Passed in basic info Bundle. 106 * @hide 107 */ 108 @ValueTypeDef(type = Integer.class) 109 public static final int BASIC_INFO_EV_BATTERY_CAPACITY = 0x11600106; 110 /** 111 * Key for EV Connector Types. This is an array of connector types the vehicle supports. 112 * Passed in basic info Bundle. 113 * @hide 114 */ 115 @ValueTypeDef(type = Integer[].class) 116 public static final int BASIC_INFO_EV_CONNECTOR_TYPES = 0x11410107; 117 118 /** 119 * @return Manufacturer of the car. Empty if not available. 120 */ 121 @NonNull getManufacturer()122 public String getManufacturer() { 123 return getPropertyWithDefaultValue(String.class, BASIC_INFO_KEY_MANUFACTURER, ""); 124 } 125 126 /** 127 * @return Model name of the car, empty if not available. This information 128 * may not necessarily allow distinguishing different car models as the same 129 * name may be used for different cars depending on manufacturers. 130 */ 131 @NonNull getModel()132 public String getModel() { 133 return getPropertyWithDefaultValue(String.class, BASIC_INFO_KEY_MODEL, ""); 134 } 135 136 /** 137 * @return Model year of the car in AD. Empty if not available. 138 * @deprecated Use {@link #getModelYearInInteger()} instead. 139 */ 140 @Deprecated 141 @NonNull getModelYear()142 public String getModelYear() { 143 int year = getModelYearInInteger(); 144 return year == 0 ? "" : Integer.toString(year); 145 } 146 147 /** 148 * @return Model year of the car in AD. 0 if not available. 149 */ getModelYearInInteger()150 public int getModelYearInInteger() { 151 return getPropertyWithDefaultValue(Integer.class, BASIC_INFO_KEY_MODEL_YEAR, 0); 152 } 153 154 /** 155 * @return always return empty string. 156 * @deprecated no support for car's identifier 157 */ 158 @Deprecated getVehicleId()159 public String getVehicleId() { 160 return ""; 161 } 162 163 /** 164 * @return Fuel capacity of the car in milliliters. 0 if car doesn't run on 165 * fuel. 166 */ getFuelCapacity()167 public float getFuelCapacity() { 168 return getPropertyWithDefaultValue(Float.class, BASIC_INFO_FUEL_CAPACITY, 0f); 169 } 170 171 /** 172 * @return Array of FUEL_TYPEs available in the car. Empty array if no fuel 173 * types available. 174 */ getFuelTypes()175 public @FuelType.Enum int[] getFuelTypes() { 176 Integer[] fuels = getPropertyWithDefaultValue(Integer[].class, BASIC_INFO_FUEL_TYPES, 177 new Integer[]{}); 178 return Arrays.stream(fuels).mapToInt(Integer::intValue).toArray(); 179 } 180 181 /** 182 * 183 * @return Battery capacity of the car in Watt-Hour(Wh). Return 0 if car doesn't run on battery. 184 */ getEvBatteryCapacity()185 public float getEvBatteryCapacity() { 186 return getPropertyWithDefaultValue(Float.class, BASIC_INFO_EV_BATTERY_CAPACITY, 0f); 187 } 188 189 /** 190 * @return Array of EV_CONNECTOR_TYPEs available in the car. Empty array if 191 * no connector types available. 192 */ getEvConnectorTypes()193 public @EvConnectorType.Enum int[] getEvConnectorTypes() { 194 Integer[] valueInHal = getPropertyWithDefaultValue(Integer[].class, 195 BASIC_INFO_EV_CONNECTOR_TYPES, new Integer[]{}); 196 197 int[] connectorTypes = new int[valueInHal.length]; 198 for (int i = 0; i < valueInHal.length; i++) { 199 switch (valueInHal[i]) { 200 case 1: // IEC_TYPE_1_AC 201 connectorTypes[i] = EvConnectorType.J1772; 202 break; 203 case 2: // IEC_TYPE_2_AC 204 connectorTypes[i] = EvConnectorType.MENNEKES; 205 break; 206 case 3: // IEC_TYPE_3_AC 207 connectorTypes[i] = EvConnectorType.SCAME; 208 break; 209 case 4: // IEC_TYPE_4_DC 210 connectorTypes[i] = EvConnectorType.CHADEMO; 211 break; 212 case 5: // IEC_TYPE_1_CCS_DC 213 connectorTypes[i] = EvConnectorType.COMBO_1; 214 break; 215 case 6: // IEC_TYPE_2_CCS_DC 216 connectorTypes[i] = EvConnectorType.COMBO_2; 217 break; 218 case 7: // TESLA_ROADSTER 219 connectorTypes[i] = EvConnectorType.TESLA_ROADSTER; 220 break; 221 case 8: // TESLA_HPWC 222 connectorTypes[i] = EvConnectorType.TESLA_HPWC; 223 break; 224 case 9: // TESLA_SUPERCHARGER 225 connectorTypes[i] = EvConnectorType.TESLA_SUPERCHARGER; 226 break; 227 case 10: // GBT_AC 228 connectorTypes[i] = EvConnectorType.GBT; 229 break; 230 case 11: // GBT_DC 231 connectorTypes[i] = EvConnectorType.GBT_DC; 232 break; 233 case 101: // OTHER 234 connectorTypes[i] = EvConnectorType.OTHER; 235 break; 236 default: 237 connectorTypes[i] = EvConnectorType.UNKNOWN; 238 } 239 } 240 return connectorTypes; 241 } 242 243 /** 244 * @return Driver seat's location. Returns {@link VehicleAreaSeat#SEAT_UNKNOWN} if the sensor 245 * is not available. 246 */ getDriverSeat()247 public @VehicleAreaSeat.Enum int getDriverSeat() { 248 return getPropertyWithDefaultValue(Integer.class, BASIC_INFO_DRIVER_SEAT, 249 VehicleAreaSeat.SEAT_UNKNOWN); 250 } 251 252 /** 253 * @return EV port location of the car. Returns {@link PortLocationType#UNKNOWN} if the sensor 254 * is not available. 255 */ getEvPortLocation()256 public @PortLocationType.Enum int getEvPortLocation() { 257 return getPropertyWithDefaultValue(Integer.class, BASIC_INFO_EV_PORT_LOCATION, 258 PortLocationType.UNKNOWN); 259 } 260 261 /** 262 * @return Fuel door location of the car.Returns {@link PortLocationType#UNKNOWN} if the sensor 263 * is not available. 264 */ getFuelDoorLocation()265 public @PortLocationType.Enum int getFuelDoorLocation() { 266 return getPropertyWithDefaultValue(Integer.class, BASIC_INFO_FUEL_DOOR_LOCATION, 267 PortLocationType.UNKNOWN); 268 } 269 getPropertyWithDefaultValue(Class<T> clazz, int propId, T defaultValue)270 private <T> T getPropertyWithDefaultValue(Class<T> clazz, int propId, T defaultValue) { 271 try { 272 CarPropertyValue<T> carProp = mCarPropertyMgr.getProperty( 273 clazz, propId, 0); 274 if (carProp != null && carProp.getStatus() == CarPropertyValue.STATUS_AVAILABLE) { 275 return carProp.getValue(); 276 } 277 } catch (Exception e) { 278 Slog.e(TAG, "Failed to get property value for 0x:" + Integer.toHexString(propId) 279 + " ,returns default value" + defaultValue); 280 } 281 return defaultValue; 282 } 283 284 /** @hide */ CarInfoManager(Car car, IBinder service)285 public CarInfoManager(Car car, IBinder service) { 286 super(car); 287 ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service); 288 mCarPropertyMgr = new CarPropertyManager(car, mCarPropertyService); 289 } 290 291 /** @hide */ onCarDisconnected()292 public void onCarDisconnected() { 293 mCarPropertyMgr.onCarDisconnected(); 294 } 295 } 296