1 /*
2 * Copyright (c) 2021-2023 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 "audio_bluetooth_manager.h"
20 #include "bluetooth_def.h"
21 #include "audio_errors.h"
22 #include "audio_common_log.h"
23 #include "bluetooth_audio_manager.h"
24 #include "bluetooth_device_manager.h"
25 #include "bluetooth_device_utils.h"
26 #include "bluetooth_hfp_ag.h"
27
28 namespace OHOS {
29 namespace Bluetooth {
30 using namespace AudioStandard;
31
32 A2dpSource *AudioA2dpManager::a2dpInstance_ = nullptr;
33 std::shared_ptr<AudioA2dpListener> AudioA2dpManager::a2dpListener_ = std::make_shared<AudioA2dpListener>();
34 int AudioA2dpManager::connectionState_ = static_cast<int>(BTConnectState::DISCONNECTED);
35 BluetoothRemoteDevice AudioA2dpManager::activeA2dpDevice_;
36 std::mutex g_a2dpInstanceLock;
37 HandsFreeAudioGateway *AudioHfpManager::hfpInstance_ = nullptr;
38 std::shared_ptr<AudioHfpListener> AudioHfpManager::hfpListener_ = std::make_shared<AudioHfpListener>();
39 AudioScene AudioHfpManager::scene_ = AUDIO_SCENE_DEFAULT;
40 AudioScene AudioHfpManager::sceneFromPolicy_ = AUDIO_SCENE_DEFAULT;
41 OHOS::Bluetooth::ScoCategory AudioHfpManager::scoCategory = OHOS::Bluetooth::ScoCategory::SCO_DEFAULT;
42 OHOS::Bluetooth::RecognitionStatus AudioHfpManager::recognitionStatus =
43 OHOS::Bluetooth::RecognitionStatus::RECOGNITION_DISCONNECTED;
44 BluetoothRemoteDevice AudioHfpManager::activeHfpDevice_;
45 std::vector<std::shared_ptr<AudioA2dpPlayingStateChangedListener>> AudioA2dpManager::a2dpPlayingStateChangedListeners_;
46 std::mutex g_activehfpDeviceLock;
47 std::mutex g_audioSceneLock;
48 std::mutex g_hfpInstanceLock;
49 std::mutex g_a2dpPlayingStateChangedLock;
50
GetAudioStreamInfo(A2dpCodecInfo codecInfo,AudioStreamInfo & audioStreamInfo)51 static bool GetAudioStreamInfo(A2dpCodecInfo codecInfo, AudioStreamInfo &audioStreamInfo)
52 {
53 AUDIO_DEBUG_LOG("codec info rate[%{public}d] format[%{public}d] channel[%{public}d]",
54 codecInfo.sampleRate, codecInfo.bitsPerSample, codecInfo.channelMode);
55 switch (codecInfo.sampleRate) {
56 case A2DP_SBC_SAMPLE_RATE_48000_USER:
57 case A2DP_L2HCV2_SAMPLE_RATE_48000_USER:
58 audioStreamInfo.samplingRate = SAMPLE_RATE_48000;
59 break;
60 case A2DP_SBC_SAMPLE_RATE_44100_USER:
61 audioStreamInfo.samplingRate = SAMPLE_RATE_44100;
62 break;
63 case A2DP_SBC_SAMPLE_RATE_32000_USER:
64 audioStreamInfo.samplingRate = SAMPLE_RATE_32000;
65 break;
66 case A2DP_SBC_SAMPLE_RATE_16000_USER:
67 audioStreamInfo.samplingRate = SAMPLE_RATE_16000;
68 break;
69 case A2DP_L2HCV2_SAMPLE_RATE_96000_USER:
70 audioStreamInfo.samplingRate = SAMPLE_RATE_96000;
71 break;
72 default:
73 return false;
74 }
75 switch (codecInfo.bitsPerSample) {
76 case A2DP_SAMPLE_BITS_16_USER:
77 audioStreamInfo.format = SAMPLE_S16LE;
78 break;
79 case A2DP_SAMPLE_BITS_24_USER:
80 audioStreamInfo.format = SAMPLE_S24LE;
81 break;
82 case A2DP_SAMPLE_BITS_32_USER:
83 audioStreamInfo.format = SAMPLE_S32LE;
84 break;
85 default:
86 return false;
87 }
88 switch (codecInfo.channelMode) {
89 case A2DP_SBC_CHANNEL_MODE_STEREO_USER:
90 audioStreamInfo.channels = STEREO;
91 break;
92 case A2DP_SBC_CHANNEL_MODE_MONO_USER:
93 audioStreamInfo.channels = MONO;
94 break;
95 default:
96 return false;
97 }
98 audioStreamInfo.encoding = ENCODING_PCM;
99 return true;
100 }
101
102 // LCOV_EXCL_START
RegisterBluetoothA2dpListener()103 void AudioA2dpManager::RegisterBluetoothA2dpListener()
104 {
105 AUDIO_INFO_LOG("AudioA2dpManager::RegisterBluetoothA2dpListener");
106 std::lock_guard<std::mutex> a2dpLock(g_a2dpInstanceLock);
107 a2dpInstance_ = A2dpSource::GetProfile();
108 CHECK_AND_RETURN_LOG(a2dpInstance_ != nullptr, "Failed to obtain A2DP profile instance");
109 a2dpInstance_->RegisterObserver(a2dpListener_);
110 }
111
UnregisterBluetoothA2dpListener()112 void AudioA2dpManager::UnregisterBluetoothA2dpListener()
113 {
114 AUDIO_INFO_LOG("AudioA2dpManager::UnregisterBluetoothA2dpListener");
115 std::lock_guard<std::mutex> a2dpLock(g_a2dpInstanceLock);
116 CHECK_AND_RETURN_LOG(a2dpInstance_ != nullptr, "A2DP profile instance unavailable");
117 a2dpInstance_->DeregisterObserver(a2dpListener_);
118 a2dpInstance_ = nullptr;
119 }
120
DisconnectBluetoothA2dpSink()121 void AudioA2dpManager::DisconnectBluetoothA2dpSink()
122 {
123 int connectionState = static_cast<int>(BTConnectState::DISCONNECTED);
124 auto a2dpList = MediaBluetoothDeviceManager::GetAllA2dpBluetoothDevice();
125 for (const auto &device : a2dpList) {
126 a2dpListener_->OnConnectionStateChanged(device, connectionState,
127 static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
128 }
129
130 auto virtualDevices = MediaBluetoothDeviceManager::GetA2dpVirtualDeviceList();
131 for (const auto &virtualDevice : virtualDevices) {
132 a2dpListener_->OnVirtualDeviceChanged(static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_REMOVE),
133 virtualDevice.GetDeviceAddr());
134 }
135
136 MediaBluetoothDeviceManager::ClearAllA2dpBluetoothDevice();
137 }
138
SetActiveA2dpDevice(const std::string & macAddress)139 int32_t AudioA2dpManager::SetActiveA2dpDevice(const std::string& macAddress)
140 {
141 std::lock_guard<std::mutex> a2dpLock(g_a2dpInstanceLock);
142 AUDIO_WARNING_LOG("incoming device:%{public}s, current device:%{public}s",
143 GetEncryptAddr(macAddress).c_str(), GetEncryptAddr(activeA2dpDevice_.GetDeviceAddr()).c_str());
144 a2dpInstance_ = A2dpSource::GetProfile();
145 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "Failed to obtain A2DP profile instance");
146 BluetoothRemoteDevice device;
147 if (macAddress != "") {
148 int32_t tmp = MediaBluetoothDeviceManager::GetConnectedA2dpBluetoothDevice(macAddress, device);
149 CHECK_AND_RETURN_RET_LOG(tmp == SUCCESS, ERROR, "the configuring A2DP device doesn't exist.");
150 } else {
151 AUDIO_INFO_LOG("Deactive A2DP device");
152 }
153 int32_t ret = a2dpInstance_->SetActiveSinkDevice(device);
154 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "SetActiveA2dpDevice failed. result: %{public}d", ret);
155 activeA2dpDevice_ = device;
156 return SUCCESS;
157 }
158
GetActiveA2dpDevice()159 std::string AudioA2dpManager::GetActiveA2dpDevice()
160 {
161 std::lock_guard<std::mutex> a2dpLock(g_a2dpInstanceLock);
162 a2dpInstance_ = A2dpSource::GetProfile();
163 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, "", "Failed to obtain A2DP profile instance");
164 BluetoothRemoteDevice device = a2dpInstance_->GetActiveSinkDevice();
165 return device.GetDeviceAddr();
166 }
167
SetDeviceAbsVolume(const std::string & macAddress,int32_t volume)168 int32_t AudioA2dpManager::SetDeviceAbsVolume(const std::string& macAddress, int32_t volume)
169 {
170 BluetoothRemoteDevice device;
171 int32_t ret = MediaBluetoothDeviceManager::GetConnectedA2dpBluetoothDevice(macAddress, device);
172 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "SetDeviceAbsVolume: the configuring A2DP device doesn't exist.");
173 return AvrcpTarget::GetProfile()->SetDeviceAbsoluteVolume(device, volume);
174 }
175
GetA2dpDeviceStreamInfo(const std::string & macAddress,AudioStreamInfo & streamInfo)176 int32_t AudioA2dpManager::GetA2dpDeviceStreamInfo(const std::string& macAddress,
177 AudioStreamInfo &streamInfo)
178 {
179 std::lock_guard<std::mutex> a2dpLock(g_a2dpInstanceLock);
180 a2dpInstance_ = A2dpSource::GetProfile();
181 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "Failed to obtain A2DP profile instance");
182 BluetoothRemoteDevice device;
183 int32_t ret = MediaBluetoothDeviceManager::GetConnectedA2dpBluetoothDevice(macAddress, device);
184 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR,
185 "GetA2dpDeviceStreamInfo: the configuring A2DP device doesn't exist.");
186 A2dpCodecStatus codecStatus = a2dpInstance_->GetCodecStatus(device);
187 bool result = GetAudioStreamInfo(codecStatus.codecInfo, streamInfo);
188 CHECK_AND_RETURN_RET_LOG(result, ERROR, "GetA2dpDeviceStreamInfo: Unsupported a2dp codec info");
189 return SUCCESS;
190 }
191
HasA2dpDeviceConnected()192 bool AudioA2dpManager::HasA2dpDeviceConnected()
193 {
194 a2dpInstance_ = A2dpSource::GetProfile();
195 CHECK_AND_RETURN_RET(a2dpInstance_, false);
196 std::vector<int32_t> states {static_cast<int32_t>(BTConnectState::CONNECTED)};
197 std::vector<BluetoothRemoteDevice> devices;
198 a2dpInstance_->GetDevicesByStates(states, devices);
199
200 return !devices.empty();
201 }
202
A2dpOffloadSessionRequest(const std::vector<A2dpStreamInfo> & info)203 int32_t AudioA2dpManager::A2dpOffloadSessionRequest(const std::vector<A2dpStreamInfo> &info)
204 {
205 CHECK_AND_RETURN_RET_LOG(activeA2dpDevice_.GetDeviceAddr() != "00:00:00:00:00:00", A2DP_NOT_OFFLOAD,
206 "Invalid mac address, not request, return A2DP_NOT_OFFLOAD.");
207 int32_t ret = a2dpInstance_->A2dpOffloadSessionRequest(activeA2dpDevice_, info);
208 AUDIO_DEBUG_LOG("Request %{public}zu stream and return a2dp offload state %{public}d", info.size(), ret);
209 return ret;
210 }
211
OffloadStartPlaying(const std::vector<int32_t> & sessionsID)212 int32_t AudioA2dpManager::OffloadStartPlaying(const std::vector<int32_t> &sessionsID)
213 {
214 CHECK_AND_RETURN_RET_LOG(activeA2dpDevice_.GetDeviceAddr() != "00:00:00:00:00:00", ERROR,
215 "Invalid mac address, not start, return error.");
216 AUDIO_DEBUG_LOG("Start playing %{public}zu stream", sessionsID.size());
217 return a2dpInstance_->OffloadStartPlaying(activeA2dpDevice_, sessionsID);
218 }
219
OffloadStopPlaying(const std::vector<int32_t> & sessionsID)220 int32_t AudioA2dpManager::OffloadStopPlaying(const std::vector<int32_t> &sessionsID)
221 {
222 if (activeA2dpDevice_.GetDeviceAddr() == "00:00:00:00:00:00") {
223 AUDIO_DEBUG_LOG("Invalid mac address, not stop, return error.");
224 return ERROR;
225 }
226 AUDIO_DEBUG_LOG("Stop playing %{public}zu stream", sessionsID.size());
227 return a2dpInstance_->OffloadStopPlaying(activeA2dpDevice_, sessionsID);
228 }
229
GetRenderPosition(uint32_t & delayValue,uint64_t & sendDataSize,uint32_t & timeStamp)230 int32_t AudioA2dpManager::GetRenderPosition(uint32_t &delayValue, uint64_t &sendDataSize, uint32_t &timeStamp)
231 {
232 if (activeA2dpDevice_.GetDeviceAddr() == "00:00:00:00:00:00") {
233 AUDIO_DEBUG_LOG("Invalid mac address, return error.");
234 return ERROR;
235 }
236 return ERROR;
237 // a2dpInstance_->GetRenderPosition(activeA2dpDevice_, delayValue, sendDataSize, timeStamp);
238 }
239
RegisterA2dpPlayingStateChangedListener(std::shared_ptr<AudioA2dpPlayingStateChangedListener> listener)240 int32_t AudioA2dpManager::RegisterA2dpPlayingStateChangedListener(
241 std::shared_ptr<AudioA2dpPlayingStateChangedListener> listener)
242 {
243 std::lock_guard<std::mutex> lock(g_a2dpPlayingStateChangedLock);
244 a2dpPlayingStateChangedListeners_.push_back(listener);
245 return SUCCESS;
246 }
247
OnA2dpPlayingStateChanged(const std::string & deviceAddress,int32_t playingState)248 void AudioA2dpManager::OnA2dpPlayingStateChanged(const std::string &deviceAddress, int32_t playingState)
249 {
250 std::lock_guard<std::mutex> lock(g_a2dpPlayingStateChangedLock);
251 for (auto listener : a2dpPlayingStateChangedListeners_) {
252 listener->OnA2dpPlayingStateChanged(deviceAddress, playingState);
253 }
254 }
255
CheckA2dpDeviceReconnect()256 void AudioA2dpManager::CheckA2dpDeviceReconnect()
257 {
258 if (a2dpInstance_ == nullptr) {
259 a2dpInstance_ = A2dpSource::GetProfile();
260 }
261 CHECK_AND_RETURN_LOG(a2dpInstance_ != nullptr, "A2DP profile instance unavailable");
262 std::vector<int32_t> states {static_cast<int32_t>(BTConnectState::CONNECTED)};
263 std::vector<BluetoothRemoteDevice> devices;
264 a2dpInstance_->GetDevicesByStates(states, devices);
265
266 for (auto &device : devices) {
267 a2dpListener_->OnConnectionStateChanged(device, static_cast<int32_t>(BTConnectState::CONNECTED),
268 static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
269
270 int32_t wearState = 0; // 0 unwear state
271 if (IsBTWearDetectionEnable(device)) {
272 wearState = BluetoothAudioManager::GetInstance().IsDeviceWearing(device);
273 if (wearState == 1) MediaBluetoothDeviceManager::SetMediaStack(device, WEAR_ACTION); // 1 wear state
274 }
275 AUDIO_WARNING_LOG("reconnect a2dp device:%{public}s, wear state:%{public}d",
276 GetEncryptAddr(device.GetDeviceAddr()).c_str(), wearState);
277 }
278
279 std::vector<std::string> virtualDevices;
280 a2dpInstance_->GetVirtualDeviceList(virtualDevices);
281 for (auto &macAddress : virtualDevices) {
282 AUDIO_WARNING_LOG("reconnect virtual a2dp device:%{public}s", GetEncryptAddr(macAddress).c_str());
283 a2dpListener_->OnVirtualDeviceChanged(static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_ADD), macAddress);
284 }
285 }
286
Connect(const std::string & macAddress)287 int32_t AudioA2dpManager::Connect(const std::string &macAddress)
288 {
289 CHECK_AND_RETURN_RET_LOG(a2dpInstance_ != nullptr, ERROR, "A2DP profile instance unavailable");
290 BluetoothRemoteDevice virtualDevice = BluetoothRemoteDevice(macAddress);
291 if (MediaBluetoothDeviceManager::IsA2dpBluetoothDeviceConnecting(macAddress)) {
292 AUDIO_WARNING_LOG("A2dp device %{public}s is connecting, ignore connect request", macAddress.c_str());
293 virtualDevice.SetVirtualAutoConnectType(CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG, 0);
294 return SUCCESS;
295 }
296 std::vector<std::string> virtualDevices;
297 a2dpInstance_->GetVirtualDeviceList(virtualDevices);
298 if (std::find(virtualDevices.begin(), virtualDevices.end(), macAddress) == virtualDevices.end()) {
299 AUDIO_WARNING_LOG("A2dp device %{public}s is not virtual device, ignore connect request",
300 macAddress.c_str());
301 return SUCCESS;
302 }
303 int32_t ret = a2dpInstance_->Connect(virtualDevice);
304 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "A2dp Connect Failed");
305 virtualDevice.SetVirtualAutoConnectType(CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG, 0);
306 return SUCCESS;
307 }
308
OnConnectionStateChanged(const BluetoothRemoteDevice & device,int state,int cause)309 void AudioA2dpListener::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state, int cause)
310 {
311 AUDIO_WARNING_LOG("state: %{public}d, macAddress: %{public}s", state,
312 GetEncryptAddr(device.GetDeviceAddr()).c_str());
313 // Record connection state and device for hdi start time to check
314 AudioA2dpManager::SetConnectionState(state);
315 if (state == static_cast<int>(BTConnectState::CONNECTING)) {
316 MediaBluetoothDeviceManager::SetMediaStack(device, BluetoothDeviceAction::CONNECTING_ACTION);
317 }
318 if (state == static_cast<int>(BTConnectState::CONNECTED)) {
319 MediaBluetoothDeviceManager::SetMediaStack(device, BluetoothDeviceAction::CONNECT_ACTION);
320 }
321 if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
322 MediaBluetoothDeviceManager::SetMediaStack(device, BluetoothDeviceAction::DISCONNECT_ACTION);
323 }
324 }
325
OnConfigurationChanged(const BluetoothRemoteDevice & device,const A2dpCodecInfo & codecInfo,int error)326 void AudioA2dpListener::OnConfigurationChanged(const BluetoothRemoteDevice &device, const A2dpCodecInfo &codecInfo,
327 int error)
328 {
329 AUDIO_INFO_LOG("OnConfigurationChanged: sampleRate: %{public}d, channels: %{public}d, format: %{public}d",
330 codecInfo.sampleRate, codecInfo.channelMode, codecInfo.bitsPerSample);
331 AudioStreamInfo streamInfo = {};
332 bool result = GetAudioStreamInfo(codecInfo, streamInfo);
333 CHECK_AND_RETURN_LOG(result, "OnConfigurationChanged: Unsupported a2dp codec info");
334 MediaBluetoothDeviceManager::UpdateA2dpDeviceConfiguration(device, streamInfo);
335 }
336
OnPlayingStatusChanged(const BluetoothRemoteDevice & device,int playingState,int error)337 void AudioA2dpListener::OnPlayingStatusChanged(const BluetoothRemoteDevice &device, int playingState, int error)
338 {
339 AUDIO_INFO_LOG("OnPlayingStatusChanged, state: %{public}d, error: %{public}d", playingState, error);
340 if (error == SUCCESS) {
341 AudioA2dpManager::OnA2dpPlayingStateChanged(device.GetDeviceAddr(), playingState);
342 }
343 }
344
OnMediaStackChanged(const BluetoothRemoteDevice & device,int action)345 void AudioA2dpListener::OnMediaStackChanged(const BluetoothRemoteDevice &device, int action)
346 {
347 AUDIO_INFO_LOG("OnMediaStackChanged, action: %{public}d", action);
348 MediaBluetoothDeviceManager::SetMediaStack(device, action);
349 }
350
OnVirtualDeviceChanged(int32_t action,std::string address)351 void AudioA2dpListener::OnVirtualDeviceChanged(int32_t action, std::string address)
352 {
353 AUDIO_WARNING_LOG("action: %{public}d, macAddress: %{public}s", action,
354 GetEncryptAddr(address).c_str());
355 if (action == static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_ADD)) {
356 MediaBluetoothDeviceManager::SetMediaStack(BluetoothRemoteDevice(address),
357 BluetoothDeviceAction::VIRTUAL_DEVICE_ADD_ACTION);
358 }
359 if (action == static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_REMOVE)) {
360 MediaBluetoothDeviceManager::SetMediaStack(BluetoothRemoteDevice(address),
361 BluetoothDeviceAction::VIRTUAL_DEVICE_REMOVE_ACTION);
362 }
363 }
364
RegisterBluetoothScoListener()365 void AudioHfpManager::RegisterBluetoothScoListener()
366 {
367 AUDIO_INFO_LOG("AudioHfpManager::RegisterBluetoothScoListener");
368 std::lock_guard<std::mutex> hfpLock(g_hfpInstanceLock);
369 hfpInstance_ = HandsFreeAudioGateway::GetProfile();
370 CHECK_AND_RETURN_LOG(hfpInstance_ != nullptr, "Failed to obtain HFP AG profile instance");
371
372 hfpInstance_->RegisterObserver(hfpListener_);
373 }
374
UnregisterBluetoothScoListener()375 void AudioHfpManager::UnregisterBluetoothScoListener()
376 {
377 AUDIO_INFO_LOG("AudioHfpManager::UnregisterBluetoothScoListene");
378 std::lock_guard<std::mutex> hfpLock(g_hfpInstanceLock);
379 CHECK_AND_RETURN_LOG(hfpInstance_ != nullptr, "HFP AG profile instance unavailable");
380
381 hfpInstance_->DeregisterObserver(hfpListener_);
382 hfpInstance_ = nullptr;
383 }
384
CheckHfpDeviceReconnect()385 void AudioHfpManager::CheckHfpDeviceReconnect()
386 {
387 if (hfpInstance_ == nullptr) {
388 hfpInstance_ = HandsFreeAudioGateway::GetProfile();
389 }
390 CHECK_AND_RETURN_LOG(hfpInstance_ != nullptr, "HFP profile instance unavailable");
391 std::vector<int32_t> states {static_cast<int32_t>(BTConnectState::CONNECTED)};
392 std::vector<BluetoothRemoteDevice> devices = hfpInstance_->GetDevicesByStates(states);
393 for (auto &device : devices) {
394 hfpListener_->OnConnectionStateChanged(device, static_cast<int32_t>(BTConnectState::CONNECTED),
395 static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
396
397 int32_t wearState = 0; // 0 unwear state
398 if (IsBTWearDetectionEnable(device)) {
399 wearState = BluetoothAudioManager::GetInstance().IsDeviceWearing(device);
400 if (wearState == 1) HfpBluetoothDeviceManager::SetHfpStack(device, WEAR_ACTION); // 1 wear state
401 }
402 AUDIO_INFO_LOG("reconnect hfp device:%{public}s, wear state:%{public}d",
403 GetEncryptAddr(device.GetDeviceAddr()).c_str(), wearState);
404 }
405
406 std::vector<std::string> virtualDevices;
407 hfpInstance_->GetVirtualDeviceList(virtualDevices);
408 for (auto &macAddress : virtualDevices) {
409 AUDIO_PRERELEASE_LOGI("reconnect virtual hfp device:%{public}s", GetEncryptAddr(macAddress).c_str());
410 hfpListener_->OnVirtualDeviceChanged(static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_ADD), macAddress);
411 }
412 }
413
HandleScoWithRecongnition(bool handleFlag,BluetoothRemoteDevice & device)414 int32_t AudioHfpManager::HandleScoWithRecongnition(bool handleFlag, BluetoothRemoteDevice &device)
415 {
416 CHECK_AND_RETURN_RET_LOG(hfpInstance_ != nullptr, ERROR, "HFP AG profile instance unavailable");
417 bool ret = true;
418 if (handleFlag) {
419 int8_t scoCategory = GetScoCategoryFromScene(scene_);
420 if (scoCategory == ScoCategory::SCO_DEFAULT &&
421 AudioHfpManager::scoCategory != ScoCategory::SCO_RECOGNITION) {
422 AUDIO_INFO_LOG("Recongnition sco connect");
423 AudioHfpManager::recognitionStatus = RecognitionStatus::RECOGNITION_CONNECTING;
424 ret = hfpInstance_->OpenVoiceRecognition(device);
425 if (ret) {
426 AudioHfpManager::scoCategory = ScoCategory::SCO_RECOGNITION;
427 AudioHfpManager::recognitionStatus = RecognitionStatus::RECOGNITION_CONNECTED;
428 }
429 } else {
430 AUDIO_WARNING_LOG("Sco Connected OR Connecting, No Need to Create");
431 }
432 } else {
433 if (AudioHfpManager::scoCategory == ScoCategory::SCO_RECOGNITION) {
434 AUDIO_INFO_LOG("Recongnition sco close");
435 AudioHfpManager::recognitionStatus = RecognitionStatus::RECOGNITION_DISCONNECTING;
436 ret = hfpInstance_->CloseVoiceRecognition(device);
437 if (ret) {
438 AudioHfpManager::scoCategory = ScoCategory::SCO_DEFAULT;
439 AudioHfpManager::recognitionStatus = RecognitionStatus::RECOGNITION_DISCONNECTED;
440 }
441 }
442 }
443 CHECK_AND_RETURN_RET_LOG(ret == true, ERROR, "HandleScoWithRecongnition failed, result: %{public}d", ret);
444 return SUCCESS;
445 }
446
ClearRecongnitionStatus()447 void AudioHfpManager::ClearRecongnitionStatus()
448 {
449 if (AudioHfpManager::scoCategory == ScoCategory::SCO_RECOGNITION) {
450 AudioHfpManager::scoCategory = ScoCategory::SCO_DEFAULT;
451 AudioHfpManager::recognitionStatus = RecognitionStatus::RECOGNITION_DISCONNECTED;
452 }
453 }
454
GetScoCategory()455 ScoCategory AudioHfpManager::GetScoCategory()
456 {
457 return scoCategory;
458 }
459
GetRecognitionStatus()460 RecognitionStatus AudioHfpManager::GetRecognitionStatus()
461 {
462 return recognitionStatus;
463 }
464
SetActiveHfpDevice(const std::string & macAddress)465 int32_t AudioHfpManager::SetActiveHfpDevice(const std::string &macAddress)
466 {
467 BluetoothRemoteDevice device;
468 if (HfpBluetoothDeviceManager::GetConnectedHfpBluetoothDevice(macAddress, device) != SUCCESS) {
469 AUDIO_ERR_LOG("SetActiveHfpDevice failed for the HFP device %{public}s does not exist.",
470 GetEncryptAddr(macAddress).c_str());
471 return ERROR;
472 }
473 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
474 AUDIO_INFO_LOG("incoming device:%{public}s, current device:%{public}s",
475 GetEncryptAddr(macAddress).c_str(), GetEncryptAddr(activeHfpDevice_.GetDeviceAddr()).c_str());
476 if (macAddress != activeHfpDevice_.GetDeviceAddr()) {
477 AUDIO_WARNING_LOG("Active hfp device is changed, need to DisconnectSco for current activeHfpDevice.");
478 int32_t ret = DisconnectSco();
479 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "DisconnectSco failed, result: %{public}d", ret);
480 }
481 std::lock_guard<std::mutex> hfpLock(g_hfpInstanceLock);
482 CHECK_AND_RETURN_RET_LOG(hfpInstance_ != nullptr, ERROR, "HFP AG profile instance unavailable");
483 bool res = hfpInstance_->SetActiveDevice(device);
484 CHECK_AND_RETURN_RET_LOG(res == true, ERROR, "SetActiveHfpDevice failed, result: %{public}d", res);
485 activeHfpDevice_ = device;
486 return SUCCESS;
487 }
488
GetActiveHfpDevice()489 std::string AudioHfpManager::GetActiveHfpDevice()
490 {
491 std::lock_guard<std::mutex> hfpLock(g_hfpInstanceLock);
492 CHECK_AND_RETURN_RET_LOG(hfpInstance_ != nullptr, "", "HFP AG profile instance unavailable");
493 BluetoothRemoteDevice device = hfpInstance_->GetActiveDevice();
494 return device.GetDeviceAddr();
495 }
496
ConnectScoWithAudioScene(AudioScene scene)497 int32_t AudioHfpManager::ConnectScoWithAudioScene(AudioScene scene)
498 {
499 if (scoCategory == ScoCategory::SCO_RECOGNITION) {
500 AUDIO_WARNING_LOG("Recognition Sco Connected");
501 return SUCCESS;
502 }
503 std::lock_guard<std::mutex> sceneLock(g_audioSceneLock);
504 int8_t lastScoCategory = GetScoCategoryFromScene(scene_);
505 int8_t newScoCategory = GetScoCategoryFromScene(scene);
506 AUDIO_INFO_LOG("new sco category is %{public}d, last sco category is %{public}d", newScoCategory, lastScoCategory);
507
508 if (lastScoCategory == newScoCategory) {
509 AUDIO_INFO_LOG("sco category %{public}d not change", newScoCategory);
510 return SUCCESS;
511 }
512 std::lock_guard<std::mutex> hfpLock(g_hfpInstanceLock);
513 CHECK_AND_RETURN_RET_LOG(hfpInstance_ != nullptr, ERROR, "HFP AG profile instance unavailable");
514 bool isInbardingEnabled = false;
515 hfpInstance_->IsInbandRingingEnabled(isInbardingEnabled);
516 if ((scene == AUDIO_SCENE_RINGING || scene == AUDIO_SCENE_VOICE_RINGING) && !isInbardingEnabled) {
517 AUDIO_WARNING_LOG("The inbarding switch is off, ignore the ring scene.");
518 return SUCCESS;
519 }
520 int32_t ret;
521 if (lastScoCategory != ScoCategory::SCO_DEFAULT) {
522 AUDIO_INFO_LOG("Entered to disConnectSco for last audioScene category.");
523 ret = hfpInstance_->DisconnectSco(static_cast<uint8_t>(lastScoCategory));
524 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR,
525 "ConnectScoWithAudioScene failed as the last SCO failed to be disconnected, result: %{public}d", ret);
526 }
527 if (newScoCategory != ScoCategory::SCO_DEFAULT) {
528 AUDIO_INFO_LOG("Entered to connectSco for new audioScene category.");
529 ret = hfpInstance_->ConnectSco(static_cast<uint8_t>(newScoCategory));
530 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "ConnectScoWithAudioScene failed, result: %{public}d", ret);
531 }
532 scene_ = scene;
533 return SUCCESS;
534 }
535
DisconnectSco()536 int32_t AudioHfpManager::DisconnectSco()
537 {
538 std::lock_guard<std::mutex> sceneLock(g_audioSceneLock);
539 int8_t currentScoCategory = GetScoCategoryFromScene(scene_);
540 if (currentScoCategory == ScoCategory::SCO_DEFAULT) {
541 AUDIO_WARNING_LOG("Current sco category is DEFAULT, not need to disconnect sco.");
542 return SUCCESS;
543 }
544 AUDIO_INFO_LOG("current sco category %{public}d", currentScoCategory);
545
546 std::lock_guard<std::mutex> hfpLock(g_hfpInstanceLock);
547 CHECK_AND_RETURN_RET_LOG(hfpInstance_ != nullptr, ERROR, "HFP AG profile instance unavailable");
548 int32_t ret = hfpInstance_->DisconnectSco(static_cast<uint8_t>(currentScoCategory));
549 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "DisconnectSco failed, result: %{public}d", ret);
550 scene_ = AUDIO_SCENE_DEFAULT;
551 return SUCCESS;
552 }
553
GetScoCategoryFromScene(AudioScene scene)554 int8_t AudioHfpManager::GetScoCategoryFromScene(AudioScene scene)
555 {
556 switch (scene) {
557 case AUDIO_SCENE_VOICE_RINGING:
558 case AUDIO_SCENE_PHONE_CALL:
559 return ScoCategory::SCO_CALLULAR;
560 case AUDIO_SCENE_RINGING:
561 case AUDIO_SCENE_PHONE_CHAT:
562 return ScoCategory::SCO_VIRTUAL;
563 default:
564 return ScoCategory::SCO_DEFAULT;
565 }
566 }
567
DisconnectBluetoothHfpSink()568 void AudioHfpManager::DisconnectBluetoothHfpSink()
569 {
570 int connectionState = static_cast<int>(BTConnectState::DISCONNECTED);
571 auto hfpList = HfpBluetoothDeviceManager::GetAllHfpBluetoothDevice();
572 for (const auto &device : hfpList) {
573 hfpListener_->OnConnectionStateChanged(device, connectionState,
574 static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
575 }
576
577 auto virtualDevices = HfpBluetoothDeviceManager::GetHfpVirtualDeviceList();
578 for (const auto &virtualDevice : virtualDevices) {
579 hfpListener_->OnVirtualDeviceChanged(static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_REMOVE),
580 virtualDevice.GetDeviceAddr());
581 }
582 HfpBluetoothDeviceManager::ClearAllHfpBluetoothDevice();
583 }
584
UpdateCurrentActiveHfpDevice(const BluetoothRemoteDevice & device)585 void AudioHfpManager::UpdateCurrentActiveHfpDevice(const BluetoothRemoteDevice &device)
586 {
587 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
588 activeHfpDevice_ = device;
589 }
590
GetCurrentActiveHfpDevice()591 std::string AudioHfpManager::GetCurrentActiveHfpDevice()
592 {
593 std::lock_guard<std::mutex> hfpDeviceLock(g_activehfpDeviceLock);
594 return activeHfpDevice_.GetDeviceAddr();
595 }
596
UpdateAudioScene(AudioScene scene)597 void AudioHfpManager::UpdateAudioScene(AudioScene scene)
598 {
599 std::lock_guard<std::mutex> sceneLock(g_audioSceneLock);
600 scene_ = scene;
601 }
602
GetCurrentAudioScene()603 AudioStandard::AudioScene AudioHfpManager::GetCurrentAudioScene()
604 {
605 std::lock_guard<std::mutex> sceneLock(g_audioSceneLock);
606 return scene_;
607 }
608
SetAudioSceneFromPolicy(AudioScene scene)609 void AudioHfpManager::SetAudioSceneFromPolicy(AudioScene scene)
610 {
611 sceneFromPolicy_ = scene;
612 }
613
GetPolicyAudioScene()614 AudioStandard::AudioScene AudioHfpManager::GetPolicyAudioScene()
615 {
616 return sceneFromPolicy_;
617 }
618
Connect(const std::string & macAddress)619 int32_t AudioHfpManager::Connect(const std::string &macAddress)
620 {
621 CHECK_AND_RETURN_RET_LOG(hfpInstance_ != nullptr, ERROR, "HFP AG profile instance unavailable");
622 BluetoothRemoteDevice virtualDevice = BluetoothRemoteDevice(macAddress);
623 if (HfpBluetoothDeviceManager::IsHfpBluetoothDeviceConnecting(macAddress)) {
624 AUDIO_WARNING_LOG("Hfp device %{public}s is connecting, ignore connect request",
625 GetEncryptAddr(macAddress).c_str());
626 virtualDevice.SetVirtualAutoConnectType(CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG, 0);
627 return SUCCESS;
628 }
629 std::vector<std::string> virtualDevices;
630 hfpInstance_->GetVirtualDeviceList(virtualDevices);
631 if (std::find(virtualDevices.begin(), virtualDevices.end(), macAddress) == virtualDevices.end()) {
632 AUDIO_WARNING_LOG("Hfp device %{public}s is not virtual device, ignore connect request",
633 GetEncryptAddr(macAddress).c_str());
634 return SUCCESS;
635 }
636 int32_t ret = hfpInstance_->Connect(virtualDevice);
637 CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "Hfp Connect Failed");
638 virtualDevice.SetVirtualAutoConnectType(CONN_REASON_MANUAL_VIRTUAL_CONNECT_PREEMPT_FLAG, 0);
639 return SUCCESS;
640 }
641
OnScoStateChanged(const BluetoothRemoteDevice & device,int state,int reason)642 void AudioHfpListener::OnScoStateChanged(const BluetoothRemoteDevice &device, int state, int reason)
643 {
644 AUDIO_WARNING_LOG("state:[%{public}d] reason:[%{public}d] device:[%{public}s]",
645 state, reason, GetEncryptAddr(device.GetDeviceAddr()).c_str());
646 // SCO_DISCONNECTED = 3, SCO_CONNECTING = 4, SCO_DISCONNECTING = 5, SCO_CONNECTED = 6
647 HfpScoConnectState scoState = static_cast<HfpScoConnectState>(state);
648 if (scoState == HfpScoConnectState::SCO_CONNECTED || scoState == HfpScoConnectState::SCO_DISCONNECTED) {
649 if (device.GetDeviceAddr() == AudioHfpManager::GetCurrentActiveHfpDevice() &&
650 scoState == HfpScoConnectState::SCO_DISCONNECTED) {
651 BluetoothRemoteDevice defaultDevice;
652 AudioHfpManager::UpdateCurrentActiveHfpDevice(defaultDevice);
653 AUDIO_WARNING_LOG("Sco disconnect, need set audio scene as default.");
654 AudioHfpManager::UpdateAudioScene(AUDIO_SCENE_DEFAULT);
655 } else if (scoState == HfpScoConnectState::SCO_CONNECTED) {
656 AudioScene audioScene = AudioHfpManager::GetPolicyAudioScene();
657 if (audioScene != AudioHfpManager::GetCurrentAudioScene()) {
658 AUDIO_WARNING_LOG("Sco connect by peripheral device, update scene_ %{public}d", audioScene);
659 AudioHfpManager::UpdateAudioScene(audioScene);
660 }
661 AudioHfpManager::UpdateCurrentActiveHfpDevice(device);
662 }
663 bool isConnected = (scoState == HfpScoConnectState::SCO_CONNECTED) ? true : false;
664
665 // VGS feature
666 bool isVgsSupported = false;
667 if (isConnected) {
668 HandsFreeAudioGateway *hfpInstance = HandsFreeAudioGateway::GetProfile();
669 CHECK_AND_RETURN_LOG(hfpInstance != nullptr, "Failed to obtain HFP AG profile instance");
670 hfpInstance->IsVgsSupported(device, isVgsSupported);
671 }
672 AUDIO_INFO_LOG("AudioHfpListener::OnScoStateChanged: isVgsSupported: [%{public}d]", isVgsSupported);
673 HfpBluetoothDeviceManager::OnScoStateChanged(device, isVgsSupported, reason);
674 }
675 }
676
OnConnectionStateChanged(const BluetoothRemoteDevice & device,int state,int cause)677 void AudioHfpListener::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state, int cause)
678 {
679 AUDIO_WARNING_LOG("state: %{public}d device: %{public}s", state,
680 GetEncryptAddr(device.GetDeviceAddr()).c_str());
681 if (state == static_cast<int>(BTConnectState::CONNECTING)) {
682 HfpBluetoothDeviceManager::SetHfpStack(device, BluetoothDeviceAction::CONNECTING_ACTION);
683 }
684 if (state == static_cast<int>(BTConnectState::CONNECTED)) {
685 HfpBluetoothDeviceManager::SetHfpStack(device, BluetoothDeviceAction::CONNECT_ACTION);
686 }
687 if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
688 if (device.GetDeviceAddr() == AudioHfpManager::GetCurrentActiveHfpDevice()) {
689 BluetoothRemoteDevice defaultDevice;
690 AudioHfpManager::UpdateCurrentActiveHfpDevice(defaultDevice);
691 AUDIO_WARNING_LOG("Current active hfp device diconnect, need set audio scene as default.");
692 AudioHfpManager::UpdateAudioScene(AUDIO_SCENE_DEFAULT);
693 }
694 HfpBluetoothDeviceManager::SetHfpStack(device, BluetoothDeviceAction::DISCONNECT_ACTION);
695 }
696 }
697
OnHfpStackChanged(const BluetoothRemoteDevice & device,int action)698 void AudioHfpListener::OnHfpStackChanged(const BluetoothRemoteDevice &device, int action)
699 {
700 AUDIO_WARNING_LOG("action: %{public}d device: %{public}s", action, GetEncryptAddr(device.GetDeviceAddr()).c_str());
701 HfpBluetoothDeviceManager::SetHfpStack(device, action);
702 }
703
OnVirtualDeviceChanged(int32_t action,std::string macAddress)704 void AudioHfpListener::OnVirtualDeviceChanged(int32_t action, std::string macAddress)
705 {
706 AUDIO_WARNING_LOG("action: %{public}d device: %{public}s", action, GetEncryptAddr(macAddress).c_str());
707 if (action == static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_ADD)) {
708 HfpBluetoothDeviceManager::SetHfpStack(BluetoothRemoteDevice(macAddress),
709 BluetoothDeviceAction::VIRTUAL_DEVICE_ADD_ACTION);
710 }
711 if (action == static_cast<int32_t>(Bluetooth::BT_VIRTUAL_DEVICE_REMOVE)) {
712 HfpBluetoothDeviceManager::SetHfpStack(BluetoothRemoteDevice(macAddress),
713 BluetoothDeviceAction::VIRTUAL_DEVICE_REMOVE_ACTION);
714 }
715 }
716 // LCOV_EXCL_STOP
717 } // namespace Bluetooth
718 } // namespace OHOS
719