Configurable audio policy engine

In Android 14, the Android Automotive Operating System (AAOS) leverages the configurable audio policy (CAP) engine car audio management within the primary audio zone. Specifically, the CAP engine allows AAOS to control only audio routing, only audio volume, or both routing and volume concurrently. The following flags can be used to control the behavior:

  • Use the useCoreAudioVolume flag to enable CAP volume management. When this value is true, the car audio service uses audio manager APIs to manage the volume groups.

  • Use the useCoreAudioRouting flag to enable CAP audio routing management. When this value is true, the car audio service uses the configurable audio policy routing to manage the audio routing.

The audio policy engine is also supported in Android by default in the form of the default audio policy engine.

Background

The CAP engine is based on Intel's parameter framework, which is a plugin-based and rule-based framework for handling parameters. For Android audio management in particular, the CAP engine introduced the ability to define XML files rules to specify the following:

  • Audio product strategy
  • Rules for audio output device selection
  • Rules for audio input device selection
  • Rules to manage volume and mute along with the volume tables

CAP initialization before Android 16

The following figure shows a high-level overview of the configurable audio policy engine configuration management as of Android 6:

CAP engine architecture pre Android 16

Figure 1. CAP engine configuration management as of Android 6.

As shown in the figure, the CAP engine configuration is obtained by the audio policy service by parsing the information from the audio_policy_engine_configuration.xml file in the vendor partition. The CAP engine configuration file uses the schema defined in audio_policy_engine_configuration.xsd to get the required information. audio_policy_engine_configuration.xml is an example for automotive. Similar examples for other form factors are in the frameworks/av/services/audiopolicy/engineconfigurable/config/example/ folder.

The following figure, shows more detailed information about how configurable audio policy engine information is loaded within the audio policy service. In this case, the parameter framework loads the structure and settings from the XML files.

CAP engine load path pre Android 16

Figure 2. CAP information loaded within the audio policy service.

CAP structure files in Android 15 and lower

To obtain the structure and settings, the audio policy service reads the ParameterFrameworkConfigurationPolicy.xml file. This references the structure information through the structure descript file location:

<StructureDescriptionFileLocation Path="Structure/Policy/PolicyClass.xml"/>

This points to structure information in the file:

/vendor/etc/parameter-framework/Structure/Policy/PolicyClass.xml

A skeleton structure is provided in Android . The structure information requires the product strategy structure information, so Android provides the buildStrategiesStructureFile.py generation tool, which can generate information from the available product strategy XML file. This can be referenced through the genrule default buildstrategiesstructurerule as follows:

genrule {
    name: "buildstrategiesstructure_gen",
    defaults: ["buildstrategiesstructurerule"],
    srcs: [
        ":audio_policy_engine_configuration_files",
    ],
}

Where audio_policy_engine_configuration_files is the audio policy engine configuration files. This example for automotive references the audio policy configuration files in the automotive folder. Other examples show how to configure a build to push the files in the device's vendor partition.

CAP settings files in Android 15 and lower

Similar to the structure, the setting information, which represents rules and values of the parameters, is referenced in the ParameterFrameworkConfigurationPolicy.xml file as:

<SettingsConfiguration>
  <ConfigurableDomainsFileLocation Path="Settings/Policy/PolicyConfigurableDomains.xml"/>
</SettingsConfiguration>

Android also provides build tools to generate this information using the audio policy engine configuration and the parameter framework files. See Configurations for more information.

AIDL audio HAL CAP initialization

Starting in Android 16, the AIDL Audio HAL API definition is expanded with the audio policy engine configurations, AudioHalCapConfiguration.aidl. The following figure shows a high-level overview of the CAP engine configuration management as of Android 16:

CAP engine aidl architecture

Figure 3. CAP engine configuration management as of Android 16.

The audio policy service obtains the CAP engine info using the AIDL Audio HAL APIs directly instead of parsing the information from XML files in the device's vendor partition.

In this configuration, the structure of the parameter framework is still loaded by the CAP engine at the audio server side.

CAP engine aidl load path

Figure 4. CAP engine structure.

In all cases, the configuration must fully specify the information pertaining to the product strategies, volume groups, and criteria.

The following figure shows a high-level overview of the AIDL audio HAL APIs that are used by the audio policy service to obtain the CAP engine configuration:

CAP engine AIDL APIS Figure 5. AIDL audio HAL APIs.

In this setup, the audio policy service obtains the following information from the AIDL audio HAL:

  • Configuration
  • Strategies
  • Volumes
  • Criteria
  • Settings

Default AIDL Audio HAL loader

To smooth the transition from HIDL to AIDL, the default audio AIDL Audio HAL provides an XML CAP engine loader. Vendor's can use this loader directly by extending their audio HAL with the default audio HAL or referencing the libaudioserviceexampleimpl library.

The default AIDL audio HAL loader uses audio_policy_engine_configuration.xml to obtain following information:

  • Configuration
  • Strategies
  • Volumes
  • Criteria

The structure information is obtained from the PolicyConfigurableDomains.xml file. The key difference from the previous mechanism is that the structure information is also obtained by the AIDL audio HAL instead of the parameter framework at the audio policy service.

Vendor's can use the domaingeneratorpolicyrule tool to generate the configurable domains using the information from the audio policy engine configuration. The automotive Cuttlefish virtual device example can be used as reference.

Structure in AIDL configuration

In Android 16 and higher, the audio policy service obtains the structure information by reading and parsing the ParameterFrameworkConfigurationCap.xml file. In particular it gets the information from the structure description file:

<StructureDescriptionFileLocation Path="Structure/Policy/CapClass.xml"/>

The framework drops the required files to the /etc/parameter-framework/ folder with the needed information.

The structure represents the parameters that should be controlled, so they should be referenced in the configuration or domains. For this, the AIDL engine config should use a predetermined name for the parameters. For the product strategies, the structures are configured in CapProductStrategies.xml.

Default product strategies

Beginning with defaults provided in the default engine, the product strategies start with the STRATEGY_ prefix:

  • STRATEGY_PHONE
  • STRATEGY_SONIFICATION
  • STRATEGY_ENFORCED_AUDIBLE
  • STRATEGY_ACCESSIBILITY
  • STRATEGY_SONIFICATION_RESPECTFUL
  • STRATEGY_MEDIA
  • STRATEGY_DTMF
  • STRATEGY_CALL_ASSISTANT
  • STRATEGY_TRANSMITTED_THROUGH_SPEAKER

This format was provided to alleviate the transition from HIDL to AIDL for devices that were using default strategies. This format change has some implications for the existing files (for example, PfW, XML) that are used to configure the engine. In particular, all the product strategy references should be changed to use the new names, for example:

Non-AIDL configuration parameter name
/Policy/policy/product_strategies/media/device_address
/Policy/policy/product_strategies/media/selected_output_devices/mask
AIDL configuration parameter name
/Policy/policy/product_strategies/STRATEGY_MEDIA/device_address
/Policy/policy/product_strategies/STRATEGY_MEDIA/selected_output_devices/mask
OEM-defined product strategies

The configurable engine provides the ability for OEMs to change the product strategies definition. To continue to support this, the product strategy file CapProductStrategies.xml also provides 40 vendor extendible product strategies from vx_1000 to vx_1039 . All vendor extensions must start with the vx_ prefix and follow with a number that represents the product strategy ID in the AIDL audio HAL product strategy definition. The rest of the definitions (for example, audio attribute groups, name) are obtained from the AudioHALProductStrategy object in the audio HAL engine configuration.

Similarly to the default product strategies, the vendor defined OEMs references must also be adapted between the non-AIDL configuration and the AIDL configuration, for example:

Non-AIDL configuration parameter name
/Policy/policy/product_strategies/oem_extension_strategy/device_address
/Policy/policy/product_strategies/oem_extension_strategy/selected_output_devices/mask
AIDL configuration parameter name
/Policy/policy/product_strategies/vx_1037/device_address
/Policy/policy/product_strategies/vx_1037/selected_output_devices/mask

Product strategies

Product strategies provide a way to customize how audio streams are categorized and grouped. This allows for greater flexibility in configuring audio devices including how they're routed and how their volumes are managed. Each product strategy can have one or more audio attribute groups, which identify streams that should be associated with that product strategy. These audio attributes groups allow for a more granular approach to categorizing audio and can be a mixture of the following types:

  • Usage types describe why a sound is being played (that is, media, notification, call).
  • Content type types describe what is being played (that is, music, speech, video, sonification).
  • Flag types define different behavior or requests with respect to the stream.
  • Tags types support any arbitrary list of vendor string values.
    • Each string must start with the VX_ followed by an alphanumeric string (for example, VX_OEM, VX_NAVIGATION)
<ProductStrategy name="music" id="1008">
    <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="media">
        <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
        <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
        <!-- Default product strategy has empty attributes -->
        <Attributes></Attributes>
    </AttributesGroup>
</ProductStrategy>

This excerpt shows an example of a product strategy used in car emulators. It contains two audio attributes with audio usage media and game respectively. This product strategy matches the MUSIC audio context used in car audio service, but there is no requirement for such matching. One of the main utilities for OEMs using the CAP along with Android is to allow for more flexible audio grouping definitions.

Volume groups

Additionally, each audio attribute group must have an associated volume group. This volume group is associated with any stream matching audio attributes belonging to the audio attribute group. The example music product strategy in the Product strategies section has the volume group media, and the definition of the media volume group is as follows:

<volumeGroup>
    <name>media</name>
    <indexMin>0</indexMin>
    <indexMax>40</indexMax>
    <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
        <point>0,-2400</point>
        <point>33,-1600</point>
        <point>66,-800</point>
        <point>100,0</point>
    </volume>
</volumeGroup>

In this definition the volume group contains:

  • Group name
  • Group minimum index
  • Group maximum index
  • Volume group curves

The volume group curves contain pointwise mapping between volume group index and volume gain in millibels. The provided points are used to linearly interpolate the best matching gain when volume is managed. Each volume group curve is associated with a device type category (for example, headset, speaker, external media).

The volume group manages the volume for the streams that are part of the audio attributes group. For example, when a stream with audio attributes containing music or game is started, the last set volume index for the media volume group is used. In this case, the corresponding device category curve is selected based on the selected device and the corresponding gain is set when the stream is started.

Configurations

In the CAP engine, configurations are used to define the conditions or rules that determine how the audio should behave. These configurations are evaluated at run time to select the appropriate rules to apply depending on the current state of the audio system.

As shown in figure 5, the API contains multiple domains, the goal of each domain is to split the logic into smaller routing problems to solve (for example, device 1, device 2).

Each domain has configurations, and each configuration has a set of rules. Rules are established on criteria that are provided by AudioPolicyManager:

  • Audio mode
  • Available input and output devices
  • Available input and output devices addresses
  • Use for
    • Media
    • Communication
    • Recording
    • Dock
    • System
    • Hdmi system audio
    • Encoded surround
    • Vibrate ringing

Each domain contains configurations that dictate the rules that should impact behavior. Note that the configuration order matters and it's important to make sure the configurations are in the required order. After the rules for a configuration are validated, the configuration is selected.

The following code shows an excerpt example of a parameter framework file, which can be used to generate the required XML file for configuring configurable domains:


supDomain: DeviceForProductStrategies
  supDomain: Music
    domain: SelectedDevice
      conf: BluetoothA2dp
        ForceUseForMedia IsNot NO_BT_A2DP
        ForceUseForCommunication IsNot BT_SCO
        AvailableOutputDevices Includes BLUETOOTH_A2DP
        component:/Policy/policy/product_strategies/vx_1000/selected_output_devices/mask
          bluetooth_a2dp = 1
          bus = 0
      conf: Bus
        AvailableOutputDevices Includes Bus
        AvailableOutputDevicesAddresses Includes BUS00_MEDIA
        component: /Policy/policy/product_strategies/vx_1000/selected_output_devices/mask
          bluetooth_a2dp = 0
          bus = 1
      conf: Default
        component: /Policy/policy/product_strategies/vx_1000/selected_output_devices/mask
          bluetooth_a2dp = 0
          bus = 0

The domain DeviceForProductStrategies defines how different rules should be applied when handling product strategies device selection. The blue parts describe the rules that should be considered and the green part is the configuration applied. This particular example contains the following configurations:

  • Select Bluetooth A2DP device for music product strategy (ID 1000, vx_1000)
    • If used for media, doesn't exclude A2DP
    • If used for communication, isn't BT SCO
    • If available devices, include BT A2DP
  • Select bus device
    • If bus devices is available
    • If address is BUS00_MEDIA
  • Select default output device otherwise

To generate the corresponding configurable policy engine XML file, run the parameter-framework (PFW) files through the build system, by defining a build rule using the following steps:

  1. In the Android.bp file, create a filegroup for the file:

    filegroup {
        name: ":device_for_product_strategies.pfw",
        srcs: ["engine/parameter-framework/Settings/device_for_product_strategyies.pfw"],
    }
    
  2. Add the file to other PfW files (if any).

    filegroup {
        name: "edd_files",
        srcs: [
            ":device_for_input_source.pfw",
            ":volumes.pfw",
            ":device_for_product_strategyies.pfw",
        ],
    }
    
  3. Create the corresponding domain generation rule:

    genrule {
        name: "domaingeneratorpolicyrule_gen",
        defaults: ["domaingeneratorpolicyrule"],
        srcs: [
            ":audio_policy_engine_criterion_types",
            ":audio_policy_pfw_structure_files",
            ":audio_policy_pfw_toplevel",
            ":edd_files",
        ],
    }
    

    Where domaingeneratorpolicyrule is a generation rule provided by the framework to generate the PolicyConfigurableDomains.xml file. The other source files (scrs) included in the domain generation rules are as follows:

    Source Description
    audio_policy_pfw_toplevel Top-level parameter-framework configuration file.
    audio_policy_pfw_structure_files Domain generation structure files, which are used to generate the configuration files.
    audio_policy_engine_criterion_types Criteria types XML file, describing the criteria used during generation.
    edd_files List of single domain files (each containing a single <ConfigurableDomain> tag).

After running the generation rule in the build, the PolicyConfigurableDomains.xml is generated with all the domains. The following shows an excerpt from the generated file using the rules PfW example:

---ConfigurableDomain Name="DeviceForProductStrategies.Music.SelectedDevice"---
<Configurations>
  <Configuration Name="BluetoothA2dp">
    <CompoundRule Type="All">
      <SelectionCriterionRule SelectionCriterion="ForceUseForMedia" MatchesWhen="IsNot" Value="NO_BT_A2DP"/>
      <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="BT_SCO"/>
      <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BLUETOOTH_A2DP"/>
    </CompoundRule>
  </Configuration>
  <Configuration Name="Bus">
    <CompoundRule Type="All">
      <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BUS"/>
      <SelectionCriterionRule SelectionCriterion="AvailableOutputDevicesAddresses" MatchesWhen="Includes" Value="BUS00_MEDIA"/>
    </CompoundRule>
  </Configuration>
  <Configuration Name="Default">
    <CompoundRule Type="All"/>
  </Configuration>
</Configurations>

CAP debugging

You can use the remote-process to dump the CAP configurations:

adb root && adb remount
adb shell remote-process unix:///dev/socket/audioserver/policy_debug dumpDomains

This shows all domains and configurations, including applicability conditions. The following shows an excerpt from the Cuttlefish automotive device using the Bluetooth A2DP, bus device, and default configurations. See Configurations:

- ConfigurableDomain: DeviceForProductStrategies.Music.SelectedDevice =
 {Sequence aware: no, Last applied configuration: Bus}
  - Configuration: BluetoothA2dp
    - CompoundRule = All
      - SelectionCriterionRule = ForceUseForMedia IsNot NO_BT_A2DP
      - SelectionCriterionRule = ForceUseForCommunication IsNot BT_SCO
      - SelectionCriterionRule = AvailableOutputDevices Includes BLUETOOTH_A2DP
  - Configuration: Bus
    - CompoundRule = All
      - SelectionCriterionRule = AvailableOutputDevices Includes BUS
      - SelectionCriterionRule = AvailableOutputDevicesAddresses Includes BUS00_MEDIA_CARD_0_DEV_0
  - Configuration: Default
    - CompoundRule = All

For further information on other command available to debug the CAP parameter framework use this tool:

adb shell remote-process unix:///dev/socket/audioserver/policy_debug help

To use the tool, OEM manufacturers must allow tuning in the device. To verify if the device allows tuning, use the following command:

adb shell cat /system/etc/parameter-framework/ParameterFrameworkConfigurationCap.xml

In Android 15 and lower, the file might be different, so use the following command:

adb shell cat /system/etc/parameter-framework/ParameterFrameworkConfigurationPolicy.xml

The file should contain TuningAllowed="true" along with the corresponding server port:

<?xml version="1.0" encoding="UTF-8"?>
<ParameterFrameworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    SystemClassName="Policy" TuningAllowed="true" ServerPort="unix:///dev/socket/audioserver/policy_debug">
    <SubsystemPlugins>
        <Location Folder="">
            <Plugin Name="libpolicy-subsystem.so"/>
        </Location>
    </SubsystemPlugins>
    <StructureDescriptionFileLocation Path="Structure/Policy/CapClass.xml"/>
</ParameterFrameworkConfiguration>

This file is autogenerated according to the type of build image (or use a different file for release or debug for legacy build). A release build sets TuningAllowed to false without a socket port (sockets are forbidden for this in release builds). Engineering and userdebug builds set it to true with the socket port used. Note that this is the file referenced by the audio_policy_pfw_toplevel. The remote-process tool must also be included in the device's make or build file:

# Tool used for debug Parameter Framework (only for eng and userdebug builds)
PRODUCT_PACKAGES_DEBUG += remote-process

The corresponding SELinux policy to allow sockets must also be included. This works for debug mode only because release mode explicitly disallows sockets:

BOARD_SEPOLICY_DIRS += frameworks/av/services/audiopolicy/engineconfigurable/sepolicy

CAP migration in Android 16

Given the major changes brought by AIDL audio HAL CAP engine and previous versions, there are various device transition scenarios that you should consider. This section covers the most prominent transition scenarios and gives recommendations for the work to enable the CAP engine configuration.

Scenario 1: New device using Android 16 or higher, no previous source for the device CAP configuration

A new device must launch with Android 16 or higher code on the vendor partition. That means, it must expose the configurable audio policy engine configuration through the AIDL audio HAL interface. Device CAP engine configuration should be copied from the examples. There should be no PfW CAP domain definition on the vendor partition.

The system image used for the device is Android 16 or higher. The audio service framework discovers the CAP configuration through the AIDL audio HAL interface, so it initializes PfW using the PfW CAP domain definition from the system image and loads the device CAP configuration received through AIDL.

For an example, see the automotive Cuttlefish virtual device, which was introduced in this change and can be referenced for the required files, build rules, and make files required for setting up the required configuration files. This works with the loaders provided in the default AIDL audio HAL.

Scenario 2: New device using Android 16 or higher, from a previous device using CAP

A new device must launch with Android 16 or higher code on the vendor partition. However, because the OEM has a usable device CAP engine configuration, the OEM would want to use it as a starting point (or fully reuse it). The AIDL version of the CAP configuration has some changes compared to the Android 15 and lower version, so the vendor must convert the existing configuration to AIDL. See the discussion in Product strategies for changes between Android 16 and lower versions for the changes required. In general, the audio framework discovers and loads the CAP configuration the same way as in Scenario 1.

Scenario 3: Existing device with CAP updating to Android 16 only the system partition

In this scenario, the vendor partition contains the Android 15 and lower version of the device CAP configuration, and the PfW CAP domain definition. The vendor partition is untouched, so it still uses HIDL HAL. The framework follows the Android 15 and lower scenario and loads all the CAP related configuration from the vendor partition.

Scenario 4: Existing device released on Android 15, with CAP

CAP wasn't supported in AIDL on Android 15, so some vendors released new devices with AIDL Audio HAL and CAP, which was loaded by the audio framework. This hybrid mode was unofficial, but is included in Android 16. Note that this mode must not be used for releasing new devices on Android 16, but rather to enable existing devices with Android 15 vendor to be updated to Android 16 (the system partition update).

The audio framework discovers the AIDL audio HAL audio configuration without the CAP configuration. For the CAP configuration, the audio policy service (audio framework) falls back to loading the CAP configuration from the vendor partition. In this case, both the PfW CAP domain definition and the device CAP configuration must be loaded from the vendor partition.

CAP migration summary

The following table summarizes compatible system and vendor configurations and requirements to the CAP configuration:

System partition Scenario Vendor partition code version Core audio HAL type PfW CAP domain definition location Device CAP configuration
Android 15 4 Android 14 or lower HIDL vendor HIDL version
Android 16 3 Android 14 or lower HIDL vendor HIDL version
Android 16 4 Android 15 AIDL vendor HIDL version
Android 16 2 Android 16 AIDL system AIDL version converted from HIDL
Android 16 1 Android 16 AIDL system AIDL version from example