Control de audioHAL

Control de audio HAL se introdujo en Android 9 para admitir casos de uso de audio relevantes para la automoción. A partir de Android 14, el control de audio HAL admite:

  • Desvanecimiento y equilibrio
  • Solicitud de enfoque de audio HAL
  • Silenciar y agachar el dispositivo
  • Cambios de ganancia del dispositivo de audio
  • Cambios en la configuración del puerto de audio

La Figura 1 muestra una descripción general de alto nivel de la arquitectura del servicio de audio del automóvil, en la que el servicio de audio del automóvil se comunica con el control de audio HAL.

Configurar audio multizona

Figura 1. Configurar audio multizona.

Desvanecimiento y equilibrio del audio

Control de audio HIDL HAL versión 1 se introdujo en Android 9 para admitir el desvanecimiento y el equilibrio del audio en casos de uso automotriz. Aparte de los efectos de audio genéricos que ya se proporcionan en Android, este mecanismo permite que las aplicaciones del sistema establezcan el equilibrio de audio y se desvanezcan a través de las API 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 llaman estas API, las respectivas API HAL de control de audio se llaman desde el servicio de audio del automóvil:

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 del control de audio HAL, incluida la nueva interfaz AIDL HAL.

Solicitud de enfoque de audio de HAL

AAOS, similar a Android, se basa en la participación activa de aplicaciones de enfoque de audio para gestionar la reproducción de audio en los automóviles. La información de enfoque se utiliza para gestionar qué transmisiones controlar para el volumen y la atenuación. Como tal, para ampliar aún más el enfoque del audio y proporcionar una mejor integración de los sonidos específicos del automóvil en la experiencia de Android, se introdujeron los siguientes atributos de audio en Android 11:

  • EMERGENCY
  • SAFETY
  • VEHICLE_STATUS
  • ANNOUNCEMENT

Además de este cambio, se agregó un mecanismo para que los sonidos que se originan fuera de Android participen en las solicitudes de enfoque de audio. Por lo tanto, se introdujo el control de audio HIDL HAL versión 2 para permitir 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);
}

Donde IFocusListener se define como:

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 API anteriores se pueden utilizar para solicitar y abandonar el enfoque de audio de HAL, respectivamente. En respuesta, el servicio de audio para automóvil considera la solicitud de enfoque de audio y reenvía los resultados de forma asincrónica al método IAudioControl#onAudioFocusChange .

Esta API también se puede utilizar para monitorear los cambios de la solicitud de enfoque de audio que se origina en el control de audio HAL. En general, cualquier solicitud de enfoque de audio permanente de HAL se considera activa , a diferencia de una solicitud de enfoque de audio de Android, en la que solo se considera activa la reproducción de la pista de audio activa correspondiente.

Migrar HIDL a AIDL control de audio HAL

Con la llegada de AIDL y la migración requerida en Android 12 (para obtener más información, consulte AIDL para HAL ), el control de audio HAL se migró a AIDL. Para las API de control de audio HIDL versión 2 existentes, la migración requirió actualizaciones menores de 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);
}

Silenciamiento de grupo de volumen

Android 12 introdujo el silenciamiento del grupo de volumen para permitir un control de silencio más completo durante las interacciones de audio del usuario. Esto permite que el control de audio HAL reciba eventos de silenciamiento interceptados por el servicio de audio del automóvil.

Para habilitar la función, los OEM deben configurar la configuración audioUseCarVolumeGroupMuting en true en el archivo car service 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, la configuración debía sobrescribirse con una superposición de recursos de tiempo de ejecución para packages/services/Car/service/res/values/config.xml (para obtener más información, consulte Personalización de la compilación con superposiciones de recursos ). Desde Android 13, puede usar superposiciones de recursos de tiempo de ejecución para cambiar un valor de configuración. Para obtener más información, consulte Cambiar el valor de los recursos de una aplicación en tiempo de ejecución .

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

Además de habilitar la función audioUseCarVolumeGroupMuting , el control de audio AIDL HAL debe implementar el mecanismo de silenciamiento del grupo 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);
}

Donde la información de silencio 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, basados ​​en:

  • Eventos clave usando el audio KEYCODE_VOLUME_MUTE {:.external}.

  • Llamadas directas al servicio de audio del automóvil mediante la API de silencio del administrador de audio del automóvil, CarAudioManager#setVolumeGroupMute .

Cuando están habilitados, ambos mecanismos activan un silencio de llamada al control de audio HAL.

Audio del coche agachándose

Android 12 introdujo la atenuación del audio del automóvil para optimizar el control de la reproducción simultánea de transmisiones de audio. Esto permite a los OEM implementar su propio comportamiento de reducción en función de la configuración de audio física de un automóvil y el estado de reproducción actual, según lo determine el servicio de audio del automóvil.

El mecanismo de atenuación se basa en los cambios de la pila de enfoque de audio. Cada vez que ocurre un cambio de enfoque (ya sea una solicitud de enfoque o un abandono de enfoque), se informa al control de audio HAL. De manera similar a la compatibilidad con el silenciamiento del grupo de volumen del automóvil, la atenuación del audio del automóvil se puede habilitar con el indicador 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, el control de audio AIDL HAL debe implementar la lógica correspondiente 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 está contenida en la información de reducción de audio:

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 automóvil contenida en las direcciones del dispositivo para (des) agachar, la información de agacharse también contiene información sobre qué usos de atributos de audio están manteniendo el foco. La intención de estos datos es informar al sistema de audio qué usos de atributos de audio están activos.

Esto es necesario ya que, en la configuración de audio del automóvil, se pueden asignar múltiples atributos de audio a un solo dispositivo y, sin información adicional, no está claro qué usos están activos.

Control de audio AIDL HAL 2.0

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

  • Enfoque de audio con PlaybackTrackMetadata
  • Devolución de llamada de ganancias de audio

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 funciones de la versión 1.0 del control de audio AIDL se conservan y se pueden utilizar. Una excepción se refiere al método de cambio de enfoque de audio, como se describe en Método de cambio de enfoque de audio .

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

Para exponer más información al sistema de audio debajo de HAL, las actualizaciones ahora exponen PlaybackTrackMetadata . En concreto, el control de audio HAL se amplió con un nuevo método:

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);
}

Sobre el método de cambio de enfoque de audio

Las operaciones de enfoque anteriores se realizan de la misma manera que las descritas en Solicitud de enfoque de audio de HAL . Sólo los metadatos de la pista de reproducción tienen más información junto con los usos de los atributos de audio. En general, a menos que se necesite la información adicional proporcionada por los metadatos de la pista de reproducción, el control de Android actualizado HAL puede continuar utilizando los métodos anteriores.

Si los desarrolladores de HAL deciden no admitir IAudioControl#onAudioFocusChangeWithMetaData , el método debería devolver resultados con el error UNKNOWN_TRANSACTION como se describe en Uso de métodos de interfaz versionados .

El servicio de audio primero llama onAudioFocusChangeWithMetaData y luego vuelve a intentar con el método onAudioFocusChange si se produce un error UNKNOWN_TRANSACTION .

Audio del coche ducking con metadatos de pistas de reproducción

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

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 está en desuso. Los desarrolladores ahora deberían usar playbackMetaDataHoldingFocus para determinar el uso de atributos de audio y otra información de audio. Dicho esto, el parámetro usagesHoldingFocus aún contiene la información requerida hasta que esta opción se elimine formalmente.

Devolución de llamada de ganancia de audio

Para que los cambios de audio debajo de HAL sean más visibles para AAOS en Android 13, agregamos un mecanismo que puede usar para comunicar los cambios de ganancia de audio desde el sistema de audio del automóvil al servicio de audio del automóvil. El mecanismo expone los cambios en el índice de volumen de ganancia de audio con el motivo respectivo por el cual se cambió la ganancia:

  • Restricciones bloqueadas o silenciadas
  • Restricciones de limitaciones
  • Restricciones de atenuación

Estos cambios exponen estas restricciones desde debajo de HAL al servicio de audio del automóvil y, finalmente, a una aplicación de interfaz de usuario del sistema para informar al usuario. La última parte, la exposición a una posible interfaz de usuario del sistema, se amplió aún más en Android 14 para permitir que las aplicaciones de la interfaz de usuario del sistema obtengan más fácilmente esta información a través de un mecanismo de devolución de llamada de información de grupo de volúmenes.

La API 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, el servicio de audio del automóvil registra la devolución de llamada de ganancia en el control de audio HAL. Cuando se llama a la API desde el control de audio HAL, el servicio de audio del automóvil responde con la acción correspondiente (como bloquear, limitar o atenuar el índice de ganancia).

HAL determina cuándo se llama a la API, principalmente para informar cambios en el estado del índice de ganancia. Específicamente según los requisitos reglamentarios, el sistema de audio del automóvil debe tomar las medidas necesarias y utilizar la devolución de llamada para informar información al servicio de audio del automóvil para permitir el consumo del usuario. Por ejemplo, para mostrar una interfaz de usuario al usuario.

Control de audio AIDL HAL 3.0

La versión HAL de control de audio AIDL de Android 14 se actualiza a la versión 3.0 para actualizar las API y proporcionar una funcionalidad de índice de ganancia de audio más sólida. La API HAL de control de audio permite que el servicio de audio configure y desactive 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 automóvil registra setModuleChangeCallback cuando se inicia el servicio o cuando se recupera de un error. Por ejemplo, una notificación de muerte de la carpeta HAL de control de audio recibida por el servicio de audio del automóvil. La implementación HAL de control de audio debe reemplazar cualquier devolución de llamada de cambio de módulo existente cuando se llama a la API.

Para la API clearModuleChangeCallback , la implementación debe borrar la devolución de llamada existente o no hacer nada si no existe ninguna. Es una buena práctica para la implementación del control de audio registrar un observador de muerte para la devolución de llamada y luego borrar la devolución de llamada si se activa la muerte en la carpeta.

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, está listo para recibir cambios en el puerto de audio a través de la API onAudioPortChanged . La API se puede utilizar para inicializar las ganancias de volumen del sistema de audio tan pronto como 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 el servicio de audio del automóvil se actualiza en consecuencia.