HAL kontrol audio

HAL kontrol audio diperkenalkan di Android 9 untuk mendukung kasus penggunaan audio yang relevan dengan otomotif. Mulai Android 14, HAL kontrol audio mendukung:

  • Pudar dan seimbang
  • Permintaan fokus audio HAL
  • Membisukan dan meredam suara perangkat
  • Perubahan gain perangkat audio
  • Perubahan konfigurasi port audio

Gambar 1 menunjukkan ringkasan umum arsitektur layanan audio mobil, tempat layanan audio mobil berkomunikasi dengan HAL kontrol audio.

Mengonfigurasi audio multi-zona

Gambar 1. Mengonfigurasi audio multi-zona.

Audio memudar dan seimbang

HAL kontrol audio HIDL versi 1 diperkenalkan di Android 9 untuk mendukung fade dan keseimbangan audio dalam kasus penggunaan otomotif. Terpisah dari efek audio generik yang sudah disediakan di Android, mekanisme ini memungkinkan aplikasi sistem menyetel keseimbangan audio dan memudar melalui CarAudioManager API:

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

Setelah API ini dipanggil, API HAL kontrol audio masing-masing akan dipanggil dari layanan audio mobil:

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

API ini tersedia di semua versi HAL kontrol audio, termasuk antarmuka HAL AIDL baru.

Permintaan fokus audio dari HAL

AAOS, mirip dengan Android, mengandalkan partisipasi aktif aplikasi pada fokus audio untuk mengelola pemutaran audio di mobil. Informasi fokus digunakan untuk mengelola streaming yang akan dikontrol untuk volume dan peredam suara. Dengan demikian, untuk lebih memperluas fokus audio dan memberikan integrasi suara khusus mobil yang lebih baik ke dalam pengalaman Android, atribut audio berikut diperkenalkan di Android 11:

  • EMERGENCY
  • SAFETY
  • VEHICLE_STATUS
  • ANNOUNCEMENT

Selain perubahan ini, mekanisme ditambahkan untuk suara yang berasal dari di luar Android untuk berpartisipasi dalam permintaan fokus audio. Dengan demikian, HAL kontrol audio HIDL versi 2 diperkenalkan untuk memungkinkan permintaan fokus yang berasal dari luar 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);
}

Dengan IFocusListener ditentukan sebagai:

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

API di atas dapat digunakan untuk meminta dan meninggalkan fokus audio dari HAL. Sebagai respons, layanan audio mobil mempertimbangkan permintaan fokus audio dan meneruskan hasilnya secara asinkron ke metode IAudioControl#onAudioFocusChange.

API ini juga dapat digunakan untuk memantau perubahan permintaan fokus audio yang berasal dari HAL kontrol audio. Secara umum, setiap permintaan fokus audio yang ada dari HAL dianggap aktif, yang berbeda dengan permintaan fokus audio dari Android, yang hanya memutar trek audio aktif yang sesuai dianggap aktif.

Memigrasikan HIDL ke HAL kontrol audio AIDL

Dengan munculnya AIDL dan migrasi yang diperlukan di Android 12 (untuk mempelajari lebih lanjut, lihat AIDL untuk HAL), HAL kontrol audio dimigrasikan ke AIDL. Untuk API kontrol audio HIDL versi 2 yang ada, migrasi memerlukan update minor pada metode yang ada:

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

Dan IFocusListener yang sesuai:

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

Pembisuan grup volume

Android 12 memperkenalkan bisukan grup volume untuk memungkinkan kontrol bisukan yang lebih komprehensif selama interaksi audio pengguna. Hal ini memungkinkan HAL kontrol audio menerima peristiwa bisukan seperti yang dicegat oleh layanan audio mobil.

Untuk mengaktifkan fitur ini, OEM harus menetapkan konfigurasi audioUseCarVolumeGroupMuting ke true di layanan mobil 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>

Sebelum Android 13, konfigurasi harus ditimpa dengan overlay resource runtime untuk packages/services/Car/service/res/values/config.xml (untuk mempelajari lebih lanjut, lihat Menyesuaikan build dengan overlay resource). Dari Android 13, Anda dapat menggunakan overlay resource runtime untuk mengubah nilai konfigurasi. Untuk mempelajari lebih lanjut, lihat Mengubah nilai resource aplikasi saat runtime.

Aplikasi sistem dapat menentukan apakah fitur diaktifkan menggunakan CarAudioManager#isAudioFeatureEnabled API. Parameter yang diteruskan harus berupa konstanta CarAudioManager.AUDIO_FEATURE_VOLUME_GROUP_MUTING. Metode ini menampilkan true jika fitur diaktifkan di perangkat, atau false jika tidak.

Selain mengaktifkan fitur audioUseCarVolumeGroupMuting, HAL kontrol audio AIDL harus menerapkan mekanisme bisukan grup volume:

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

Info bisukan berisi informasi bisukan yang relevan untuk sistem 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 memiliki dua mekanisme berbeda untuk membisukan, berdasarkan:

  • Peristiwa utama menggunakan KEYCODE_VOLUME_MUTE audio.

  • Panggilan langsung ke layanan audio mobil menggunakan API bisukan pengelola audio mobil, CarAudioManager#setVolumeGroupMute.

Jika diaktifkan, kedua mekanisme tersebut akan memicu bisukan panggilan ke HAL kontrol audio.

Pengecilan volume audio mobil

Android 12 memperkenalkan audio mobil yang diredam untuk mengoptimalkan kontrol pemutaran simultan streaming audio. Hal ini memungkinkan OEM menerapkan perilaku bisukan mereka sendiri berdasarkan konfigurasi audio fisik mobil dan status pemutaran saat ini, seperti yang ditentukan oleh layanan audio mobil.

Mekanisme pengecilan volume didasarkan pada perubahan stack fokus audio. Setiap kali terjadi perubahan fokus (baik permintaan fokus maupun pengabaian fokus), HAL kontrol audio akan diberi tahu. Serupa dengan dukungan bisukan grup volume mobil, audio mobil dapat dibisukan dengan flag konfigurasi 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>

Untuk mengaktifkan fitur ini, HAL kontrol audio AIDL harus menerapkan logika yang relevan dengan sinyal yang diterima dari layanan audio mobil:

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

Informasi sistem audio yang relevan terdapat dalam informasi ducking 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;
}

Selain informasi konfigurasi audio mobil yang terdapat di alamat perangkat untuk (tidak) menyembunyikan, informasi penyembunyian juga berisi informasi tentang penggunaan atribut audio yang mempertahankan fokus. Tujuan data ini adalah untuk memberi tahu sistem audio penggunaan atribut audio mana yang aktif.

Hal ini diperlukan karena, dalam konfigurasi audio mobil, beberapa atribut audio dapat ditetapkan ke satu perangkat dan, tanpa informasi tambahan, tidak jelas penggunaan mana yang aktif.

HAL 2.0 kontrol audio AIDL

Untuk mengupdate API dan memfasilitasi fungsi baru, HAL kontrol audio AIDL diupdate ke versi 2.0 di Android 13:

  • Fokus audio dengan PlaybackTrackMetadata
  • Callback penguatan audio

Metadata pemutaran ditentukan di android.hardware.audio.common sebagai berikut:

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

Semua fungsi lain dari kontrol audio AIDL versi 1.0 tetap ada dan dapat digunakan. Pengecualian berkaitan dengan metode perubahan fokus audio, seperti yang dijelaskan dalam Pada metode perubahan fokus audio.

Fokus kontrol audio dengan metadata trek pemutaran

Untuk mengekspos lebih banyak informasi ke sistem audio di bawah HAL, update kini mengekspos PlaybackTrackMetadata. Secara khusus, HAL kontrol audio diperluas dengan metode baru:

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

Perubahan yang serupa dan sesuai dilakukan pada 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);
}

Pada metode perubahan fokus audio

Operasi fokus di atas berfungsi dengan cara yang sama seperti yang dijelaskan dalam Permintaan fokus audio dari HAL. Hanya metadata trek pemutaran yang memiliki informasi selengkapnya beserta penggunaan atribut audio. Secara umum, kecuali jika informasi tambahan yang diberikan oleh metadata trek pemutaran diperlukan, HAL kontrol Android yang diupdate dapat terus menggunakan metode sebelumnya.

Jika developer HAL memutuskan untuk tidak mendukung IAudioControl#onAudioFocusChangeWithMetaData, metode harus menampilkan hasil dengan error UNKNOWN_TRANSACTION seperti yang dijelaskan dalam Menggunakan Metode Antarmuka Versi.

Layanan audio pertama-tama memanggil onAudioFocusChangeWithMetaData, lalu mencoba lagi dengan metode onAudioFocusChange jika terjadi kegagalan UNKNOWN_TRANSACTION.

Audio mobil yang diredam dengan metadata trek pemutaran

HAL kontrol audio AIDL versi 2.0 menambahkan metadata trek pemutaran ke info audio ducking:

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 tidak digunakan lagi. Developer kini harus menggunakan playbackMetaDataHoldingFocus untuk menentukan penggunaan atribut audio dan informasi audio lainnya. Meskipun demikian, parameter usagesHoldingFocus masih berisi informasi yang diperlukan hingga opsi ini dihapus secara resmi.

Callback gain audio

Agar perubahan audio di bawah HAL lebih terlihat oleh AAOS di Android 13, kami menambahkan mekanisme yang dapat Anda gunakan untuk menyampaikan perubahan penguatan audio dari sistem audio mobil ke layanan audio mobil. Mekanisme ini mengekspos perubahan indeks volume penguatan audio dengan alasan masing-masing penguatan diubah:

  • Pembatasan yang diblokir atau dibisukan
  • Batasan pembatasan
  • Batasan atenuasi

Perubahan ini mengekspos batasan ini dari bawah HAL ke layanan audio mobil dan, akhirnya, ke aplikasi UI sistem untuk memberi tahu pengguna. Bagian terakhir, eksposur ke kemungkinan UI sistem, diperluas lebih lanjut di Android 14 untuk memungkinkan aplikasi UI sistem mendapatkan informasi ini dengan lebih mudah melalui mekanisme callback informasi grup volume.

HAL API kontrol audio mendaftarkan callback gain sebagai berikut:

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 ditentukan sebagai berikut:

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

Seperti yang ditandai dalam dokumentasi API, callback gain didaftarkan oleh layanan audio mobil ke HAL kontrol audio. Saat API dipanggil dari HAL kontrol audio, layanan audio mobil akan merespons dengan tindakan yang sesuai (seperti memblokir, membatasi, atau melemahkan indeks gain) .

HAL menentukan kapan API dipanggil, terutama untuk melaporkan perubahan pada status indeks gain. Khusus untuk persyaratan peraturan, sistem audio mobil harus mengambil tindakan yang diperlukan dan menggunakan callback untuk melaporkan informasi ke layanan audio mobil agar memungkinkan penggunaan pengguna. Misalnya, untuk menampilkan UI kepada pengguna.

HAL kontrol audio AIDL 3.0

Versi HAL kontrol audio AIDL Android 14 diupdate ke versi 3.0 untuk mengupdate API guna memberikan fungsi indeks gain audio yang lebih andal. HAL API kontrol audio memungkinkan layanan audio menetapkan dan membatalkan penetapan 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();
}

setModuleChangeCallback didaftarkan oleh layanan audio mobil saat layanan dimulai atau saat memulihkan dari error. Misalnya, notifikasi penghentian binder HAL kontrol audio yang diterima oleh layanan audio mobil. Implementasi HAL kontrol audio harus mengganti callback perubahan modul yang ada saat API dipanggil.

Untuk clearModuleChangeCallback API, penerapan harus menghapus callback yang ada atau tidak melakukan apa pun jika tidak ada. Praktik terbaik untuk implementasi kontrol audio adalah mendaftarkan observer penghentian untuk callback lalu menghapus callback jika penghentian binder dipicu.

IModuleChangeCallback didefinisikan sebagai berikut:

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

Saat callback perubahan modul didaftarkan oleh layanan audio mobil, callback tersebut siap menerima perubahan port audio melalui onAudioPortChanged API. API dapat digunakan untuk melakukan inisialisasi penguatan volume untuk sistem audio segera setelah callback didaftarkan. Untuk perubahan penguatan dinamis lainnya, API dapat dipanggil kapan saja. Perubahan yang sesuai akan diterapkan dan layanan audio mobil akan diperbarui sesuai kebutuhan.