In Android’s Audio Hardware Abstraction Layer (HAL) and AudioFlinger service, audio_policy_configuration.xml serves as the declarative wiring manifest. It defines all supported audio stream types, hardware endpoints, sampling formats, and valid routing connections between AudioFlinger mix tracks and physical or virtual device hardware.

Visual Architecture: AudioFlinger to Audio HAL Routing

Understanding how AudioFlinger routes PCM audio streams to physical hardware requires tracing the path from software mix ports to physical device ports:

Android Audio HAL Architecture Diagramtext
+---------------------------------------------------------------------------------+
| AUDIOFLINGER & AUDIO POLICY MANAGER                                             |
+---------------------------------------------------------------------------------+
| [AudioTrack / App]  -> Writes PCM stream (e.g. 48kHz Stereo 16-bit)             |
|                               |                                                 |
| [mixPort "primary output"]   -> Source Mix Endpoint in audio_policy_config.xml  |
|                               |                                                 |
| [<route>]                    -> Explicit XML link connecting mixPort to device |
|                               |                                                 |
| [devicePort "Speaker"]       -> Hardware Sink Endpoint (AUDIO_DEVICE_OUT_SPEAKER)|
+-------------------------------+-------------------------------------------------+
                                |
                                v
+---------------------------------------------------------------------------------+
| AUDIO HAL / ALSA DRIVER (.so)                                                   |
+---------------------------------------------------------------------------------+
| Writes audio buffer to Kernel ALSA / PCM Hardware Driver                        |
+---------------------------------------------------------------------------------+

Core XML Elements in audio_policy_configuration.xml

The configuration file is structured into root <modules> representing separate audio HAL implementations (such as primary, a2dp, usb, and r_submix). Each module encapsulates four primary XML elements:

  • `<mixPorts>` - Declares software stream endpoints. A mixPort acting as a source receives PCM/compressed audio from AudioFlinger, while a sink mixPort captures incoming microphone audio.

  • `<devicePorts>` - Declares physical hardware ports (e.g. Speaker, Earpiece, Wired Headset, Built-in Mic) with supported sample rates, channel masks, and encoding formats.

  • `<routes>` - Defines valid connection paths between mixPorts and devicePorts. AudioFlinger will only route audio to a device if an explicit <route> element permits the connection.

  • `<attachedDevices>` - Lists devices permanently present on the target platform (such as internal speakers and built-in microphones).

1. Production XML Schema Example

Below is an XML snippet demonstrating how a primary audio module declares mixPorts, devicePorts, and routing paths:

vendor/etc/audio_policy_configuration.xmlxml
<audioPolicyConfiguration version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>Speaker</item>
                <item>Built-in Mic</item>
            </attachedDevices>
            <defaultOutputDevice>Speaker</defaultOutputDevice>
            <mixPorts>
                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="primary input" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
                <devicePort tagName="Built-in Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="Speaker" sources="primary output"/>
                <route type="mix" sink="primary input" sources="Built-in Mic"/>
            </routes>
        </module>
    </modules>
</audioPolicyConfiguration>

What You Learned from This XML Configuration:

  • `role` Attributes: role="source" on a mixPort means it outputs audio from AudioFlinger to hardware; role="sink" on a devicePort means it consumes audio (like a speaker).

  • `flags="AUDIO_OUTPUT_FLAG_PRIMARY"`: Marks the default low-latency hardware stream used for system UI sounds, notifications, and ringtones.

  • `<routes>` Validation: The line <route type="mix" sink="Speaker" sources="primary output"/> explicitly authorizes AudioFlinger to stream audio from primary output to the Speaker hardware devicePort.

2. Runtime Inspection and ADB Debugging Commands

To inspect active audio policy state, verify parsed routes, and troubleshoot audio routing failures on a running Android device, use dumpsys media.audio_policy via ADB shell:

Terminalbash
adb shell dumpsys media.audio_policy | grep -A 20 "Audio Policy Config"
HW Modules dump:
- Status: 0
- Module 1 "primary":
  - Inputs:
    - primary input
  - Outputs:
    - primary output
  - Devices:
    - Speaker
    - Built-in Mic

What You Learned from dumpsys Output:

  • Module Binding Verification: Confirms that AudioPolicyService parsed /vendor/etc/audio_policy_configuration.xml without schema errors.

  • Active Hardware Status: Shows whether primary output successfully registered output sinks and input sources with the underlying HAL.

Terminalbash
adb logcat | grep -iE "AudioPolicy|AudioHAL|AudioFlinger"
D/AudioPolicyManager: loadAudioPolicyConfig() loaded /vendor/etc/audio_policy_configuration.xml successfully

Gotchas and Common Audio Routing Issues

  • Missing `<route>` declaration - Even if both <mixPort> and <devicePort> are declared with matching sample rates, audio fails to play if no <route> element connects the mixPort source to the devicePort sink.

  • Format & Channel Mask Mismatch - If a track requests 44.1 kHz stereo but the mixPort only defines 48.0 kHz, AudioFlinger fails to open the HAL output stream unless resampling is explicitly allowed by mixPort flags.

  • `AUDIO_OUTPUT_FLAG_DIRECT` or `OFFLOAD` Failures - Compressed offload streams require exact hardware support. If sample rates or formats do not match hardware capabilities, the stream fails to initialize.

Mastering audio_policy_configuration.xml allows Android BSP engineers to accurately configure Audio HAL routing, integrate new hardware codecs, and troubleshoot complex audio routing failures.