組み合わされたオーディオデバイスルーティング機能により、複数のオーディオデバイスに同時にオーディオをストリーミングするためのサポートが追加されます。この機能を使用すると、特権アプリはシステムAPIを介して特定の戦略に複数の優先デバイスを選択できます。アプリは、この機能によって提供されるパブリックAPIを使用することで、オーディオデバイスの機能をより正確に検出できます。 Androidバージョン11以下の場合、オーディオフレームワークの実装では、同時に接続された同じタイプの複数のオーディオデバイス(たとえば、2つのBluetooth A2DPヘッドセット)のサポートが制限されています。デフォルトのオーディオルーティングルールでは、ユーザーが特定のユースケースで同じタイプの複数のデバイスを選択することもできません。
Android 12以降、これらの制限は、オーディオブロードキャスト、BLEオーディオヘッドフォンのグループへのマルチキャスト、または複数のUSBサウンドカードの同時使用などの新しいユースケースを可能にするために削除されました。
このページでは、複数のオーディオデバイスへのストリーミングオーディオのサポートを実装する方法と、この機能の実装を検証する方法について説明します。
複数のオーディオデバイスへのストリーミングオーディオのサポート
Android 12には、この機能をサポートする2セットのAPIがあります。
- システムAPIは、戦略のために複数の優先デバイスを処理します。
- ベンダーがオーディオHALの一部として実装したHIDLインターフェイスは、デバイスの機能を報告します。
次のセクションでは、これらの各APIについて詳しく説明します。
戦略のための複数の優先デバイスの処理
Audio Policy Managerは、複数のオーディオデバイスへのオーディオのストリーミングを同時にサポートするためのシステムAPIを提供します。これらのシステムAPIを使用すると、特定の戦略で複数の優先デバイスを設定、取得、および削除できます。 Android 12までは、この機能は1台のデバイスでのみサポートされていました。
オーディオポリシーマネージャーは、アクティブメディアデバイスの概念を導入して、メディア再生用に選択される可能性が最も高いデバイスを記述します。取り外し可能なデバイスが接続されている場合、このデバイスにルーティングできるオーディオHAL出力ストリームを開いて、サポートされている属性をプローブする必要がある場合があります。
出力ストリームを開くときは、オーディオデバイスを指定する必要があります。アクティブメディアデバイスは、このコンテキストで出力ストリームが開かれるときに使用されるデバイスです。
アクティブなメディアデバイスの選択は、接続または切断された実際のデバイスに応じて変わる可能性があります。 Audio Policy Managerは、次の一連のルールを使用してアクティブなメディアデバイスを選択します。
- メディアに推奨されるすべてのデバイスが使用可能な場合、それらはすべてアクティブデバイスとして選択されます。
- それ以外の場合は、最後に接続されたリムーバブルデバイスが選択されます。
- 接続されているリムーバブルデバイスがない場合、出力デバイスを選択するためのデフォルトのオーディオポリシールールが、アクティブなデバイスを選択するために適用されます。
再生に最適な構成が選択されるように、出力ストリームを再度開いてアクティブデバイスにルーティングするには、次の基準を満たす必要があります。
- 出力ストリームはアクティブなデバイスをサポートする必要があります。
- 出力ストリームは動的プロファイルをサポートする必要があります。
- 出力ストリームは、現在アクティブなデバイスにルーティングされてはなりません。
新しいデバイス選択を適用するために、Audio Policy Managerは、出力ストリームがアイドル状態の場合はデバイス接続時に出力ストリームを閉じて再度開き、出力ストリームがスタンバイ状態になるまで延期します。
 Audio Policy Managerは、( AudioManager.javaで定義されている)システムAPIの次のリストを提供します。
- setPreferredDeviceForStrategy- 特定の戦略のオーディオルーティングに優先するデバイスを設定します。優先デバイスが設定された時点ではデバイスが使用できない場合がありますが、使用可能になると使用されることに注意してください。 
- removePreferredDeviceForStrategy- 以前に - setPreferredDeviceForStrategyまたは- setPreferredDevicesForStrategyで設定された優先オーディオデバイスを削除します。
- getPreferredDeviceForStrategy- setPreferredDeviceForStrategyまたは- setPreferredDevicesForStrategyで以前に設定されたオーディオストラテジーの優先デバイスを返します。
- setPreferredDevicesForStrategy- 特定の戦略に優先するデバイスを設定します。 
- getPreferredDevicesForStrategy- setPreferredDeviceForStrategyまたは- setPreferredDevicesForStrategyで以前に設定されたオーディオストラテジーの優先デバイスを返します。
- OnPreferredDevicesForStrategyChangedListener- 特定のオーディオ戦略に設定されている優先オーディオデバイスの変更を通知するためのインターフェイスを定義します。 
- addOnPreferredDevicesForStrategyChangedListener- ストラテジー優先オーディオデバイスへの変更の通知を受け取るリスナーを追加します。 
- removeOnPreferredDevicesForStrategyChangedListener- 戦略優先オーディオデバイスへの変更の以前に追加されたリスナーを削除します。 
レポートデバイスの機能
オーディオHAL実装の一部として、ベンダーはレポートデバイス機能をサポートするAPIを実装します。このセクションでは、デバイスの機能を報告するために使用されるデータタイプと方法について説明し、複数のデバイスをサポートするためにオーディオHIDL HALV7に加えられたいくつかの変更を一覧表示します。
データ型
オーディオHIDLHAL V7では、デバイスの機能はAudioProfileおよびAudioTransport構造を使用して報告されます。 AudioTransport構造は、既知のオーディオ形式の場合はAudioProfileを使用し、プラットフォームで認識されていない形式の場合は生のハードウェア記述子を使用して、オーディオポートの機能を記述します。 AudioProfile構造には、 types.halの次のコードブロックに示すように、オーディオ形式、プロファイルでサポートされているサンプルレート、およびチャネルマスクのリストが含まれています。
/**
* Configurations supported for a certain audio format.
*/
struct AudioProfile {
   AudioFormat format;
   /** List of the sample rates (in Hz) supported by the profile. */
   vec<uint32_t> sampleRates;
   /** List of channel masks supported by the profile. */
   vec<AudioChannelMask> channelMasks;
};
オーディオHIDLHAL V7では、 AudioPortデータ型はAudioTransportおよびAudioProfile構造で定義され、デバイスの機能を記述します。
オーディオHALメソッド
Audio Policy Managerは、次の方法を使用してデバイスの機能を照会します。
-  getParameters:サポートされているオーディオ形式やそれぞれのサンプリングレートなど、ベンダー固有のパラメータ値を取得するための一般的なメソッド。
-  getAudioPort:指定されたオーディオポートでサポートされている属性(サンプリングレート、フォーマット、チャネルマスク、ゲインコントローラーなど)のリストを返します。
 IDevice.halの次のコードは、 getAudioPortメソッドのインターフェイスを示しています。
   /**
    * Returns the list of supported attributes for a given audio port.
    *
    * As input, 'port' contains the information (type, role, address etc...)
    * needed by the HAL to identify the port.
    *
    * As output, 'resultPort' contains possible attributes (sampling rates,
    * formats, channel masks, gain controllers...) for this port.
    *
    * @param port port identifier.
    * @return retval operation completion status.
    * @return resultPort port descriptor with all parameters filled up.
    */
   getAudioPort(AudioPort port)
           generates (Result retval, AudioPort resultPort);
レガシーAPIへの変更
複数のオーディオプロファイルをサポートするために、レガシーAPIのバージョン3.2では、 audio_port_v7と呼ばれる新しい構造が追加されています。詳細については、ソースコードを参照してください。
 audio_port_v7が追加されたため、レガシーAPIのバージョン3.2では、 audio_port_v7構造を使用してデバイスの機能を照会するためにget_audio_port_v7という新しいAPIが追加されています。
 audio.hの次のコードは、 audio.hの定義を示してget_audio_port_v7ます。
/**
 * Fills the list of supported attributes for a given audio port.
 * As input, "port" contains the information (type, role, address etc...)
 * needed by the HAL to identify the port.
 * As output, "port" contains possible attributes (sampling rates,
 * formats, channel masks, gain controllers...) for this port. The
 * possible attributes are saved as audio profiles, which contains audio
 * format and the supported sampling rates and channel masks.
 */
 int (*get_audio_port_v7)(struct audio_hw_device *dev,
                          struct audio_port_v7 *port);
従来のAPIバージョンが3.2未満で、HIDL HALバージョンが7以上の場合、従来のget_audio_portからのデータを新しいAudioPort形式に入力する必要があります。この場合、 get_audio_portから報告されたすべてのサンプルレートとチャネルマスクは、返されたすべての形式でサポートされていると見なされ、 get_audio_port値から新しいAudioPort構造への簡単なマッピングが可能になります。
API実装の例
このセクションでは、前のセクションで説明したAPIを使用するメソッドを含むいくつかのテストスイートについて説明します。これらのAPIの実装方法と使用方法の例については、これらのメソッドを参照してください。
 setPreferredDevicesForStrategy 、 getPreferredDevicesForStrategy 、 removePreferredDeviceForStrategy 、およびOnPreferredDevicesForStrategyChangedListenerシステムAPIの使用例は、GTSにあるPreferredDeviceRoutingTestメソッドにあります。
使用中のAudioDeviceInfoの新しい構造の例を確認するには、CTSにあるAudioManagerTest#testGetDevicesメソッドを参照してください。
 audio_hal.c get_audio_port_v7あり、複数のデバイスの機能がどのように照会されるかを示しています。
検証
このセクションでは、Audio ManagerのCTSおよびGTS(Google Mobile Services Test Suite)検証に関する情報を提供します。
CTSテスト
CTSテストはandroid.media.cts.AudioManagerTestにあります。
以下は、利用可能なAudioManagerテストのリストです。
- AudioManagerTest#testGetDevices- オーディオデバイスの正確な機能を確認します。また、 - AudioDeviceInfo構造で返されたオーディオプロファイルが、古いフラット化された配列形式のコンテンツを保持しているが、新しい- AudioProfile形式であることを確認します。
- AudioManagerTest#testPreferredDevicesForStrategyおよび- AudioManagerTest#testPreferredDeviceForCapturePreset- ストラテジーおよびキャプチャプリセット関連のAPIテストに推奨されるデバイスが正常に完了することを確認します。 
GTSテスト
GTSテストはcom.google.android.gts.audioservice.AudioServiceHostTestにあります。
ストラテジーおよびキャプチャプリセットの優先デバイスのAPIが正しく機能するかどうかを検証するには、 AudioServiceHostTest#testPreferredDeviceRoutingおよびAudioServiceHostTest#testPreferredDeviceRoutingForCapturePresetテストを実行します。
