Kontrol audio HAL

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

  • Memudar dan menyeimbangkan
  • Permintaan fokus audio HAL
  • Perangkat tidak bersuara dan merunduk
  • Perubahan penguatan perangkat audio
  • Konfigurasi port audio berubah

Gambar 1 menunjukkan ikhtisar tingkat tinggi arsitektur layanan audio mobil, di mana layanan audio mobil berkomunikasi dengan kontrol audio HAL.

Konfigurasikan audio multi-zona

Gambar 1. Konfigurasikan audio multi-zona.

Audio memudar dan seimbang

Kontrol audio HIDL HAL versi 1 diperkenalkan di Android 9 untuk mendukung pemudaran dan keseimbangan audio dalam kasus penggunaan otomotif. Terpisah dari efek audio umum yang sudah disediakan di Android, mekanisme ini memungkinkan aplikasi sistem menyetel keseimbangan dan fade audio 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, masing-masing API HAL kontrol audio 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 tersedia di semua versi kontrol audio HAL, termasuk antarmuka AIDL HAL yang 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 mengatur aliran mana yang harus dikontrol volume dan pengecilannya. Oleh karena itu, untuk lebih memperluas fokus audio dan memberikan integrasi yang lebih baik dari suara spesifik mobil ke dalam pengalaman Android, atribut audio berikut diperkenalkan di Android 11:

  • EMERGENCY
  • SAFETY
  • VEHICLE_STATUS
  • ANNOUNCEMENT

Selain perubahan ini, ditambahkan mekanisme untuk suara yang berasal dari luar Android untuk berpartisipasi dalam permintaan fokus audio. Oleh karena itu, kontrol audio HIDL HAL 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);
}

Dimana IFocusListener didefinisikan 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 masing-masing dapat digunakan untuk meminta dan mengabaikan fokus audio dari HAL. Sebagai tanggapan, 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 kontrol audio HAL. Secara umum, setiap permintaan fokus audio tetap dari HAL dianggap aktif , berbeda dengan permintaan fokus audio dari Android, yang hanya memutar trek audio aktif terkait yang dianggap aktif.

Migrasikan HIDL ke kontrol audio AIDL HAL

Dengan munculnya AIDL dan migrasi yang diperlukan di Android 12 (untuk mempelajari lebih lanjut, lihat AIDL untuk HAL ), kontrol audio HAL dimigrasikan ke AIDL. Untuk API kontrol audio HIDL versi 2 yang ada, migrasi memerlukan sedikit pembaruan 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);
}

Grup volume dimatikan

Android 12 memperkenalkan fitur mute grup volume untuk memungkinkan kontrol mute yang lebih komprehensif selama interaksi audio pengguna. Hal ini memungkinkan kontrol audio HAL menerima kejadian mematikan seperti yang disadap oleh layanan audio mobil.

Untuk mengaktifkan fitur ini, OEM harus menyetel 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 resource overlay ). Mulai Android 13, Anda dapat menggunakan overlay sumber daya runtime untuk mengubah nilai konfigurasi. Untuk mempelajari lebih lanjut, lihat Mengubah nilai sumber daya aplikasi saat runtime .

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

Selain mengaktifkan fitur audioUseCarVolumeGroupMuting , kontrol audio AIDL HAL harus menerapkan mekanisme mematikan 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);
}

Jika info bisu berisi informasi bisu terkait 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 mematikan suara, berdasarkan:

  • Peristiwa penting menggunakan audio KEYCODE_VOLUME_MUTE {:.external}.

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

Saat diaktifkan, kedua mekanisme memicu panggilan bisu ke kontrol audio HAL.

Audio mobil merunduk

Android 12 memperkenalkan pengecilan audio mobil untuk mengoptimalkan kontrol pemutaran streaming audio secara bersamaan. Hal ini memungkinkan OEM untuk menerapkan perilaku merunduknya sendiri berdasarkan konfigurasi audio fisik mobil dan status pemutaran saat ini, sebagaimana ditentukan oleh layanan audio mobil.

Mekanisme pengecilan didasarkan pada perubahan tumpukan fokus audio. Setiap kali terjadi perubahan fokus (baik permintaan fokus atau pengabaian fokus), kontrol audio HAL akan diinformasikan. Mirip dengan dukungan pembungkaman grup volume mobil, pengecilan audio mobil dapat diaktifkan 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, kontrol audio AIDL HAL 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 pengecilan 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 dalam alamat perangkat ke (tidak) bebek, informasi pengelak juga berisi informasi tentang penggunaan atribut audio mana yang menjadi fokus. Tujuan dari data ini adalah untuk menginformasikan 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.

Kontrol audio AIDL HAL 2.0

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

  • Fokus audio dengan PlaybackTrackMetadata
  • Panggilan balik perolehan 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 dijelaskan dalam Tentang metode perubahan fokus audio .

Fokus kontrol audio dengan metadata trek pemutaran

Untuk memaparkan lebih banyak informasi ke sistem audio di bawah HAL, pembaruan kini mengekspos PlaybackTrackMetadata . Secara khusus, kontrol audio HAL 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 serupa 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);
}

Tentang metode perubahan fokus audio

Operasi fokus di atas dilakukan dengan cara yang sama seperti yang dijelaskan dalam Permintaan fokus audio dari HAL . Hanya metadata trek pemutaran yang memiliki informasi lebih lanjut beserta penggunaan atribut audio. Secara umum, kecuali informasi tambahan yang disediakan oleh metadata trek pemutaran diperlukan, kontrol android HAL yang diperbarui dapat terus menggunakan metode sebelumnya.

Jika pengembang HAL memutuskan untuk tidak mendukung IAudioControl#onAudioFocusChangeWithMetaData , metode tersebut akan mengembalikan hasil dengan kesalahan UNKNOWN_TRANSACTION seperti yang dijelaskan Menggunakan Metode Antarmuka Berversi .

Layanan audio terlebih dahulu memanggil onAudioFocusChangeWithMetaData lalu mencoba lagi dengan metode onAudioFocusChange jika terjadi kegagalan UNKNOWN_TRANSACTION .

Audio mobil merunduk dengan metadata trek pemutaran

Versi 2.0 dari kontrol audio AIDL HAL menambahkan metadata trek pemutaran ke info pengecilan 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 tidak digunakan lagi. Pengembang sekarang 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.

Panggilan balik penguatan audio

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

  • Pembatasan yang diblokir atau dibungkam
  • Batasan keterbatasan
  • Pembatasan atenuasi

Perubahan ini memaparkan pembatasan mulai dari bawah HAL pada layanan audio mobil dan, pada akhirnya, pada aplikasi UI sistem untuk memberi tahu pengguna. Bagian terakhir, paparan terhadap kemungkinan UI sistem, diperluas lebih lanjut di Android 14 agar aplikasi UI sistem lebih mudah mendapatkan informasi ini melalui mekanisme callback informasi grup volume.

API HAL kontrol audio mendaftarkan panggilan balik penguatan 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 didefinisikan 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 disorot dalam dokumentasi API, panggilan balik penguatan didaftarkan oleh layanan audio mobil ke kontrol audio HAL. Saat API dipanggil dari kontrol audio HAL, layanan audio mobil merespons dengan tindakan yang sesuai (seperti memblokir, membatasi, atau melemahkan indeks penguatan).

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

Kontrol audio AIDL HAL 3.0

Versi HAL kontrol audio AIDL Android 14 diperbarui ke versi 3.0 untuk memperbarui API guna menyediakan fungsionalitas indeks penguatan audio yang lebih kuat. API HAL kontrol audio memungkinkan layanan audio menyetel dan membatalkan setelan 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 pemulihan dari kesalahan. Misalnya, pemberitahuan kematian pengikat HAL kontrol audio yang diterima oleh layanan audio mobil. Implementasi HAL kontrol audio harus menggantikan callback perubahan modul yang ada saat API dipanggil.

Untuk API clearModuleChangeCallback , implementasinya harus menghapus callback yang ada atau tidak melakukan apa pun jika tidak ada. Merupakan praktik yang baik bagi implementasi kontrol audio untuk mendaftarkan pengamat kematian untuk panggilan balik dan kemudian menghapus panggilan balik jika kematian pengikat terpicu.

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

Ketika callback perubahan modul didaftarkan oleh layanan audio mobil, ia siap menerima perubahan port audio melalui API onAudioPortChanged . API dapat digunakan untuk menginisialisasi peningkatan volume untuk sistem audio segera setelah panggilan balik didaftarkan. Untuk perubahan penguatan dinamis lainnya, API dapat dipanggil kapan saja. Perubahan yang sesuai diterapkan dan layanan audio mobil diperbarui sesuai dengan itu.