Add getCodecCapabilities as a supported function.

Add the ability to get a list of supported codecs and their capabilites
through the HIDL interface.

Bug: 111519504
Test: Compile
Change-Id: I61dff240a98d59cb99b526d8988d0d0245140ee4
diff --git a/bluetooth/audio/2.0/Android.bp b/bluetooth/audio/2.0/Android.bp
index 6049fe2..5d67f75 100644
--- a/bluetooth/audio/2.0/Android.bp
+++ b/bluetooth/audio/2.0/Android.bp
@@ -16,13 +16,25 @@
     ],
     types: [
         "AacObjectType",
+        "AacParameters",
+        "AacVariableBitRate",
+        "AptxParameters",
+        "AudioCapabilities",
+        "AudioConfiguration",
         "BitsPerSample",
         "ChannelMode",
+        "CodecCapabilities",
         "CodecConfiguration",
         "CodecType",
         "LdacChannelMode",
+        "LdacParameters",
+        "LdacQualityIndex",
+        "PcmParameters",
         "SampleRate",
+        "SbcAllocMethod",
+        "SbcBlockLength",
         "SbcChannelMode",
+        "SbcParameters",
         "SessionType",
         "Status",
         "TimeSpec",
diff --git a/bluetooth/audio/2.0/IBluetoothAudioPort.hal b/bluetooth/audio/2.0/IBluetoothAudioPort.hal
index 17d13b8..fedc8d3 100644
--- a/bluetooth/audio/2.0/IBluetoothAudioPort.hal
+++ b/bluetooth/audio/2.0/IBluetoothAudioPort.hal
@@ -27,6 +27,9 @@
  *
  * Moreover, the Audio HAL can also get the presentation position of the stream
  * and provide stream metadata.
+ *
+ * Note: For HIDL APIs with a "generates" statement, the callback parameter used
+ * for return value must be invoked synchronously before the API call returns.
  */
 interface IBluetoothAudioPort {
     /**
diff --git a/bluetooth/audio/2.0/IBluetoothAudioProvider.hal b/bluetooth/audio/2.0/IBluetoothAudioProvider.hal
index bb5eb1b..2b08cc3 100644
--- a/bluetooth/audio/2.0/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.0/IBluetoothAudioProvider.hal
@@ -23,6 +23,9 @@
  *
  * The Bluetooth stack calls methods in this interface to start and end audio
  * sessions and sends callback events to the Audio HAL.
+ *
+ * Note: For HIDL APIs with a "generates" statement, the callback parameter used
+ * for return value must be invoked synchronously before the API call returns.
  */
 interface IBluetoothAudioProvider {
 
@@ -35,8 +38,10 @@
      * Note: endSession() must be called to unregister this IBluetoothAudioPort
      *
      * @param hostIf An instance of IBluetoothAudioPort for stream control
-     * @param codecConfig The codec configuration negotiated with the remote
-     *    device
+     * @param audioConfig The audio configuration negotiated with the remote
+     *    device. The PCM parameters are set if software based encoding,
+     *    otherwise the correct codec configuration is used for hardware
+     *    encoding.
      *
      * @return status One of the following
      *    SUCCESS if this IBluetoothAudioPort was successfully registered with
@@ -47,10 +52,10 @@
      *        any other reason
      * @return dataMQ The fast message queue for audio data from this provider.
      *    Audio data will be in PCM format as specified by the
-     *    codecConfig.pcmDataConfiguration parameter.
-     *    nullptr if streaming is offloaded to hardware or on failure.
+     *    audioConfig.pcmConfig parameter.
+     *    Invalid if streaming is offloaded to hardware or on failure.
      */
-    startSession(IBluetoothAudioPort hostIf, CodecConfiguration codecConfig)
+    startSession(IBluetoothAudioPort hostIf, AudioConfiguration audioConfig)
                 generates (Status status, fmq_sync<uint8_t> dataMQ);
 
     /**
diff --git a/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.hal b/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.hal
index 56b8594..1025665 100644
--- a/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.hal
+++ b/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.hal
@@ -25,6 +25,9 @@
  * When the Bluetooth stack is ready to create an audio session, it must first
  * obtain the IBluetoothAudioProvider for that session type by calling
  * openProvider().
+ *
+ * Note: For HIDL APIs with a "generates" statement, the callback parameter used
+ * for return value must be invoked synchronously before the API call returns.
  */
 interface IBluetoothAudioProvidersFactory {
 
@@ -43,4 +46,26 @@
      */
     openProvider(SessionType sessionType)
         generates (Status status, IBluetoothAudioProvider provider);
+
+    /**
+     * Gets a list of audio capabilities for a session type.
+     *
+     * For software encoding, the PCM capabilities are returned.
+     * For hardware encoding, the supported codecs and their capabilities are
+     * returned.
+     *
+     * @param sessionType The session type (e.g.
+     *    A2DP_SOFTWARE_ENCODING_DATAPATH).
+     * @return audioCapabilities A list containing all the capabilities
+     *    supported by the sesson type. The capabilities is a list of
+     *    available options when configuring the codec for the session.
+     *    For software encoding it is the PCM data rate.
+     *    For hardware encoding it is the list of supported codecs and their
+     *    capabilities.
+     *    If a provider isn't supported, an empty list should be returned.
+     *    Note: Only one entry should exist per codec when using hardware
+     *    encoding.
+     */
+     getProviderCapabilities(SessionType sessionType)
+         generates (vec<AudioCapabilities> audioCapabilities);
 };
diff --git a/bluetooth/audio/2.0/types.hal b/bluetooth/audio/2.0/types.hal
index 9286948..909dd57 100644
--- a/bluetooth/audio/2.0/types.hal
+++ b/bluetooth/audio/2.0/types.hal
@@ -17,6 +17,14 @@
 package android.hardware.bluetooth.audio@2.0;
 
 /**
+ * The different audio parameter structs are used to provide a method to list
+ * all the Capabilities of a codec as well as to configure the codecs. All
+ * fields are bitfields unless specified. If used as a configuration, only one
+ * bit may be enabled. If used for Capabilities, enable all bits corresponding to
+ * supported features.
+ */
+
+/**
  * POSIX timespec.
  */
 struct TimeSpec {
@@ -85,6 +93,25 @@
     MONO = 0x08,
 };
 
+enum SbcBlockLength : uint8_t {
+    BLOCKS_4 = 0x80,
+    BLOCKS_8 = 0x40,
+    BLOCKS_12 = 0x20,
+    BLOCKS_16 = 0x10,
+};
+
+enum SbcNumSubbands : uint8_t {
+    SUBBAND_4 = 0x08,
+    SUBBAND_8 = 0x04,
+};
+
+enum SbcAllocMethod : uint8_t {
+    /** SNR */
+    ALLOC_MD_S = 0x02,
+    /** Loudness */
+    ALLOC_MD_L = 0x01,
+};
+
 enum AacObjectType : uint8_t {
     /** MPEG-2 Low Complexity. Support is Mandatory. */
     MPEG2_LC = 0x80,
@@ -96,6 +123,11 @@
     MPEG4_SCALABLE = 0x10,
 };
 
+enum AacVariableBitRate : uint8_t {
+    ENABLED = 0x80,
+    DISABLED = 0x00,
+};
+
 enum LdacChannelMode : uint8_t {
     /** Channel Mode: 3 bits */
     UNKNOWN = 0x00,
@@ -104,67 +136,117 @@
     MONO = 0x04,
 };
 
-struct CodecConfiguration {
-    /** Audio PCM data configuration */
-    struct PcmDataConfiguration {
-        /** Sampling rate for encoder */
-        SampleRate sampleRate;
-        /** Bits per sample for encoder */
-        BitsPerSample bitsPerSample;
-        /** Channel mode for encoder */
-        ChannelMode channelMode;
-    } pcmDataConfiguration;
+enum LdacQualityIndex : uint8_t {
+    // 990kbps
+    QUALITY_HIGH = 0x00,
+    // 660kbps
+    QUALITY_MID = 0x01,
+    // 330kbps
+    QUALITY_LOW = 0x02,
+    // Adaptive Bit Rate mode
+    QUALITY_ABR = 0x7F,
+};
 
-    /** Encoded audio data codec configuration. It is used only if the
-     * HAL is responsible for encoding the PCM audio data. */
-    struct EncodedDataConfiguration {
-        /** Bluetooth A2DP codec */
-        CodecType codecType;
-        /**
-         * The encoded audio bitrate in bits / second.
-         * 0x00000000 - The audio bitrate is not specified / unused
-         * 0x00000001 - 0x00FFFFFF - Encoded audio bitrate in bits/second
-         * 0x01000000 - 0xFFFFFFFF - Reserved
-         */
-        uint32_t encodedAudioBitrate;
-        /** Peer MTU (in octets) */
-        uint16_t peerMtu;
-        /** Content protection by SCMS-T */
-        bool isScmstEnabled;
-        safe_union CodecSpecific {
-            /**
-             * SBC Codec specific information
-             * Refer to SBC Codec specific information elements in A2DP v1.3
-             * Profile Specification.
-             */
-            struct SbcData {
-                /** Reserved: 4 bits | Channel Mode: 4 bits */
-                SbcChannelMode channelMode;
-                /** Block length: 4 bits | Subbands: 2 bits | Allocation Method: 2 bits */
-                uint8_t codecParameters;
-                /** Minimum bitpool value */
-                uint8_t minBitpool;
-                /** Maximum bitpool value */
-                uint8_t maxBitpool;
-            } sbcData;
-            struct AacData {
-                /** AAC Object Type */
-                AacObjectType aacObjectType;
-                /** True if Variable Bit Rate is enabled */
-                bool variableBitRateEnabled;
-            } aacData;
-            struct LdacData {
-                /** Reserved: 5 bits | Channel Mode: 3 bits */
-                LdacChannelMode channelMode;
-                /**
-                 * LDAC bitrate index value:
-                 * 0x00 - High
-                 * 0x01 - Mid
-                 * 0x02 - Low
-                 * 0x7F - ABR (Adaptive Bit Rate)
-                 */
-                uint8_t bitrateIndex;
-            } ldacData;
-        } codecSpecific;
-    } encodedDataConfiguration;
+/** Used for Software Encoding audio feed parameters */
+struct PcmParameters {
+    SampleRate sampleRate;
+    ChannelMode channelMode;
+    BitsPerSample bitsPerSample;
+};
+
+/**
+ * Used for Hardware Encoding SBC codec parameters.
+ * minBitpool and maxBitpool are not bitfields.
+ */
+struct SbcParameters {
+    SampleRate sampleRate;
+    SbcChannelMode channelMode;
+    SbcBlockLength blockLength;
+    SbcNumSubbands numSubbands;
+    SbcAllocMethod allocMethod;
+    BitsPerSample bitsPerSample;
+    uint8_t minBitpool;
+    uint8_t maxBitpool;
+};
+
+/** Used for Hardware Encoding AAC codec parameters */
+struct AacParameters {
+    AacObjectType objectType;
+    SampleRate sampleRate;
+    ChannelMode channelMode;
+    AacVariableBitRate variableBitRateEnabled;
+    BitsPerSample bitsPerSample;
+};
+
+/**
+ * Used for Hardware Encoding LDAC codec parameters
+ * Only used when configuring the codec. When Capabilities are requested, this
+ * field is left empty since all qualities must be supported. Not a bitfield.
+ */
+struct LdacParameters {
+    SampleRate sampleRate;
+    LdacChannelMode channelMode;
+    LdacQualityIndex qualityIndex;
+    BitsPerSample bitsPerSample;
+};
+
+/** Used for Hardware Encoding AptX and AptX-HD codec parameters */
+struct AptxParameters {
+    SampleRate sampleRate;
+    ChannelMode channelMode;
+    BitsPerSample bitsPerSample;
+};
+
+/**
+ * Used to specify the capabilities of the codecs supported by Hardware Encoding.
+ * AptX and AptX-HD both use the AptxParameters field.
+ */
+struct CodecCapabilities {
+    CodecType codecType;
+
+    safe_union Capabilities {
+      SbcParameters sbcCapabilities;
+      AacParameters aacCapabilities;
+      LdacParameters ldacCapabilities;
+      AptxParameters aptxCapabilities;
+    } capabilities;
+};
+
+/** Used to specify the capabilities of the different session types. */
+safe_union AudioCapabilities {
+    PcmParameters pcmCapabilities;
+    CodecCapabilities codecCapabilities;
+};
+
+/**
+ * Used to configure a Hardware Encoding session.
+ * AptX and AptX-HD both use the AptxParameters field.
+ */
+struct CodecConfiguration {
+    CodecType codecType;
+    /**
+     * The encoded audio bitrate in bits / second.
+     * 0x00000000 - The audio bitrate is not specified / unused
+     * 0x00000001 - 0x00FFFFFF - Encoded audio bitrate in bits/second
+     * 0x01000000 - 0xFFFFFFFF - Reserved
+     *
+     * The HAL needs to support all legal bitrates for the selected codec.
+     */
+    uint32_t encodedAudioBitrate;
+    /** Peer MTU (in octets) */
+    uint16_t peerMtu;
+    /** Content protection by SCMS-T */
+    bool isScmstEnabled;
+    safe_union CodecSpecific {
+        SbcParameters sbcConfig;
+        AacParameters aacConfig;
+        LdacParameters ldacConfig;
+        AptxParameters aptxConfig;
+    } config;
+};
+
+/** Used to configure either a Hardware or Software Encoding session based on session type */
+safe_union AudioConfiguration {
+    PcmParameters pcmConfig;
+    CodecConfiguration codecConfig;
 };