1 /*
2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef LOG_TAG
16 #define LOG_TAG "AudioBluetoothManager"
17 #endif
18
19 #include <shared_mutex>
20 #include "audio_bluetooth_manager.h"
21 #include "bluetooth_def.h"
22 #include "audio_errors.h"
23 #include "audio_common_log.h"
24 #include "audio_utils.h"
25 #include "bluetooth_audio_manager.h"
26 #include "bluetooth_device_manager.h"
27 #include "bluetooth_device_utils.h"
28 #include "bluetooth_hfp_interface.h"
29 #include "hisysevent.h"
30
31 namespace OHOS {
32 namespace Bluetooth {
33 using namespace AudioStandard;
34
35 const int32_t BT_VIRTUAL_DEVICE_ADD = 0;
36 const int32_t BT_VIRTUAL_DEVICE_REMOVE = 1;
37 constexpr const uint8_t CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG = 0x03;
38 A2dpSource *AudioA2dpManager::a2dpInstance_ = nullptr;
39 std::shared_ptr<AudioA2dpListener> AudioA2dpManager::a2dpListener_ = std::make_shared<AudioA2dpListener>();
40 int AudioA2dpManager::connectionState_ = static_cast<int>(BTConnectState::DISCONNECTED);
41 int32_t AudioA2dpManager::captureConnectionState_ = static_cast<int32_t>(BTHdapConnectState::DISCONNECTED);
42 BluetoothRemoteDevice AudioA2dpManager::activeA2dpDevice_;
43 std::shared_mutex g_a2dpInstanceLock;
44 std::shared_ptr<AudioHfpListener> AudioHfpManager::hfpListener_ = std::make_shared<AudioHfpListener>();
45 std::atomic<AudioScene> AudioHfpManager::scene_ = AUDIO_SCENE_DEFAULT;
46 BluetoothRemoteDevice AudioHfpManager::activeHfpDevice_;
47 std::atomic<bool> AudioHfpManager::isRecognitionScene_ = false;
48 std::atomic<bool> AudioHfpManager::isRecordScene_ = false;
49 std::map<std::string, bool> AudioHfpManager::virtualCalls_;
50 std::map<std::string, std::list<int32_t>> AudioHfpManager::virtualCallStreams_;
51 std::mutex AudioHfpManager::virtualCallMutex_;
52 std::vector<std::shared_ptr<AudioA2dpPlayingStateChangedListener>> AudioA2dpManager::a2dpPlayingStateChangedListeners_;
53 std::mutex g_activehfpDeviceLock;
54 std::mutex g_a2dpPlayingStateChangedLock;
55 static const int32_t BT_SET_ACTIVE_DEVICE_TIMEOUT = 8; //BtService SetActiveDevice 8s timeout
56
GetAudioStreamInfo(A2dpCodecInfo codecInfo,AudioStreamInfo & audioStreamInfo)57 static bool GetAudioStreamInfo(A2dpCodecInfo codecInfo, AudioStreamInfo &audioStreamInfo)
58 {
59 AUDIO_DEBUG_LOG("codec info rate[%{public}d] format[%{public}d] channel[%{public}d]",
60 codecInfo.sampleRate, codecInfo.bitsPerSample, codecInfo.channelMode);
61 switch (codecInfo.sampleRate) {
62 case A2DP_SBC_SAMPLE_RATE_48000_USER:
63 case A2DP_L2HCV2_SAMPLE_RATE_48000_USER:
64 audioStreamInfo.samplingRate = SAMPLE_RATE_48000;
65 break;
66 case A2DP_SBC_SAMPLE_RATE_44100_USER:
67 audioStreamInfo.samplingRate = SAMPLE_RATE_44100;
68 break;
69 case A2DP_SBC_SAMPLE_RATE_32000_USER:
70 audioStreamInfo.samplingRate = SAMPLE_RATE_32000;
71 break;
72 case A2DP_SBC_SAMPLE_RATE_16000_USER:
73 audioStreamInfo.samplingRate = SAMPLE_RATE_16000;
74 break;
75 case A2DP_L2HCV2_SAMPLE_RATE_96000_USER:
76 audioStreamInfo.samplingRate = SAMPLE_RATE_96000;
77 break;
78 default:
79 return false;
80 }
81 switch (codecInfo.bitsPerSample) {
82 case A2DP_SAMPLE_BITS_16_USER:
83 audioStreamInfo.format = SAMPLE_S16LE;
84 break;
85 case A2DP_SAMPLE_BITS_24_USER:
86 audioStreamInfo.format = SAMPLE_S24LE;
87 break;
88 case A2DP_SAMPLE_BITS_32_USER:
89 audioStreamInfo.format = SAMPLE_S32LE;
90 break;
91 default:
92 return false;
93 }
94 switch (codecInfo.channelMode) {
95 case A2DP_SBC_CHANNEL_MODE_STEREO_USER:
96 audioStreamInfo.channels = STEREO;
97 break;
98 case A2DP_SBC_CHANNEL_MODE_MONO_USER:
99 audioStreamInfo.channels = MONO;
100 break;
101 default:
102 return false;
103 }
104 audioStreamInfo.encoding = ENCODING_PCM;
105 return true;
106 }
107
108 // LCOV_EXCL_START
RegisterBluetoothA2dpListener()109 void AudioA2dpManager::RegisterBluetoothA2dpListener()
110 {
111 AUDIO_INFO_LOG("in");
112 std::lock_guard<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
113 a2dpInstance_ = A2dpSource::GetProfile();
114 CHECK_AND_RETURN_LOG(a2dpInstance_ != nullptr, "Failed to obtain A2DP profile instance");
115 a2dpInstance_->RegisterObserver(a2dpListener_);
116 }
117
UnregisterBluetoothA2dpListener()118 void AudioA2dpManager::UnregisterBluetoothA2dpListener()
119 {
120 AUDIO_INFO_LOG("in");
121 std::lock_guard<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
122 CHECK_AND_RETURN_LOG(a2dpInstance_ != nullptr, "A2DP profile instance unavailable");
123
124 a2dpInstance_->DeregisterObserver(a2dpListener_);
125 a2dpInstance_ = nullptr;
126 }
127
DisconnectBluetoothA2dpSink()128 void AudioA2dpManager::DisconnectBluetoothA2dpSink()
129 {
130 int connectionState = static_cast<int>(BTConnectState::DISCONNECTED);
131 auto a2dpList = MediaBluetoothDeviceManager::GetAllA2dpBluetoothDevice();
132 for (const auto &device : a2dpList) {
133 if (a2dpListener_ != nullptr) {
134 a2dpListener_->OnConnectionStateChanged(device, connectionState,
135 static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
136 }
137 }
138
139 auto virtualDevices = MediaBluetoothDeviceManager::GetA2dpVirtualDeviceList();
140 for (const auto &virtualDevice : virtualDevices) {
141 if (a2dpListener_ != nullptr) {
142 a2dpListener_->OnVirtualDeviceChanged(static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_REMOVE),
143 virtualDevice.GetDeviceAddr());
144 }
145 }
146
147 MediaBluetoothDeviceManager::ClearAllA2dpBluetoothDevice();
148 }
149
DisconnectBluetoothA2dpSource()150 void AudioA2dpManager::DisconnectBluetoothA2dpSource()
151 {
152 CHECK_AND_RETURN_LOG(a2dpListener_ != nullptr, "a2dpListener_ is nullptr");
153 int captureConnectionState = static_cast<int>(BTHdapConnectState::DISCONNECTED);
154 auto a2dpInList = A2dpInBluetoothDeviceManager::GetAllA2dpInBluetoothDevice();
155 A2dpCodecInfo defaultCodecInfo = {};
156 for (const auto &device : a2dpInList) {
157 a2dpListener_->OnCaptureConnectionStateChanged(device, captureConnectionState, defaultCodecInfo);
158 }
159 A2dpInBluetoothDeviceManager::ClearAllA2dpInBluetoothDevice();
160 A2dpInBluetoothDeviceManager::ClearAllA2dpInStreamInfo();
161 }
162
SetActiveA2dpDevice(const std::string & macAddress)163 int32_t AudioA2dpManager::SetActiveA2dpDevice(const std::string& macAddress)
164 {
165 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
166 AUDIO_WARNING_LOG("incoming device:%{public}s, current device:%{public}s",
167 GetEncryptAddr(macAddress).c_str(), GetEncryptAddr(activeA2dpDevice_.GetDeviceAddr()).c_str());
168 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "A2DP profile instance is null");
169 BluetoothRemoteDevice device;
170 if (macAddress != "") {
171 int32_t tmp = MediaBluetoothDeviceManager::GetConnectedA2dpBluetoothDevice(macAddress, device);
172 CHECK_AND_RETURN_RET_LOG(tmp == SUCCESS, ERROR, "the configuring A2DP device doesn't exist.");
173 } else {
174 AUDIO_INFO_LOG("Deactive A2DP device");
175 }
176 int32_t ret = a2dpInstance_->SetActiveSinkDevice(device);
177 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "SetActiveA2dpDevice failed. result: %{public}d", ret);
178 activeA2dpDevice_ = device;
179 return SUCCESS;
180 }
181
GetActiveA2dpDevice()182 std::string AudioA2dpManager::GetActiveA2dpDevice()
183 {
184 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
185 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, "", "A2DP profile instance is null");
186 BluetoothRemoteDevice device = a2dpInstance_->GetActiveSinkDevice();
187 return device.GetDeviceAddr();
188 }
189
SetDeviceAbsVolume(const std::string & macAddress,int32_t volume)190 int32_t AudioA2dpManager::SetDeviceAbsVolume(const std::string& macAddress, int32_t volume)
191 {
192 BluetoothRemoteDevice device;
193 int32_t ret = MediaBluetoothDeviceManager::GetConnectedA2dpBluetoothDevice(macAddress, device);
194 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "SetDeviceAbsVolume: the configuring A2DP device doesn't exist.");
195 return AvrcpTarget::GetProfile()->SetDeviceAbsoluteVolume(device, volume);
196 }
197
GetA2dpDeviceStreamInfo(const std::string & macAddress,AudioStreamInfo & streamInfo)198 int32_t AudioA2dpManager::GetA2dpDeviceStreamInfo(const std::string& macAddress,
199 AudioStreamInfo &streamInfo)
200 {
201 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
202 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "A2DP profile instance is null");
203 BluetoothRemoteDevice device;
204 int32_t ret = MediaBluetoothDeviceManager::GetConnectedA2dpBluetoothDevice(macAddress, device);
205 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR,
206 "GetA2dpDeviceStreamInfo: the configuring A2DP device doesn't exist.");
207 A2dpCodecStatus codecStatus = a2dpInstance_->GetCodecStatus(device);
208 bool result = GetAudioStreamInfo(codecStatus.codecInfo, streamInfo);
209 CHECK_AND_RETURN_RET_LOG(result, ERROR, "GetA2dpDeviceStreamInfo: Unsupported a2dp codec info");
210 return SUCCESS;
211 }
212
GetA2dpInDeviceStreamInfo(const std::string & macAddress,AudioStreamInfo & streamInfo)213 int32_t AudioA2dpManager::GetA2dpInDeviceStreamInfo(const std::string &macAddress,
214 AudioStreamInfo &streamInfo)
215 {
216 bool ret = A2dpInBluetoothDeviceManager::GetA2dpInDeviceStreamInfo(macAddress, streamInfo);
217 CHECK_AND_RETURN_RET_LOG(ret == true, ERROR, "the StreamInfo of the a2dp input device doesn't exist.");
218 return SUCCESS;
219 }
220
HasA2dpDeviceConnected()221 bool AudioA2dpManager::HasA2dpDeviceConnected()
222 {
223 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
224 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, false, "A2DP profile instance is null");
225 std::vector<int32_t> states {static_cast<int32_t>(BTConnectState::CONNECTED)};
226 std::vector<BluetoothRemoteDevice> devices;
227 a2dpInstance_->GetDevicesByStates(states, devices);
228
229 return !devices.empty();
230 }
231
A2dpOffloadSessionRequest(const std::vector<A2dpStreamInfo> & info)232 int32_t AudioA2dpManager::A2dpOffloadSessionRequest(const std::vector<A2dpStreamInfo> &info)
233 {
234 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
235 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "A2DP profile instance is null");
236 CHECK_AND_RETURN_RET_LOG(activeA2dpDevice_.GetDeviceAddr() != "00:00:00:00:00:00", A2DP_NOT_OFFLOAD,
237 "Invalid mac address, not request, return A2DP_NOT_OFFLOAD.");
238 int32_t ret = a2dpInstance_->A2dpOffloadSessionRequest(activeA2dpDevice_, info);
239 AUDIO_DEBUG_LOG("Request %{public}zu stream and return a2dp offload state %{public}d", info.size(), ret);
240 return ret;
241 }
242
OffloadStartPlaying(const std::vector<int32_t> & sessionsID)243 int32_t AudioA2dpManager::OffloadStartPlaying(const std::vector<int32_t> &sessionsID)
244 {
245 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
246 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "A2DP profile instance is null");
247 CHECK_AND_RETURN_RET_LOG(activeA2dpDevice_.GetDeviceAddr() != "00:00:00:00:00:00", ERROR,
248 "Invalid mac address, not start, return error.");
249 AUDIO_DEBUG_LOG("Start playing %{public}zu stream", sessionsID.size());
250 return a2dpInstance_->OffloadStartPlaying(activeA2dpDevice_, sessionsID);
251 }
252
OffloadStopPlaying(const std::vector<int32_t> & sessionsID)253 int32_t AudioA2dpManager::OffloadStopPlaying(const std::vector<int32_t> &sessionsID)
254 {
255 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
256 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "A2DP profile instance is null");
257 if (activeA2dpDevice_.GetDeviceAddr() == "00:00:00:00:00:00") {
258 AUDIO_DEBUG_LOG("Invalid mac address, not stop, return error.");
259 return ERROR;
260 }
261 AUDIO_DEBUG_LOG("Stop playing %{public}zu stream", sessionsID.size());
262 return a2dpInstance_->OffloadStopPlaying(activeA2dpDevice_, sessionsID);
263 }
264
GetRenderPosition(uint32_t & delayValue,uint64_t & sendDataSize,uint32_t & timeStamp)265 int32_t AudioA2dpManager::GetRenderPosition(uint32_t &delayValue, uint64_t &sendDataSize, uint32_t &timeStamp)
266 {
267 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
268 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "A2DP profile instance is null");
269 if (activeA2dpDevice_.GetDeviceAddr() == "00:00:00:00:00:00") {
270 AUDIO_DEBUG_LOG("Invalid mac address, return error.");
271 return ERROR;
272 }
273 return a2dpInstance_->GetRenderPosition(activeA2dpDevice_, delayValue, sendDataSize, timeStamp);
274 }
275
RegisterA2dpPlayingStateChangedListener(std::shared_ptr<AudioA2dpPlayingStateChangedListener> listener)276 int32_t AudioA2dpManager::RegisterA2dpPlayingStateChangedListener(
277 std::shared_ptr<AudioA2dpPlayingStateChangedListener> listener)
278 {
279 std::lock_guard<std::mutex> lock(g_a2dpPlayingStateChangedLock);
280 a2dpPlayingStateChangedListeners_.push_back(listener);
281 return SUCCESS;
282 }
283
OnA2dpPlayingStateChanged(const std::string & deviceAddress,int32_t playingState)284 void AudioA2dpManager::OnA2dpPlayingStateChanged(const std::string &deviceAddress, int32_t playingState)
285 {
286 std::lock_guard<std::mutex> lock(g_a2dpPlayingStateChangedLock);
287 for (auto listener : a2dpPlayingStateChangedListeners_) {
288 listener->OnA2dpPlayingStateChanged(deviceAddress, playingState);
289 }
290 }
291
CheckA2dpDeviceReconnect()292 void AudioA2dpManager::CheckA2dpDeviceReconnect()
293 {
294 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
295 CHECK_AND_RETURN_LOG(a2dpInstance_ != nullptr, "A2DP profile instance is null");
296 CHECK_AND_RETURN_LOG(a2dpListener_ != nullptr, "a2dpListener_ is nullptr");
297 std::vector<int32_t> states {static_cast<int32_t>(BTConnectState::CONNECTED)};
298 std::vector<BluetoothRemoteDevice> devices;
299 a2dpInstance_->GetDevicesByStates(states, devices);
300
301 for (auto &device : devices) {
302 a2dpListener_->OnConnectionStateChanged(device, static_cast<int32_t>(BTConnectState::CONNECTED),
303 static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
304
305 int32_t wearState = 0; // 0 unwear state
306 if (IsBTWearDetectionEnable(device)) {
307 wearState = BluetoothAudioManager::GetInstance().IsDeviceWearing(device);
308 if (wearState == 1) MediaBluetoothDeviceManager::SetMediaStack(device, WEAR_ACTION); // 1 wear state
309 }
310 AUDIO_WARNING_LOG("reconnect a2dp device:%{public}s, wear state:%{public}d",
311 GetEncryptAddr(device.GetDeviceAddr()).c_str(), wearState);
312 }
313
314 std::vector<std::string> virtualDevices;
315 a2dpInstance_->GetVirtualDeviceList(virtualDevices);
316 for (auto &macAddress : virtualDevices) {
317 AUDIO_WARNING_LOG("reconnect virtual a2dp device:%{public}s", GetEncryptAddr(macAddress).c_str());
318 a2dpListener_->OnVirtualDeviceChanged(static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_ADD), macAddress);
319 }
320 }
321
Connect(const std::string & macAddress)322 int32_t AudioA2dpManager::Connect(const std::string &macAddress)
323 {
324 std::shared_lock<std::shared_mutex> a2dpLock(g_a2dpInstanceLock);
325 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "A2DP profile instance unavailable");
326 BluetoothRemoteDevice virtualDevice = BluetoothRemoteDevice(macAddress);
327 if (MediaBluetoothDeviceManager::IsA2dpBluetoothDeviceConnecting(macAddress)) {
328 AUDIO_WARNING_LOG("A2dp device %{public}s is connecting, ignore connect request",
329 GetEncryptAddr(macAddress).c_str());
330 virtualDevice.SetVirtualAutoConnectType(CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG, 0);
331 return SUCCESS;
332 }
333 std::vector<std::string> virtualDevices;
334 a2dpInstance_->GetVirtualDeviceList(virtualDevices);
335 if (std::find(virtualDevices.begin(), virtualDevices.end(), macAddress) == virtualDevices.end()) {
336 AUDIO_WARNING_LOG("A2dp device %{public}s is not virtual device, ignore connect request",
337 GetEncryptAddr(macAddress).c_str());
338 return SUCCESS;
339 }
340 int32_t ret = a2dpInstance_->Connect(virtualDevice);
341 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "A2dp Connect Failed");
342 virtualDevice.SetVirtualAutoConnectType(CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG, 0);
343 return SUCCESS;
344 }
345
OnConnectionStateChanged(const BluetoothRemoteDevice & device,int state,int cause)346 void AudioA2dpListener::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state, int cause)
347 {
348 AUDIO_WARNING_LOG("state: %{public}d, macAddress: %{public}s", state,
349 GetEncryptAddr(device.GetDeviceAddr()).c_str());
350 // Record connection state and device for hdi start time to check
351 AudioA2dpManager::SetConnectionState(state);
352 if (state == static_cast<int>(BTConnectState::CONNECTING)) {
353 MediaBluetoothDeviceManager::SetMediaStack(device, BluetoothDeviceAction::CONNECTING_ACTION);
354 }
355 if (state == static_cast<int>(BTConnectState::CONNECTED)) {
356 MediaBluetoothDeviceManager::SetMediaStack(device, BluetoothDeviceAction::CONNECT_ACTION);
357 }
358 if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
359 MediaBluetoothDeviceManager::SetMediaStack(device, BluetoothDeviceAction::DISCONNECT_ACTION);
360 }
361 }
362
OnConfigurationChanged(const BluetoothRemoteDevice & device,const A2dpCodecInfo & codecInfo,int error)363 void AudioA2dpListener::OnConfigurationChanged(const BluetoothRemoteDevice &device, const A2dpCodecInfo &codecInfo,
364 int error)
365 {
366 AUDIO_INFO_LOG("OnConfigurationChanged: sampleRate: %{public}d, channels: %{public}d, format: %{public}d",
367 codecInfo.sampleRate, codecInfo.channelMode, codecInfo.bitsPerSample);
368 AudioStreamInfo streamInfo = {};
369 bool result = GetAudioStreamInfo(codecInfo, streamInfo);
370 CHECK_AND_RETURN_LOG(result, "OnConfigurationChanged: Unsupported a2dp codec info");
371 MediaBluetoothDeviceManager::UpdateA2dpDeviceConfiguration(device, streamInfo);
372 }
373
OnPlayingStatusChanged(const BluetoothRemoteDevice & device,int playingState,int error)374 void AudioA2dpListener::OnPlayingStatusChanged(const BluetoothRemoteDevice &device, int playingState, int error)
375 {
376 AUDIO_INFO_LOG("OnPlayingStatusChanged, state: %{public}d, error: %{public}d", playingState, error);
377 if (error == SUCCESS) {
378 AudioA2dpManager::OnA2dpPlayingStateChanged(device.GetDeviceAddr(), playingState);
379 }
380 }
381
OnMediaStackChanged(const BluetoothRemoteDevice & device,int action)382 void AudioA2dpListener::OnMediaStackChanged(const BluetoothRemoteDevice &device, int action)
383 {
384 AUDIO_WARNING_LOG("action: %{public}d, macAddress: %{public}s", action,
385 GetEncryptAddr(device.GetDeviceAddr()).c_str());
386 MediaBluetoothDeviceManager::SetMediaStack(device, action);
387 }
388
OnVirtualDeviceChanged(int32_t action,std::string macAddress)389 void AudioA2dpListener::OnVirtualDeviceChanged(int32_t action, std::string macAddress)
390 {
391 AUDIO_WARNING_LOG("action: %{public}d, macAddress: %{public}s", action, GetEncryptAddr(macAddress).c_str());
392 if (action == static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_ADD)) {
393 MediaBluetoothDeviceManager::SetMediaStack(BluetoothRemoteDevice(macAddress),
394 BluetoothDeviceAction::VIRTUAL_DEVICE_ADD_ACTION);
395 }
396 if (action == static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_REMOVE)) {
397 MediaBluetoothDeviceManager::SetMediaStack(BluetoothRemoteDevice(macAddress),
398 BluetoothDeviceAction::VIRTUAL_DEVICE_REMOVE_ACTION);
399 }
400 }
401
OnCaptureConnectionStateChanged(const BluetoothRemoteDevice & device,int state,const A2dpCodecInfo & codecInfo)402 void AudioA2dpListener::OnCaptureConnectionStateChanged(const BluetoothRemoteDevice &device, int state,
403 const A2dpCodecInfo &codecInfo)
404 {
405 AUDIO_INFO_LOG("capture connection state: %{public}d", state);
406 AudioA2dpManager::SetCaptureConnectionState(static_cast<int32_t>(state));
407 AudioStreamInfo streamInfo = {};
408 if (state == static_cast<int>(BTHdapConnectState::CONNECTED)) {
409 AUDIO_INFO_LOG("A2dpInCodecInfo: sampleRate: %{public}d, channels: %{public}d, format: %{public}d",
410 codecInfo.sampleRate, codecInfo.channelMode, codecInfo.bitsPerSample);
411 bool result = GetAudioStreamInfo(codecInfo, streamInfo);
412 CHECK_AND_RETURN_LOG(result == true, "Unsupported a2dpIn codec info");
413 A2dpInBluetoothDeviceManager::SetA2dpInStack(device, streamInfo, BluetoothDeviceAction::CONNECT_ACTION);
414 } else if (state == static_cast<int>(BTHdapConnectState::DISCONNECTED)) {
415 A2dpInBluetoothDeviceManager::SetA2dpInStack(device, streamInfo, BluetoothDeviceAction::DISCONNECT_ACTION);
416 }
417 }
418
RegisterBluetoothScoListener()419 void AudioHfpManager::RegisterBluetoothScoListener()
420 {
421 HfpBluetoothDeviceManager::RegisterDisconnectScoFunc(&DisconnectScoForDevice);
422 AUDIO_INFO_LOG("in");
423 BluetoothHfpInterface::GetInstance().RegisterObserver(hfpListener_);
424 }
425
UnregisterBluetoothScoListener()426 void AudioHfpManager::UnregisterBluetoothScoListener()
427 {
428 AUDIO_INFO_LOG("in");
429 BluetoothHfpInterface::GetInstance().DeregisterObserver(hfpListener_);
430 }
431
CheckHfpDeviceReconnect()432 void AudioHfpManager::CheckHfpDeviceReconnect()
433 {
434 std::vector<int32_t> states {static_cast<int32_t>(BTConnectState::CONNECTED)};
435 std::vector<BluetoothRemoteDevice> devices = BluetoothHfpInterface::GetInstance().GetDevicesByStates(states);
436 for (auto &device : devices) {
437 if (hfpListener_ != nullptr) {
438 hfpListener_->OnConnectionStateChanged(device,
439 static_cast<int32_t>(BTConnectState::CONNECTED),
440 static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
441 }
442
443 int32_t wearState = 0; // 0 unwear state
444 if (IsBTWearDetectionEnable(device)) {
445 wearState = BluetoothAudioManager::GetInstance().IsDeviceWearing(device);
446 if (wearState == 1) HfpBluetoothDeviceManager::SetHfpStack(device, WEAR_ACTION); // 1 wear state
447 }
448 AUDIO_INFO_LOG("reconnect hfp device:%{public}s, wear state:%{public}d",
449 GetEncryptAddr(device.GetDeviceAddr()).c_str(), wearState);
450 }
451
452 if (hfpListener_ != nullptr) {
453 std::vector<std::string> virtualDevices;
454 BluetoothHfpInterface::GetInstance().GetVirtualDeviceList(virtualDevices);
455 for (auto &macAddress : virtualDevices) {
456 AUDIO_PRERELEASE_LOGI("reconnect virtual hfp device:%{public}s",
457 GetEncryptAddr(macAddress).c_str());
458 hfpListener_->OnVirtualDeviceChanged(static_cast<int32_t>(
459 Bluetooth::BT_VIRTUAL_DEVICE_ADD), macAddress);
460 }
461 }
462 }
463
SetActiveHfpDevice(const std::string & macAddress)464 int32_t AudioHfpManager::SetActiveHfpDevice(const std::string &macAddress)
465 {
466 AudioXCollie audioXCollie("AudioHfpManager::SetActiveHfpDevice", BT_SET_ACTIVE_DEVICE_TIMEOUT,
467 nullptr, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
468 BluetoothRemoteDevice device;
469 if (HfpBluetoothDeviceManager::GetConnectedHfpBluetoothDevice(macAddress, device) != SUCCESS) {
470 AUDIO_ERR_LOG("SetActiveHfpDevice failed for the HFP device, %{public}s does not exist.",
471 GetEncryptAddr(macAddress).c_str());
472 return ERROR;
473 }
474 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
475 AUDIO_INFO_LOG("incoming device:%{public}s, current device:%{public}s",
476 GetEncryptAddr(macAddress).c_str(), GetEncryptAddr(activeHfpDevice_.GetDeviceAddr()).c_str());
477 if (macAddress != activeHfpDevice_.GetDeviceAddr()) {
478 AUDIO_WARNING_LOG("Active hfp device is changed, need to DisconnectSco for current activeHfpDevice.");
479 int32_t ret = DisconnectScoWrapper();
480 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "DisconnectSco failed, result: %{public}d", ret);
481 }
482 int32_t res = BluetoothHfpInterface::GetInstance().SetActiveDevice(device);
483 CHECK_AND_RETURN_RET_LOG(res == SUCCESS, ERROR, "SetActiveHfpDevice failed, result: %{public}d", res);
484 activeHfpDevice_ = device;
485 return SUCCESS;
486 }
487
UpdateActiveHfpDevice(const BluetoothRemoteDevice & device)488 int32_t AudioHfpManager::UpdateActiveHfpDevice(const BluetoothRemoteDevice &device)
489 {
490 AUDIO_INFO_LOG("update active device:%{public}s, current device:%{public}s",
491 GetEncryptAddr(device.GetDeviceAddr()).c_str(),
492 GetEncryptAddr(activeHfpDevice_.GetDeviceAddr()).c_str());
493 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
494 int32_t res = BluetoothHfpInterface::GetInstance().SetActiveDevice(device);
495 CHECK_AND_RETURN_RET_LOG(res == SUCCESS, ERROR, "SetActiveDevice failed, result: %{public}d", res);
496 activeHfpDevice_ = device;
497 return TryUpdateScoCategoryNoLock();
498 }
499
GetActiveHfpDevice()500 std::string AudioHfpManager::GetActiveHfpDevice()
501 {
502 BluetoothRemoteDevice device = BluetoothHfpInterface::GetInstance().GetActiveDevice();
503 return device.GetDeviceAddr();
504 }
505
DisconnectSco()506 int32_t AudioHfpManager::DisconnectSco()
507 {
508 AUDIO_INFO_LOG("disconnect sco from outer");
509 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
510 return DisconnectScoWrapper();
511 }
512
DisconnectBluetoothHfpSink()513 void AudioHfpManager::DisconnectBluetoothHfpSink()
514 {
515 int32_t connectionState = static_cast<int32_t>(BTConnectState::DISCONNECTED);
516 if (hfpListener_ != nullptr) {
517 auto hfpList = HfpBluetoothDeviceManager::GetAllHfpBluetoothDevice();
518 for (const auto &device : hfpList) {
519 hfpListener_->OnConnectionStateChanged(device, connectionState,
520 static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
521 }
522
523 auto virtualDevices = HfpBluetoothDeviceManager::GetHfpVirtualDeviceList();
524 for (const auto &virtualDevice : virtualDevices) {
525 hfpListener_->OnVirtualDeviceChanged(static_cast<int32_t>(
526 Bluetooth::BT_VIRTUAL_DEVICE_REMOVE),
527 virtualDevice.GetDeviceAddr());
528 }
529 }
530 HfpBluetoothDeviceManager::ClearAllHfpBluetoothDevice();
531 }
532
ClearCurrentActiveHfpDevice(const BluetoothRemoteDevice & device)533 void AudioHfpManager::ClearCurrentActiveHfpDevice(const BluetoothRemoteDevice &device)
534 {
535 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
536 if (device.GetDeviceAddr() != activeHfpDevice_.GetDeviceAddr()) {
537 return;
538 }
539 AUDIO_INFO_LOG("clear current active hfp device:%{public}s",
540 GetEncryptAddr(device.GetDeviceAddr()).c_str());
541 BluetoothScoManager::GetInstance().ResetScoState(activeHfpDevice_);
542 activeHfpDevice_ = BluetoothRemoteDevice();
543 }
544
Connect(const std::string & macAddress)545 int32_t AudioHfpManager::Connect(const std::string &macAddress)
546 {
547 BluetoothRemoteDevice virtualDevice = BluetoothRemoteDevice(macAddress);
548 if (HfpBluetoothDeviceManager::IsHfpBluetoothDeviceConnecting(macAddress)) {
549 AUDIO_WARNING_LOG("Hfp device %{public}s is connecting, ignore connect request",
550 GetEncryptAddr(macAddress).c_str());
551 virtualDevice.SetVirtualAutoConnectType(CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG, 0);
552 return SUCCESS;
553 }
554 std::vector<std::string> virtualDevices;
555 BluetoothHfpInterface::GetInstance().GetVirtualDeviceList(virtualDevices);
556 if (std::find(virtualDevices.begin(), virtualDevices.end(), macAddress) == virtualDevices.end()) {
557 AUDIO_WARNING_LOG("Hfp device %{public}s is not virtual device, ignore connect request",
558 GetEncryptAddr(macAddress).c_str());
559 return SUCCESS;
560 }
561 int32_t ret = BluetoothHfpInterface::GetInstance().Connect(virtualDevice);
562 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "Hfp Connect Failed");
563 virtualDevice.SetVirtualAutoConnectType(CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG, 0);
564 return SUCCESS;
565 }
566
UpdateAudioScene(AudioScene scene,bool isRecordScene)567 int32_t AudioHfpManager::UpdateAudioScene(AudioScene scene, bool isRecordScene)
568 {
569 if (scene_.load() != scene) {
570 AUDIO_INFO_LOG("update audio scene from %{public}d to %{public}d", scene_.load(), scene);
571 }
572 if (isRecordScene_.load() != isRecordScene) {
573 AUDIO_INFO_LOG("%{public}s record scene", isRecordScene ? "is" : "not");
574 }
575 scene_.store(scene);
576 isRecordScene_.store(isRecordScene);
577 return TryUpdateScoCategory();
578 }
579
UpdateAudioScene(AudioScene scene)580 int32_t AudioHfpManager::UpdateAudioScene(AudioScene scene)
581 {
582 if (scene_.load() != scene) {
583 AUDIO_INFO_LOG("update audio scene from %{public}d to %{public}d", scene_.load(), scene);
584 }
585 scene_.store(scene);
586 return TryUpdateScoCategory();
587 }
588
HandleScoWithRecongnition(bool handleFlag)589 int32_t AudioHfpManager::HandleScoWithRecongnition(bool handleFlag)
590 {
591 if (isRecognitionScene_.load() != handleFlag) {
592 AUDIO_INFO_LOG("%{public}s recognition scene", handleFlag ? "is" : "not");
593 }
594 isRecognitionScene_.store(handleFlag);
595 return TryUpdateScoCategory();
596 }
597
IsRecognitionStatus()598 bool AudioHfpManager::IsRecognitionStatus()
599 {
600 return BluetoothScoManager::GetInstance().IsInScoCategory(ScoCategory::SCO_RECOGNITION);
601 }
602
SetVirtualCall(const std::string & name,const bool isVirtual)603 int32_t AudioHfpManager::SetVirtualCall(const std::string &name, const bool isVirtual)
604 {
605 {
606 CHECK_AND_RETURN_RET(virtualCalls_[name] != isVirtual, SUCCESS);
607 std::lock_guard<std::mutex> hfpDeviceLock(virtualCallMutex_);
608 virtualCalls_[name] = isVirtual;
609 }
610
611 AUDIO_INFO_LOG("set virtual call %{public}d by service %{public}s", isVirtual, name.c_str());
612 return TryUpdateScoCategory();
613 }
614
AddVirtualCallBundleName(const std::string & name,int32_t streamId)615 int32_t AudioHfpManager::AddVirtualCallBundleName(const std::string &name, int32_t streamId)
616 {
617 {
618 std::lock_guard<std::mutex> hfpDeviceLock(virtualCallMutex_);
619 if (virtualCallStreams_.find(name) == virtualCallStreams_.end()) {
620 std::list<int32_t> streamIds;
621 streamIds.push_back(streamId);
622 virtualCallStreams_[name] = streamIds;
623 } else {
624 virtualCallStreams_[name].push_back(streamId);
625 }
626 AUDIO_INFO_LOG("add virtual call bundlename %{public}s streamId %{public}d size %{public}zu",
627 name.c_str(), streamId, virtualCallStreams_[name].size());
628 }
629
630 return TryUpdateScoCategory();
631 }
632
DeleteVirtualCallStream(int32_t streamId)633 void AudioHfpManager::DeleteVirtualCallStream(int32_t streamId)
634 {
635 {
636 std::lock_guard<std::mutex> hfpDeviceLock(virtualCallMutex_);
637 std::string bundleName;
638 for (auto &stream : virtualCallStreams_) {
639 bool found = false;
640 for (auto it = stream.second.begin(); it != stream.second.end();) {
641 if (*it == streamId) {
642 found = true;
643 stream.second.erase(it);
644 break;
645 }
646 it++;
647 }
648 if (found) {
649 bundleName = stream.first;
650 break;
651 }
652 }
653 if (bundleName.empty()) {
654 AUDIO_WARNING_LOG("not found bundle name %{public}s", bundleName.c_str());
655 return;
656 }
657
658 AUDIO_INFO_LOG("del virtual call name %{public}s streamId %{public}d size %{public}zu",
659 bundleName.c_str(), streamId, virtualCallStreams_[bundleName].size());
660 if (virtualCallStreams_[bundleName].size() == 0) {
661 virtualCallStreams_.erase(bundleName);
662 }
663 }
664
665 TryUpdateScoCategory();
666 }
667
IsVirtualCall()668 bool AudioHfpManager::IsVirtualCall()
669 {
670 std::lock_guard<std::mutex> hfpDeviceLock(virtualCallMutex_);
671 for (const auto &it : virtualCallStreams_) {
672 if (virtualCalls_.find(it.first) != virtualCalls_.end()) {
673 AUDIO_INFO_LOG("not virtual call for service %{public}s", it.first.c_str());
674 return false;
675 }
676 std::string suffix = "meetimeservice";
677 if (std::mismatch(suffix.rbegin(), suffix.rend(), it.first.rbegin()).first ==
678 suffix.rend()) {
679 AUDIO_INFO_LOG("not virtual call for service %{public}s", it.first.c_str());
680 return false;
681 }
682 }
683 AUDIO_INFO_LOG("is virtual call");
684 return true;
685 }
686
IsAudioScoStateConnect()687 bool AudioHfpManager::IsAudioScoStateConnect()
688 {
689 AudioScoState scoState = BluetoothScoManager::GetInstance().GetAudioScoState();
690 return (scoState == AudioScoState::CONNECTED || scoState == AudioScoState::CONNECTING);
691 }
692
JudgeScoCategory()693 ScoCategory AudioHfpManager::JudgeScoCategory()
694 {
695 bool isInbardingEnabled = false;
696 BluetoothHfpInterface::GetInstance().IsInbandRingingEnabled(isInbardingEnabled);
697
698 auto scene = scene_.load();
699 if ((scene == AUDIO_SCENE_RINGING || scene == AUDIO_SCENE_VOICE_RINGING) && !isInbardingEnabled) {
700 AUDIO_WARNING_LOG("The inbarding switch is off, ignore the ring scene.");
701 return isRecognitionScene_.load() ? ScoCategory::SCO_RECOGNITION : ScoCategory::SCO_DEFAULT;
702 }
703
704 if (scene == AUDIO_SCENE_VOICE_RINGING || scene == AUDIO_SCENE_PHONE_CALL) {
705 return ScoCategory::SCO_CALLULAR;
706 } else if (scene == AUDIO_SCENE_RINGING || scene == AUDIO_SCENE_PHONE_CHAT) {
707 return !IsVirtualCall() ? ScoCategory::SCO_CALLULAR : ScoCategory::SCO_VIRTUAL;
708 }
709
710 return isRecognitionScene_.load() ? ScoCategory::SCO_RECOGNITION : ScoCategory::SCO_DEFAULT;
711 }
712
TryUpdateScoCategory()713 int32_t AudioHfpManager::TryUpdateScoCategory()
714 {
715 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
716 return TryUpdateScoCategoryNoLock();
717 }
718
TryUpdateScoCategoryNoLock()719 int32_t AudioHfpManager::TryUpdateScoCategoryNoLock()
720 {
721 BluetoothRemoteDevice defaultDevice;
722 if (!activeHfpDevice_.IsValidBluetoothRemoteDevice() ||
723 activeHfpDevice_.GetDeviceAddr() == defaultDevice.GetDeviceAddr()) {
724 AUDIO_INFO_LOG("current device: %{public}s is invalid",
725 GetEncryptAddr(activeHfpDevice_.GetDeviceAddr()).c_str());
726 return DisconnectScoWrapper();
727 }
728
729 auto category = JudgeScoCategory();
730 if (category == ScoCategory::SCO_DEFAULT && !isRecordScene_.load()) {
731 return DisconnectScoWrapper();
732 }
733
734 int32_t ret = BluetoothScoManager::GetInstance().HandleScoConnect(category, activeHfpDevice_);
735 if (ret != SUCCESS) {
736 WriteScoOprFaultEvent();
737 }
738 return ret;
739 }
740
DisconnectScoForDevice(const BluetoothRemoteDevice & device)741 void AudioHfpManager::DisconnectScoForDevice(const BluetoothRemoteDevice &device)
742 {
743 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
744
745 if (device.GetDeviceAddr() != activeHfpDevice_.GetDeviceAddr()) {
746 AUDIO_WARNING_LOG("disconnect sco for device %{public}s but active device %{public}s",
747 GetEncryptAddr(device.GetDeviceAddr()).c_str(),
748 GetEncryptAddr(activeHfpDevice_.GetDeviceAddr()).c_str());
749 return;
750 }
751 DisconnectScoWrapper();
752 }
753
DisconnectScoWrapper()754 int32_t AudioHfpManager::DisconnectScoWrapper()
755 {
756 int32_t ret = BluetoothScoManager::GetInstance().HandleScoDisconnect(activeHfpDevice_);
757 if (ret != SUCCESS) {
758 WriteScoOprFaultEvent();
759 }
760 return ret;
761 }
762
WriteScoOprFaultEvent()763 void AudioHfpManager::WriteScoOprFaultEvent()
764 {
765 auto ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AUDIO, "SCO_STATE_AUDIO",
766 HiviewDFX::HiSysEvent::EventType::FAULT,
767 "PKG_NAME", "",
768 "SCO_ADDRESS", BluetoothScoManager::GetInstance().GetAudioScoDevice().GetDeviceAddr(),
769 "SCENE", static_cast<uint8_t>(scene_.load()),
770 "SCO_MODE", static_cast<uint8_t>(BluetoothScoManager::GetInstance().GetAudioScoCategory()),
771 "AUDIO_SCO_STATE", static_cast<uint8_t>(BluetoothScoManager::GetInstance().GetAudioScoState()),
772 "RET", static_cast<uint8_t>(BluetoothHfpInterface::GetInstance().GetLastError()));
773 if (ret) {
774 AUDIO_ERR_LOG("write event fail: SCO_STATE_AUDIO, ret = %{public}d", ret);
775 }
776 }
777
GetAudioScoDeviceMac()778 std::string AudioHfpManager::GetAudioScoDeviceMac()
779 {
780 return BluetoothScoManager::GetInstance().GetAudioScoDevice().GetDeviceAddr().c_str();
781 }
782
OnScoStateChanged(const BluetoothRemoteDevice & device,int state,int reason)783 void AudioHfpListener::OnScoStateChanged(const BluetoothRemoteDevice &device, int state, int reason)
784 {
785 AUDIO_WARNING_LOG("state:[%{public}d] reason:[%{public}d] device:[%{public}s]",
786 state, reason, GetEncryptAddr(device.GetDeviceAddr()).c_str());
787 // SCO_DISCONNECTED = 3, SCO_CONNECTING = 4, SCO_DISCONNECTING = 5, SCO_CONNECTED = 6
788 HfpScoConnectState scoState = static_cast<HfpScoConnectState>(state);
789 if (scoState == HfpScoConnectState::SCO_CONNECTED || scoState == HfpScoConnectState::SCO_DISCONNECTED) {
790 if (scoState == HfpScoConnectState::SCO_CONNECTED && reason == HFP_AG_SCO_REMOTE_USER_SET_UP) {
791 AudioHfpManager::UpdateActiveHfpDevice(device);
792 } else {
793 bool isConnected = (scoState == HfpScoConnectState::SCO_CONNECTED) ? true : false;
794 BluetoothScoManager::GetInstance().UpdateScoState(scoState, device, reason);
795 HfpBluetoothDeviceManager::OnScoStateChanged(device, isConnected, reason);
796 }
797 }
798 }
799
OnConnectionStateChanged(const BluetoothRemoteDevice & device,int state,int cause)800 void AudioHfpListener::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state, int cause)
801 {
802 AUDIO_WARNING_LOG("state: %{public}d device: %{public}s", state, GetEncryptAddr(device.GetDeviceAddr()).c_str());
803 if (state == static_cast<int>(BTConnectState::CONNECTING)) {
804 HfpBluetoothDeviceManager::SetHfpStack(device, BluetoothDeviceAction::CONNECTING_ACTION);
805 }
806 if (state == static_cast<int>(BTConnectState::CONNECTED)) {
807 HfpBluetoothDeviceManager::SetHfpStack(device, BluetoothDeviceAction::CONNECT_ACTION);
808 }
809 if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
810 AudioHfpManager::ClearCurrentActiveHfpDevice(device);
811 HfpBluetoothDeviceManager::SetHfpStack(device, BluetoothDeviceAction::DISCONNECT_ACTION);
812 }
813 }
814
OnHfpStackChanged(const BluetoothRemoteDevice & device,int action)815 void AudioHfpListener::OnHfpStackChanged(const BluetoothRemoteDevice &device, int action)
816 {
817 AUDIO_WARNING_LOG("action: %{public}d device: %{public}s", action, GetEncryptAddr(device.GetDeviceAddr()).c_str());
818 HfpBluetoothDeviceManager::SetHfpStack(device, action);
819 }
820
OnVirtualDeviceChanged(int32_t action,std::string macAddress)821 void AudioHfpListener::OnVirtualDeviceChanged(int32_t action, std::string macAddress)
822 {
823 AUDIO_WARNING_LOG("action: %{public}d device: %{public}s", action, GetEncryptAddr(macAddress).c_str());
824 if (action == static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_ADD)) {
825 HfpBluetoothDeviceManager::SetHfpStack(BluetoothRemoteDevice(macAddress),
826 BluetoothDeviceAction::VIRTUAL_DEVICE_ADD_ACTION);
827 }
828 if (action == static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_REMOVE)) {
829 HfpBluetoothDeviceManager::SetHfpStack(BluetoothRemoteDevice(macAddress),
830 BluetoothDeviceAction::VIRTUAL_DEVICE_REMOVE_ACTION);
831 }
832 }
833 // LCOV_EXCL_STOP
834 } // namespace Bluetooth
835 } // namespace OHOS
836