1 /*
2 * Copyright (c) 2021-2024 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 "AudioA2dpOffloadManager"
17 #endif
18
19 #include "audio_a2dp_offload_manager.h"
20 #include <ability_manager_client.h>
21 #include "iservice_registry.h"
22 #include "parameter.h"
23 #include "parameters.h"
24 #include "audio_utils.h"
25 #include "audio_policy_log.h"
26 #include "audio_utils.h"
27 #include "audio_manager_listener_stub.h"
28 #include "audio_inner_call.h"
29 #include "media_monitor_manager.h"
30 #include "audio_affinity_manager.h"
31 #include "audio_stream_collector.h"
32 #include "audio_policy_manager_factory.h"
33 #include "audio_spatialization_manager.h"
34 #include "audio_spatialization_service.h"
35 #include "audio_router_center.h"
36
37 #include "audio_policy_utils.h"
38 #include "audio_server_proxy.h"
39
40 namespace OHOS {
41 namespace AudioStandard {
42 const int32_t A2DP_PLAYING = 2;
43 const int32_t A2DP_STOPPED = 1;
44 const int32_t DATA_LINK_CONNECTING = 10;
45 const int32_t DATA_LINK_CONNECTED = 11;
46 const int32_t CONNECTION_TIMEOUT_IN_MS = 1000; // 1000ms
47
48 #ifdef BLUETOOTH_ENABLE
49 const unsigned int BLUETOOTH_TIME_OUT_SECONDS = 8;
50 #endif
51
GetEncryptAddr(const std::string & addr)52 static std::string GetEncryptAddr(const std::string &addr)
53 {
54 const int32_t START_POS = 6;
55 const int32_t END_POS = 13;
56 const int32_t ADDRESS_STR_LEN = 17;
57 if (addr.empty() || addr.length() != ADDRESS_STR_LEN) {
58 return std::string("");
59 }
60 std::string tmp = "**:**:**:**:**:**";
61 std::string out = addr;
62 for (int i = START_POS; i <= END_POS; i++) {
63 out[i] = tmp[i];
64 }
65 return out;
66 }
67
OnA2dpPlayingStateChanged(const std::string & deviceAddress,int32_t playingState)68 void AudioA2dpOffloadManager::OnA2dpPlayingStateChanged(const std::string &deviceAddress, int32_t playingState)
69 {
70 A2dpOffloadConnectionState state = audioA2dpOffloadFlag_.GetCurrentOffloadConnectedState();
71 AUDIO_INFO_LOG("OnA2dpPlayingStateChanged current A2dpOffload MacAddr:%{public}s, incoming MacAddr:%{public}s, "
72 "currentStatus:%{public}d, incommingState:%{public}d", GetEncryptAddr(a2dpOffloadDeviceAddress_).c_str(),
73 GetEncryptAddr(deviceAddress).c_str(), state, playingState);
74 if (deviceAddress != a2dpOffloadDeviceAddress_) {
75 if (playingState == A2DP_STOPPED && state == CONNECTION_STATUS_CONNECTED) {
76 return;
77 }
78 // below is A2dp(not offload scenario)
79 audioA2dpOffloadFlag_.SetCurrentOffloadConnectedState(CONNECTION_STATUS_DISCONNECTED);
80 return;
81 }
82
83 // deviceAddress matched
84 if (playingState == A2DP_PLAYING) {
85 if (state == CONNECTION_STATUS_CONNECTING) {
86 AUDIO_INFO_LOG("OnA2dpPlayingStateChanged state change "
87 "from %{public}d to %{public}d", state, CONNECTION_STATUS_CONNECTED);
88
89 for (int32_t sessionId : connectionTriggerSessionIds_) {
90 AudioServerProxy::GetInstance().UpdateSessionConnectionStateProxy(sessionId, DATA_LINK_CONNECTED);
91 }
92 std::vector<int32_t>().swap(connectionTriggerSessionIds_);
93 connectionCV_.notify_all();
94 }
95 audioA2dpOffloadFlag_.SetCurrentOffloadConnectedState(CONNECTION_STATUS_CONNECTED);
96 } else if (playingState == A2DP_STOPPED) {
97 AUDIO_INFO_LOG("OnA2dpPlayingStateChanged state change "
98 "from %{public}d to %{public}d", state, CONNECTION_STATUS_DISCONNECTED);
99 audioA2dpOffloadFlag_.SetCurrentOffloadConnectedState(CONNECTION_STATUS_DISCONNECTED);
100 a2dpOffloadDeviceAddress_ = "";
101 std::vector<int32_t>().swap(connectionTriggerSessionIds_);
102 } else {
103 // at the current moment, we only handle the PLAYING and STOPPED state,
104 // will handle other state in the future
105 AUDIO_INFO_LOG("OnA2dpPlayingStateChanged state: %{public}d, "
106 "received unexpected state:%{public}d", state, playingState);
107 }
108 }
109
ConnectA2dpOffload(const std::string & deviceAddress,const std::vector<int32_t> & sessionIds)110 void AudioA2dpOffloadManager::ConnectA2dpOffload(const std::string &deviceAddress,
111 const std::vector<int32_t> &sessionIds)
112 {
113 AUDIO_INFO_LOG("start connecting a2dpOffload for MacAddr:%{public}s.", GetEncryptAddr(deviceAddress).c_str());
114 A2dpOffloadConnectionState state = audioA2dpOffloadFlag_.GetCurrentOffloadConnectedState();
115 a2dpOffloadDeviceAddress_ = deviceAddress;
116 connectionTriggerSessionIds_.assign(sessionIds.begin(), sessionIds.end());
117
118 for (int32_t sessionId : connectionTriggerSessionIds_) {
119 AudioServerProxy::GetInstance().UpdateSessionConnectionStateProxy(sessionId, DATA_LINK_CONNECTING);
120 }
121
122 if (state == CONNECTION_STATUS_CONNECTED || state == CONNECTION_STATUS_CONNECTING) {
123 AUDIO_INFO_LOG("state already in %{public}d, "
124 "status, no need to trigger another waiting", state);
125 return;
126 }
127
128 std::thread switchThread(&AudioA2dpOffloadManager::WaitForConnectionCompleted, this);
129 switchThread.detach();
130 AUDIO_INFO_LOG("state change from %{public}d to %{public}d",
131 state, CONNECTION_STATUS_CONNECTING);
132 audioA2dpOffloadFlag_.SetCurrentOffloadConnectedState(CONNECTION_STATUS_CONNECTING);
133 }
134
WaitForConnectionCompleted()135 void AudioA2dpOffloadManager::WaitForConnectionCompleted()
136 {
137 std::unique_lock<std::mutex> waitLock(connectionMutex_);
138 bool connectionCompleted = connectionCV_.wait_for(waitLock,
139 std::chrono::milliseconds(CONNECTION_TIMEOUT_IN_MS), [this] {
140 return audioA2dpOffloadFlag_.GetCurrentOffloadConnectedState() == CONNECTION_STATUS_CONNECTED;
141 });
142 // a2dp connection timeout, anyway we should notify client dataLink OK in order to allow the data flow begin
143 AUDIO_INFO_LOG("WaitForConnectionCompleted unblocked, connectionCompleted is %{public}d", connectionCompleted);
144
145 if (!connectionCompleted) {
146 AUDIO_INFO_LOG("state change from %{public}d to %{public}d",
147 audioA2dpOffloadFlag_.GetCurrentOffloadConnectedState(), CONNECTION_STATUS_TIMEOUT);
148 audioA2dpOffloadFlag_.SetCurrentOffloadConnectedState(CONNECTION_STATUS_CONNECTED);
149 for (int32_t sessionId : connectionTriggerSessionIds_) {
150 AudioServerProxy::GetInstance().UpdateSessionConnectionStateProxy(sessionId, DATA_LINK_CONNECTED);
151 }
152 std::vector<int32_t>().swap(connectionTriggerSessionIds_);
153 }
154 waitLock.unlock();
155 FetchStreamForA2dpOffload(false);
156 return;
157 }
158
IsA2dpOffloadConnecting(int32_t sessionId)159 bool AudioA2dpOffloadManager::IsA2dpOffloadConnecting(int32_t sessionId)
160 {
161 if (audioA2dpOffloadFlag_.GetCurrentOffloadConnectedState() == CONNECTION_STATUS_CONNECTING) {
162 if (std::find(connectionTriggerSessionIds_.begin(), connectionTriggerSessionIds_.end(), sessionId) !=
163 connectionTriggerSessionIds_.end()) {
164 return true;
165 }
166 }
167 return false;
168 }
169
IsA2dpOffloadConnected()170 bool AudioA2dpOffloadManager::IsA2dpOffloadConnected()
171 {
172 return audioA2dpOffloadFlag_.GetCurrentOffloadConnectedState() == CONNECTION_STATUS_CONNECTED;
173 }
174
OffloadStartPlaying(const std::vector<int32_t> & sessionIds)175 int32_t AudioA2dpOffloadManager::OffloadStartPlaying(const std::vector<int32_t> &sessionIds)
176 {
177 #ifdef BLUETOOTH_ENABLE
178 AUDIO_INFO_LOG("OffloadStartPlaying, a2dpOffloadFlag_: %{public}d, sessionIds: %{public}zu",
179 GetA2dpOffloadFlag(), sessionIds.size());
180 if (GetA2dpOffloadFlag() != A2DP_OFFLOAD || sessionIds.size() == 0) {
181 return SUCCESS;
182 }
183 int32_t ret = audioA2dpOffloadFlag_.OffloadStartPlaying(sessionIds);
184 A2dpOffloadConnectionState state = audioA2dpOffloadFlag_.GetCurrentOffloadConnectedState();
185 if (ret == SUCCESS && (state != CONNECTION_STATUS_CONNECTED)) {
186 ConnectA2dpOffload(Bluetooth::AudioA2dpManager::GetActiveA2dpDevice(), sessionIds);
187 }
188 return ret;
189 #else
190 return SUCCESS;
191 #endif
192 }
193
OffloadStopPlaying(const std::vector<int32_t> & sessionIds)194 int32_t AudioA2dpOffloadManager::OffloadStopPlaying(const std::vector<int32_t> &sessionIds)
195 {
196 #ifdef BLUETOOTH_ENABLE
197 AUDIO_PRERELEASE_LOGI("OffloadStopPlaying, a2dpOffloadFlag_: %{public}d, sessionIds: %{public}zu",
198 GetA2dpOffloadFlag(), sessionIds.size());
199 if (GetA2dpOffloadFlag() != A2DP_OFFLOAD || sessionIds.size() == 0) {
200 return SUCCESS;
201 }
202 return audioA2dpOffloadFlag_.OffloadStopPlaying(sessionIds);
203 #else
204 return SUCCESS;
205 #endif
206 }
207
SetA2dpOffloadFlag(BluetoothOffloadState state)208 void AudioA2dpOffloadManager::SetA2dpOffloadFlag(BluetoothOffloadState state)
209 {
210 audioA2dpOffloadFlag_.SetA2dpOffloadFlag(state);
211 }
212
GetA2dpOffloadFlag()213 BluetoothOffloadState AudioA2dpOffloadManager::GetA2dpOffloadFlag()
214 {
215 return audioA2dpOffloadFlag_.GetA2dpOffloadFlag();
216 }
217
UpdateA2dpOffloadFlagForAllStream(std::unordered_map<uint32_t,bool> & sessionIDToSpatializationEnableMap,DeviceType deviceType)218 void AudioA2dpOffloadManager::UpdateA2dpOffloadFlagForAllStream(
219 std::unordered_map<uint32_t, bool> &sessionIDToSpatializationEnableMap, DeviceType deviceType)
220 {
221 #ifdef BLUETOOTH_ENABLE
222 vector<Bluetooth::A2dpStreamInfo> allSessionInfos;
223 Bluetooth::A2dpStreamInfo a2dpStreamInfo;
224 vector<shared_ptr<AudioRendererChangeInfo>> audioRendererChangeInfos;
225 streamCollector_.GetCurrentRendererChangeInfos(audioRendererChangeInfos);
226 std::vector<int32_t> stopPlayingStream(0);
227 for (auto &changeInfo : audioRendererChangeInfos) {
228 if (changeInfo->rendererState != RENDERER_RUNNING) {
229 stopPlayingStream.emplace_back(changeInfo->sessionId);
230 continue;
231 }
232 a2dpStreamInfo.sessionId = changeInfo->sessionId;
233 a2dpStreamInfo.streamType = streamCollector_.GetStreamType(changeInfo->sessionId);
234 if (sessionIDToSpatializationEnableMap.count(static_cast<uint32_t>(a2dpStreamInfo.sessionId))) {
235 a2dpStreamInfo.isSpatialAudio =
236 sessionIDToSpatializationEnableMap[static_cast<uint32_t>(a2dpStreamInfo.sessionId)];
237 } else {
238 a2dpStreamInfo.isSpatialAudio = 0;
239 }
240 allSessionInfos.push_back(a2dpStreamInfo);
241 }
242 if (stopPlayingStream.size() > 0) {
243 OffloadStopPlaying(stopPlayingStream);
244 }
245 UpdateA2dpOffloadFlag(allSessionInfos, deviceType);
246 #endif
247 AUDIO_DEBUG_LOG("deviceType %{public}d", deviceType);
248 }
249
UpdateA2dpOffloadFlagForAllStream(DeviceType deviceType)250 int32_t AudioA2dpOffloadManager::UpdateA2dpOffloadFlagForAllStream(DeviceType deviceType)
251 {
252 int32_t activeSessionsSize = 0;
253 #ifdef BLUETOOTH_ENABLE
254 vector<Bluetooth::A2dpStreamInfo> allSessionInfos;
255 Bluetooth::A2dpStreamInfo a2dpStreamInfo;
256 vector<shared_ptr<AudioRendererChangeInfo>> audioRendererChangeInfos;
257 streamCollector_.GetCurrentRendererChangeInfos(audioRendererChangeInfos);
258 {
259 AudioXCollie audioXCollie("AudioA2dpOffloadManager::UpdateA2dpOffloadFlagForAllStream",
260 BLUETOOTH_TIME_OUT_SECONDS);
261 std::vector<int32_t> stopPlayingStream(0);
262 for (auto &changeInfo : audioRendererChangeInfos) {
263 if (changeInfo->rendererState != RENDERER_RUNNING) {
264 stopPlayingStream.emplace_back(changeInfo->sessionId);
265 continue;
266 }
267 a2dpStreamInfo.sessionId = changeInfo->sessionId;
268 a2dpStreamInfo.streamType = streamCollector_.GetStreamType(changeInfo->sessionId);
269 StreamUsage tempStreamUsage = changeInfo->rendererInfo.streamUsage;
270 AudioSpatializationState spatialState =
271 AudioSpatializationService::GetAudioSpatializationService().GetSpatializationState(tempStreamUsage);
272 a2dpStreamInfo.isSpatialAudio = spatialState.spatializationEnabled;
273 allSessionInfos.push_back(a2dpStreamInfo);
274 }
275 if (stopPlayingStream.size() > 0) {
276 OffloadStopPlaying(stopPlayingStream);
277 }
278 }
279 UpdateA2dpOffloadFlag(allSessionInfos, deviceType);
280 activeSessionsSize = static_cast<int32_t>(allSessionInfos.size());
281 #endif
282 AUDIO_DEBUG_LOG("deviceType %{public}d", deviceType);
283 return activeSessionsSize;
284 }
285
UpdateOffloadWhenActiveDeviceSwitchFromA2dp()286 void AudioA2dpOffloadManager::UpdateOffloadWhenActiveDeviceSwitchFromA2dp()
287 {
288 AUDIO_PRERELEASE_LOGI("a2dpOffloadFlag change from %{public}d to %{public}d", GetA2dpOffloadFlag(),
289 NO_A2DP_DEVICE);
290 std::vector<int32_t> allSessions;
291 GetAllRunningStreamSession(allSessions);
292 OffloadStopPlaying(allSessions);
293 SetA2dpOffloadFlag(NO_A2DP_DEVICE);
294 for (auto it = allSessions.begin(); it != allSessions.end(); ++it) {
295 audioOffloadStream_.ResetOffloadMode(*it);
296 }
297 }
298
299 #ifdef BLUETOOTH_ENABLE
UpdateA2dpOffloadFlag(const std::vector<Bluetooth::A2dpStreamInfo> & allActiveSessions,DeviceType deviceType)300 void AudioA2dpOffloadManager::UpdateA2dpOffloadFlag(const std::vector<Bluetooth::A2dpStreamInfo> &allActiveSessions,
301 DeviceType deviceType)
302 {
303 if (allActiveSessions.size() == 0) {
304 AUDIO_PRERELEASE_LOGI("no active sessions");
305 return;
306 }
307 auto receiveOffloadFlag = NO_A2DP_DEVICE;
308 if (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP) {
309 receiveOffloadFlag = static_cast<BluetoothOffloadState>(Bluetooth::AudioA2dpManager::A2dpOffloadSessionRequest(
310 allActiveSessions));
311 } else if (audioActiveDevice_.GetCurrentOutputDeviceType() == DEVICE_TYPE_BLUETOOTH_A2DP &&
312 audioActiveDevice_.GetCurrentOutputDeviceNetworkId() == LOCAL_NETWORK_ID && deviceType == DEVICE_TYPE_NONE) {
313 receiveOffloadFlag = static_cast<BluetoothOffloadState>(Bluetooth::AudioA2dpManager::A2dpOffloadSessionRequest(
314 allActiveSessions));
315 }
316
317 std::lock_guard<std::mutex> lock(switchA2dpOffloadMutex_);
318 AUDIO_PRERELEASE_LOGI("deviceType: %{public}d, currentActiveDevice_: %{public}d, allActiveSessions: %{public}zu, "
319 "a2dpOffloadFlag: %{public}d, receiveOffloadFlag: %{public}d",
320 deviceType, audioActiveDevice_.GetCurrentOutputDeviceType(), allActiveSessions.size(), GetA2dpOffloadFlag(),
321 receiveOffloadFlag);
322
323 if (receiveOffloadFlag == NO_A2DP_DEVICE) {
324 UpdateOffloadWhenActiveDeviceSwitchFromA2dp();
325 } else if (receiveOffloadFlag != GetA2dpOffloadFlag()) {
326 if (GetA2dpOffloadFlag() == A2DP_OFFLOAD) {
327 HandleA2dpDeviceOutOffload(receiveOffloadFlag);
328 } else if (receiveOffloadFlag == A2DP_OFFLOAD) {
329 HandleA2dpDeviceInOffload(receiveOffloadFlag);
330 } else {
331 AUDIO_INFO_LOG("a2dpOffloadFlag change from %{public}d to %{public}d", GetA2dpOffloadFlag(),
332 receiveOffloadFlag);
333 SetA2dpOffloadFlag(receiveOffloadFlag);
334 }
335 } else if (GetA2dpOffloadFlag() == A2DP_OFFLOAD) {
336 std::vector<int32_t> allSessions;
337 GetAllRunningStreamSession(allSessions);
338 OffloadStartPlaying(allSessions);
339 AudioServerProxy::GetInstance().UpdateEffectBtOffloadSupportedProxy(true);
340 audioOffloadStream_.ResetOffloadModeOnSpatializationChanged(allSessions);
341 GetA2dpOffloadCodecAndSendToDsp();
342 std::string activePort = BLUETOOTH_SPEAKER;
343 audioPolicyManager_.SuspendAudioDevice(activePort, true);
344 }
345 }
346
347 #endif
348
HandleA2dpDeviceOutOffload(BluetoothOffloadState a2dpOffloadFlag)349 int32_t AudioA2dpOffloadManager::HandleA2dpDeviceOutOffload(BluetoothOffloadState a2dpOffloadFlag)
350 {
351 #ifdef BLUETOOTH_ENABLE
352 AUDIO_INFO_LOG("a2dpOffloadFlag change from %{public}d to %{public}d", GetA2dpOffloadFlag(), a2dpOffloadFlag);
353 std::vector<int32_t> allSessions;
354 GetAllRunningStreamSession(allSessions);
355 OffloadStopPlaying(allSessions);
356 SetA2dpOffloadFlag(a2dpOffloadFlag);
357
358 DeviceType dev = audioActiveDevice_.GetCurrentOutputDeviceType();
359 AudioPolicyUtils::GetInstance().UpdateEffectDefaultSink(dev);
360 AUDIO_INFO_LOG("Handle A2dpDevice Out Offload");
361
362 FetchStreamForA2dpOffload(true);
363
364 if (audioActiveDevice_.GetCurrentOutputDeviceType() == DEVICE_TYPE_BLUETOOTH_A2DP) {
365 return HandleActiveDevice(DEVICE_TYPE_BLUETOOTH_A2DP);
366 } else {
367 return SUCCESS;
368 }
369 #else
370 return ERROR;
371 #endif
372 }
373
HandleA2dpDeviceInOffload(BluetoothOffloadState a2dpOffloadFlag)374 int32_t AudioA2dpOffloadManager::HandleA2dpDeviceInOffload(BluetoothOffloadState a2dpOffloadFlag)
375 {
376 #ifdef BLUETOOTH_ENABLE
377 AUDIO_INFO_LOG("a2dpOffloadFlag change from %{public}d to %{public}d", GetA2dpOffloadFlag(), a2dpOffloadFlag);
378 SetA2dpOffloadFlag(a2dpOffloadFlag);
379 GetA2dpOffloadCodecAndSendToDsp();
380 std::vector<int32_t> allSessions;
381 GetAllRunningStreamSession(allSessions);
382 OffloadStartPlaying(allSessions);
383
384 DeviceType dev = audioActiveDevice_.GetCurrentOutputDeviceType();
385 AudioPolicyUtils::GetInstance().UpdateEffectDefaultSink(dev);
386 AUDIO_INFO_LOG("Handle A2dpDevice In Offload");
387 AudioServerProxy::GetInstance().UpdateEffectBtOffloadSupportedProxy(true);
388
389 if (IsA2dpOffloadConnected()) {
390 AUDIO_INFO_LOG("A2dpOffload has been connected, Fetch stream");
391 FetchStreamForA2dpOffload(true);
392 }
393 return SUCCESS;
394 #else
395 return ERROR;
396 #endif
397 }
398
GetA2dpOffloadCodecAndSendToDsp()399 void AudioA2dpOffloadManager::GetA2dpOffloadCodecAndSendToDsp()
400 {
401 #ifdef BLUETOOTH_ENABLE
402 if (audioActiveDevice_.GetCurrentOutputDeviceType() != DEVICE_TYPE_BLUETOOTH_A2DP) {
403 return;
404 }
405 Bluetooth::BluetoothRemoteDevice bluetoothRemoteDevice_
406 = Bluetooth::AudioA2dpManager::GetCurrentActiveA2dpDevice();
407 Bluetooth::A2dpOffloadCodecStatus offloadCodeStatus = Bluetooth::A2dpSource::GetProfile()->
408 GetOffloadCodecStatus(bluetoothRemoteDevice_);
409 std::string key = "AUDIO_EXT_PARAM_KEY_A2DP_OFFLOAD_CONFIG";
410 std::string value = std::to_string(offloadCodeStatus.offloadInfo.mediaPacketHeader) + ","
411 + std::to_string(offloadCodeStatus.offloadInfo.mPt) + ","
412 + std::to_string(offloadCodeStatus.offloadInfo.ssrc) + ","
413 + std::to_string(offloadCodeStatus.offloadInfo.boundaryFlag) + ","
414 + std::to_string(offloadCodeStatus.offloadInfo.broadcastFlag) + ","
415 + std::to_string(offloadCodeStatus.offloadInfo.codecType) + ","
416 + std::to_string(offloadCodeStatus.offloadInfo.maxLatency) + ","
417 + std::to_string(offloadCodeStatus.offloadInfo.scmsTEnable) + ","
418 + std::to_string(offloadCodeStatus.offloadInfo.sampleRate) + ","
419 + std::to_string(offloadCodeStatus.offloadInfo.encodedAudioBitrate) + ","
420 + std::to_string(offloadCodeStatus.offloadInfo.bitsPerSample) + ","
421 + std::to_string(offloadCodeStatus.offloadInfo.chMode) + ","
422 + std::to_string(offloadCodeStatus.offloadInfo.aclHdl) + ","
423 + std::to_string(offloadCodeStatus.offloadInfo.l2cRcid) + ","
424 + std::to_string(offloadCodeStatus.offloadInfo.mtu) + ","
425 + std::to_string(offloadCodeStatus.offloadInfo.codecSpecific0) + ","
426 + std::to_string(offloadCodeStatus.offloadInfo.codecSpecific1) + ","
427 + std::to_string(offloadCodeStatus.offloadInfo.codecSpecific2) + ","
428 + std::to_string(offloadCodeStatus.offloadInfo.codecSpecific3) + ","
429 + std::to_string(offloadCodeStatus.offloadInfo.codecSpecific4) + ","
430 + std::to_string(offloadCodeStatus.offloadInfo.codecSpecific5) + ","
431 + std::to_string(offloadCodeStatus.offloadInfo.codecSpecific6) + ","
432 + std::to_string(offloadCodeStatus.offloadInfo.codecSpecific7) + ";";
433
434 AudioServerProxy::GetInstance().SetAudioParameterProxy(key, value);
435 AUDIO_INFO_LOG("update offloadcodec[%{public}s]", value.c_str());
436 #endif
437 }
438
HandleActiveDevice(DeviceType deviceType)439 int32_t AudioA2dpOffloadManager::HandleActiveDevice(DeviceType deviceType)
440 {
441 DeviceType curOutputDeviceType = audioActiveDevice_.GetCurrentOutputDeviceType();
442 if (GetVolumeGroupType(curOutputDeviceType) != GetVolumeGroupType(deviceType)) {
443 audioVolumeManager_.SetVolumeForSwitchDevice(deviceType);
444 }
445 if (audioConfigManager_.GetUpdateRouteSupport()) {
446 audioActiveDevice_.UpdateActiveDeviceRoute(deviceType, DeviceFlag::OUTPUT_DEVICES_FLAG);
447 }
448 std::string sinkPortName = AudioPolicyUtils::GetInstance().GetSinkPortName(deviceType);
449 std::string sourcePortName = AudioPolicyUtils::GetInstance().GetSourcePortName(deviceType);
450 if (sinkPortName == PORT_NONE && sourcePortName == PORT_NONE) {
451 AUDIO_ERR_LOG("failed for sinkPortName and sourcePortName are none");
452 return ERR_OPERATION_FAILED;
453 }
454 if (sinkPortName != PORT_NONE) {
455 audioIOHandleMap_.GetSinkIOHandle(deviceType);
456 audioPolicyManager_.SuspendAudioDevice(sinkPortName, false);
457 }
458 if (sourcePortName != PORT_NONE) {
459 audioIOHandleMap_.GetSourceIOHandle(deviceType);
460 audioPolicyManager_.SuspendAudioDevice(sourcePortName, false);
461 }
462 audioActiveDevice_.UpdateInputDeviceInfo(deviceType);
463
464 return SUCCESS;
465 }
466
FetchStreamForA2dpOffload(const bool & requireReset)467 void AudioA2dpOffloadManager::FetchStreamForA2dpOffload(const bool &requireReset)
468 {
469 vector<shared_ptr<AudioRendererChangeInfo>> rendererChangeInfos;
470 streamCollector_.GetCurrentRendererChangeInfos(rendererChangeInfos);
471 AUDIO_INFO_LOG("FetchStreamForA2dpOffload start for %{public}zu stream", rendererChangeInfos.size());
472 for (auto &rendererChangeInfo : rendererChangeInfos) {
473 if (!audioDeviceCommon_.IsRendererStreamRunning(rendererChangeInfo)) {
474 continue;
475 }
476 vector<std::shared_ptr<AudioDeviceDescriptor>> descs =
477 audioRouterCenter_.FetchOutputDevices(rendererChangeInfo->rendererInfo.streamUsage,
478 rendererChangeInfo->clientUID);
479
480 if (descs.front()->deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP) {
481 if (requireReset) {
482 int32_t ret = audioDeviceCommon_.ActivateA2dpDevice(descs.front(), rendererChangeInfos);
483 CHECK_AND_RETURN_LOG(ret == SUCCESS, "activate a2dp [%{public}s] failed",
484 GetEncryptAddr(descs.front()->macAddress_).c_str());
485 std::string activePort = BLUETOOTH_SPEAKER;
486 audioPolicyManager_.SuspendAudioDevice(activePort, true);
487 }
488 if (rendererChangeInfo->rendererInfo.rendererFlags == AUDIO_FLAG_MMAP) {
489 AudioServerProxy::GetInstance().ResetAudioEndpointProxy();
490 }
491 audioDeviceCommon_.FetchStreamForA2dpMchStream(rendererChangeInfo, descs);
492 }
493 }
494 }
495
GetAllRunningStreamSession(std::vector<int32_t> & allSessions,bool doStop)496 void AudioA2dpOffloadManager::GetAllRunningStreamSession(std::vector<int32_t> &allSessions, bool doStop)
497 {
498 #ifdef BLUETOOTH_ENABLE
499 std::vector<std::shared_ptr<AudioRendererChangeInfo>> rendererChangeInfos;
500 streamCollector_.GetCurrentRendererChangeInfos(rendererChangeInfos);
501 std::vector<int32_t> stopPlayingStream(0);
502 for (auto &changeInfo : rendererChangeInfos) {
503 if (changeInfo->rendererState != RENDERER_RUNNING) {
504 if (doStop) {
505 stopPlayingStream.push_back(changeInfo->sessionId);
506 }
507 continue;
508 }
509 allSessions.push_back(changeInfo->sessionId);
510 }
511 if (doStop && stopPlayingStream.size() > 0) {
512 OffloadStopPlaying(stopPlayingStream);
513 }
514 #endif
515 }
516
GetVolumeGroupType(DeviceType deviceType)517 std::string AudioA2dpOffloadManager::GetVolumeGroupType(DeviceType deviceType)
518 {
519 std::string volumeGroupType = "";
520 switch (deviceType) {
521 case DEVICE_TYPE_EARPIECE:
522 case DEVICE_TYPE_SPEAKER:
523 case DEVICE_TYPE_DP:
524 case DEVICE_TYPE_HDMI:
525 volumeGroupType = "build-in";
526 break;
527 case DEVICE_TYPE_BLUETOOTH_A2DP:
528 case DEVICE_TYPE_BLUETOOTH_SCO:
529 volumeGroupType = "wireless";
530 break;
531 case DEVICE_TYPE_WIRED_HEADSET:
532 case DEVICE_TYPE_USB_HEADSET:
533 case DEVICE_TYPE_USB_ARM_HEADSET:
534 volumeGroupType = "wired";
535 break;
536 default:
537 AUDIO_ERR_LOG("device %{public}d is not supported", deviceType);
538 break;
539 }
540 return volumeGroupType;
541 }
542
543 }
544 }