Google is committed to advancing racial equity for Black communities. See how.

Multi-Zone Overview

With automotive comes a new set of use cases around concurrent users interacting with the platform and looking to consume separate media. For example, a driver can play music in the cabin while passengers in the back seat are watching a YouTube video on the rear display. Multi-zone audio enables this by allowing different audio sources to play concurrently through different areas of the vehicle.

Multi-zone audio in Android 10 enables OEMs to configure audio into separate zones. Each zone is a collection of devices within the vehicle with its own volume groups, routing configuration for contexts, and focus management. In this manner, the main cabin could be configured as one audio zone, while the rear display's headphone jacks be configured as a second zone.

The zones are defined as part of car_audio_configuration.xml. CarAudioService then reads the configuration and helps AudioService route audio streams based on their associated zone. Each zone still defines rules for routing based on contexts and the applications uid. When a player is created, CarAudioService determines for which zone the player is associated with, and then based on the usage, which device the AudioFlinger should route the audio to.

Focus is also maintained independently for each audio zone. This enables applications in different zones to independently produce audio without interfering with each other while having applications still respect changes in focus within their zone. CarZonesAudioFocus within CarAudioService is responsible for managing focus for each zone.

Configure multi-zone audio

Figure 1. Configure multi-zone audio

Configuring multiple zones

In Android 10 car_audio_configuration.xml replaces car_volumes_groups.xml and IAudioControl.getBusForContext. In the new configuration file, a list of zones is defined. Each zone has one or more volume groups with their associated devices, and each device has the contexts that should be routed it within that zone. It's required that all contexts are represented within each zone.

The audio_policy, which typically lives in the vendor partition, represents the audio hardware configuration of the board. All devices referenced in car_audio_configuration.xml will be defined within the audio_policy_configuration.xml.

Enabling multi-zone support

When the multi-zone audio is present, you must set the audioUseDynamicRouting flag to true:

<resources>
    <bool name="audioUseDynamicRouting">true</bool>
</resources>

When false, the CarAudioService will fall back to using car_volumes_groups.xml and IAudioControl.getBusForContext. While no changes are required at the HAL layer, since the car_audio_configuration.xml file defines the device to context relationship the IAudioControl.getBusForContext is deprecated for Android 10.

Primary Zone

The primary zone is where all audio will be routed to by default. There can only be one primary zone, which is indicated in the configuration by the attribute isPrimary="true". If no primary zone is specified, the system will by default nominate the first zone in the list.

Sample Configuration

For the example use case defined earlier, the vehicle would need two zones, a primary zone and a rear seat entertainment system. With that, a possible car_audio_configuration.xml would be defined as follows:

<audioZoneConfiguration version="1.0">
       <zone name="primary zone" isPrimary="true">
           <volumeGroups>
               <group>
                   <device address="bus0_media_out">
                       <context context="music"/>
                   </device>
                   <device address="bus3_call_ring_out">
                       <context context="call_ring"/>
                   </device>
                   <device address="bus6_notification_out">
                       <context context="notification"/>
                   </device>
                   <device address="bus7_system_sound_out">
                       <context context="system_sound"/>
                   </device>
               </group>
               <group>
                   <device address="bus1_navigation_out">
                       <context context="navigation"/>
                   </device>
                   <device address="bus2_voice_command_out">
                       <context context="voice_command"/>
                   </device>
               </group>
               <group>
                   <device address="bus4_call_out">
                       <context context="call"/>
                   </device>
               </group>
               <group>
                   <device address="bus5_alarm_out">
                       <context context="alarm"/>
                   </device>
               </group>
           </volumeGroups>
           <displays>
                <display port="0"/>
           </displays>
       </zone>
        <zone name="rear seat zone">
           <volumeGroups>
               <group>
                   <device address="bus100_rear_seat">
                       <context context="music"/>
                       <context context="navigation"/>
                       <context context="voice_command"/>
                       <context context="call_ring"/>
                       <context context="call"/>
                       <context context="alarm"/>
                       <context context="notification"/>
                       <context context="system_sound"/>
                   </device>
               </group>
           </volumeGroups>
           <displays>
               <display port="1"/>
           </displays>
    </zones>
</audioZoneConfiguration>

Here the primary zone has separated out contexts to individual devices. This enables the HAL to apply different post-processing effects and mixing on each device output using the vehicle's hardware. The devices have been arranged into four volume groups: media, navigation, calls, and alarms. If the system is configured to useFixedVolume, then the volume levels for each group will be passed onto the HAL to apply to the output of these devices.

For the secondary zone, the expected output is through a single headphone jack. In this example, all usages are routed to the single device and volume group to keep things simple.

For each zone, an optional list of displays can be included, with a physical display port associated with each display. This enables some applications to query for the zone associated with a specific display that it wants to target (see below).

New hidden APIs (OEMs and system applications only)

A series of hidden APIs have been introduced to CarAudioManager in 10 to allow apps to query and set audio zones and focus.

int[] getAudioZoneIds();
int getZoneIdForUid(int uid);
boolean setZoneIdForUid(int zoneId, int uid);
boolean clearZoneIdForUid(int uid);
int getZoneIdForDisplay(Display display);

Changing zones for an app

By default, all audio routes to the primary zone. To update an application to be routed to a different zone, use setZoneIdForUid:

int zoneIdForDisplayId =
mCarAudioManager.getZoneIdForDisplay(selectedDisplay);

Int uid = mContext.getPackageManager() .getApplicationInfo(mContext.getPackageName(), 0) .uid;
if (mCarAudioManager.setZoneIdForUid(zoneId, info.uid)) { Log.d(TAG, "Zone successfully updated"); } else { Log.d(TAG, "Failed to change zone"); }

Note: Streams cannot dynamically switch zones. Therefore, playback must be stopped to change zones.