Android 10 では、car_volumes_groups.xml
と IAudioControl.getBusForContext
が car_audio_configuration.xml
に置き換えられています。新しい構成ファイルでは、ゾーンのリストが定義されています。各ゾーンには 1 つ以上の音量グループが存在し、それぞれのグループにデバイスが関連付けられています。各デバイスには、そのゾーン内にルーティングする必要があるコンテキストがあります。すべてのコンテキストが各ゾーン内で表現される必要があります。
オーディオ ルーティングの構成
オーディオ ポリシー ファイル(通常はベンダー パーティションに存在します)は、ボードのオーディオ ハードウェア構成を表します。car_audio_configuration.xml
で参照されるデバイスはすべて、audio_policy_configuration.xml
内で定義する必要があります。
AAOS ルーティングを有効にする
AAOS ベースのルーティングを使用するには、audioUseDynamicRouting
フラグを true
に設定する必要があります。
<resources> <bool name="audioUseDynamicRouting">true</bool> </resources>
false
に設定すると、ルーティングと CarAudioService
の大部分が無効になり、OS は AudioService
のデフォルトの動作にフォールバックします。
プライマリ ゾーン
デフォルトでは、すべての音声がプライマリ ゾーンにルーティングされます。属性 isPrimary="true"
により構成で指定できるプライマリ ゾーンは 1 つのみです。
構成の例
たとえば、車両に 2 つのゾーン(プライマリ ゾーンとバックシート エンターテイメント システム)があるとします。この場合、car_audio_configuration.xml
は次のように定義されることが考えられます。
<audioZoneConfiguration version="2.0"> <zone name="primary zone" isPrimary="true"> <volumeGroups> <group> <device address="bus0_media_out"> <context context="music"/> <context context="announcement"/> </device> <device address="bus3_call_ring_out"> <context context="call_ring"/> </device> <device address="bus6_notification_out"> <context context="notification"/> </device> <device address="bus7_system_sound_out"> <context context="system_sound"/> <context context="emergency"/> <context context="safety"/> <context context="vehicle_status"/> </device> </group> <group> <device address="bus1_navigation_out"> <context context="navigation"/> </device> <device address="bus2_voice_command_out"> <context context="voice_command"/> </device> </group> <group> <device address="bus4_call_out"> <context context="call"/> </device> </group> <group> <device address="bus5_alarm_out"> <context context="alarm"/> </device> </group> </volumeGroups> </zone> <zone name="rear seat zone" audioZoneId="1"> <volumeGroups> <group> <device address="bus100_rear_seat"> <context context="music"/> <context context="navigation"/> <context context="voice_command"/> <context context="call_ring"/> <context context="call"/> <context context="alarm"/> <context context="notification"/> <context context="system_sound"/> <context context="emergency"/> <context context="safety"/> <context context="vehicle_status"/> <context context="announcement"/> </device> </group> </volumeGroups> </zones> </audioZoneConfiguration>
このプライマリ ゾーンには、各種のデバイスと、それぞれが持つコンテキストがあります。これにより、HAL は車両のハードウェアを使用して、さまざまな後処理効果を適用し、各デバイス出力にミキシングできます。デバイスは、メディア、ナビゲーション、通話、アラームの 4 つの音量グループに分類されています。システムが useFixedVolume
に構成されている場合は、各グループの音量レベルが HAL に渡され、これらのデバイスの出力に適用されます。
セカンダリ ゾーンについては、1 つの出力デバイスによる出力が想定されます。この例では、わかりやすくするために、すべての使用が 1 つのデバイスと音量グループにルーティングされます。
乗員ゾーンのオーディオ構成
Android 11 では car_audio_configuraton.xml
がさらに拡張され、audioZoneId
と occupantZoneId
という 2 つの新しいフィールドが導入されました。1 つ目の audioZoneId
を使用すると、ゾーン管理をより適切に制御できます。一方、occupantZoneId
を使用すると、ユーザー ID ベースのルーティングを構成できます。
これらの新しいフィールドを使用するには、car_audio_configuration.xml
の V2 が必要です。上のオーディオ構成を見直し、新しいフィールドを乗員ゾーン ID とオーディオ ゾーン ID のマッピングに使用すると、音量グループ定義のない新しい構成を次のように設定できます。
<audioZoneConfiguration version="2.0"> <zone name="primary zone" isPrimary="true" occupantZoneId="0"> ... </zone> <zone name="rear seat zone" audioZoneId="1" occupantZoneId="1"> ... </zone> </zones> </audioZoneConfiguration>
上の構成では、プライマリ ゾーンから乗員ゾーン 0 へのマッピングと、audioZoneId
1 から乗員ゾーン occupantZoneId
1 へのマッピングを定義しています。一般に、乗員ゾーンとオーディオ ゾーンの間のマッピングは構成できますが、1 対 1 のマッピングである必要があります。2 つの新しいフィールドを定義したルールを以下に示します。
- プライマリ ゾーンの
audioZoneId
は常にゼロです。 audioZoneId
とoccupantZoneId
の番号を繰り返すことはできません。audioZoneId
とoccupantZoneId
は 1 対 1 のマッピングのみ可能です。
アプリ UID 経由のルーティング
Android 10 では、一連の非表示 API が CarAudioManager
に導入され、アプリでオーディオ ゾーンとフォーカスを照会して設定できるようになりました。
int[] getAudioZoneIds(); int getZoneIdForUid(int uid); boolean setZoneIdForUid(int zoneId, int uid); boolean clearZoneIdForUid(int uid);
この API により、ファースト パーティ アプリはアプリの UID に基づいてオーディオ ルーティングを管理できます。そのため、オーディオ ゾーン ID とアプリの UID も必要です。この情報があれば、CarAudioManager#setZoneIdForUid
API を使用してオーディオ ルーティングを設定できます。
アプリのゾーンの変更
デフォルトでは、すべてのオーディオがプライマリ ゾーンにルーティングされます。別のゾーンにルーティングされるようにアプリを更新するには、CarAudioManager#setZoneIdForUid
を使用します。
// Find zone to play int zoneId = ... // Find application's uid Int uid = mContext.getPackageManager() .getApplicationInfo(mContext.getPackageName(), 0) .uid; if (mCarAudioManager.setZoneIdForUid(zoneId, info.uid)) { Log.d(TAG, "Zone successfully updated"); } else { Log.d(TAG, "Failed to change zone"); }
注: ストリームとフォーカスでは、ゾーンを動的に切り替えることができません。したがって、ゾーンを変更するには、再生を停止してフォーカスする必要があります。
ユーザー ID によるルーティング
アプリケーションの UID ベースのルーティングでは、各アプリのオーディオ ルーティングを細かく制御できますが、アプリが実際に音声フォーカスをリクエストしオーディオを再生する前に、各アプリのオーディオ ルーティングを定義する必要もあります。この問題を軽減し、サードパーティ アプリが変更なしでオーディオを再生できるようにするために、CarAudioService
は車両の乗員ゾーンとオーディオ ゾーンのマッピングを使用して、ユーザー ID ベースのルーティングを定義します。こうすることで、ユーザーが乗員ゾーンのカーオーディオ サービスにログインすると通知されます。このシグナルにより、音声フォーカスの管理とルーティングがすべてのオーディオ ゾーンに対して自動的に構成されます。
アプリの UID ベースのルーティングは引き続き使用できますが、ユーザー ID ルーティングとは別に行う必要があります。つまり、乗員ゾーンからカーオーディオ ゾーンへのマッピングが定義されている場合、UID ベースのルーティングは無効となり、CarAudioManager#setZoneidForUid
を呼び出そうとするとエラーがスローされます。
オーディオ ルーティングとフォーカス管理は乗員ゾーン管理によって簡素化されていますが、ユーザーは依然として乗員ゾーンに割り当てられる必要があります。これを行うには、CarOccupantZoneManager#assignProfileUserToOccupantZone
を使用します。この API にはユーザーを管理する権限が必要です。現時点では、OEM がなんらかのシステム UI を使用してユーザーから乗員ゾーンへの割り当てを管理することが想定されています。これが完了すると、アプリの起動、オーディオ ルーティング、フォーカス管理すべてが、ユーザーに対して自動的に構成されます。
setPreferredDevice によるルーティング
前述の変更に加えて、Android 11 には、各ゾーンに関連付けられた出力デバイスを照会する新しい API である CarAudioManager#getOutputDeviceForUsage(int zoneId, int usage) もあります。
この API を使用すると、特定のゾーンとオーディオ属性の使用状況について、出力デバイスに照会できます。このように、ファースト パーティ アプリはプレーヤーの setPreferredDevice
API を活用して、オーディオを別のゾーンにルーティングできます。getOutputDeviceForUsage
API はシステム API であり、PERMISSION_CAR_CONTROL_AUDIO_SETTINGS
が必要です。特定のゾーンのメディア デバイスを検索し、setPreferredDevice
API を使用してそのデバイスにルーティングする例を次に示します。
audioZoneId = ... ; mediaDeviceInfo = mCarAudioManager .getOutputDeviceForUsage(audioZoneId, AudioAttributes.USAGE_MEDIA); … mPlayer.setPreferredDevice(mediaDeviceInfo);