From b87c6a2acc2f8b92542559bed2c84a8146b72dce Mon Sep 17 00:00:00 2001 From: seveno0 Date: Sat, 24 May 2025 21:23:58 +0800 Subject: [PATCH] mock when bt render/capture invalid Signed-off-by: seveno0 --- .../sink/bluetooth_audio_render_sink.h | 4 +++ .../include/sink/i_audio_render_sink.h | 1 + .../source/bluetooth_audio_capture_source.h | 4 +++ .../include/source/i_audio_capture_source.h | 1 + .../sink/bluetooth_audio_render_sink.cpp | 35 +++++++++++++++++-- .../source/bluetooth_audio_capture_source.cpp | 34 ++++++++++++++++-- .../bluetooth_audio_render_sink_unit_test.cpp | 14 ++++++++ ...uetooth_audio_capture_source_unit_test.cpp | 14 ++++++++ .../ipc_proxy/include/audio_server_proxy.h | 1 + .../ipc_proxy/src/audio_server_proxy.cpp | 9 +++++ .../service/service/audio_device_status.cpp | 5 +++ .../client/include/audio_manager_base.h | 7 ++++ .../client/include/audio_manager_proxy.h | 1 + .../include/pulseaudio_ipc_interface_code.h | 3 +- .../client/src/audio_manager_proxy.cpp | 13 +++++++ .../server/include/audio_server.h | 1 + .../server/src/audio_manager_stub.cpp | 9 +++++ .../audio_service/server/src/audio_server.cpp | 29 +++++++++++++++ 18 files changed, 179 insertions(+), 6 deletions(-) diff --git a/frameworks/native/hdiadapter_new/include/sink/bluetooth_audio_render_sink.h b/frameworks/native/hdiadapter_new/include/sink/bluetooth_audio_render_sink.h index 74526e4452..fb18d867c6 100644 --- a/frameworks/native/hdiadapter_new/include/sink/bluetooth_audio_render_sink.h +++ b/frameworks/native/hdiadapter_new/include/sink/bluetooth_audio_render_sink.h @@ -78,6 +78,8 @@ public: int32_t UpdateAppsUid(const int32_t appsUid[MAX_MIX_CHANNELS], const size_t size) final; int32_t UpdateAppsUid(const std::vector &appsUid) final; + void SetInvalidState(void) override; + void DumpInfo(std::string &dumpString) override; private: @@ -99,6 +101,7 @@ private: void CheckUpdateState(char *data, uint64_t len); int32_t DoRenderFrame(char &data, uint64_t len, uint64_t &writeLen); void UpdateSinkState(bool started); + bool IsValidState(void); // low latency int32_t PrepareMmapBuffer(void); @@ -134,6 +137,7 @@ private: bool started_ = false; bool paused_ = false; std::atomic suspend_ = false; + bool validState_ = true; float leftVolume_ = DEFAULT_VOLUME_LEVEL; float rightVolume_ = DEFAULT_VOLUME_LEVEL; uint32_t hdiRenderId_ = 0; diff --git a/frameworks/native/hdiadapter_new/include/sink/i_audio_render_sink.h b/frameworks/native/hdiadapter_new/include/sink/i_audio_render_sink.h index 876e6ea0f8..28f8e21193 100644 --- a/frameworks/native/hdiadapter_new/include/sink/i_audio_render_sink.h +++ b/frameworks/native/hdiadapter_new/include/sink/i_audio_render_sink.h @@ -88,6 +88,7 @@ public: virtual int32_t SetRenderEmpty(int32_t durationUs) SUCCESS_RET virtual void SetAddress(const std::string &address) {} + virtual void SetInvalidState(void) {} virtual void DumpInfo(std::string &dumpString) = 0; diff --git a/frameworks/native/hdiadapter_new/include/source/bluetooth_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/bluetooth_audio_capture_source.h index 77207ae212..5c13e6eceb 100644 --- a/frameworks/native/hdiadapter_new/include/source/bluetooth_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/bluetooth_audio_capture_source.h @@ -71,6 +71,8 @@ public: int32_t UpdateAppsUid(const int32_t appsUid[PA_MAX_OUTPUTS_PER_SOURCE], const size_t size) final; int32_t UpdateAppsUid(const std::vector &appsUid) final; + void SetInvalidState(void) override; + void DumpInfo(std::string &dumpString) override; void SetDmDeviceType(uint16_t dmDeviceType) override; @@ -86,6 +88,7 @@ private: void CheckLatencySignal(uint8_t *frame, size_t replyBytes); void CheckUpdateState(char *frame, size_t replyBytes); int32_t DoStop(void); + bool IsValidState(void); private: static constexpr uint32_t AUDIO_CHANNELCOUNT = 2; @@ -106,6 +109,7 @@ private: bool sourceInited_ = false; bool started_ = false; bool paused_ = false; + bool validState_ = true; float leftVolume_ = 0.0; float rightVolume_ = 0.0; std::mutex statusMutex_; diff --git a/frameworks/native/hdiadapter_new/include/source/i_audio_capture_source.h b/frameworks/native/hdiadapter_new/include/source/i_audio_capture_source.h index e5c21a5b38..e890e88fa1 100644 --- a/frameworks/native/hdiadapter_new/include/source/i_audio_capture_source.h +++ b/frameworks/native/hdiadapter_new/include/source/i_audio_capture_source.h @@ -77,6 +77,7 @@ public: virtual int32_t UpdateAppsUid(const std::vector &appsUid) = 0; virtual void SetAddress(const std::string &address) {} + virtual void SetInvalidState(void) {} virtual void DumpInfo(std::string &dumpString) {} diff --git a/frameworks/native/hdiadapter_new/sink/bluetooth_audio_render_sink.cpp b/frameworks/native/hdiadapter_new/sink/bluetooth_audio_render_sink.cpp index 50cb214913..76f24ca9e5 100644 --- a/frameworks/native/hdiadapter_new/sink/bluetooth_audio_render_sink.cpp +++ b/frameworks/native/hdiadapter_new/sink/bluetooth_audio_render_sink.cpp @@ -49,7 +49,7 @@ BluetoothAudioRenderSink::~BluetoothAudioRenderSink() int32_t BluetoothAudioRenderSink::Init(const IAudioSinkAttr &attr) { std::lock_guard lock(sinkMutex_); - if (sinkInited_) { + if (sinkInited_ && IsValidState()) { AUDIO_WARNING_LOG("sink already inited"); ++sinkInitCount_; return SUCCESS; @@ -89,8 +89,11 @@ void BluetoothAudioRenderSink::DeInit(void) std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_BLUETOOTH); CHECK_AND_RETURN(deviceManager != nullptr); std::string adapterNameCase = isBluetoothLowLatency_ ? "bt_a2dp_fast" : "bt_a2dp"; - deviceManager->DestroyRender(adapterNameCase, hdiRenderId_); + if (IsValidState()) { + deviceManager->DestroyRender(adapterNameCase, hdiRenderId_); + } audioRender_ = nullptr; + validState_ = true; DumpFileUtil::CloseDumpFile(&dumpFile_); } @@ -127,7 +130,7 @@ int32_t BluetoothAudioRenderSink::Start(void) int32_t tryCount = 3; while (tryCount-- > 0) { AUDIO_INFO_LOG("try to start bluetooth render"); - CHECK_AND_BREAK_LOG(audioRender_ != nullptr, "Bluetooth renderer is nullptr"); + CHECK_AND_BREAK_LOG(audioRender_ != nullptr && IsValidState(), "Bluetooth renderer is nullptr"); int32_t ret = audioRender_->control.Start(reinterpret_cast(audioRender_)); if (ret) { AUDIO_ERR_LOG("start fail, remain %{public}d attempt(s)", tryCount); @@ -168,6 +171,7 @@ int32_t BluetoothAudioRenderSink::Stop(void) return SUCCESS; } CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); Trace renderTrace("BluetoothAudioRenderSink::Stop inner stop"); AUDIO_DEBUG_LOG("before render stop"); int32_t ret = audioRender_->control.Stop(reinterpret_cast(audioRender_)); @@ -184,6 +188,7 @@ int32_t BluetoothAudioRenderSink::Resume(void) std::lock_guard lock(sinkMutex_); AUDIO_INFO_LOG("in"); CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); if (!paused_) { @@ -201,6 +206,7 @@ int32_t BluetoothAudioRenderSink::Pause(void) std::lock_guard lock(sinkMutex_); AUDIO_INFO_LOG("in"); CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); if (paused_) { @@ -216,6 +222,7 @@ int32_t BluetoothAudioRenderSink::Flush(void) { AUDIO_INFO_LOG("in"); CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); int32_t ret = audioRender_->control.Flush(reinterpret_cast(audioRender_)); @@ -227,6 +234,7 @@ int32_t BluetoothAudioRenderSink::Reset(void) { AUDIO_INFO_LOG("in"); CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); int32_t ret = audioRender_->control.Flush(reinterpret_cast(audioRender_)); @@ -237,6 +245,7 @@ int32_t BluetoothAudioRenderSink::Reset(void) int32_t BluetoothAudioRenderSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen) { CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); if (audioMonoState_) { AdjustStereoToMono(&data, len); } @@ -293,6 +302,7 @@ void BluetoothAudioRenderSink::SetAudioParameter(const AudioParamKey key, const { AUDIO_INFO_LOG("key: %{public}d, condition: %{public}s, value: %{public}s", key, condition.c_str(), value.c_str()); CHECK_AND_RETURN_LOG(audioRender_ != nullptr, "render is nullptr"); + CHECK_AND_RETURN(IsValidState()); int32_t ret = audioRender_->attr.SetExtraParams(reinterpret_cast(audioRender_), value.c_str()); if (ret != SUCCESS) { AUDIO_WARNING_LOG("set parameter fail, error code: %{public}d", ret); @@ -327,6 +337,7 @@ std::string BluetoothAudioRenderSink::GetAudioParameter(const AudioParamKey key, int32_t BluetoothAudioRenderSink::SetVolume(float left, float right) { CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); leftVolume_ = left; rightVolume_ = right; @@ -358,6 +369,7 @@ int32_t BluetoothAudioRenderSink::GetLatency(uint32_t &latency) { Trace trace("BluetoothAudioRenderSink::GetLatency"); CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); uint32_t hdiLatency; int32_t ret = audioRender_->GetLatency(audioRender_, &hdiLatency); @@ -369,6 +381,7 @@ int32_t BluetoothAudioRenderSink::GetLatency(uint32_t &latency) int32_t BluetoothAudioRenderSink::GetTransactionId(uint64_t &transactionId) { CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); transactionId = reinterpret_cast(audioRender_); return SUCCESS; } @@ -499,6 +512,12 @@ int32_t BluetoothAudioRenderSink::UpdateAppsUid(const std::vector &apps return SUCCESS; } +void BluetoothAudioRenderSink::SetInvalidState(void) +{ + AUDIO_INFO_LOG("in"); + validState_ = false; +} + void BluetoothAudioRenderSink::DumpInfo(std::string &dumpString) { dumpString += "type: BtSink\tstarted: " + std::string(started_ ? "true" : "false") + "\tisLowLatency: " + @@ -519,6 +538,7 @@ int32_t BluetoothAudioRenderSink::GetMmapBufferInfo(int &fd, uint32_t &totalSize int32_t BluetoothAudioRenderSink::GetMmapHandlePosition(uint64_t &frames, int64_t &timeSec, int64_t &timeNanoSec) { CHECK_AND_RETURN_RET_LOG(audioRender_ != nullptr, ERR_INVALID_HANDLE, "render is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); struct AudioTimeStamp stamp = {}; int32_t ret = audioRender_->attr.GetMmapPosition(audioRender_, &frames, &stamp); @@ -630,6 +650,7 @@ int32_t BluetoothAudioRenderSink::CreateRender(void) void *render = deviceManager->CreateRender(adapterNameCase, ¶m, &deviceDesc, hdiRenderId_); audioRender_ = static_cast(render); CHECK_AND_RETURN_RET(audioRender_ != nullptr, ERR_NOT_STARTED); + validState_ = true; return SUCCESS; } @@ -782,6 +803,14 @@ void BluetoothAudioRenderSink::UpdateSinkState(bool started) callback_.OnRenderSinkStateChange(GenerateUniqueID(AUDIO_HDI_RENDER_ID_BASE, HDI_RENDER_OFFSET_BLUETOOTH), started); } +bool BluetoothAudioRenderSink::IsValidState(void) +{ + if (!validState_) { + AUDIO_WARNING_LOG("disconnected, render invalid"); + } + return validState_; +} + int32_t BluetoothAudioRenderSink::PrepareMmapBuffer(void) { uint32_t totalBufferInMs = 40; // 40: 5 * (6 + 2 * (1)) = 40ms, the buffer size, not latency diff --git a/frameworks/native/hdiadapter_new/source/bluetooth_audio_capture_source.cpp b/frameworks/native/hdiadapter_new/source/bluetooth_audio_capture_source.cpp index e8e2561b01..b14e049915 100644 --- a/frameworks/native/hdiadapter_new/source/bluetooth_audio_capture_source.cpp +++ b/frameworks/native/hdiadapter_new/source/bluetooth_audio_capture_source.cpp @@ -54,7 +54,7 @@ BluetoothAudioCaptureSource::~BluetoothAudioCaptureSource() int32_t BluetoothAudioCaptureSource::Init(const IAudioSourceAttr &attr) { - if (sourceInited_) { + if (sourceInited_ && IsValidState()) { AUDIO_WARNING_LOG("source already inited"); return SUCCESS; } @@ -84,8 +84,11 @@ void BluetoothAudioCaptureSource::DeInit(void) HdiAdapterManager &manager = HdiAdapterManager::GetInstance(); std::shared_ptr deviceManager = manager.GetDeviceManager(HDI_DEVICE_MANAGER_TYPE_BLUETOOTH); CHECK_AND_RETURN(deviceManager != nullptr); - deviceManager->DestroyCapture(adapterNameCase_, hdiCaptureId_); + if (IsValidState()) { + deviceManager->DestroyCapture(adapterNameCase_, hdiCaptureId_); + } audioCapture_ = nullptr; + validState_ = true; DumpFileUtil::CloseDumpFile(&dumpFile_); } @@ -123,6 +126,7 @@ int32_t BluetoothAudioCaptureSource::Start(void) } callback_.OnCaptureState(true); CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); int32_t ret = audioCapture_->control.Start(reinterpret_cast(audioCapture_)); if (ret < 0) { AUDIO_ERR_LOG("start fail"); @@ -160,6 +164,7 @@ int32_t BluetoothAudioCaptureSource::Resume(void) std::lock_guard lock(statusMutex_); AUDIO_INFO_LOG("in"); CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); Trace trace("BluetoothAudioCaptureSource::Resume"); @@ -174,6 +179,7 @@ int32_t BluetoothAudioCaptureSource::Pause(void) std::lock_guard lock(statusMutex_); AUDIO_INFO_LOG("in"); CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); Trace trace("BluetoothAudioCaptureSource::Pause"); @@ -187,6 +193,7 @@ int32_t BluetoothAudioCaptureSource::Flush(void) { AUDIO_INFO_LOG("in"); CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); Trace trace("BluetoothAudioCaptureSource::Flush"); @@ -199,6 +206,7 @@ int32_t BluetoothAudioCaptureSource::Reset(void) { AUDIO_INFO_LOG("in"); CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); Trace trace("BluetoothAudioCaptureSource::Reset"); @@ -210,6 +218,7 @@ int32_t BluetoothAudioCaptureSource::Reset(void) int32_t BluetoothAudioCaptureSource::CaptureFrame(char *frame, uint64_t requestBytes, uint64_t &replyBytes) { CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); Trace trace("BluetoothAudioCaptureSource::CaptureFrame"); AudioCapturerSourceTsRecorder recorder(replyBytes, audioSrcClock_); @@ -250,6 +259,7 @@ std::string BluetoothAudioCaptureSource::GetAudioParameter(const AudioParamKey k int32_t BluetoothAudioCaptureSource::SetVolume(float left, float right) { CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); leftVolume_ = left; rightVolume_ = right; @@ -270,6 +280,7 @@ int32_t BluetoothAudioCaptureSource::SetVolume(float left, float right) int32_t BluetoothAudioCaptureSource::GetVolume(float &left, float &right) { CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); float val = 0.0; audioCapture_->volume.GetVolume(reinterpret_cast(audioCapture_), &val); @@ -283,6 +294,7 @@ int32_t BluetoothAudioCaptureSource::SetMute(bool isMute) AUDIO_INFO_LOG("isMute: %{public}d", isMute); muteState_ = isMute; CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); if (sourceInited_) { int32_t ret = audioCapture_->volume.SetMute(reinterpret_cast(audioCapture_), isMute); @@ -299,6 +311,7 @@ int32_t BluetoothAudioCaptureSource::SetMute(bool isMute) int32_t BluetoothAudioCaptureSource::GetMute(bool &isMute) { CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); bool hdiMuteState = false; int32_t ret = audioCapture_->volume.GetMute(reinterpret_cast(audioCapture_), &hdiMuteState); if (ret != SUCCESS) { @@ -365,6 +378,12 @@ int32_t BluetoothAudioCaptureSource::UpdateAppsUid(const std::vector &a return SUCCESS; } +void BluetoothAudioCaptureSource::SetInvalidState(void) +{ + AUDIO_INFO_LOG("in"); + validState_ = false; +} + void BluetoothAudioCaptureSource::DumpInfo(std::string &dumpString) { dumpString += "type: BtSource\tstarted: " + std::string(started_ ? "true" : "false") + "\thalName: " + halName_ + @@ -457,6 +476,8 @@ int32_t BluetoothAudioCaptureSource::CreateCapture(void) audioCapture_ = static_cast(capture); CHECK_AND_RETURN_RET(audioCapture_ != nullptr, ERR_NOT_STARTED); SetAudioRouteInfoForEnhanceChain(); + validState_ = true; + return SUCCESS; } @@ -534,6 +555,7 @@ int32_t BluetoothAudioCaptureSource::DoStop(void) } #endif CHECK_AND_RETURN_RET_LOG(audioCapture_ != nullptr, ERR_INVALID_HANDLE, "capture is nullptr"); + CHECK_AND_RETURN_RET(IsValidState(), ERR_INVALID_HANDLE); CHECK_AND_RETURN_RET_LOG(started_, ERR_OPERATION_FAILED, "not start, invalid state"); int32_t ret = audioCapture_->control.Stop(reinterpret_cast(audioCapture_)); CHECK_AND_RETURN_RET_LOG(ret >= 0, ERR_OPERATION_FAILED, "stop fail"); @@ -543,6 +565,14 @@ int32_t BluetoothAudioCaptureSource::DoStop(void) return SUCCESS; } +bool BluetoothAudioCaptureSource::IsValidState(void) +{ + if (!validState_) { + AUDIO_WARNING_LOG("disconnected, capture invalid"); + } + return validState_; +} + void BluetoothAudioCaptureSource::SetDmDeviceType(uint16_t dmDeviceType) { AUDIO_INFO_LOG("not support"); diff --git a/frameworks/native/hdiadapter_new/test/unittest/sink/bluetooth_audio_render_sink_unit_test.cpp b/frameworks/native/hdiadapter_new/test/unittest/sink/bluetooth_audio_render_sink_unit_test.cpp index 1349152e79..75749e04da 100644 --- a/frameworks/native/hdiadapter_new/test/unittest/sink/bluetooth_audio_render_sink_unit_test.cpp +++ b/frameworks/native/hdiadapter_new/test/unittest/sink/bluetooth_audio_render_sink_unit_test.cpp @@ -167,5 +167,19 @@ HWTEST_F(BluetoothAudioRenderSinkUnitTest, BluetoothSinkUnitTest_006, TestSize.L EXPECT_EQ(ret, ERR_NOT_SUPPORTED); } +/** + * @tc.name : Test BluetoothSink API + * @tc.number : BluetoothSinkUnitTest_007 + * @tc.desc : Test bluetooth sink set invalid state + */ +HWTEST_F(BluetoothAudioRenderSinkUnitTest, BluetoothSinkUnitTest_007, TestSize.Level1) +{ + EXPECT_TRUE(sink_); + sink_->SetInvalidState(); + (void)sink_->Init(attr_); + sink_->DeInit(); + EXPECT_FALSE(sink_->IsInited()); +} + } // namespace AudioStandard } // namespace OHOS diff --git a/frameworks/native/hdiadapter_new/test/unittest/source/bluetooth_audio_capture_source_unit_test.cpp b/frameworks/native/hdiadapter_new/test/unittest/source/bluetooth_audio_capture_source_unit_test.cpp index 0ffab23dec..a44aaf1099 100644 --- a/frameworks/native/hdiadapter_new/test/unittest/source/bluetooth_audio_capture_source_unit_test.cpp +++ b/frameworks/native/hdiadapter_new/test/unittest/source/bluetooth_audio_capture_source_unit_test.cpp @@ -176,5 +176,19 @@ HWTEST_F(BluetoothAudioCaptureSourceUnitTest, BluetoothSourceUnitTest_007, TestS EXPECT_EQ(ret, ERR_NOT_SUPPORTED); } +/** + * @tc.name : Test BluetoothSource API + * @tc.number : BluetoothSourceUnitTest_008 + * @tc.desc : Test bluetooth source set invalid state + */ +HWTEST_F(BluetoothAudioCaptureSourceUnitTest, BluetoothSourceUnitTest_008, TestSize.Level1) +{ + EXPECT_TRUE(source_); + source_->SetInvalidState(); + (void)source_->Init(attr_); + source_->DeInit(); + EXPECT_FALSE(source_->IsInited()); +} + } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_policy/server/infra/ipc_proxy/include/audio_server_proxy.h b/services/audio_policy/server/infra/ipc_proxy/include/audio_server_proxy.h index 8e9df11f27..308a33bf57 100644 --- a/services/audio_policy/server/infra/ipc_proxy/include/audio_server_proxy.h +++ b/services/audio_policy/server/infra/ipc_proxy/include/audio_server_proxy.h @@ -114,6 +114,7 @@ public: bool IsAcousticEchoCancelerSupported(SourceType sourceType); void SetLatestMuteState(const uint32_t sessionId, const bool muteFlag); void SetSessionMuteState(const uint32_t sessionId, const bool insert, const bool muteFlag); + void SetBtHdiInvalidState(); private: AudioServerProxy() {} ~AudioServerProxy() {} diff --git a/services/audio_policy/server/infra/ipc_proxy/src/audio_server_proxy.cpp b/services/audio_policy/server/infra/ipc_proxy/src/audio_server_proxy.cpp index c5ff760db5..5d1719f21f 100644 --- a/services/audio_policy/server/infra/ipc_proxy/src/audio_server_proxy.cpp +++ b/services/audio_policy/server/infra/ipc_proxy/src/audio_server_proxy.cpp @@ -617,5 +617,14 @@ void AudioServerProxy::SetSessionMuteState(const uint32_t sessionId, const bool gsp->SetSessionMuteState(sessionId, insert, muteFlag); IPCSkeleton::SetCallingIdentity(identity); } + +void AudioServerProxy::SetBtHdiInvalidState() +{ + const sptr gsp = GetAudioServerProxy(); + CHECK_AND_RETURN_LOG(gsp != nullptr, "Service proxy unavailable"); + std::string identity = IPCSkeleton::ResetCallingIdentity(); + gsp->SetBtHdiInvalidState(); + IPCSkeleton::SetCallingIdentity(identity); +} } } diff --git a/services/audio_policy/server/src/service/service/audio_device_status.cpp b/services/audio_policy/server/src/service/service/audio_device_status.cpp index 69e2ab3035..bb1f239b75 100644 --- a/services/audio_policy/server/src/service/service/audio_device_status.cpp +++ b/services/audio_policy/server/src/service/service/audio_device_status.cpp @@ -452,6 +452,11 @@ int32_t AudioDeviceStatus::HandleLocalDeviceDisconnected(const AudioDeviceDescri } else if (updatedDesc.deviceType_ == DEVICE_TYPE_USB_HEADSET || updatedDesc.deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET) { AudioServerProxy::GetInstance().UnloadHdiAdapterProxy(HDI_DEVICE_MANAGER_TYPE_LOCAL, "usb", false); + } else if (updatedDesc.deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP) { + AudioServerProxy::GetInstance().SetBtHdiInvalidState(); + AudioServerProxy::GetInstance().UnloadHdiAdapterProxy(HDI_DEVICE_MANAGER_TYPE_BLUETOOTH, "bt_a2dp", true); + AudioServerProxy::GetInstance().UnloadHdiAdapterProxy(HDI_DEVICE_MANAGER_TYPE_BLUETOOTH, "bt_a2dp_fast", true); + AudioServerProxy::GetInstance().UnloadHdiAdapterProxy(HDI_DEVICE_MANAGER_TYPE_BLUETOOTH, "bt_hdap", true); } return SUCCESS; } diff --git a/services/audio_service/client/include/audio_manager_base.h b/services/audio_service/client/include/audio_manager_base.h index 2c7e92e9e8..65b6d99efc 100644 --- a/services/audio_service/client/include/audio_manager_base.h +++ b/services/audio_service/client/include/audio_manager_base.h @@ -635,6 +635,12 @@ public: const DataTransferMonitorParam ¶m) = 0; virtual int32_t UnregisterDataTransferMonitorParam(const int32_t &callbackId) = 0; + /** + * Set bluetooth hdi invalid state + * + * @return none. + */ + virtual void SetBtHdiInvalidState() = 0; public: DECLARE_INTERFACE_DESCRIPTOR(u"IStandardAudioService"); }; @@ -746,6 +752,7 @@ private: int HandleRegisterDataTransferCallback(MessageParcel &data, MessageParcel &reply); int HandleRegisterDataTransferMonitorParam(MessageParcel &data, MessageParcel &reply); int HandleUnregisterDataTransferMonitorParam(MessageParcel &data, MessageParcel &reply); + int HandleSetBtHdiInvalidState(MessageParcel &data, MessageParcel &reply); int HandleSecondPartCode(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); int HandleThirdPartCode(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); diff --git a/services/audio_service/client/include/audio_manager_proxy.h b/services/audio_service/client/include/audio_manager_proxy.h index e69796fbf7..466ee4ce4c 100644 --- a/services/audio_service/client/include/audio_manager_proxy.h +++ b/services/audio_service/client/include/audio_manager_proxy.h @@ -143,6 +143,7 @@ public: void DestroyHdiPort(uint32_t id) override; void SetDeviceConnectedFlag(bool flag) override; bool IsAcousticEchoCancelerSupported(SourceType sourceType) override; + void SetBtHdiInvalidState() override; private: static inline BrokerDelegator delegator_; diff --git a/services/audio_service/client/include/pulseaudio_ipc_interface_code.h b/services/audio_service/client/include/pulseaudio_ipc_interface_code.h index dada0118ad..7825ef756d 100644 --- a/services/audio_service/client/include/pulseaudio_ipc_interface_code.h +++ b/services/audio_service/client/include/pulseaudio_ipc_interface_code.h @@ -117,7 +117,8 @@ namespace AudioStandard { REMOVE_THREAD_FROM_AUDIOWORKGROUP, START_AUDIOWORKGROUP, STOP_AUDIOWORKGROUP, - AUDIO_SERVER_CODE_MAX = STOP_AUDIOWORKGROUP, + SET_BT_HDI_INVALID_STATE, + AUDIO_SERVER_CODE_MAX = SET_BT_HDI_INVALID_STATE, }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/client/src/audio_manager_proxy.cpp b/services/audio_service/client/src/audio_manager_proxy.cpp index fa0aee1179..274431cbea 100644 --- a/services/audio_service/client/src/audio_manager_proxy.cpp +++ b/services/audio_service/client/src/audio_manager_proxy.cpp @@ -1919,5 +1919,18 @@ int32_t AudioManagerProxy::StopGroup(int32_t pid, int32_t workgroupId) return AUDIO_OK; } +void AudioManagerProxy::SetBtHdiInvalidState() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool ret = data.WriteInterfaceToken(GetDescriptor()); + CHECK_AND_RETURN_LOG(ret, "WriteInterfaceToken failed"); + + int32_t error = Remote()->SendRequest( + static_cast(AudioServerInterfaceCode::SET_BT_HDI_INVALID_STATE), data, reply, option); + CHECK_AND_RETURN_LOG(error == ERR_NONE, "SetBtHdiInvalidState failed, error: %{public}d", error); +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/include/audio_server.h b/services/audio_service/server/include/audio_server.h index 2c78beaac6..f331b96508 100644 --- a/services/audio_service/server/include/audio_server.h +++ b/services/audio_service/server/include/audio_server.h @@ -240,6 +240,7 @@ public: int32_t UnregisterDataTransferMonitorParam(const int32_t &callbackId) override; void OnDataTransferStateChange(const int32_t &pid, const int32_t &callbackId, const AudioRendererDataTransferStateChangeInfo &info) override; + void SetBtHdiInvalidState() override; protected: void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; diff --git a/services/audio_service/server/src/audio_manager_stub.cpp b/services/audio_service/server/src/audio_manager_stub.cpp index 9beb2839c1..56f89f739a 100644 --- a/services/audio_service/server/src/audio_manager_stub.cpp +++ b/services/audio_service/server/src/audio_manager_stub.cpp @@ -138,6 +138,7 @@ const char *g_audioServerCodeStrs[] = { "REMOVE_THREAD_FROM_AUDIOWORKGROUP", "START_AUDIOWORKGROUP", "STOP_AUDIOWORKGROUP", + "SET_BT_HDI_INVALID_STATE", }; constexpr size_t CODE_NUMS = sizeof(g_audioServerCodeStrs) / sizeof(const char *); static_assert(CODE_NUMS == (static_cast (AudioServerInterfaceCode::AUDIO_SERVER_CODE_MAX) + 1), @@ -898,6 +899,8 @@ int AudioManagerStub::HandleSixthPartCode(uint32_t code, MessageParcel &data, Me return HandleUnregisterDataTransferMonitorParam(data, reply); case static_cast(AudioServerInterfaceCode::REGISTER_DATATRANSFER_CALLBACK): return HandleRegisterDataTransferCallback(data, reply); + case static_cast(AudioServerInterfaceCode::SET_BT_HDI_INVALID_STATE): + return HandleSetBtHdiInvalidState(data, reply); default: AUDIO_ERR_LOG("default case, need check AudioManagerStub"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -1487,5 +1490,11 @@ int AudioManagerStub::HandleStopAudioWorkgroup(MessageParcel &data, MessageParce reply.WriteInt32(ret); return AUDIO_OK; } + +int AudioManagerStub::HandleSetBtHdiInvalidState(MessageParcel &data, MessageParcel &reply) +{ + SetBtHdiInvalidState(); + return AUDIO_OK; +} } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/server/src/audio_server.cpp b/services/audio_service/server/src/audio_server.cpp index 3d091d571b..65e2ec58e2 100644 --- a/services/audio_service/server/src/audio_server.cpp +++ b/services/audio_service/server/src/audio_server.cpp @@ -2681,5 +2681,34 @@ int32_t AudioServer::StopGroup(int32_t pid, int32_t workgroupId) return audioResourceService_->StopGroup(pid, workgroupId); } +void AudioServer::SetBtHdiInvalidState() +{ + int32_t callingUid = IPCSkeleton::GetCallingUid(); + CHECK_AND_RETURN_LOG(PermissionUtil::VerifyIsAudio(), "refused for %{public}d", callingUid); + auto limitFunc = [](uint32_t id) -> bool { + std::string info = IdHandler::GetInstance().ParseInfo(id); + if (IdHandler::GetInstance().ParseType(id) == HDI_ID_TYPE_BLUETOOTH) { + return true; + } + return false; + }; + auto sinkProcessFunc = [limitFunc](uint32_t renderId, std::shared_ptr sink) -> int32_t { + CHECK_AND_RETURN_RET(limitFunc(renderId), SUCCESS); + CHECK_AND_RETURN_RET(sink != nullptr, SUCCESS); + + sink->SetInvalidState(); + return SUCCESS; + }; + (void)HdiAdapterManager::GetInstance().ProcessSink(sinkProcessFunc); + auto sourceProcessFunc = [limitFunc](uint32_t captureId, std::shared_ptr source) -> int32_t { + CHECK_AND_RETURN_RET(limitFunc(captureId), SUCCESS); + CHECK_AND_RETURN_RET(source != nullptr, SUCCESS); + + source->SetInvalidState(); + return SUCCESS; + }; + (void)HdiAdapterManager::GetInstance().ProcessSource(sourceProcessFunc); +} + } // namespace AudioStandard } // namespace OHOS -- Gitee