HAL de control de audio

La HAL de control de audio se introdujo en Android 9 admiten casos de uso de audio relevantes para la industria automotriz. A partir de Android 14, la HAL de control de audio admite lo siguiente:

  • Atenuación y equilibrio
  • Solicitud de foco de audio de HAL
  • Silenciamiento y atenuación del dispositivo
  • Cambios en la ganancia del dispositivo de audio
  • Cambios en la configuración del puerto de audio

En la Figura 1, se muestra una descripción general de alto nivel de la arquitectura del servicio de audio para vehículos, en que el servicio de audio del auto se comunica con la HAL de control de audio.

Configura el audio multizona

Figura 1: Configura el audio multizona.

Atenuación y equilibrio de audio

La versión 1 de la HAL de control de audio HIDL se introdujo en Android 9 para admitir atenuación y equilibrio de audio en el uso en automóviles diferentes. Aparte de los efectos de audio genéricos que ya se proporcionan en Android, este formato Permite que las apps del sistema establezcan el equilibrio del audio y atenúen el audio. APIs de CarAudioManager:

class CarAudioManager {
       /**
       *   Adjust the relative volume in the front vs back of the vehicle cabin.
       *
       *   @param value in the range -1.0 to 1.0 for fully toward the back through
       *   fully toward the front. 0.0 means evenly balanced.
       */
       @SystemApi
       @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME)
       public void setFadeTowardFront(float value);

       /**
       *   Adjust the relative volume on the left vs right side of the vehicle cabin.
       *
       *   @param value in the range -1.0 to 1.0 for fully toward the left through
       *   fully toward the right. 0.0 means evenly balanced.
       */
       @SystemApi
       @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME)
       public void setBalanceTowardRight(float value);
}

Una vez que se llama a estas APIs, se llama a las respectivas APIs de HAL de control de audio desde el servicio de audio para automóviles:

interface IAudioControl {
       /**
       *   Control the right/left balance setting of the car speakers.
       */
       oneway setBalanceTowardRight(float value);

       /**
       *   Control the fore/aft fade setting of the car speakers.
       */
       oneway setFadeTowardFront(float value);
}

La API está disponible en todas las versiones de la HAL de control de audio, incluida la nueva Interfaz de la HAL del AIDL.

Solicitud de foco de audio de la HAL

AAOS, al igual que Android, se basa en la participación activa de las aplicaciones en audio para administrar la reproducción de audio en autos. La información de enfoque se usa para administrar que transmite para controlar el volumen y la atenuación. Por lo tanto, para seguir expandiendo el foco de audio y proporcionar una mejor integración de sonidos específicos del vehículo en la experiencia de Android, los siguientes atributos de audio se presentaron en Android 11:

  • EMERGENCY
  • SAFETY
  • VEHICLE_STATUS
  • ANNOUNCEMENT

Además de este cambio, se agregó un mecanismo para los sonidos que se originan en fuera de Android para participar en solicitudes de foco de audio. Por lo tanto, el audio HIDL la versión 2 de la HAL de control se introdujo para permitir las solicitudes de enfoque que se originan desde fuera de Android:

interface IAudioControl {
       /**
       *   Registers focus listener to be used by HAL for requesting and
       *   abandoning audio focus.
       *   @param listener the listener interface
       *   @return closeHandle A handle to unregister observer.
       */
       registerFocusListener(IFocusListener listener)
       generates (ICloseHandle closeHandle);

       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   @param usage The audio usage associated with the focus change
       *   @param zoneId The identifier for the audio zone that the HAL is
       *   playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred
       */
       oneway onAudioFocusChange(bitfield<AudioUsage> usage, int32_t zoneId,
       bitfield<AudioFocusChange> focusChange);
}

En el ejemplo anterior, IFocusListener se define de la siguiente manera:

interface IFocusListener {
       /**
       *   Called whenever HAL is requesting focus as it is starting to play
       *   audio of a given usage in a specified zone.
       *
       *   @param usage The audio usage associated with the focus request
       *    {@code AttributeUsage}
       *   @param zoneId The identifier for the audio zone where the HAL is
       *    requesting focus
       *   @param focusGain The AudioFocusChange associated with this request.
       */
       oneway requestAudioFocus(bitfield<AudioUsage> usage,
       int32_t zoneId, bitfield<AudioFocusChange> focusGain);
       /**
       *   Called whenever HAL is abandoning focus as it is finished playing audio
       *   of a given usage in a specific zone.
       *
       *   @param usage The audio usage for which the HAL is abandoning focus
       *    {@code AttributeUsage}
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       */
       oneway abandonAudioFocus(bitfield<AudioUsage> usage, int32_t zoneId);
}

Las APIs anteriores se pueden usar para solicitar y abandonar el foco de audio de la HAL, respectivamente. En respuesta, el servicio de audio para el automóvil considera el foco de audio envía una solicitud y reenvía los resultados de forma asíncrona al IAudioControl#onAudioFocusChange.

Esta API también se puede usar para supervisar los cambios en la solicitud de foco de audio que se origina en la HAL de control de audio. En general, cualquier foco de audio de pie solicitud de la HAL se considera activa, lo cual difiere de un foco de audio en la que solo la reproducción de una pista de audio activa se considera activa.

Cómo migrar el HIDL a la HAL de control de audio del AIDL

Con la llegada del AIDL y la migración necesaria en Android 12 (para obtener más información, consulta AIDL para HAL), la HAL de control de audio se se migran al AIDL. Para las APIs de la versión 2 de control de audio HIDL existentes, la migración requirió actualizaciones menores a los métodos existentes:

interface IAudioControl {
       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   @param usage The audio usage associated with the focus change
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone that the HAL is
       *        playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred.
       */
       oneway void onAudioFocusChange(in String usage, in int zoneId,
              in AudioFocusChange focusChange);
       /**
       *   Registers focus listener to be used by HAL for requesting and
       *   abandoning audio focus.
       *   @param listener the listener interface.
       */
       oneway void registerFocusListener(in IFocusListener listener);
       /**
       *   Control the right/left balance setting of the car speakers.
       */
       oneway void setBalanceTowardRight(in float value);
       /**
       *   Control the fore/aft fade setting of the car speakers.
       */
       oneway void setFadeTowardFront(in float value);
}

Y el IFocusListener correspondiente:

       interface IFocusListener {
       /**
       *   Called whenever HAL is abandoning focus as it is finished playing audio
       *   of a given usage in a specific zone.
       *
       *   @param usage The audio usage for which the HAL is abandoning focus
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone that the HAL
       *        abandoning focus
       */
       oneway void abandonAudioFocus(in String usage, in int zoneId);
       /**
       *   Called whenever HAL is requesting focus as it is starting to play audio
       *        of a given usage in a specified zone.
       *
       *   @param usage The audio usage associated with the focus request
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone where the HAL is
       *        requesting focus
       *   @param focusGain The AudioFocusChange associated with this request.
       */
       oneway void requestAudioFocus(in String usage, in int zoneId,
              in AudioFocusChange focusGain);
}

Silenciar el grupo de volúmenes

En Android 12, se incorporó el silenciamiento de grupos de volumen para permitir un control de silencio más integral durante las interacciones de audio del usuario. Esta permite que la HAL de control de audio reciba eventos de silenciamiento cuando el auto intercepte servicio de audio.

Para habilitar la función, los OEM deben establecer la configuración de audioUseCarVolumeGroupMuting. a true en el servicio de automóviles config.xml:

<!-- Configuration to enable muting of individual volume groups.
If this is set to false, muting of individual volume groups is disabled,
instead muting will toggle master mute. If this is set to true, car volume
group muting is enabled and each individual volume group can be muted separately. -->
<bool name="audioUseCarVolumeGroupMuting">true</bool>

Antes de Android 13, se debía reemplazar la configuración con una superposición de recursos de entorno de ejecución para packages/services/Car/service/res/values/config.xml (para obtener más información, consulta Personaliza la compilación con recursos superposiciones). En Android puedes usar superposiciones de recursos de tiempo de ejecución para modificar un de configuración de Terraform. Para obtener más información, consulta Cómo cambiar el valor de los recursos de una app durante el tiempo de ejecución.

Las aplicaciones del sistema pueden determinar si la función está habilitada con la API de CarAudioManager#isAudioFeatureEnabled. El parámetro que se pase debe ser el CarAudioManager.AUDIO_FEATURE_VOLUME_GROUP_MUTING. El método devuelve Es true si la función está habilitada en el dispositivo; de lo contrario, es false.

Además de habilitar la función audioUseCarVolumeGroupMuting, el AIDL La HAL de control de audio debe implementar el mecanismo para silenciar grupos de volumen:

interface IAudioControl {
       /**
       *   Notifies HAL of changes in output devices that the HAL should apply
       *   muting to.
       *
       *   This will be called in response to changes in audio mute state for each
       *   volume group and will include a {@link MutingInfo} object per audio
       *   zone that experienced a mute state event.
       *
       *   @param mutingInfos an array of {@link MutingInfo} objects for the audio
       *   zones where audio mute state has changed.
       */
       oneway void onDevicesToMuteChange(in MutingInfo[] mutingInfos);
}

En el que la información de silenciamiento contiene la información de silencio pertinente para el sistema de audio:

parcelable MutingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be muted.
       */
       String[] deviceAddressesToMute;
       /**
       *   List of addresses for audio output devices that were previously be
       *   muted and should now be unmuted.
       */
       String[] deviceAddressesToUnmute;
}

AAOS tiene dos mecanismos diferentes para silenciar, en función de lo siguiente:

  • Eventos clave que usan el audio KEYCODE_VOLUME_MUTE.

  • Realizar llamadas directas al servicio de audio para vehículos con la API de silencio del administrador de audio para vehículos CarAudioManager#setVolumeGroupMute

Cuando se habilitan, ambos mecanismos activan el silenciamiento de una llamada en la HAL de control de audio.

Autosilenciado de fondo

Android 12 introdujo el autosilenciado de fondo para optimizar el control de simultaneidad reproducciones de audio. Esto permite a los OEM implementar su propio autosilenciado de fondo comportamiento basado en la configuración física de audio del vehículo y la reproducción actual según lo determinado por el servicio de audio del vehículo.

El mecanismo de autosilenciado se basa en los cambios en la pila de foco de audio. Cada vez que un se produce un cambio de foco (ya sea una solicitud o un abandono de foco), el audio de control. Similar a la opción de silenciar el grupo de volumen del auto, El autosilenciado de fondo se puede habilitar con la marca de configuración audioUseHalDuckingSignals:

<!-- Configuration to enable IAudioControl#onDevicesToDuckChange API to
inform HAL when to duck. If this is set to true, the API will receive signals
indicating which output devices to duck as well as what usages are currently
holding focus. If set to false, the API will not be called. -->
<bool name="audioUseHalDuckingSignals">true</bool>

Para habilitar la función, la HAL de control de audio del AIDL debe implementar los lógica con la señal recibida del servicio de audio del automóvil:

interface IAudioControl {
       /**
       *   Notifies HAL of changes in output devices that the HAL should apply
       *   ducking to.
       *
       *   This will be called in response to changes in audio focus, and will
       *   include a {@link DuckingInfo} object per audio zone that experienced
       *   a change in audo focus.
       *
       *   @param duckingInfos an array of {@link DuckingInfo} objects for the
       *   audio zones where audio focus has changed.
       */
       oneway void onDevicesToDuckChange(in DuckingInfo[] duckingInfos);
}

La información relevante del sistema de audio se incluye en el autosilenciado de fondo. información:

parcelable DuckingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be ducked.
       */
       String[] deviceAddressesToDuck;
       /**
       *   List of addresses for audio output devices that were previously be
       *   ducked and should now be unducked.
       */
       String[] deviceAddressesToUnduck;
       /**
       *   List of usages currently holding focus for this audio zone.
       */
       String[] usagesHoldingFocus;
}

Además de la información de configuración del audio del auto que se incluye en las direcciones del dispositivo a (un)duck, el autosilenciado de fondo también contiene información sobre qué audio los usos de atributos se mantienen el foco. El objetivo de estos datos es informar sistema de audio en el que los usos de atributos de audio están activos.

Esto es necesario porque, en la configuración de audio del vehículo, se pueden usar varias pueden asignarse a un solo dispositivo y, sin la información, no está claro qué usos están activos.

HAL de control de audio del AIDL 2.0

Para actualizar las APIs y facilitar nuevas funcionalidades, la HAL de control de audio del AIDL se actualizó a la versión 2.0 en Android 13:

  • Enfoque de audio con PlaybackTrackMetadata
  • El audio recibe devolución de llamada

Los metadatos de reproducción se definen en android.hardware.audio.common de la siguiente manera:

parcelable PlaybackTrackMetadata {
       AudioUsage usage = INVALID;
       AudioContentType contentType = UNKNOWN;
       float gain;
       AudioChannelLayout channelMask;
       AudioDevice sourceDevice;
       String[] tags;
}

Todas las demás funcionalidades del control de audio versión 1.0 del AIDL se mantuvieron y se pueden que se usan. La excepción se relaciona con el método de cambio de foco de audio, como se describe en En el método de cambio de foco de audio:

Enfoque de control de audio con metadatos de pistas de reproducción

Para exponer más información al sistema de audio debajo de la HAL, las actualizaciones ahora exponen PlaybackTrackMetadata Específicamente, se expandió la HAL de control de audio con un método nuevo:

interface IAudioControl {
       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   The HAL is not required to wait for a callback of AUDIOFOCUS_GAIN
       *   before playing audio, nor is it required to stop playing audio in the
       *   event of a AUDIOFOCUS_LOSS callback is received.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL is
       *    playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred.
       */
       oneway void onAudioFocusChangeWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId,
       in AudioFocusChange focusChange);
}

Se realiza un cambio similar y correspondiente en IFocusListener:

       /**
       *   Called to indicate that the audio output stream associated with
       *   {@link android.hardware.audio.common.PlaybackTrackMetadata} is
       *   abandoning focus as playback has stopped.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       */
       oneway void abandonAudioFocusWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId);
       /**
       *   Called to indicate that the audio output stream associated with
       *   {@link android.hardware.audio.common.PlaybackTrackMetadata} has taken
       *   the focus as playback is starting for the corresponding stream.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       *   @param focusGain The focus type requested.
       */
       oneway void requestAudioFocusWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId,
       in AudioFocusChange focusGain);
}

En el método de cambio de foco de audio

Las operaciones de enfoque anteriores se realizan de la misma manera que las descritas en Audio de enfoque de la HAL. Solo los metadatos de la pista de reproducción tienen más junto con los usos de atributos de audio. En general, a menos que los requisitos que proporcionan los metadatos de la pista de reproducción, se actualiza control HAL puede seguir usando los métodos anteriores.

Si los desarrolladores de HAL deciden no admitir IAudioControl#onAudioFocusChangeWithMetaData, el método debería mostrar resultados con el error UNKNOWN_TRANSACTION, como se describe en Cómo usar una interfaz con versiones Métodos.

El servicio de audio primero llama a onAudioFocusChangeWithMetaData y luego, los reintenta con el método onAudioFocusChange si un UNKNOWN_TRANSACTION los resultados de errores.

Autosilenciado de fondo con metadatos de pistas de reproducción

La versión 2.0 de la HAL de control de audio del AIDL agregó los metadatos de la pista de reproducción a la información del autosilenciado de fondo:

parcelable DuckingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be ducked.
       */
       String[] deviceAddressesToDuck;
       /**
       *   List of addresses for audio output devices that were previously be
       *   ducked and should now be unducked.
       */
       String[] deviceAddressesToUnduck;
       /**
       *   List of usages currently holding focus for this audio zone.
       */
       String[] usagesHoldingFocus;
       /**
       *   List of output stream metadata associated with the current focus
       *   holder for this audio zone
       */
       @nullable PlaybackTrackMetadata[] playbackMetaDataHoldingFocus;
}

usagesHoldingFocus ya no está disponible. Los desarrolladores ahora deberían usar playbackMetaDataHoldingFocus para determinar el uso del atributo de audio y otras información de audio. Dicho esto, el parámetro usagesHoldingFocus todavía contiene la información requerida hasta que esta opción se elimine formalmente.

Devolución de llamada de ganancia de audio

Si quieres hacer cambios de audio debajo de la HAL, más visible para el AAOS en Android 13, agregamos un mecanismo que puedes usar para comunicarte el audio recibe cambios del sistema de audio del automóvil al servicio de audio del automóvil. El mecanismo expone los cambios en el índice de volumen de audio con un motivo respectivo se modificó la ganancia:

  • Restricciones bloqueadas o silenciadas
  • Limitaciones y restricciones
  • Restricciones de atenuación

Estos cambios exponen las restricciones inferiores de la HAL al un servicio de audio para autos y, por último, una app de IU del sistema para informar al usuario. La última parte, la exposición a una posible IU del sistema, se amplió aún más en Android 14 para permitir que las apps de la IU del sistema obtengan esta información más fácilmente a través de un mecanismo de devolución de llamada de información de grupos de volúmenes.

La API de HAL de control de audio registra la devolución de llamada de ganancia de la siguiente manera:

interface IAudioControl {
       /**
       *   Registers callback to be used by HAL for reporting unexpected gain(s)
       *    changed and the reason(s) why.
       *
       *   @param callback The {@link IAudioGainCallback}.
       */
       oneway void registerGainCallback(in IAudioGainCallback callback);
}

IAudioGainCallback se define de la siguiente manera:

interface IAudioGainCallback {
       /**
       *   Used to indicate that one or more audio device port gains have changed,
       *   i.e. initiated by HAL, not by CarAudioService.
       *   This is the counter part of the
       *   {@link onDevicesToDuckChange}, {@link onDevicesToMuteChange} and,
       *   {@link setAudioDeviceGainsChanged} APIs.
       *
       *   @param reasons List of reasons that triggered the given gains changed.
       *   @param gains List of gains affected by the change.
       */
       void onAudioDeviceGainsChanged(in Reasons[] reasons,
       in AudioGainConfigInfo[] gains);
}

Como se destaca en la documentación de la API, la devolución de llamada de ganancia se registra en el el servicio de audio del auto a la HAL de control de audio. Cuando se llama a la API desde HAL de control de audio, el servicio de audio del auto responde con la acción correspondiente (como bloquear, limitar o atenuar el índice de ganancia) .

La HAL determina cuándo se llama a la API, principalmente para informar cambios a la y obtener el estado de índice. El sistema de audio del vehículo, específico de los requisitos reglamentarios debe realizar la acción requerida y usar la devolución de llamada para informar la información a el servicio de audio del automóvil para permitir el consumo del usuario. Por ejemplo, para mostrar una IU para el usuario.

HAL de control de audio del AIDL 3.0

La versión de la HAL de control de audio del AIDL de Android 14 es Se actualizó a la versión 3.0 para actualizar las APIs y proporcionar una ganancia de audio más sólida. de índice de Google. La API de la HAL de control de audio permite que el servicio de audio haga lo siguiente: Establece y desactiva un IModuleChangeCallback:

interface IAudioControl {
       /**
       *   Sets callback with HAL for notifying changes to hardware module
       *   (that is: {@link android.hardware.audio.core.IModule}) configurations.
       *
       *   @param callback The {@link IModuleChangeCallback} interface to use
       *    use when new updates are available for
       */
       void setModuleChangeCallback(in IModuleChangeCallback callback);
       /**
       *   Clears module change callback
       */
       void clearModuleChangeCallback();
}

El servicio de audio del vehículo registra el setModuleChangeCallback cuando se inicia el servicio o cuando se recupera de un error. Por ejemplo, un control de audio Notificación de cierre de HAL de Binder recibida por el servicio de audio para automóviles El audio la implementación de control de HAL debe reemplazar cualquier devolución de llamada de cambio de módulo existente cuando se llama a la API.

Para la API de clearModuleChangeCallback, la implementación debe borrar los devolución de llamada existente o no hacer nada si no existe una. Es una buena práctica la implementación del control de audio a fin de registrar un observador de muertes para la devolución de llamada y, luego, borrar la devolución de llamada si se activa el cierre de Binder.

IModuleChangeCallback se define de la siguiente manera:

oneway interface IModuleChangeCallback {
       /**
       *   Used to indicate that one or more {@link AudioPort} configs have
       *   changed. Implementations MUST return at least one AudioPort.
       *
       *   @param audioPorts list of {@link AudioPort} that are updated
       */
       void onAudioPortsChanged(in AudioPort[] audioPorts);
}

Cuando el servicio de audio del automóvil registra la devolución de llamada de cambio de módulo, se Listo para recibir cambios de puerto de audio a través de la API de onAudioPortChanged. El Se puede usar la API para inicializar el aumento de volumen para el sistema de audio en cuanto se registra la devolución de llamada. Para otros cambios de ganancia dinámica, se puede llamar a la API en cualquier momento. Se aplican los cambios correspondientes y se actualiza el servicio de audio para automóviles según corresponda.