diff options
Diffstat (limited to 'bluetooth')
16 files changed, 805 insertions, 145 deletions
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp index 0e22e44490..7f610ef3d0 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp @@ -55,21 +55,20 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession( const std::shared_ptr<IBluetoothAudioPort>& host_if, const AudioConfiguration& audio_config, const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) { - if (audio_config.getTag() != AudioConfiguration::leAudioConfig) { + if (session_type_ == + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + if (audio_config.getTag() != AudioConfiguration::leAudioBroadcastConfig) { + LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" + << audio_config.toString(); + *_aidl_return = DataMQDesc(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + } else if (audio_config.getTag() != AudioConfiguration::leAudioConfig) { LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" << audio_config.toString(); *_aidl_return = DataMQDesc(); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - const auto& le_audio_config = - audio_config.get<AudioConfiguration::leAudioConfig>(); - if (!BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid( - session_type_, le_audio_config)) { - LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration=" - << le_audio_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } return BluetoothAudioProvider::startSession( host_if, audio_config, latency_modes, _aidl_return); diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp index ebd728db34..e9b74b771c 100644 --- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp +++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp @@ -23,6 +23,7 @@ #include <android/binder_process.h> #include <binder/IServiceManager.h> #include <binder/ProcessState.h> +#include <cutils/properties.h> #include <fmq/AidlMessageQueue.h> #include <cstdint> @@ -248,7 +249,8 @@ class BluetoothAudioProviderFactoryAidl case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: { - ASSERT_FALSE(temp_provider_capabilities_.empty()); + // empty capability means offload is unsupported since capabilities are + // not hardcoded for (auto audio_capability : temp_provider_capabilities_) { ASSERT_EQ(audio_capability.getTag(), AudioCapabilities::leAudioCapabilities); @@ -513,8 +515,9 @@ class BluetoothAudioProviderFactoryAidl for (auto channel_mode : opus_capability->channelMode) { OpusConfiguration opus_data{ .samplingFrequencyHz = samplingFrequencyHz, + .frameDurationUs = frameDurationUs, .channelMode = channel_mode, - .frameDurationUs = frameDurationUs}; + }; opus_codec_specifics.push_back( CodecConfiguration::CodecSpecific(opus_data)); } @@ -623,8 +626,8 @@ TEST_P(BluetoothAudioProviderA2dpEncodingSoftwareAidl, for (auto channel_mode : a2dp_channel_modes) { PcmConfiguration pcm_config{ .sampleRateHz = sample_rate, - .bitsPerSample = bits_per_sample, .channelMode = channel_mode, + .bitsPerSample = bits_per_sample, }; bool is_codec_config_valid = IsPcmConfigSupported(pcm_config); DataMQDesc mq_desc; @@ -937,8 +940,8 @@ TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl, for (auto channel_mode : hearing_aid_channel_modes_) { PcmConfiguration pcm_config{ .sampleRateHz = sample_rate, - .bitsPerSample = bits_per_sample, .channelMode = channel_mode, + .bitsPerSample = bits_per_sample, }; bool is_codec_config_valid = IsPcmConfigSupported(pcm_config); DataMQDesc mq_desc; @@ -1008,8 +1011,8 @@ TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl, for (auto data_interval_us : le_audio_output_data_interval_us_) { PcmConfiguration pcm_config{ .sampleRateHz = sample_rate, - .bitsPerSample = bits_per_sample, .channelMode = channel_mode, + .bitsPerSample = bits_per_sample, .dataIntervalUs = data_interval_us, }; bool is_codec_config_valid = @@ -1081,8 +1084,8 @@ TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl, for (auto data_interval_us : le_audio_input_data_interval_us_) { PcmConfiguration pcm_config{ .sampleRateHz = sample_rate, - .bitsPerSample = bits_per_sample, .channelMode = channel_mode, + .bitsPerSample = bits_per_sample, .dataIntervalUs = data_interval_us, }; bool is_codec_config_valid = @@ -1144,7 +1147,7 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl bool supported) { std::vector<Lc3Configuration> le_audio_codec_configs; if (!supported) { - Lc3Configuration lc3_config{.samplingFrequencyHz = 0, .pcmBitDepth = 0}; + Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0}; le_audio_codec_configs.push_back(lc3_config); return le_audio_codec_configs; } @@ -1428,8 +1431,8 @@ TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl, for (auto data_interval_us : le_audio_output_data_interval_us_) { PcmConfiguration pcm_config{ .sampleRateHz = sample_rate, - .bitsPerSample = bits_per_sample, .channelMode = channel_mode, + .bitsPerSample = bits_per_sample, .dataIntervalUs = data_interval_us, }; bool is_codec_config_valid = @@ -1490,7 +1493,7 @@ class BluetoothAudioProviderLeAudioBroadcastHardwareAidl std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) { std::vector<Lc3Configuration> le_audio_codec_configs; if (!supported) { - Lc3Configuration lc3_config{.samplingFrequencyHz = 0, .pcmBitDepth = 0}; + Lc3Configuration lc3_config{.pcmBitDepth = 0, .samplingFrequencyHz = 0}; le_audio_codec_configs.push_back(lc3_config); return le_audio_codec_configs; } @@ -1650,8 +1653,8 @@ TEST_P(BluetoothAudioProviderA2dpDecodingSoftwareAidl, for (auto channel_mode : a2dp_channel_modes) { PcmConfiguration pcm_config{ .sampleRateHz = sample_rate, - .bitsPerSample = bits_per_sample, .channelMode = channel_mode, + .bitsPerSample = bits_per_sample, }; bool is_codec_config_valid = IsPcmConfigSupported(pcm_config); DataMQDesc mq_desc; diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp index d08cb0a8e6..674dd116cf 100644 --- a/bluetooth/audio/utils/Android.bp +++ b/bluetooth/audio/utils/Android.bp @@ -40,9 +40,13 @@ cc_library_shared { "aidl_session/BluetoothAudioCodecs.cpp", "aidl_session/BluetoothAudioSession.cpp", "aidl_session/HidlToAidlMiddleware.cpp", + "aidl_session/BluetoothLeAudioCodecsProvider.cpp", ], export_include_dirs: ["aidl_session/"], - header_libs: ["libhardware_headers"], + header_libs: [ + "libhardware_headers", + "libxsdc-utils", + ], shared_libs: [ "android.hardware.bluetooth.audio@2.0", "android.hardware.bluetooth.audio@2.1", @@ -53,5 +57,15 @@ cc_library_shared { "liblog", "android.hardware.bluetooth.audio-V2-ndk", "libhidlbase", + "libxml2", ], + generated_sources: ["le_audio_codec_capabilities"], + generated_headers: ["le_audio_codec_capabilities"], +} + +xsd_config { + name: "le_audio_codec_capabilities", + srcs: ["le_audio_codec_capabilities/le_audio_codec_capabilities.xsd"], + package_name: "aidl.android.hardware.bluetooth.audio.setting", + api_dir: "le_audio_codec_capabilities/schema", } diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp index b858f504ed..855dd28718 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp @@ -32,6 +32,8 @@ #include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h> #include <android-base/logging.h> +#include "BluetoothLeAudioCodecsProvider.h" + namespace aidl { namespace android { namespace hardware { @@ -96,67 +98,6 @@ const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = { std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities; -static const UnicastCapability kInvalidUnicastCapability = { - .codecType = CodecType::UNKNOWN}; - -static const BroadcastCapability kInvalidBroadcastCapability = { - .codecType = CodecType::UNKNOWN}; - -// Default Supported Codecs -// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30 -static const Lc3Capabilities kLc3Capability_16_1 = { - .samplingFrequencyHz = {16000}, - .frameDurationUs = {7500}, - .octetsPerFrame = {30}}; - -// Default Supported Codecs -// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40 -static const Lc3Capabilities kLc3Capability_16_2 = { - .samplingFrequencyHz = {16000}, - .frameDurationUs = {10000}, - .octetsPerFrame = {40}}; - -// Default Supported Codecs -// LC3 24_2: sample rate: 24 kHz, frame duration: 10 ms, octets per frame: 60 -static const Lc3Capabilities kLc3Capability_24_2 = { - .samplingFrequencyHz = {24000}, - .frameDurationUs = {10000}, - .octetsPerFrame = {60}}; - -// Default Supported Codecs -// LC3 32_2: sample rate: 32 kHz, frame duration: 10 ms, octets per frame: 80 -static const Lc3Capabilities kLc3Capability_32_2 = { - .samplingFrequencyHz = {32000}, - .frameDurationUs = {10000}, - .octetsPerFrame = {80}}; - -// Default Supported Codecs -// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120 -static const Lc3Capabilities kLc3Capability_48_4 = { - .samplingFrequencyHz = {48000}, - .frameDurationUs = {10000}, - .octetsPerFrame = {120}}; - -static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = { - kLc3Capability_48_4, kLc3Capability_32_2, kLc3Capability_24_2, - kLc3Capability_16_2, kLc3Capability_16_1}; - -static AudioLocation stereoAudio = static_cast<AudioLocation>( - static_cast<uint8_t>(AudioLocation::FRONT_LEFT) | - static_cast<uint8_t>(AudioLocation::FRONT_RIGHT)); -static AudioLocation monoAudio = AudioLocation::UNKNOWN; - -// Stores the supported setting of audio location, connected device, and the -// channel count for each device -std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>> - supportedDeviceSetting = { - // Stereo, two connected device, one for L one for R - std::make_tuple(stereoAudio, 2, 1), - // Stereo, one connected device for both L and R - std::make_tuple(stereoAudio, 1, 2), - // Mono - std::make_tuple(monoAudio, 1, 1)}; - template <class T> bool BluetoothAudioCodecs::ContainedInVector( const std::vector<T>& vector, const typename identity<T>::type& target) { @@ -321,19 +262,6 @@ bool BluetoothAudioCodecs::IsOffloadOpusConfigurationValid( return false; } -bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid( - const SessionType& session_type, const LeAudioConfiguration&) { - if (session_type != - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && - session_type != - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH && - session_type != - SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { - return false; - } - return true; -} - std::vector<PcmCapabilities> BluetoothAudioCodecs::GetSoftwarePcmCapabilities() { return {kDefaultSoftwarePcmCapabilities}; @@ -457,19 +385,6 @@ bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid( return false; } -UnicastCapability composeUnicastLc3Capability( - AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount, - const Lc3Capabilities& capability) { - return { - .codecType = CodecType::LC3, - .supportedChannel = audioLocation, - .deviceCount = deviceCnt, - .channelCountPerDevice = channelCount, - .leAudioCodecCapabilities = - UnicastCapability::LeAudioCodecCapabilities(capability), - }; -} - std::vector<LeAudioCodecCapabilitiesSetting> BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities( const SessionType& session_type) { @@ -483,34 +398,8 @@ BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities( } if (kDefaultOffloadLeAudioCapabilities.empty()) { - for (auto [audioLocation, deviceCnt, channelCount] : - supportedDeviceSetting) { - for (auto capability : supportedLc3CapabilityList) { - UnicastCapability lc3Capability = composeUnicastLc3Capability( - audioLocation, deviceCnt, channelCount, capability); - UnicastCapability lc3MonoDecodeCapability = - composeUnicastLc3Capability(monoAudio, 1, 1, capability); - - // Adds the capability for encode only - kDefaultOffloadLeAudioCapabilities.push_back( - {.unicastEncodeCapability = lc3Capability, - .unicastDecodeCapability = kInvalidUnicastCapability, - .broadcastCapability = kInvalidBroadcastCapability}); - - // Adds the capability for decode only - kDefaultOffloadLeAudioCapabilities.push_back( - {.unicastEncodeCapability = kInvalidUnicastCapability, - .unicastDecodeCapability = lc3Capability, - .broadcastCapability = kInvalidBroadcastCapability}); - - // Adds the capability for the case that encode and decode exist at the - // same time - kDefaultOffloadLeAudioCapabilities.push_back( - {.unicastEncodeCapability = lc3Capability, - .unicastDecodeCapability = lc3MonoDecodeCapability, - .broadcastCapability = kInvalidBroadcastCapability}); - } - } + kDefaultOffloadLeAudioCapabilities = + BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(); } return kDefaultOffloadLeAudioCapabilities; diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h index ed0598b975..e3d657b497 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h @@ -44,9 +44,6 @@ class BluetoothAudioCodecs { static bool IsOffloadCodecConfigurationValid( const SessionType& session_type, const CodecConfiguration& codec_config); - static bool IsOffloadLeAudioConfigurationValid( - const SessionType& session_type, const LeAudioConfiguration&); - static std::vector<LeAudioCodecCapabilitiesSetting> GetLeAudioOffloadCodecCapabilities(const SessionType& session_type); diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp index 3214bf2228..2b0caadeae 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp @@ -60,12 +60,14 @@ void BluetoothAudioSession::OnSessionStarted( LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) << " MqDescriptor Invalid"; audio_config_ = nullptr; + leaudio_connection_map_ = nullptr; } else { stack_iface_ = stack_iface; latency_modes_ = latency_modes; LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ", AudioConfiguration=" << audio_config.toString(); ReportSessionStatus(); + is_streaming_ = false; } } @@ -74,11 +76,13 @@ void BluetoothAudioSession::OnSessionEnded() { bool toggled = IsSessionReady(); LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); audio_config_ = nullptr; + leaudio_connection_map_ = nullptr; stack_iface_ = nullptr; UpdateDataPath(nullptr); if (toggled) { ReportSessionStatus(); } + is_streaming_ = false; } /*** @@ -106,6 +110,14 @@ const AudioConfiguration BluetoothAudioSession::GetAudioConfig() { return *audio_config_; } +const AudioConfiguration BluetoothAudioSession::GetLeAudioConnectionMap() { + std::lock_guard<std::recursive_mutex> guard(mutex_); + if (!IsSessionReady()) { + return AudioConfiguration(LeAudioConfiguration{}); + } + return *leaudio_connection_map_; +} + void BluetoothAudioSession::ReportAudioConfigChanged( const AudioConfiguration& audio_config) { if (session_type_ != @@ -114,8 +126,56 @@ void BluetoothAudioSession::ReportAudioConfigChanged( SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { return; } + std::lock_guard<std::recursive_mutex> guard(mutex_); - audio_config_ = std::make_unique<AudioConfiguration>(audio_config); + if (audio_config.getTag() != AudioConfiguration::leAudioConfig) { + LOG(ERROR) << __func__ << " invalid audio config type for SessionType =" + << toString(session_type_); + return; + } + + if (is_streaming_) { + if (audio_config_ == nullptr) { + LOG(ERROR) << __func__ << " for SessionType=" << toString(session_type_) + << " audio_config_ is nullptr during streaming. It shouldn't " + "be happened"; + return; + } + + auto new_leaudio_config = + audio_config.get<AudioConfiguration::leAudioConfig>(); + auto current_leaudio_config = + (*audio_config_).get<AudioConfiguration::leAudioConfig>(); + if (new_leaudio_config.codecType != current_leaudio_config.codecType) { + LOG(ERROR) + << __func__ << " for SessionType=" << toString(session_type_) + << " codec type changed during streaming. It shouldn't be happened "; + } + auto new_lc3_config = new_leaudio_config.leAudioCodecConfig + .get<LeAudioCodecConfiguration::lc3Config>(); + auto current_lc3_config = current_leaudio_config.leAudioCodecConfig + .get<LeAudioCodecConfiguration::lc3Config>(); + if ((new_lc3_config.pcmBitDepth != current_lc3_config.pcmBitDepth) || + (new_lc3_config.samplingFrequencyHz != + current_lc3_config.samplingFrequencyHz) || + (new_lc3_config.frameDurationUs != + current_lc3_config.frameDurationUs) || + (new_lc3_config.octetsPerFrame != current_lc3_config.octetsPerFrame) || + (new_lc3_config.blocksPerSdu != current_lc3_config.blocksPerSdu)) { + LOG(ERROR) + << __func__ << " for SessionType=" << toString(session_type_) + << " lc3 config changed during streaming. It shouldn't be happened"; + return; + } + + leaudio_connection_map_ = + std::make_unique<AudioConfiguration>(audio_config); + } else { + audio_config_ = std::make_unique<AudioConfiguration>(audio_config); + leaudio_connection_map_ = + std::make_unique<AudioConfiguration>(audio_config); + } + if (observers_.empty()) { LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) << " has NO port state observer"; @@ -127,7 +187,11 @@ void BluetoothAudioSession::ReportAudioConfigChanged( LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_) << ", bluetooth_audio=0x" << ::android::base::StringPrintf("%04x", cookie); - if (cb->audio_configuration_changed_cb_ != nullptr) { + if (is_streaming_) { + if (cb->soft_audio_configuration_changed_cb_ != nullptr) { + cb->soft_audio_configuration_changed_cb_(cookie); + } + } else if (cb->audio_configuration_changed_cb_ != nullptr) { cb->audio_configuration_changed_cb_(cookie); } } @@ -274,11 +338,14 @@ bool BluetoothAudioSession::UpdateAudioConfig( bool is_offload_a2dp_session = (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH); - bool is_offload_le_audio_session = + bool is_offload_le_audio_unicast_session = (session_type_ == SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || session_type_ == SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH); + bool is_offload_le_audio_broadcast_session = + (session_type_ == + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH); auto audio_config_tag = audio_config.getTag(); bool is_software_audio_config = (is_software_session && @@ -286,11 +353,15 @@ bool BluetoothAudioSession::UpdateAudioConfig( bool is_a2dp_offload_audio_config = (is_offload_a2dp_session && audio_config_tag == AudioConfiguration::a2dpConfig); - bool is_le_audio_offload_audio_config = - (is_offload_le_audio_session && + bool is_le_audio_offload_unicast_audio_config = + (is_offload_le_audio_unicast_session && audio_config_tag == AudioConfiguration::leAudioConfig); + bool is_le_audio_offload_broadcast_audio_config = + (is_offload_le_audio_broadcast_session && + audio_config_tag == AudioConfiguration::leAudioBroadcastConfig); if (!is_software_audio_config && !is_a2dp_offload_audio_config && - !is_le_audio_offload_audio_config) { + !is_le_audio_offload_unicast_audio_config && + !is_le_audio_offload_broadcast_audio_config) { return false; } audio_config_ = std::make_unique<AudioConfiguration>(audio_config); @@ -410,6 +481,12 @@ void BluetoothAudioSession::ReportControlStatus(bool start_resp, << " has NO port state observer"; return; } + if (start_resp && status == BluetoothAudioStatus::SUCCESS) { + is_streaming_ = true; + } else if (!start_resp && (status == BluetoothAudioStatus::SUCCESS || + status == BluetoothAudioStatus::RECONFIGURATION)) { + is_streaming_ = false; + } for (auto& observer : observers_) { uint16_t cookie = observer.first; std::shared_ptr<PortStatusCallbacks> callback = observer.second; diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h index 5bf17bd3d2..faf4ffbabe 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h @@ -102,6 +102,13 @@ struct PortStatusCallbacks { ***/ std::function<void(uint16_t cookie, bool allowed)> low_latency_mode_allowed_cb_; + /*** + * soft_audio_configuration_changed_cb_ - when the Bluetooth stack change + * the streamMap during the streaming, the BluetoothAudioProvider will invoke + * this callback to report to the bluetooth_audio module. + * @param: cookie - indicates which bluetooth_audio output should handle + ***/ + std::function<void(uint16_t cookie)> soft_audio_configuration_changed_cb_; }; class BluetoothAudioSession { @@ -159,6 +166,12 @@ class BluetoothAudioSession { const AudioConfiguration GetAudioConfig(); /*** + * The control function is for the bluetooth_audio module to get the current + * LE audio connection map + ***/ + const AudioConfiguration GetLeAudioConnectionMap(); + + /*** * The report function is used to report that the Bluetooth stack has notified * the audio configuration changed, and will invoke * audio_configuration_changed_cb_ to notify registered bluetooth_audio @@ -206,8 +219,11 @@ class BluetoothAudioSession { std::unique_ptr<DataMQ> data_mq_; // audio data configuration for both software and offloading std::unique_ptr<AudioConfiguration> audio_config_; + std::unique_ptr<AudioConfiguration> leaudio_connection_map_; std::vector<LatencyMode> latency_modes_; bool low_latency_allowed_ = true; + // saving those steaming state based on the session_type + bool is_streaming_ = false; // saving those registered bluetooth_audio's callbacks std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks>> diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h index 0782c824e1..881c6c10b2 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h @@ -95,6 +95,25 @@ class BluetoothAudioSessionControl { } /*** + * The control API for the bluetooth_audio module to get current + * LE audio connection map + ***/ + static const AudioConfiguration GetLeAudioConnectionMap( + const SessionType& session_type) { + std::shared_ptr<BluetoothAudioSession> session_ptr = + BluetoothAudioSessionInstance::GetSessionInstance(session_type); + if ((session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) && + session_ptr != nullptr) { + return session_ptr->GetLeAudioConnectionMap(); + } + + return AudioConfiguration(LeAudioConfiguration{}); + } + + /*** * Those control APIs for the bluetooth_audio module to start / suspend / stop * stream, to check position, and to update metadata. diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp new file mode 100644 index 0000000000..bf492706c8 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "BTAudioCodecsProviderAidl" + +#include "BluetoothLeAudioCodecsProvider.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +static const char* kLeAudioCodecCapabilitiesFile = + "/vendor/etc/le_audio_codec_capabilities.xml"; + +static const AudioLocation kStereoAudio = static_cast<AudioLocation>( + static_cast<uint8_t>(AudioLocation::FRONT_LEFT) | + static_cast<uint8_t>(AudioLocation::FRONT_RIGHT)); +static const AudioLocation kMonoAudio = AudioLocation::UNKNOWN; + +static std::vector<LeAudioCodecCapabilitiesSetting> leAudioCodecCapabilities; + +std::vector<LeAudioCodecCapabilitiesSetting> +BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities() { + if (!leAudioCodecCapabilities.empty()) { + return leAudioCodecCapabilities; + } + + const auto le_audio_offload_setting = + setting::readLeAudioOffloadSetting(kLeAudioCodecCapabilitiesFile); + if (!le_audio_offload_setting.has_value()) { + LOG(ERROR) << __func__ << ": Failed to read " + << kLeAudioCodecCapabilitiesFile; + return {}; + } + + std::vector<setting::Scenario> supported_scenarios = + GetScenarios(le_audio_offload_setting); + if (supported_scenarios.empty()) { + LOG(ERROR) << __func__ << ": No scenarios in " + << kLeAudioCodecCapabilitiesFile; + return {}; + } + + UpdateConfigurationsToMap(le_audio_offload_setting); + if (configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No configurations in " + << kLeAudioCodecCapabilitiesFile; + return {}; + } + + UpdateCodecConfigurationsToMap(le_audio_offload_setting); + if (codec_configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No codec configurations in " + << kLeAudioCodecCapabilitiesFile; + return {}; + } + + UpdateStrategyConfigurationsToMap(le_audio_offload_setting); + if (strategy_configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No strategy configurations in " + << kLeAudioCodecCapabilitiesFile; + return {}; + } + + leAudioCodecCapabilities = + ComposeLeAudioCodecCapabilities(supported_scenarios); + return leAudioCodecCapabilities; +} + +std::vector<setting::Scenario> BluetoothLeAudioCodecsProvider::GetScenarios( + const std::optional<setting::LeAudioOffloadSetting>& + le_audio_offload_setting) { + std::vector<setting::Scenario> supported_scenarios; + if (le_audio_offload_setting->hasScenarioList()) { + for (const auto& scenario_list : + le_audio_offload_setting->getScenarioList()) { + if (!scenario_list.hasScenario()) { + continue; + } + for (const auto& scenario : scenario_list.getScenario()) { + if (scenario.hasEncode() && scenario.hasDecode()) { + supported_scenarios.push_back(scenario); + } + } + } + } + return supported_scenarios; +} + +void BluetoothLeAudioCodecsProvider::UpdateConfigurationsToMap( + const std::optional<setting::LeAudioOffloadSetting>& + le_audio_offload_setting) { + if (le_audio_offload_setting->hasConfigurationList()) { + for (const auto& configuration_list : + le_audio_offload_setting->getConfigurationList()) { + if (!configuration_list.hasConfiguration()) { + continue; + } + for (const auto& configuration : configuration_list.getConfiguration()) { + if (configuration.hasName() && configuration.hasCodecConfiguration() && + configuration.hasStrategyConfiguration()) { + configuration_map_.insert( + make_pair(configuration.getName(), configuration)); + } + } + } + } +} + +void BluetoothLeAudioCodecsProvider::UpdateCodecConfigurationsToMap( + const std::optional<setting::LeAudioOffloadSetting>& + le_audio_offload_setting) { + if (le_audio_offload_setting->hasCodecConfigurationList()) { + for (const auto& codec_configuration_list : + le_audio_offload_setting->getCodecConfigurationList()) { + if (!codec_configuration_list.hasCodecConfiguration()) { + continue; + } + for (const auto& codec_configuration : + codec_configuration_list.getCodecConfiguration()) { + if (IsValidCodecConfiguration(codec_configuration)) { + codec_configuration_map_.insert( + make_pair(codec_configuration.getName(), codec_configuration)); + } + } + } + } +} + +void BluetoothLeAudioCodecsProvider::UpdateStrategyConfigurationsToMap( + const std::optional<setting::LeAudioOffloadSetting>& + le_audio_offload_setting) { + if (le_audio_offload_setting->hasStrategyConfigurationList()) { + for (const auto& strategy_configuration_list : + le_audio_offload_setting->getStrategyConfigurationList()) { + if (!strategy_configuration_list.hasStrategyConfiguration()) { + continue; + } + for (const auto& strategy_configuration : + strategy_configuration_list.getStrategyConfiguration()) { + if (IsValidStrategyConfiguration(strategy_configuration)) { + strategy_configuration_map_.insert(make_pair( + strategy_configuration.getName(), strategy_configuration)); + } + } + } + } +} + +std::vector<LeAudioCodecCapabilitiesSetting> +BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities( + const std::vector<setting::Scenario>& supported_scenarios) { + std::vector<LeAudioCodecCapabilitiesSetting> le_audio_codec_capabilities; + for (const auto& scenario : supported_scenarios) { + UnicastCapability unicast_encode_capability = + GetUnicastCapability(scenario.getEncode()); + UnicastCapability unicast_decode_capability = + GetUnicastCapability(scenario.getDecode()); + // encode and decode cannot be unknown at the same time + if (unicast_encode_capability.codecType == CodecType::UNKNOWN && + unicast_decode_capability.codecType == CodecType::UNKNOWN) { + continue; + } + BroadcastCapability broadcast_capability = {.codecType = + CodecType::UNKNOWN}; + le_audio_codec_capabilities.push_back( + {.unicastEncodeCapability = unicast_encode_capability, + .unicastDecodeCapability = unicast_decode_capability, + .broadcastCapability = broadcast_capability}); + } + return le_audio_codec_capabilities; +} + +UnicastCapability BluetoothLeAudioCodecsProvider::GetUnicastCapability( + const std::string& coding_direction) { + if (coding_direction == "invalid") { + return {.codecType = CodecType::UNKNOWN}; + } + + auto configuration_iter = configuration_map_.find(coding_direction); + if (configuration_iter == configuration_map_.end()) { + return {.codecType = CodecType::UNKNOWN}; + } + + auto codec_configuration_iter = codec_configuration_map_.find( + configuration_iter->second.getCodecConfiguration()); + if (codec_configuration_iter == codec_configuration_map_.end()) { + return {.codecType = CodecType::UNKNOWN}; + } + + auto strategy_configuration_iter = strategy_configuration_map_.find( + configuration_iter->second.getStrategyConfiguration()); + if (strategy_configuration_iter == strategy_configuration_map_.end()) { + return {.codecType = CodecType::UNKNOWN}; + } + + CodecType codec_type = + GetCodecType(codec_configuration_iter->second.getCodec()); + if (codec_type == CodecType::LC3) { + return ComposeUnicastCapability( + codec_type, + GetAudioLocation( + strategy_configuration_iter->second.getAudioLocation()), + strategy_configuration_iter->second.getConnectedDevice(), + strategy_configuration_iter->second.getChannelCount(), + ComposeLc3Capability(codec_configuration_iter->second)); + } + return {.codecType = CodecType::UNKNOWN}; +} + +template <class T> +UnicastCapability BluetoothLeAudioCodecsProvider::ComposeUnicastCapability( + const CodecType& codec_type, const AudioLocation& audio_location, + const uint8_t& device_cnt, const uint8_t& channel_count, + const T& capability) { + return { + .codecType = codec_type, + .supportedChannel = audio_location, + .deviceCount = device_cnt, + .channelCountPerDevice = channel_count, + .leAudioCodecCapabilities = + UnicastCapability::LeAudioCodecCapabilities(capability), + }; +} + +Lc3Capabilities BluetoothLeAudioCodecsProvider::ComposeLc3Capability( + const setting::CodecConfiguration& codec_configuration) { + return {.samplingFrequencyHz = {codec_configuration.getSamplingFrequency()}, + .frameDurationUs = {codec_configuration.getFrameDurationUs()}, + .octetsPerFrame = {codec_configuration.getOctetsPerCodecFrame()}}; +} + +AudioLocation BluetoothLeAudioCodecsProvider::GetAudioLocation( + const setting::AudioLocation& audio_location) { + switch (audio_location) { + case setting::AudioLocation::MONO: + return kMonoAudio; + case setting::AudioLocation::STEREO: + return kStereoAudio; + default: + return AudioLocation::UNKNOWN; + } +} + +CodecType BluetoothLeAudioCodecsProvider::GetCodecType( + const setting::CodecType& codec_type) { + switch (codec_type) { + case setting::CodecType::LC3: + return CodecType::LC3; + default: + return CodecType::UNKNOWN; + } +} + +bool BluetoothLeAudioCodecsProvider::IsValidCodecConfiguration( + const setting::CodecConfiguration& codec_configuration) { + return codec_configuration.hasName() && codec_configuration.hasCodec() && + codec_configuration.hasSamplingFrequency() && + codec_configuration.hasFrameDurationUs() && + codec_configuration.hasOctetsPerCodecFrame(); +} + +bool BluetoothLeAudioCodecsProvider::IsValidStrategyConfiguration( + const setting::StrategyConfiguration& strategy_configuration) { + if (!strategy_configuration.hasName() || + !strategy_configuration.hasAudioLocation() || + !strategy_configuration.hasConnectedDevice() || + !strategy_configuration.hasChannelCount()) { + return false; + } + if (strategy_configuration.getAudioLocation() == + setting::AudioLocation::STEREO) { + if ((strategy_configuration.getConnectedDevice() == 2 && + strategy_configuration.getChannelCount() == 1) || + (strategy_configuration.getConnectedDevice() == 1 && + strategy_configuration.getChannelCount() == 2)) { + // Stereo + // 1. two connected device, one for L one for R + // 2. one connected device for both L and R + return true; + } + } else if (strategy_configuration.getAudioLocation() == + setting::AudioLocation::MONO) { + if (strategy_configuration.getConnectedDevice() == 1 && + strategy_configuration.getChannelCount() == 1) { + // Mono + return true; + } + } + return false; +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h new file mode 100644 index 0000000000..402235f0cd --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h> +#include <android-base/logging.h> + +#include <unordered_map> + +#include "aidl_android_hardware_bluetooth_audio_setting.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +class BluetoothLeAudioCodecsProvider { + public: + static std::vector<LeAudioCodecCapabilitiesSetting> + GetLeAudioCodecCapabilities(); + + private: + static inline std::unordered_map<std::string, setting::Configuration> + configuration_map_; + static inline std::unordered_map<std::string, setting::CodecConfiguration> + codec_configuration_map_; + static inline std::unordered_map<std::string, setting::StrategyConfiguration> + strategy_configuration_map_; + + static std::vector<setting::Scenario> GetScenarios( + const std::optional<setting::LeAudioOffloadSetting>& + le_audio_offload_setting); + static void UpdateConfigurationsToMap( + const std::optional<setting::LeAudioOffloadSetting>& + le_audio_offload_setting); + static void UpdateCodecConfigurationsToMap( + const std::optional<setting::LeAudioOffloadSetting>& + le_audio_offload_setting); + static void UpdateStrategyConfigurationsToMap( + const std::optional<setting::LeAudioOffloadSetting>& + le_audio_offload_setting); + + static std::vector<LeAudioCodecCapabilitiesSetting> + ComposeLeAudioCodecCapabilities( + const std::vector<setting::Scenario>& supported_scenarios); + + static UnicastCapability GetUnicastCapability( + const std::string& coding_direction); + template <class T> + static inline UnicastCapability ComposeUnicastCapability( + const CodecType& codec_type, const AudioLocation& audio_location, + const uint8_t& device_cnt, const uint8_t& channel_count, + const T& capability); + + static inline Lc3Capabilities ComposeLc3Capability( + const setting::CodecConfiguration& codec_configuration); + + static inline AudioLocation GetAudioLocation( + const setting::AudioLocation& audio_location); + static inline CodecType GetCodecType(const setting::CodecType& codec_type); + + static inline bool IsValidCodecConfiguration( + const setting::CodecConfiguration& codec_configuration); + static inline bool IsValidStrategyConfiguration( + const setting::StrategyConfiguration& strategy_configuration); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml new file mode 100644 index 0000000000..c7904b338c --- /dev/null +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--- + This is an example to configure LE Audio hardware offload supported capability settings + In the follow list, there would be only one list in this file. Add element into each list as needed. + + codecConfigurationList: + Supported codec capability along with its parameter setting + + strategyConfigurationList: + ASE Configuration strategies + + configurationList: + For each configuration , there are two attributes + - codecConfiguration + - strategyConfiguration + + scenarioList: + There would be only one `scenarios` group + For each scenario, the are two attributes + - encode + - decode + If a scenario is unidirectional, mark another direction as `invalid` + The configuration should be chosen from `configurationList` +--> +<leAudioOffloadSetting> + <scenarioList> + <!-- encode only --> + <scenario encode="OneChanMono_16_1" decode="invalid"/> + <scenario encode="TwoChanStereo_16_1" decode="invalid"/> + <scenario encode="OneChanStereo_16_1" decode="invalid"/> + <scenario encode="OneChanMono_16_2" decode="invalid"/> + <scenario encode="TwoChanStereo_16_2" decode="invalid"/> + <scenario encode="OneChanStereo_16_2" decode="invalid"/> + <!-- encode and decode --> + <scenario encode="OneChanStereo_16_1" decode="OneChanStereo_16_1"/> + <scenario encode="OneChanStereo_16_1" decode="OneChanMono_16_1"/> + <scenario encode="TwoChanStereo_16_1" decode="OneChanMono_16_1"/> + <scenario encode="OneChanMono_16_1" decode="OneChanMono_16_1"/> + <scenario encode="OneChanStereo_16_2" decode="OneChanStereo_16_2"/> + <scenario encode="OneChanStereo_16_2" decode="OneChanMono_16_2"/> + <scenario encode="TwoChanStereo_16_2" decode="OneChanMono_16_2"/> + <scenario encode="OneChanMono_16_2" decode="OneChanMono_16_2"/> + </scenarioList> + <configurationList> + <configuration name="OneChanMono_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/> + <configuration name="TwoChanStereo_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/> + <configuration name="OneChanStereo_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/> + <configuration name="OneChanMono_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/> + <configuration name="TwoChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/> + <configuration name="OneChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/> + </configurationList> + <codecConfigurationList> + <codecConfiguration name="LC3_16k_1" codec="LC3" samplingFrequency="16000" frameDurationUs="7500" octetsPerCodecFrame="30"/> + <codecConfiguration name="LC3_16k_2" codec="LC3" samplingFrequency="16000" frameDurationUs="10000" octetsPerCodecFrame="40"/> + </codecConfigurationList> + <strategyConfigurationList> + <strategyConfiguration name="STEREO_ONE_CIS_PER_DEVICE" audioLocation="STEREO" connectedDevice="2" channelCount="1"/> + <strategyConfiguration name="STEREO_TWO_CISES_PER_DEVICE" audioLocation="STEREO" connectedDevice="1" channelCount="2"/> + <strategyConfiguration name="MONO_ONE_CIS_PER_DEVICE" audioLocation="MONO" connectedDevice="1" channelCount="1"/> + </strategyConfigurationList> +</leAudioOffloadSetting> diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd new file mode 100644 index 0000000000..213e5974da --- /dev/null +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd @@ -0,0 +1,74 @@ +<!-- LE Audio Offload Codec Capability Schema --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="leAudioOffloadSetting"> + <xs:complexType> + <xs:element ref="scenarioList" minOccurs="1" maxOccurs="1"/> + <xs:element ref="configurationList" minOccurs="1" maxOccurs="1"/> + <xs:element ref="codecConfigurationList" minOccurs="1" maxOccurs="1"/> + <xs:element ref="strategyConfigurationList" minOccurs="1" maxOccurs="1"/> + </xs:complexType> + </xs:element> + <xs:element name="scenarioList"> + <xs:complexType> + <xs:element ref="scenario" minOccurs="1" maxOccurs="unbounded"/> + </xs:complexType> + </xs:element> + <xs:element name="configurationList"> + <xs:complexType> + <xs:element ref="configuration" minOccurs="1" maxOccurs="unbounded"/> + </xs:complexType> + </xs:element> + <xs:element name="codecConfigurationList"> + <xs:complexType> + <xs:element ref="codecConfiguration" minOccurs="1" maxOccurs="unbounded"/> + </xs:complexType> + </xs:element> + <xs:element name="strategyConfigurationList"> + <xs:complexType> + <xs:element ref="strategyConfiguration" minOccurs="1" maxOccurs="unbounded"/> + </xs:complexType> + </xs:element> + <xs:element name="scenario"> + <xs:complexType> + <xs:attribute name="encode" type="xs:string"/> + <xs:attribute name="decode" type="xs:string"/> + </xs:complexType> + </xs:element> + <xs:element name="configuration"> + <xs:complexType> + <xs:attribute name="name" type="xs:string"/> + <xs:attribute name="codecConfiguration" type="xs:string"/> + <xs:attribute name="strategyConfiguration" type="xs:string"/> + </xs:complexType> + </xs:element> + <xs:element name="codecConfiguration"> + <xs:complexType> + <xs:attribute name="name" type="xs:string"/> + <xs:attribute name="codec" type="codecType"/> + <xs:attribute name="pcmBitDepth" type="xs:unsignedByte"/> + <xs:attribute name="samplingFrequency" type="xs:int"/> + <xs:attribute name="frameDurationUs" type="xs:int"/> + <xs:attribute name="octetsPerCodecFrame" type="xs:int"/> + <xs:attribute name="codecFrameBlocksPerSdu" type="xs:unsignedByte"/> + </xs:complexType> + </xs:element> + <xs:element name="strategyConfiguration"> + <xs:complexType> + <xs:attribute name="name" type="xs:string"/> + <xs:attribute name="audioLocation" type="audioLocation"/> + <xs:attribute name="connectedDevice" type="xs:unsignedByte"/> + <xs:attribute name="channelCount" type="xs:unsignedByte"/> + </xs:complexType> + </xs:element> + <xs:simpleType name="audioLocation"> + <xs:restriction base="xs:string"> + <xs:enumeration value="MONO"/> + <xs:enumeration value="STEREO"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="codecType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="LC3"/> + </xs:restriction> + </xs:simpleType> +</xs:schema> diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt new file mode 100644 index 0000000000..06aa21a7b3 --- /dev/null +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt @@ -0,0 +1,111 @@ +// Signature format: 2.0 +package aidl.android.hardware.bluetooth.audio.setting { + + public enum AudioLocation { + method public String getRawName(); + enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.AudioLocation MONO; + enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.AudioLocation STEREO; + } + + public class CodecConfiguration { + ctor public CodecConfiguration(); + method public aidl.android.hardware.bluetooth.audio.setting.CodecType getCodec(); + method public short getCodecFrameBlocksPerSdu(); + method public int getFrameDurationUs(); + method public String getName(); + method public int getOctetsPerCodecFrame(); + method public short getPcmBitDepth(); + method public int getSamplingFrequency(); + method public void setCodec(aidl.android.hardware.bluetooth.audio.setting.CodecType); + method public void setCodecFrameBlocksPerSdu(short); + method public void setFrameDurationUs(int); + method public void setName(String); + method public void setOctetsPerCodecFrame(int); + method public void setPcmBitDepth(short); + method public void setSamplingFrequency(int); + } + + public class CodecConfigurationList { + ctor public CodecConfigurationList(); + method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.CodecConfiguration> getCodecConfiguration(); + } + + public enum CodecType { + method public String getRawName(); + enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.CodecType LC3; + } + + public class Configuration { + ctor public Configuration(); + method public String getCodecConfiguration(); + method public String getName(); + method public String getStrategyConfiguration(); + method public void setCodecConfiguration(String); + method public void setName(String); + method public void setStrategyConfiguration(String); + } + + public class ConfigurationList { + ctor public ConfigurationList(); + method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.Configuration> getConfiguration(); + } + + public class LeAudioOffloadSetting { + ctor public LeAudioOffloadSetting(); + method public aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList getCodecConfigurationList(); + method public aidl.android.hardware.bluetooth.audio.setting.ConfigurationList getConfigurationList(); + method public aidl.android.hardware.bluetooth.audio.setting.ScenarioList getScenarioList(); + method public aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList getStrategyConfigurationList(); + method public void setCodecConfigurationList(aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList); + method public void setConfigurationList(aidl.android.hardware.bluetooth.audio.setting.ConfigurationList); + method public void setScenarioList(aidl.android.hardware.bluetooth.audio.setting.ScenarioList); + method public void setStrategyConfigurationList(aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList); + } + + public class Scenario { + ctor public Scenario(); + method public String getDecode(); + method public String getEncode(); + method public void setDecode(String); + method public void setEncode(String); + } + + public class ScenarioList { + ctor public ScenarioList(); + method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.Scenario> getScenario(); + } + + public class StrategyConfiguration { + ctor public StrategyConfiguration(); + method public aidl.android.hardware.bluetooth.audio.setting.AudioLocation getAudioLocation(); + method public short getChannelCount(); + method public short getConnectedDevice(); + method public String getName(); + method public void setAudioLocation(aidl.android.hardware.bluetooth.audio.setting.AudioLocation); + method public void setChannelCount(short); + method public void setConnectedDevice(short); + method public void setName(String); + } + + public class StrategyConfigurationList { + ctor public StrategyConfigurationList(); + method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.StrategyConfiguration> getStrategyConfiguration(); + } + + public class XmlParser { + ctor public XmlParser(); + method public static aidl.android.hardware.bluetooth.audio.setting.CodecConfiguration readCodecConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList readCodecConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static aidl.android.hardware.bluetooth.audio.setting.Configuration readConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static aidl.android.hardware.bluetooth.audio.setting.ConfigurationList readConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static aidl.android.hardware.bluetooth.audio.setting.LeAudioOffloadSetting readLeAudioOffloadSetting(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static aidl.android.hardware.bluetooth.audio.setting.Scenario readScenario(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static aidl.android.hardware.bluetooth.audio.setting.ScenarioList readScenarioList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static aidl.android.hardware.bluetooth.audio.setting.StrategyConfiguration readStrategyConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList readStrategyConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + } + +} + diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_current.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_current.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_current.txt diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_removed.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_removed.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_removed.txt diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/removed.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/removed.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 |