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.
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. |
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.
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.
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
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:
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.
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
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 onStateChanged
method to send a
SUSPEND_EXIT
message to applications and services when it wakes up.
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
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:
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);
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.CarPowerStateListene
r 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. |
To unregister all listener objects registered to CPM, call the clearListener
method:
powerManager.clearListener();
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.
The requestShutdownOnNextSuspend()
method instructs CPMS to shut down instead of deep
sleep at the next opportunity.
Integrators are responsible for implementing the following items:
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.
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. |
Use this property to report Android's current power management state.This property contains two integers:
int32Values[0]
: VehicleApPowerStateReport
enum of current state int32Values[1]
: Time in milliseconds to postpone or sleep/shutdown. This value
depends on the first value.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.
This property is sent by the VMCU to transition Android into a different power state and contains two integers:
int32Values[0]
: VehicleApPowerStateReq
enum value, which represents
the new state into which to transitionint32Values[1]
: VehicleApPowerStateShutdownParam
enum value. This is
sent only for a SHUTDOWN_PREPARE
message and conveys to Android what options it
contains.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. |
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. |
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.
OEMs must be careful to write applications so that they can be shut down quickly and not postpone the process indefinitely.
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 |
This class diagram displays the Java classes and interfaces in the power management system:
Figure 5. Power class diagram
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