diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp index 292d352b9c..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,18 +110,72 @@ const AudioConfiguration BluetoothAudioSession::GetAudioConfig() { return *audio_config_; } +const AudioConfiguration BluetoothAudioSession::GetLeAudioConnectionMap() { + std::lock_guard guard(mutex_); + if (!IsSessionReady()) { + return AudioConfiguration(LeAudioConfiguration{}); + } + return *leaudio_connection_map_; +} + void BluetoothAudioSession::ReportAudioConfigChanged( const AudioConfiguration& audio_config) { 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) { + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { return; } + std::lock_guard guard(mutex_); - audio_config_ = std::make_unique(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(); + auto current_leaudio_config = + (*audio_config_).get(); + 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(); + auto current_lc3_config = current_leaudio_config.leAudioCodecConfig + .get(); + 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(audio_config); + } else { + audio_config_ = std::make_unique(audio_config); + leaudio_connection_map_ = + std::make_unique(audio_config); + } + if (observers_.empty()) { LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) << " has NO port state observer"; @@ -129,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); } } @@ -419,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 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 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 soft_audio_configuration_changed_cb_; }; class BluetoothAudioSession { @@ -158,6 +165,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 @@ -206,8 +219,11 @@ class BluetoothAudioSession { std::unique_ptr data_mq_; // audio data configuration for both software and offloading std::unique_ptr audio_config_; + std::unique_ptr leaudio_connection_map_; std::vector 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> 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 @@ -94,6 +94,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 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