Android Automotive (AAE) P introduces a new state – deep sleep – into the AAE P power management state machine. To implement this state, AAE P provides a new power management service and interface: CarPowerManagementService and CarPowerManager.

State transitions are triggered by the Vehicle MCU (VMCU). To enable AAE to communicate with the VMCU, integrators must implement several components. Integrators are responsible for integrating with the VHAL and the kernel implementation. Integrators are also responsible for disabling wake sources and ensuring that shutdowns are not postponed indefinitely.

Terminology

These terms are used throughout this document:

Term Description
Application Processor (AP) Part of the System on Chip (SoC).
Board Support Processor (BSP) All of the chip and hardware specific code necessary for the product to work. Typically provided by the SoC vendor and hardware manufacturer. This covers items such as device drivers, the PMIC sequencing code, and SoC bringup.
CarPowerManager (CPM) Exposes an API for applications to register for power state changes.
CarPowerManagementService (CPMS) Implements the car power state machine, interfaces with VHAL, and performs the final calls to suspend() and shutdown().
CarServiceHelperService (CSHS) Provides a hook into SystemServer for OK, provided that is the Car Service.
General Purpose Input / Output (GPIO) A digital signal pin for general purpose use.
Hibernate AKA Suspend to Disk (S2D/S4). The SoC is placed into S4 power mode (hibernate) and RAM content is written to non-volatile media (such as flash or disk) and the entire system is powered off. Android does not currently implement hibernate.
Media Processor (MP) See System on Chip (SoC).
Power Management Integrated Circuit (PMIC) Chip used to manage power requirements for the host system.
System on a Chip (SoC) Main processor that runs Android, typically supplied by manufacturers such as Intel, Mediatek, Nvidia, Qualcomm, Renesas, and Texas Instruments.
Suspend AKA Suspend to RAM (S2R or STR). The SoC is placed into S3 power mode and the CPU is powered off while RAM remains powered on.
Vehicle HAL (VHAL) The Android API used to interface with the vehicle network. The Tier 1 partner or OEM is responsible for writing this module. The vehicle network can use any physical layer (such as CAN, LIN, MOST, and Ethernet). The VHAL abstracts this vehicle network to enable Android to interact with the vehicle.
Vehicle Interface Processor (VIP) See Vehicle MCU.
Vehicle MCU (VMCU) The microcontroller that provides the interface between the vehicle network and the SoC. The SoC communicates with the VMCU via USB, UART, SPI, and GPIO signals.

System design

This section describes how AAE represents the application processor's power state and which modules implement the power management system. This material also describes how these modules work together and how state transitions typically occur.

Car power state machine

AAE uses a state machine to represent the power state of the AP. This state machine provides these five states, as illustrated below:

Figure 1. Car power state machine

The initial state of this state machine is OFF. This state can transition into two states, ON:DISP OFF and ON: FULL. Both states indicate the AP is on. The difference lies in the display's power state. ON: DISP OFF means that the AP is running and displays are turned off. When display turns on, the ON: DISP OFF state transitions into ON:FULL (and vice versa).

The AP is turned off in two cases. In both cases, the state machine first changes state to SHUTDOWN PREPARE and then transitions to OFF or DEEP SLEEP:

When this power management state machine enters the DEEP SLEEP state, the AP runs Suspend to RAM. For example, the AP suspends its state (such as register stored value) in RAM. When the AP wakes up, all states are restored.

Power management modules

These five modules comprise the power management system:

Module name Description
CarPowerManager Java/C++ API
CarPowerManagementService Responsible for coordinating the sleep/suspend power state
Vehicle HAL Interface to VMCU
libsuspend Native library to place the device into suspend
Kernel Suspend to RAM implementation

The deep sleep feature (suspending Android to RAM) is implemented in the kernel. This feature is exposed to the user space as a special file located at /sys/power/state. AAE is suspended by writing mem to this file.

libsuspend is a native library that implements forcesuspend(). This function uses /sys/power/state to suspend AAE. forcesuspend() can be called from system services, including CPMS.

The CPMS coordinates the power state with other services and HALs. The CPMS implements the state machine described above and sends notifications to every observer when a power state transition occurs. This service also uses libsuspend and the VHAL to send messages to the hardware.

Some properties are defined in the VHAL. To communicate with the VMCU, the CPMS reads and writes these properties. Applications can use the interface defined in the CPM to monitor power state changes. This interface also enables applications to acquire the boot reason and to send shutdown requests. This API can be called from Java and C++ and are annotated with @hide / @System API, which means it is available to privileged applications only. The relationship between these five modules, applications, and services is illustrated below:

Figure 2. Power components reference diagram

Typical message sequence

The previous section described the modules that comprise the power management system. This section uses the following two examples to explain how the modules and applications communicate:

Enter deep sleep

Only the VMCU can initiate deep sleep. Once deep sleep is initiated, the VMCU sends a notification to the CPMS via the VHAL. The CPMS changes the state to SHUTDOWN PREPARE and broadcasts this state transition to all observers (the applications and services that monitor CPMS) by calling the onStateChanged() method with a new state ID provided by the CPM.

The CPM mediates between the applications/services and the CPMS. The onStateChanged() method for the applications/services is synchronously invoked in the CPM's onStateChanged() method. After which, the finished method of the CPMS is invoked to notify the CPMS that the target application or service is ready to suspend. The CPM's onStateChanged() method runs asynchronously. Therefore, some delay occurs between the calling of the onStateChanged() method to all CPM objects and the receiving of the finished message from all these objects. During this time, the CPMS continues to send shutdown postpone requests to the VHAL.

Once the CPMS receives the finished message from all CPM objects, the CPMS sends AP_POWER_STATE_REPORT to the VHAL, which then notifies the VMCU that the AP is ready to suspend. The CPMS also calls its suspend method, which suspends the kernel with a feature provided by libsuspend.

The entire sequence described above is illustrated in the following sequence diagram:

Figure 3. Enter deep sleep sequence diagram

Exit deep sleep

The sequence to exit suspend is also initiated by the VMCU. The VMCU turns on the AP and the AP restores the suspended Android from RAM. The CPMS uses onStateChangedmethod to send a SUSPEND_EXIT message to applications and services when it wakes up.

To access the reason, applications and services can call the getBootReason() method provided by the CPM. This method returns these values, as notified from the VMCU to the VHAL:

Figure 4. Exit deep sleep sequence diagram

Programming interfaces provided by CPM

This section describes the Java and C++ API provided by the CPM for system applications and services. The process to call the CPM in C++ is identical to that used by the Java API. This API enables the system software to:

PowerTestFragment.java in com.google.android.car.kitchensink.power illustrates how to use these APIs in Java. Use these steps to call the APIs provided by the CPM:

  1. To acquire the CPM instance, call the Car API.
  2. Call the appropriate method on the object created in Step 1.

Creating a CarPowerManager object

To create a CPM object, call the Car object's getCarManager() method. This method is a facade used to create CM objects. Specify android.car.Car.POWER_SERVICE as an argument to create a CPM object.

Car car = Car.createCar(this, carCallbacks);
car.connect();
CarPowerManager powerManager =
  (CarPowerManager)car.getCarManager(android.car.Car.POWER_SERVICE);

CarPowerStateListener and registration

System applications and services can receive power state change notifications by implementing CarPowerManager.CarPowerStateListener. This interface defines one method onStateChanged(), which is a callback function invoked when the power state of CPMS is changed. The following example defines a new anonymous class that implements the interface:

private final CarPowerManager.CarPowerStateListener listener =
  new CarPowerManager.CarPowerStateListener () {
    @Override
     public void onStateChanged(int state) {
       Log.i(TAG, "onStateChanged() state = " + state);
     }
};

To instruct this listener object to monitor a power state transition, create a new execution thread and register the listener and this thread to the PM object:

executer = new ThreadPerTaskExecuter();
powerManager.setListener(powerListener, executer);

When the power state is changed, the onStateChanged() method of the listener object is invoked with a value to represent the new power state. The association between actual value and power state is defined in CarPowerManager.CarPowerStateListener and is shown in the following table:

Name Description
SHUTDOWN_CANCELED Shutdown is canceled and power state is returned to the normal state.
SHUTDOWN_ENTER Enter the shutdown state. Applications are expected to clean up and be ready to shutdown.
SUSPEND_ENTER Enter the suspend state. Applications are expected to clean up and be ready to suspend.
SUSPEND_EXIT Wake up from suspend or resume from a cancelled suspend.

CarPowerStateListener unregistration

To unregister all listener objects registered to CPM, call the clearListener method:

powerManager.clearListener();

Boot reason acquisition

To acquire the boot reason, call the getBootReason method, which communicates with the CPMS and returns one of the following five boot reasons:

Name Description
BOOT_REASON_USER_POWER_ON A user presses the power key or rotates the ignition switch to boot the device.
BOOT_REASON_DOOR_UNLOCK Door unlocks, which causes the device to boot.
BOOT_REASON_TIMER Timer expires and vehicle wakes up the AP.
BOOT_REASON_DOOR_OPEN Door opens, which causes the device to boot.
BOOT_REASON_REMOTE_START User activates remote start.

These boot reasons are defined in the CPM. The following sample code demonstrates boot reason acquisition:

try{
  int bootReason = carPowerManager.getBootReason();
  if (bootReason == CarPowerManager.BOOT_REASON_TIMER){
    doSomething;
  }else{
    doSomethingElse();
  }
}catch(CarNotConnectedException e){
   Log.e("Failed to getBootReason()" + e);
}

This method throws a CarNotConnectedException when it fails to communicate with the CPMS.

Shutdown request on next suspend

The requestShutdownOnNextSuspend()method instructs CPMS to shut down instead of deep sleep at the next opportunity.

System integration on your Android implementation

Integrators are responsible for implementing the following items:

Kernel interface: /sys/power/state

First, implement the Linux suspend power state. Android places a device into suspend mode when an application or service writes mem into a file located at /sys/power/state. This function may include the sending of a GPIO to the VMCU to notify the VMCU that the device has shut down completely. The Integrator is also responsible for removing any race conditions between VHAL sending the final message to the VMCU and the system going into suspend or shutdown mode.

VHAL responsibility

The VHAL provides an interface between the vehicle network and Android. The VHAL:

When the CPMS informs the VHAL that it is ready to shut down, the VHAL sends the shutdown ready message to the VMCU. Typically, on-chip peripherals such as UART, SPI, and USB transmit the message. Once the message has been sent, the VHAL calls the kernel command to suspend or shutdown the device. Before doing so, in the case of a shutdown, the VHAL or BSP may toggle a GPIO to instruct the VMCU that it is safe to remove power from the device.

The VHAL must support the following properties, which control power management via the VHAL:

Name Description
AP_POWER_STATE_REPORT Android reports state transitions to the VMCU with this property, using VehicleApPowerStateSet enum values.
AP_POWER_STATE_REQ The VMCU uses this property to instruct Android to transition to different power states, using VehicleApPowerStateReq enum values.
AP_POWER_BOOTUP_REASON The VMCU reports the wake reason to Android, using the VehicleApPowerBootupReason enum values.

AP_POWER_STATE_REPORT

Use this property to report Android's current power management state.This property contains two integers:

The first value can take one of the following values. Types.hal contains more specific descriptions, which are stored in the hardware/interfaces/automotive/vehicle/2.0.

Value name Description Second value
BOOT_COMPLETE AP has completed boot up and can start shutdown.
DEEP_SLEEP_ENTRY AP is entering the deep sleep state. Must be set
DEEP_SLEEP_EXIT AP is exiting the deep sleep state.
SHUTDOWN_POSTPONE Android is requesting to postpone shutdown . Must be set
SHUTDOWN_START AP is starting shutdown. The VMCU can turn on AP after the time specified in the second value. Must be set
DISPLAY_OFF User has requested to turn off the display of the head unit.
DISPLAY_ON User has requested to turn on the display of the head unit.

The state can be set asynchronously (in the case of BOOT_COMPLETE) or in response to a request via the VMCU. When the state is set to SHUTDOWN_START, DEEP_SLEEP_ENTRY, or SHUTDOWN_POSTPONE, an integer value in milliseconds is sent to notify the VMCU for how long the AP must postpone shutdown or sleep.

AP_POWER_STATE_REQ

This property is sent by the VMCU to transition Android into a different power state and contains two integers:

The first integer value represents the new state into which Android is to transit. The semantics are defined in types.hal and provided in the following table:

Value name Description
OFF AP is turned off.
DEEP_SLEEP AP is in deep sleep.
ON_DISP_OFF AP is on, but display is off.
N_FULL AP and display are on.
SHUTDOWN_START AP is starting shutdown. The VMCU can turn on the AP after the time specified in the second value.
SHUTDOWN_PREPARE The VMCU has requested the AP to shut down. The AP can either enter sleep state or start a full shutdown.

VehicleApPowerStateShutdownParam is also defined in types.hal. This enum has three elements, as described below:

Value name Description
SHUTDOWN_IMMEDIATELY The AP must shut down immediately. Postpone is not allowed.
CAN_SLEEP The AP can enter deep sleep instead of shutting down completely.
SHUTDOWN_ONLY The AP can only shut down when postponing is allowed.

AP_POWER_BOOTUP_REASON

This property is set by the VMCU whenever Android is booted up or resumed from suspend. This property instructs Android which event triggered the wakeup. This value must remain static until Android is rebooted or completes a suspend/wake cycle. This property can take a VehicleApPowerBootupReason value, which is defined in types.hal as follows:

Value name Description
USER_POWER_ON Power on because the user pressed the power key or rotated the ignition switch.
USER_UNLOCK Automatic power on triggered by a user unlocking a door (or any other type of automatic user detection).
TIMER Automatic power on triggered by a timer. This occurs only when the AP has requested wakeup after a specific duration, as specified in VehicleApPowerSetState#SHUTDOWN_START.

Wake sources

Use Integrator to disable the appropriate wake sources when the device is in suspend mode. Common wake sources include heartbeats, modem, wifi, and Bluetooth. The only valid wake source must be an interrupt from the VMCU to wake up the SoC. This assumes that the VMCU can listen to the modem for remote wakeup events (such as remote engine start). If this functionality is pushed to the AP, then another wake source to service the modem must be added. In the current design, the Integrator supplies a file with a list of wake sources to be turned off. The CPMS iterates through this file and manages the turning off and on of the wake sources at suspend time.

Applications

OEMs must be careful to write applications so that they can be shut down quickly and not postpone the process indefinitely.

Appendix

Directories in the source code tree

Content Directory
CarPowerManager-related code. packages/services/Car/car-lib/src/android/car/hardware/power
CarPowerManagementService and so on. packages/services/Car/service/src/com/android/car
Services dealing with the VHAL, such as VehicleHal and HAlClient. packages/services/Car/service/src/com/android/car/hal
VHAL interface and property definitions. hardware/interfaces/automotive/vehicle/2.0
Sample app to provide some idea about the CarPowerManager. packages/services/Car/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink
libsuspend resides in this directory. system/core/libsuspend

Class diagram

This class diagram displays the Java classes and interfaces in the power management system:

Figure 5. Power class diagram

Object relationship

The following graph illustrates which objects have references to other objects. An edge means that the source object holds a reference to the target object. For example, VehicleHAL has a reference to a PropertyHalService object.

Figure 6. Object reference diagram