Device type limit

In Android audio, audio_devices_t is used to represent the audio device type. It's widely used in audio source code as a bit field to filter or select one or more specified devices. Prior to Android 11, there was a limit of 30 audio input/output device types, and no spare slots to add new audio device types. We've removed the limit on the number of audio device types to allow new audio device types to be added.

To remove the limit on the number of audio device types, audio device types are now enumerated values instead of bit masks.

All the existing audio device types are kept as is. AUDIO_DEVICE_BIT_IN is still used to distinguish input or output devices. When adding new audio device types, they're enumerated values in the gaps between existing values.

OEMs shouldn't use audio_devices_t as a bit mask, because that can cause unexpected results when new enumerated audio device types are added.

Examples and source

Before Android 11, there were two typical usages of audio device types as bit masks.

  • Using the audio_devices_t value to represent multiple audio devices.
  • Checking if the audio_devices_t value contains audio device types from a specified category.

To represent multiple audio device types, a class named DeviceTypeSet in the /libaudiofoundation/include/media/AudioContainers.h is used, which is a std::set container of audio_devices_t. The class is declared in the vendor-available libaudiofoundation library. To represent multiple audio device types in C code, an array or a list of audio_devices_t can be used.

To check if a single device type is of a specified category, use helper functions audio_is_.*_device in /system/media/audio/include/system/audio.h. For multiple audio device types case, use helper functions in libaudiofoundation. For example, use areAllOfSameDeviceType (DeviceTypeSet, std::function) in AudioContainers.h to check if all the given audio device types are of the same type.

Implementation

OEMs need to remove audio device type bit field representation from audio HAL implementation.

  1. Remove all storage of devices on a bit field.

    audio_devices_t shouldn't be used to represent multiple audio device types. Instead, use a list or vector.

  2. Stop using bit operations for device types comparisons.

    Before Android 11, audio device types can be used as a bitfield. In that case, it's common to use bit operations for device types comparisons. When new, enumerated audio device types are added, the bit operations may cause unexpected results. Instead, use helper functions as an alternative. If there's a single audio device type, then use direct comparison to compare the two values. To check if an audio device type is of a specified category, use helper functions in /system/media/audio/include/system/audio.h. For example, audio_is_output_device(audio_devices_t device).

  3. Stop using predefined values for groups of audio device types.

    There are some predefined values for groups of audio device types, AUDIO_DEVICE_OUT_ALL, in system/media/audio/include/system/audio-base-utils.h. All these values are reserved but might be deprecated as they won't be correct when new enumerated audio device types are added. There are new groups of audio device types defined in audio-base-utils.h, which are arrays of audio device types, such as AUDIO_DEVICE_OUT_ALL_ARRAY.

  4. Implement the create_audio_patch() and release_audio_patch() methods for routing instead of set_parameters.

    The set_parameters method uses audio device types as a bitfield, so there can be unexpected results if new enumerated audio device types are added.

    Currently, two kinds of audio patches are required:

    • Mix to device patches, for playback
    • Device to mix patches, for recording

    In subsequent updates, additional patches might be required for device to device.

    When creating an audio patch, if the patch handle isn’t specified, the audio HAL is required to generate a unique patch handle that can identify the audio patch. Otherwise, the audio HAL should use the given audio patch handle to update the audio patch.

    If using a legacy audio HAL and the AOSP HIDL wrapper, the legacy audio HAL should set the major HAL version to 3.0.

    To enable the audio patch feature, the audio HAL should set the major HAL version to 3.0 or higher. Refer to Device::supportsAudioPatches() in default HIDL implementation for more information, which can also be found on audio HAL for Cuttlefish.

Customization

It's not possible to turn the feature off, or to revert the audio device refactoring in the framework that makes it possible to add audio device types.

All of the audio device types added allow representing a device type with a single bit set, so current HAL implementations still work.

If new audio device types are added and OEMs want to use them, they have to upgrade their audio HAL implementation and move to HIDL version 6.0 or higher. It's mandatory to upgrade the major HAL version to 3.0 and implement the create_audio_patch and release_audio_patch methods, because using set_parameters to route the stream can cause unexpected results when new audio device types are added.

Validation

The required work for OEMs is to update their HAL implementations. VTS for audio HAL can be used to validate if the implementation works as intended. All the tests can be found in the VTS files.