Categories
Android Automotive

Car data points in Android Automotive

When following the Android Automotive overview, it might seem that not much of the car info is available for developers. It is even stated that only media apps are allowed and there is no documentation about car properties.

Looking further into the car emulator and Android source code, it looks like more is on the table.

Emulator VHAL properties

Maybe the first thing to notice is that the car emulator has some data points available. For instance, door locks and seat positions:

Data points in the emulator

From this we could assume that these properties are also readable/settable. Let’s look at the android.car package in 10.0.0_r40 branch. This is the recommended branch when using a phone as an Automotive Development Platform.

Car properties

All of the car properties are defined in VehiclePropertyIds file. They can be read with CarPropertyManager. However, when trying to read the car VIN,

String vin = propertyManager.getProperty<String>(INFO_VIN, VEHICLE_AREA_TYPE_GLOBAL)?.value 

a SecurityException is thrown. This means the app needs to request user permission to access this data.

Permissions

There are 3 files that should be used to combine the property with the permission:

/**
* Door lock
* Requires permission: {@link Car#PERMISSION_CONTROL_CAR_DOORS}.
*/
public static final int DOOR_LOCK = 371198722;
  • Car.java defines this permission as a string
/**
* Permission necessary to control car's door.
* @hide
*/
@SystemApi
public static final String PERMISSION_CONTROL_CAR_DOORS = "android.car.permission.CONTROL_CAR_DOORS";
<!-- Allows an application to control the vehicle doors.
    <p>Protection level: signature|privileged
-->
<permission
android:name="android.car.permission.CONTROL_CAR_DOORS"
android:protectionLevel="signature|privileged". android:label="@string/car_permission_label_control_car_doors" android:description="@string/car_permission_desc_control_car_doors" />

The name of this permission should be used to ask for the user consent via app’s AndroidManifest:

<uses-permission android:name="android.car.permission.CONTROL_CAR_DOORS"/>

However, when asking for this permission, it doesn’t show any dialog and reading the car doors value will fail.

Permission types

When looking at the Doors permission, it’s protectionLevel is set to

android:protectionLevel="signature|privileged"

This means that this property is available for system apps only.

There are 3 types of Car permissions:

  • normal – permission granted by default.
  • dangerous – user is asked for the permission.
  • signature|privileged – Only system apps have access to these properties.

From this it can be concluded that only normal and dangerous level properties could be accessible for developers.

⭐️ To disguise yourself as a system app and access the signature|privileged properties, one can sign her application with build keys. Be sure to use the same build or build the emulator from the branch where keys are located.

Car system service

All car-related services are encompassed in the Car System Service. This service can be accessed via adb and then properties can be queried or set via dumpsys:

# 16200B02 is hex value of door lock property 371198722
adb shell dumpsys car_service get-property-value 16200B02  1

Use adb shell dumpsys car_service -h to get more info about available commands.

List of properties and their permissions

Navigating between the 3 files that contain car properties and their permissions can be difficult. To help with that, here is a list of these items merged together from the 10.0.0_r40 branch:

INFO_MAKE : [normal]
INFO_MODEL : [normal]
INFO_MODEL_YEAR : [normal]
INFO_FUEL_CAPACITY : [normal]
INFO_FUEL_TYPE : [normal]
INFO_EV_BATTERY_CAPACITY : [normal]
INFO_EV_CONNECTOR_TYPE : [normal]
INFO_FUEL_DOOR_LOCATION : [normal]
INFO_EV_PORT_LOCATION : [normal]
INFO_DRIVER_SEAT : [normal]
FUEL_DOOR_OPEN : [normal]
EV_CHARGE_PORT_OPEN : [normal]
EV_CHARGE_PORT_CONNECTED : [normal]
GEAR_SELECTION : [normal]
CURRENT_GEAR : [normal]
PARKING_BRAKE_ON : [normal]
PARKING_BRAKE_AUTO_APPLY : [normal]
NIGHT_MODE : [normal]
IGNITION_STATE : [normal]
DISTANCE_DISPLAY_UNITS : [normal, normal, signaturePrivileged]
FUEL_VOLUME_DISPLAY_UNITS : [normal, normal, signaturePrivileged]
TIRE_PRESSURE_DISPLAY_UNITS : [normal, normal, signaturePrivileged]
EV_BATTERY_DISPLAY_UNITS : [normal, normal, signaturePrivileged]
VEHICLE_SPEED_DISPLAY_UNITS : [normal, normal, signaturePrivileged]
FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME : [normal, normal, signaturePrivileged]
ENV_OUTSIDE_TEMPERATURE : [normal]
PERF_VEHICLE_SPEED : [dangerous]
PERF_VEHICLE_SPEED_DISPLAY : [dangerous]
WHEEL_TICK : [dangerous]
FUEL_LEVEL : [dangerous]
EV_BATTERY_LEVEL : [dangerous]
EV_BATTERY_INSTANTANEOUS_CHARGE_RATE : [dangerous]
RANGE_REMAINING : [dangerous]
FUEL_LEVEL_LOW : [dangerous]
INFO_VIN : [signaturePrivileged]
PERF_ODOMETER : [signaturePrivileged]
PERF_STEERING_ANGLE : [signaturePrivileged]
ENGINE_COOLANT_TEMP : [signaturePrivileged]
ENGINE_OIL_LEVEL : [signaturePrivileged]
ENGINE_OIL_TEMP : [signaturePrivileged]
ENGINE_RPM : [signaturePrivileged]
TIRE_PRESSURE : [signaturePrivileged]
TURN_SIGNAL_STATE : [signaturePrivileged]
ABS_ACTIVE : [signaturePrivileged]
TRACTION_CONTROL_ACTIVE : [signaturePrivileged]
HVAC_FAN_SPEED : [signaturePrivileged]
HVAC_FAN_DIRECTION : [signaturePrivileged]
HVAC_TEMPERATURE_CURRENT : [signaturePrivileged]
HVAC_TEMPERATURE_SET : [signaturePrivileged]
HVAC_DEFROSTER : [signaturePrivileged]
HVAC_AC_ON : [signaturePrivileged]
HVAC_MAX_AC_ON : [signaturePrivileged]
HVAC_MAX_DEFROST_ON : [signaturePrivileged]
HVAC_RECIRC_ON : [signaturePrivileged]
HVAC_DUAL_ON : [signaturePrivileged]
HVAC_AUTO_ON : [signaturePrivileged]
HVAC_SEAT_TEMPERATURE : [signaturePrivileged]
HVAC_SIDE_MIRROR_HEAT : [signaturePrivileged]
HVAC_STEERING_WHEEL_HEAT : [signaturePrivileged]
HVAC_TEMPERATURE_DISPLAY_UNITS : [signaturePrivileged]
HVAC_ACTUAL_FAN_SPEED_RPM : [signaturePrivileged]
HVAC_POWER_ON : [signaturePrivileged]
HVAC_FAN_DIRECTION_AVAILABLE : [signaturePrivileged]
HVAC_AUTO_RECIRC_ON : [signaturePrivileged]
HVAC_SEAT_VENTILATION : [signaturePrivileged]
AP_POWER_STATE_REQ : [signaturePrivileged]
AP_POWER_STATE_REPORT : [signaturePrivileged]
AP_POWER_BOOTUP_REASON : [signaturePrivileged]
DISPLAY_BRIGHTNESS : [signaturePrivileged]
DOOR_POS : [signaturePrivileged]
DOOR_MOVE : [signaturePrivileged]
DOOR_LOCK : [signaturePrivileged]
MIRROR_Z_POS : [signaturePrivileged]
MIRROR_Z_MOVE : [signaturePrivileged]
MIRROR_Y_POS : [signaturePrivileged]
MIRROR_Y_MOVE : [signaturePrivileged]
MIRROR_LOCK : [signaturePrivileged]
MIRROR_FOLD : [signaturePrivileged]
SEAT_MEMORY_SELECT : [signaturePrivileged]
SEAT_MEMORY_SET : [signaturePrivileged]
SEAT_BELT_BUCKLED : [signaturePrivileged]
SEAT_BELT_HEIGHT_POS : [signaturePrivileged]
SEAT_BELT_HEIGHT_MOVE : [signaturePrivileged]
SEAT_FORE_AFT_POS : [signaturePrivileged]
SEAT_FORE_AFT_MOVE : [signaturePrivileged]
SEAT_BACKREST_ANGLE_1_POS : [signaturePrivileged]
SEAT_BACKREST_ANGLE_1_MOVE : [signaturePrivileged]
SEAT_BACKREST_ANGLE_2_POS : [signaturePrivileged]
SEAT_BACKREST_ANGLE_2_MOVE : [signaturePrivileged]
SEAT_HEIGHT_POS : [signaturePrivileged]
SEAT_HEIGHT_MOVE : [signaturePrivileged]
SEAT_DEPTH_POS : [signaturePrivileged]
SEAT_DEPTH_MOVE : [signaturePrivileged]
SEAT_TILT_POS : [signaturePrivileged]
SEAT_TILT_MOVE : [signaturePrivileged]
SEAT_LUMBAR_FORE_AFT_POS : [signaturePrivileged]
SEAT_LUMBAR_FORE_AFT_MOVE : [signaturePrivileged]
SEAT_LUMBAR_SIDE_SUPPORT_POS : [signaturePrivileged]
SEAT_LUMBAR_SIDE_SUPPORT_MOVE : [signaturePrivileged]
SEAT_HEADREST_HEIGHT_POS : [signaturePrivileged]
SEAT_HEADREST_HEIGHT_MOVE : [signaturePrivileged]
SEAT_HEADREST_ANGLE_POS : [signaturePrivileged]
SEAT_HEADREST_ANGLE_MOVE : [signaturePrivileged]
SEAT_HEADREST_FORE_AFT_POS : [signaturePrivileged]
SEAT_HEADREST_FORE_AFT_MOVE : [signaturePrivileged]
SEAT_OCCUPANCY : [signaturePrivileged]
WINDOW_POS : [signaturePrivileged]
WINDOW_MOVE : [signaturePrivileged]
WINDOW_LOCK : [signaturePrivileged]
VEHICLE_MAP_SERVICE : [signaturePrivileged, signaturePrivileged]
OBD2_LIVE_FRAME : [signaturePrivileged]
OBD2_FREEZE_FRAME : [signaturePrivileged]
OBD2_FREEZE_FRAME_INFO : [signaturePrivileged]
OBD2_FREEZE_FRAME_CLEAR : [signaturePrivileged]
HEADLIGHTS_STATE : [signaturePrivileged]
HIGH_BEAM_LIGHTS_STATE : [signaturePrivileged]
FOG_LIGHTS_STATE : [signaturePrivileged]
HAZARD_LIGHTS_STATE : [signaturePrivileged]
HEADLIGHTS_SWITCH : [signaturePrivileged]
HIGH_BEAM_LIGHTS_SWITCH : [signaturePrivileged]
FOG_LIGHTS_SWITCH : [signaturePrivileged]
HAZARD_LIGHTS_SWITCH : [signaturePrivileged]
CABIN_LIGHTS_STATE : [signaturePrivileged]
CABIN_LIGHTS_SWITCH : [signaturePrivileged]
READING_LIGHTS_STATE : [signaturePrivileged]
READING_LIGHTS_SWITCH : [signaturePrivileged]

Conclusion

Only when looking at the Android Automotive source code, it comes obvious that different car data points can be available.

Developers need to keep in mind that most of it is for car manufacturers only. Of the public information, some could be available by default, and some with user permission.