Android 9 では、以前のバージョンの Vehicle HAL の AUDIO_*
プロパティを非推奨とし、明示的な関数呼び出しと型付きパラメータ リストを含む専用の Audio Control HAL に置き換えています。
この新しい HAL は、構成や音量調節のために車両のオーディオ エンジンとやり取りするエントリ ポイントを提供するメインのインターフェース オブジェクトとして IAudioControl
を公開します。システムには、このオブジェクトのインスタンスを 1 つだけ含めることができます。このインスタンスは、起動時に CarAudioService
によって作成されます。このオブジェクトは、従来の Android Audio HAL の自動車用拡張機能です。ほとんどの実装では、Audio HAL インターフェースを公開する場合と同じプロセスで IAudioControl interfaces
も公開できます。
サポートされているインターフェース
AudioControl
HAL は、次のインターフェースをサポートしています。
getBusforContext
。ContextNumber
からbusAddress
へのマッピングを取得するために、コンテキストごとに起動時に 1 回呼び出されます。使用例: 車両が各コンテキストの物理出力ストリームのルーティング先をフレームワークに指定できるようにします。コンテキストごとに、有効なバス数(0~バス数-1)を返す必要があります。認識されないgetBusForContext(ContextNumber contextNumber) generates (uint32_t busNumber);
contextNumber
が発生した場合は、-1 が返されます。無効なbusNumber
が返されるコンテキストは、バス 0 にルーティングされます。
このメカニズムを介して同じbusNumber
に関連付けられた同時実行サウンドは、AndroidAudioFlinger
によってミックスされてから単一ストリームとして Audio HAL に配信されます。これは、車両 HAL プロパティのAUDIO_HW_VARIANT
とAUDIO_ROUTING_POLICY
より優先されます。setBalanceTowardRight
。車両スピーカーの左右のバランス設定を制御します。使用例: スピーカーの音量を車両の右側(+)または左側(-)に切り替えます。0.0 は中央、+1.0 は完全右方、-1.0 は完全左方、-1~1 の範囲外の値はエラーです。setBalanceTowardRight(float value);
setFadeTowardFront
。車両スピーカーの前後のフェード設定を制御します。使用例: スピーカーの音量を車両の前方(+)または後方(-)に切り替えます。 0.0 は中央、+1.0 は完全前方、-1.0 は完全後方、-1~1 の範囲外の値はエラーです。setFadeTowardFront(float value);
音量の設定
Android Automotive の実装では、ソフトウェア ミキサーの代わりにハードウェア アンプを使用して音量を調節する必要があります。想定外の事態を回避するには、device/generic/car/emulator/audio/overlay/frameworks/base/core/res/res/values/config.xml
で config_useFixedVolume
フラグを true
に設定します(必要に応じてオーバーレイします)。
<resources> <!-- Car uses hardware amplifier for volume. --> <bool name="config_useFixedVolume">true</bool> </resources>
config_useFixedVolume
フラグが設定されていない(または false
に設定されている)場合、アプリで AudioManager.setStreamVolume()
を呼び出して、ソフトウェア ミキサーのストリーム タイプ別に音量を変更できます。これは他のアプリに影響を及ぼす可能性があり、ソフトウェア ミキサーで音量を下げると、ハードウェア アンプで受信した信号で利用できる有効ビットが少なくなるため、望ましくない場合があります。
音量グループの構成
CarAudioService
は、packages/services/Car/service/res/xml/car_volume_group.xml
で定義されたボリューム グループを使用します。必要に応じて、このファイルをオーバーライドして音量グループを再定義できます。グループは、XML ファイル内での定義の順序によって実行時に識別されます。ID の範囲は 0~N-1 で、N は音量グループの数です。例:
<volumeGroups xmlns:car="http://schemas.android.com/apk/res-auto"> <group> <context car:context="music"/> <context car:context="call_ring"/> <context car:context="notification"/> <context car:context="system_sound"/> </group> <group> <context car:context="navigation"/> <context car:context="voice_command"/> </group> <group> <context car:context="call"/> </group> <group> <context car:context="alarm"/> </group> </volumeGroups>
この構成で使用される属性は packages/services/Car/service/res/values/attrs.xml
で定義されています。
音量キーイベントの処理
Android では、KEYCODE_VOLUME_UP
、KEYCODE_VOLUME_DOWN
、KEYCODE_VOLUME_MUTE
など、音量調節用のいくつかのキーコードを定義しています。デフォルトでは、Android は音量キーイベントをアプリにルーティングします。Automotive の実装においては、こうしたキーイベントを CarAudioService
に対して強制実行する必要があります。その後、必要に応じて setGroupVolume
または setMasterMute
を呼び出すことができます。
この動作を強制するには、device/generic/car/emulator/car/overlay/frameworks/base/core/res/res/values/config.xml
で config_handleVolumeKeysInWindowManager
フラグを true
に設定します。
<resources> <bool name="config_handleVolumeKeysInWindowManager">true</bool> </resources>
CarAudioManager API
CarAudioManager
は、CarAudioService
を使用して車両のオーディオ システムを構成および制御します。このマネージャーはシステム内のほとんどのアプリには表示されませんが、音量コントローラなどの車両固有のコンポーネントは CarAudioManager
API を使用してシステムと通信できます。
以下のセクションでは、CarAudioManager API
に対する Android 9 の変更点について説明します。
サポート終了 API
Android 9 は、既存の AudioManager
getDeviceList
API を使用してデバイス列挙を処理するため、次の車両固有の機能はサポート終了となり、削除されました。
String[] getSupportedExternalSourceTypes()
String[] getSupportedRadioTypes()
Android 9 は、AudioAttributes.AttributeUsage
またはボリューム グループベースのエントリ ポイントを使用して音量を処理するため、streamType
に依存する次の API は削除されています。
void setStreamVolume(int streamType, int index, int flags)
int getStreamMaxVolume(int streamType)
int getStreamMinVolume(int streamType)
void setVolumeController(IVolumeController controller)
新しい API
Android 9 では、(音量グループに明示的に基づいて)アンプ ハードウェアを制御するための次の新しい API が追加されています。
int getVolumeGroupIdForUsage(@AudioAttributes.AttributeUsage int usage)
int getVolumeGroupCount()
int getGroupVolume(int groupId)
int getGroupMaxVolume(int groupId)
int getGroupMinVolume(int groupId)
さらに、Android 9 には、System GUI で使用する次の新しいシステム API が用意されています。
void setGroupVolume(int groupId, int index, int flags)
void registerVolumeChangeObserver(@NonNull ContentObserver observer)
void unregisterVolumeChangeObserver(@NonNull ContentObserver observer)
void registerVolumeCallback(@NonNull IBinder binder)
void unregisterVolumeCallback(@NonNull IBinder binder)
void setFadeToFront(float value)
Void setBalanceToRight(float value)
最後に、Android 9 では外部ソース管理用の新しい API が追加されています。こうした API は、メディアタイプに基づいた外部ソースから出力バスへのオーディオ ルーティングのサポートを主目的としています。また、場合によっては、サードパーティ アプリによる外部デバイスへのアクセスを有効にすることもできます。
String[] getExternalSources()
。AUX_LINE
、FM_TUNER
、TV_TUNER
、BUS_INPUT
のタイプのシステムで利用可能なオーディオ ポートを識別するアドレスの配列を返します。CarPatchHandle createAudioPatch(String sourceAddress, int carUsage)
。ソースアドレスを、指定されたcarUsage
に関連付けられた出力BUS
にルーティングします。int releaseAudioPatch(CarPatchHandle patch)
。提供されたパッチを削除します。CarPatchHandle
の作成元が予期せず終了した場合は、AudioPolicyService::removeNotificationClient()
によって自動的に処理されます。
オーディオ パッチの作成
ミックスポートまたはデバイスポートの 2 つのオーディオ ポート間にオーディオ パッチを作成できます。通常、ミックスポートからデバイスポートへのオーディオ パッチは再生用で、逆方向はキャプチャ用です。
たとえば、FM_TUNER
ソースからメディアシンクにオーディオ サンプルを直接ルーティングするオーディオ パッチは、ソフトウェア ミキサーをバイパスします。その後、ハードウェア ミキサーを使用して、Android のオーディオ サンプルとシンク用の FM_TUNER
をミックスする必要があります。FM_TUNER
ソースからメディアシンクにオーディオ パッチを直接作成する場合は次の点にご注意ください。
- 音量調節はメディアシンクに適用され、Android と
FM_TUNER
両方の音声に影響します。 - ユーザーはシンプルなアプリの切り替え機能で Android と
FM_TUNER
の音声を切り替えることができる必要があります(明示的なメディアソースの選択は不要でなければなりません)。
Automotive の実装では、2 つのデバイスポート間にオーディオ パッチを作成する必要が生じる場合もあります。その場合はまず、audio_policy_configuration.xml
でデバイスポートと可能なルートを宣言し、ミックスポートをこれらのデバイスポートに関連付けます。
構成の例
device/generic/car/emulator/audio/audio_policy_configuration.xml
もご覧ください。
<audioPolicyConfiguration> <modules> <module name="primary" halVersion="3.0"> <attachedDevices> <item>bus0_media_out</item> <item>bus1_audio_patch_test_in</item> </attachedDevices> <mixPorts> <mixPort name="mixport_bus0_media_out" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="mixport_audio_patch_in" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/> </mixPort> </mixPorts> <devicePorts> <devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus0_media_out"> <profile balance="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> <gains> <gain name="" mode="AUDIO_GAIN_MODE_JOINT" minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort> <devicePort tagName="bus1_audio_patch_test_in" type="AUDIO_DEVICE_IN_BUS" role="source" address="bus1_audio_patch_test_in"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/> <gains> <gain name="" mode="AUDIO_GAIN_MODE_JOINT" minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort> </devicePorts> <routes> <route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out,bus1_audio_patch_test_in"/> <route type="mix" sink="mixport_audio_patch_in" sources="bus1_audio_patch_test_in"/> </routes> </module> </modules> </audioPolicyConfiguration>
オーディオ ドライバ用 API
getExternalSources()
を使用して使用可能なソースのリスト(アドレスで識別)を取得すると、オーディオの用途ごとにこうしたソースとシンクポートの間にオーディオ パッチを作成できます。Audio HAL の対応するエントリ ポイントは IDevice.hal
に表示されます。
Interface IDevice { ... / * Creates an audio patch between several source and sink ports. The handle * is allocated by the HAL and must be unique for this audio HAL module. * * @param sources patch sources. * @param sinks patch sinks. * @return retval operation completion status. * @return patch created patch handle. */ createAudioPatch(vec<AudioPortConfig> sources, vec<AudioPortConfig> sinks) generates (Result retval, AudioPatchHandle patch); * Release an audio patch. * * @param patch patch handle. * @return retval operation completion status. */ releaseAudioPatch(AudioPatchHandle patch) generates (Result retval); ... }
音量設定 UI の構成
Android 9 では、音量設定 UI が音量グループの構成と切り離されています(「音量グループの構成」の説明に従ってオーバーレイできます)。そのため、将来的に音量グループの構成が変わっても変更は不要です。
車両設定 UI では、packages/apps/Car/Settings/res/xml/car_volume_items.xml
ファイルには、定義された各 AudioAttributes.USAGE
に関連付けられた UI 要素(タイトルとアイコン リソース)が含まれます。このファイルは、各 VolumeGroup に含まれる最初に認識された用途に関連付けられたリソースを使用して、定義された VolumeGroup の適切なレンダリングを可能にします。
たとえば次の例では、voice_communication
と voice_communication_signalling
の両方を含む VolumeGroup を定義しています。車両設定 UI のデフォルトの実装では、voice_communication
に関連付けられたリソースを使用して VolumeGroup をレンダリングします。これがファイル内で最初に一致するためです。
<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto"> <item car:usage="voice_communication" car:title="@*android:string/volume_call" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="voice_communication_signalling" car:title="@*android:string/volume_call" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="media" car:title="@*android:string/volume_music" car:icon="@*android:drawable/ic_audio_media"/> <item car:usage="game" car:title="@*android:string/volume_music" car:icon="@*android:drawable/ic_audio_media"/> <item car:usage="alarm" car:title="@*android:string/volume_alarm" car:icon="@*android:drawable/ic_audio_alarm"/> <item car:usage="assistance_navigation_guidance" car:title="@string/navi_volume_title" car:icon="@drawable/ic_audio_navi"/> <item car:usage="notification_ringtone" car:title="@*android:string/volume_ringtone" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistant" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> <item car:usage="notification" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_request" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_instant" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_delayed" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_event" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistance_accessibility" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistance_sonification" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> <item car:usage="unknown" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> </carVolumeItems>
上記の構成で使用される属性と値は packages/apps/Car/Settings/res/values/attrs.xml
で宣言されています。音量設定 UI は、次の VolumeGroup
ベースの CarAudioManager
API を使用します。
getVolumeGroupCount()
: 描画するコントロールの数を確認します。getGroupMinVolume()
およびgetGroupMaxVolume()
: 下限値と上限値を取得します。getGroupVolume()
: 現在の音量を取得します。registerVolumeChangeObserver()
: 音量の変更に関する通知を受け取ります。