1 /*
2 * Copyright (c) 2024-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 "AudioCapturerSession"
17 #endif
18
19 #include "audio_capturer_session.h"
20 #include <ability_manager_client.h>
21 #include "iservice_registry.h"
22 #include "parameter.h"
23 #include "parameters.h"
24 #include "audio_policy_log.h"
25
26 #include "audio_policy_utils.h"
27 #include "audio_core_service.h"
28 #include "audio_zone_service.h"
29 namespace {
30 #include "v5_0/iaudio_manager.h"
31 }
32
33 namespace OHOS {
34 namespace AudioStandard {
35 namespace {
36 const uint32_t PCM_8_BIT = 8;
37 const float RENDER_FRAME_INTERVAL_IN_SECONDS = 0.02;
38 const std::string PIPE_PRIMARY_INPUT = "primary_input";
39 const std::string PIPE_WAKEUP_INPUT = "wakeup_input";
40
41 inline const std::unordered_set<SourceType> specialSourceTypeSet_ = {
42 SOURCE_TYPE_PLAYBACK_CAPTURE,
43 SOURCE_TYPE_WAKEUP,
44 SOURCE_TYPE_VIRTUAL_CAPTURE,
45 SOURCE_TYPE_REMOTE_CAST
46 };
47
48 const std::map<SourceType, AudioInputType> FWKTYPE_TO_HDITYPE_MAP = {
49 { SOURCE_TYPE_INVALID, AUDIO_INPUT_DEFAULT_TYPE},
50 { SOURCE_TYPE_MIC, AUDIO_INPUT_MIC_TYPE},
51 { SOURCE_TYPE_PLAYBACK_CAPTURE, AUDIO_INPUT_MIC_TYPE},
52 { SOURCE_TYPE_ULTRASONIC, AUDIO_INPUT_MIC_TYPE},
53 { SOURCE_TYPE_WAKEUP, AUDIO_INPUT_SPEECH_WAKEUP_TYPE},
54 { SOURCE_TYPE_VOICE_TRANSCRIPTION, AUDIO_INPUT_VOICE_COMMUNICATION_TYPE},
55 { SOURCE_TYPE_VOICE_COMMUNICATION, AUDIO_INPUT_VOICE_COMMUNICATION_TYPE},
56 { SOURCE_TYPE_VOICE_RECOGNITION, AUDIO_INPUT_VOICE_RECOGNITION_TYPE},
57 { SOURCE_TYPE_VOICE_CALL, AUDIO_INPUT_VOICE_CALL_TYPE},
58 { SOURCE_TYPE_CAMCORDER, AUDIO_INPUT_CAMCORDER_TYPE},
59 { SOURCE_TYPE_EC, AUDIO_INPUT_EC_TYPE},
60 { SOURCE_TYPE_MIC_REF, AUDIO_INPUT_NOISE_REDUCTION_TYPE},
61 { SOURCE_TYPE_UNPROCESSED, AUDIO_INPUT_RAW_TYPE},
62 { SOURCE_TYPE_LIVE, AUDIO_INPUT_LIVE_TYPE},
63 };
64
ConvertToHDIAudioInputType(SourceType sourceType)65 uint32_t ConvertToHDIAudioInputType(SourceType sourceType)
66 {
67 if (FWKTYPE_TO_HDITYPE_MAP.find(sourceType) != FWKTYPE_TO_HDITYPE_MAP.end()) {
68 auto iter = FWKTYPE_TO_HDITYPE_MAP.find(sourceType);
69 return static_cast<uint32_t>(iter->second);
70 }
71
72 return static_cast<uint32_t>(AUDIO_INPUT_MIC_TYPE);
73 }
74
75 const std::map<SourceType, int> NORMAL_SOURCETYPE_PRIORITY = {
76 // from high to low
77 {SOURCE_TYPE_VOICE_CALL, 8},
78 {SOURCE_TYPE_VOICE_COMMUNICATION, 7},
79 {SOURCE_TYPE_VOICE_MESSAGE, 6},
80 {SOURCE_TYPE_LIVE, 5},
81 {SOURCE_TYPE_VOICE_RECOGNITION, 4},
82 {SOURCE_TYPE_VOICE_TRANSCRIPTION, 4},
83 {SOURCE_TYPE_MIC, 3},
84 {SOURCE_TYPE_CAMCORDER, 3},
85 {SOURCE_TYPE_UNPROCESSED, 2},
86 {SOURCE_TYPE_ULTRASONIC, 1},
87 {SOURCE_TYPE_INVALID, 0},
88 };
89
IsHigherPrioritySourceType(SourceType newSource,SourceType currentSource)90 bool IsHigherPrioritySourceType(SourceType newSource, SourceType currentSource)
91 {
92 AUDIO_INFO_LOG("newSource sourceType:%{public}d currentSource sourceType:%{public}d", newSource, currentSource);
93
94 if (!AudioEcManager::GetInstance().GetEcFeatureEnable() &&
95 (ConvertToHDIAudioInputType(newSource) == ConvertToHDIAudioInputType(currentSource))) {
96 return false;
97 }
98
99 auto newIter = NORMAL_SOURCETYPE_PRIORITY.find(newSource);
100 auto currIter = NORMAL_SOURCETYPE_PRIORITY.find(currentSource);
101 if (newIter == NORMAL_SOURCETYPE_PRIORITY.end() || currIter == NORMAL_SOURCETYPE_PRIORITY.end() ||
102 (newSource == currentSource)) {
103 return false;
104 }
105 return newIter->second >= currIter->second;
106 }
107 } // namespace
108
Init(std::shared_ptr<AudioA2dpOffloadManager> audioA2dpOffloadManager)109 void AudioCapturerSession::Init(std::shared_ptr<AudioA2dpOffloadManager> audioA2dpOffloadManager)
110 {
111 audioA2dpOffloadManager_ = audioA2dpOffloadManager;
112 }
113
DeInit()114 void AudioCapturerSession::DeInit()
115 {
116 audioA2dpOffloadManager_ = nullptr;
117 }
118
SetConfigParserFlag()119 void AudioCapturerSession::SetConfigParserFlag()
120 {
121 isPolicyConfigParsered_ = true;
122 }
123
LoadInnerCapturerSink(std::string moduleName,AudioStreamInfo streamInfo)124 void AudioCapturerSession::LoadInnerCapturerSink(std::string moduleName, AudioStreamInfo streamInfo)
125 {
126 #ifdef HAS_FEATURE_INNERCAPTURER
127 AUDIO_INFO_LOG("Start");
128 uint32_t bufferSize = streamInfo.samplingRate *
129 AudioPolicyUtils::GetInstance().PcmFormatToBytes(streamInfo.format) *
130 streamInfo.channels * RENDER_FRAME_INTERVAL_IN_SECONDS;
131
132 AudioModuleInfo moduleInfo = {};
133 moduleInfo.lib = "libmodule-inner-capturer-sink.z.so";
134 moduleInfo.format = AudioPolicyUtils::GetInstance().ConvertToHDIAudioFormat(streamInfo.format);
135 moduleInfo.name = moduleName;
136 moduleInfo.networkId = "LocalDevice";
137 moduleInfo.channels = std::to_string(streamInfo.channels);
138 moduleInfo.rate = std::to_string(streamInfo.samplingRate);
139 moduleInfo.bufferSize = std::to_string(bufferSize);
140
141 audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo);
142 #endif
143 }
144
UnloadInnerCapturerSink(std::string moduleName)145 void AudioCapturerSession::UnloadInnerCapturerSink(std::string moduleName)
146 {
147 #ifdef HAS_FEATURE_INNERCAPTURER
148 audioIOHandleMap_.ClosePortAndEraseIOHandle(moduleName);
149 #endif
150 }
151
HandleRemoteCastDevice(bool isConnected,AudioStreamInfo streamInfo)152 void AudioCapturerSession::HandleRemoteCastDevice(bool isConnected, AudioStreamInfo streamInfo)
153 {
154 #ifdef HAS_FEATURE_INNERCAPTURER
155 AUDIO_INFO_LOG("Is connected: %{public}d", isConnected);
156 AudioDeviceDescriptor updatedDesc = AudioDeviceDescriptor(DEVICE_TYPE_REMOTE_CAST,
157 AudioPolicyUtils::GetInstance().GetDeviceRole(DEVICE_TYPE_REMOTE_CAST));
158 std::vector<std::shared_ptr<AudioDeviceDescriptor>> descForCb = {};
159 if (isConnected) {
160 // If device already in list, remove it else do not modify the list
161 audioConnectedDevice_.DelConnectedDevice(updatedDesc.networkId_, updatedDesc.deviceType_,
162 updatedDesc.macAddress_);
163 audioDeviceCommon_.UpdateConnectedDevicesWhenConnecting(updatedDesc, descForCb);
164 LoadInnerCapturerSink(REMOTE_CAST_INNER_CAPTURER_SINK_NAME, streamInfo);
165 audioPolicyManager_.ResetRemoteCastDeviceVolume();
166 } else {
167 audioDeviceCommon_.UpdateConnectedDevicesWhenDisconnecting(updatedDesc, descForCb);
168 AudioCoreService::GetCoreService()->FetchOutputDeviceAndRoute("HandleRemoteCastDevice_1",
169 AudioStreamDeviceChangeReasonExt::ExtEnum::OLD_DEVICE_UNAVALIABLE_EXT);
170 UnloadInnerCapturerSink(REMOTE_CAST_INNER_CAPTURER_SINK_NAME);
171 }
172 // remove device from golbal when device has been added to audio zone in superlanch-dual
173 int32_t res = AudioZoneService::GetInstance().UpdateDeviceFromGlobalForAllZone(
174 audioConnectedDevice_.GetConnectedDeviceByType(LOCAL_NETWORK_ID, DEVICE_TYPE_REMOTE_CAST));
175 if (res == SUCCESS) {
176 AUDIO_INFO_LOG("Enable remotecast device for audio zone, remove from global list");
177 audioDeviceCommon_.UpdateConnectedDevicesWhenDisconnecting(updatedDesc, descForCb);
178 }
179 AudioCoreService::GetCoreService()->FetchOutputDeviceAndRoute("HandleRemoteCastDevice_2");
180 AudioCoreService::GetCoreService()->FetchInputDeviceAndRoute("HandleRemoteCastDevice_2");
181
182 // update a2dp offload
183 if (audioA2dpOffloadManager_) {
184 audioA2dpOffloadManager_->UpdateA2dpOffloadFlagForAllStream();
185 }
186 #endif
187 }
188
FindRunningNormalSession(uint32_t sessionId,AudioCapturerChangeInfo & runningSessionInfo)189 bool AudioCapturerSession::FindRunningNormalSession(uint32_t sessionId, AudioCapturerChangeInfo &runningSessionInfo)
190 {
191 bool hasSession = false;
192 SourceType tmpSource = SOURCE_TYPE_INVALID;
193 AudioStreamCollector &streamCollector = AudioStreamCollector::GetAudioStreamCollector();
194 std::vector<std::shared_ptr<AudioCapturerChangeInfo>> capturerChangeInfos;
195 streamCollector.GetCurrentCapturerChangeInfos(capturerChangeInfos);
196
197 for (const auto &info : capturerChangeInfos) {
198 if (!info || sessionWithNormalSourceType_.find(info->sessionId) == sessionWithNormalSourceType_.end()) {
199 continue;
200 }
201 tmpSource = sessionWithNormalSourceType_[info->sessionId].sourceType;
202 if (info->capturerState != CAPTURER_RUNNING || static_cast<uint32_t>(info->sessionId) == sessionId ||
203 specialSourceTypeSet_.count(tmpSource) != 0) {
204 continue;
205 }
206 if (IsHigherPrioritySourceType(tmpSource, runningSessionInfo.capturerInfo.sourceType)) {
207 hasSession = true;
208 runningSessionInfo = *info;
209 }
210 }
211
212 AUDIO_INFO_LOG("find ret: %{public}d, session: %{public}d, sourceType: %{public}d",
213 static_cast<int32_t>(hasSession), runningSessionInfo.sessionId, runningSessionInfo.capturerInfo.sourceType);
214
215 return hasSession;
216 }
217
ReloadCaptureSessionSoftLink()218 int32_t AudioCapturerSession::ReloadCaptureSessionSoftLink()
219 {
220 std::lock_guard<std::mutex> lock(onCapturerSessionChangedMutex_);
221 bool hasSession = false;
222 auto pipes = AudioPipeManager::GetPipeManager()->GetPipeList();
223 if (pipes.empty()) {
224 AUDIO_ERR_LOG("pipes invalid");
225 return hasSession;
226 }
227 AudioStreamDescriptor targetStream;
228 for (auto pipe : pipes) {
229 if (pipe == nullptr || pipe->streamDescriptors_.empty()) {
230 AUDIO_WARNING_LOG("pipe invalid");
231 continue;
232 }
233 if (pipe->pipeRole_ == AudioPipeRole::PIPE_ROLE_OUTPUT || (pipe->routeFlag_ & AUDIO_INPUT_FLAG_FAST) != 0) {
234 AUDIO_INFO_LOG("ignore pipe for pipeRole_: %{public}d, routeFlag_: %{public}d",
235 pipe->pipeRole_, pipe->routeFlag_);
236 continue;
237 }
238 for (auto streamDescriptor : pipe->streamDescriptors_) {
239 if (streamDescriptor == nullptr ||
240 sessionWithNormalSourceType_.find(streamDescriptor->sessionId_) ==
241 sessionWithNormalSourceType_.end()) {
242 AUDIO_WARNING_LOG("streamDescriptor invalid");
243 continue;
244 }
245 SourceType higherSourceType = sessionWithNormalSourceType_[streamDescriptor->sessionId_].sourceType;
246 if (streamDescriptor->streamStatus_ != AudioStreamStatus::STREAM_STATUS_STARTED ||
247 specialSourceTypeSet_.count(higherSourceType) != 0) {
248 continue;
249 }
250 if (IsHigherPrioritySourceType(higherSourceType, targetStream.capturerInfo_.sourceType)) {
251 hasSession = true;
252 targetStream = *streamDescriptor;
253 }
254 }
255 }
256
257 CHECK_AND_RETURN_RET_LOG(hasSession, ERROR, "no need to reload session");
258 AUDIO_INFO_LOG("start reload session: %{public}u", targetStream.sessionId_);
259
260 audioEcManager_.ReloadSourceForSession(sessionWithNormalSourceType_[targetStream.sessionId_]);
261 audioEcManager_.SetOpenedNormalSourceSessionId(targetStream.sessionId_);
262 return SUCCESS;
263 }
264
ReloadCaptureSession(uint32_t sessionId,SessionOperation operation)265 int32_t AudioCapturerSession::ReloadCaptureSession(uint32_t sessionId, SessionOperation operation)
266 {
267 AUDIO_INFO_LOG("prepare reload session: %{public}u with operation: %{public}d", sessionId, operation);
268 std::lock_guard<std::mutex> lock(onCapturerSessionChangedMutex_);
269 uint32_t targetSessionId = sessionId;
270 AudioCapturerChangeInfo runningSessionInfo = {};
271 bool needReload = false;
272
273 if (sessionWithNormalSourceType_.count(sessionId) == 0 ||
274 (specialSourceTypeSet_.count(sessionWithNormalSourceType_[sessionId].sourceType) != 0)) {
275 AUDIO_ERR_LOG("sessionId error!");
276 return ERROR;
277 }
278
279 SessionInfo targetSession = sessionWithNormalSourceType_[sessionId];
280 bool findRunningSessionRet = FindRunningNormalSession(targetSessionId, runningSessionInfo);
281 switch (operation) {
282 case SESSION_OPERATION_START:
283 if (findRunningSessionRet &&
284 IsHigherPrioritySourceType(targetSession.sourceType, runningSessionInfo.capturerInfo.sourceType)) {
285 needReload = true;
286 } else if (!findRunningSessionRet && (audioEcManager_.GetSourceOpened() != targetSession.sourceType)) {
287 needReload = true;
288 }
289 break;
290 case SESSION_OPERATION_PAUSE:
291 case SESSION_OPERATION_STOP:
292 if (findRunningSessionRet && (targetSession.sourceType == audioEcManager_.GetSourceOpened())) {
293 needReload = true;
294 targetSessionId = static_cast<uint32_t>(runningSessionInfo.sessionId);
295 targetSession = sessionWithNormalSourceType_[targetSessionId];
296 }
297 break;
298 default:
299 AUDIO_ERR_LOG("operation parameter error!");
300 break;
301 }
302
303 CHECK_AND_RETURN_RET_LOG(needReload, ERROR, "no need to reload session");
304 AUDIO_INFO_LOG("start reload session: %{public}u", targetSessionId);
305 audioEcManager_.ReloadSourceForSession(targetSession);
306 audioEcManager_.SetOpenedNormalSourceSessionId(targetSessionId);
307
308 return SUCCESS;
309 }
310
OnCapturerSessionAdded(uint64_t sessionID,SessionInfo sessionInfo,AudioStreamInfo streamInfo)311 int32_t AudioCapturerSession::OnCapturerSessionAdded(uint64_t sessionID, SessionInfo sessionInfo,
312 AudioStreamInfo streamInfo)
313 {
314 std::lock_guard<std::mutex> lock(onCapturerSessionChangedMutex_);
315 AUDIO_INFO_LOG("sessionID: %{public}" PRIu64 " source: %{public}d", sessionID, sessionInfo.sourceType);
316 CHECK_AND_RETURN_RET_LOG(isPolicyConfigParsered_ && audioVolumeManager_.GetLoadFlag(), ERROR,
317 "policyConfig not loaded");
318
319 if (sessionIdisRemovedSet_.count(sessionID) > 0) {
320 sessionIdisRemovedSet_.erase(sessionID);
321 AUDIO_INFO_LOG("sessionID: %{public}" PRIu64 " had already been removed earlier", sessionID);
322 return SUCCESS;
323 }
324 if (specialSourceTypeSet_.count(sessionInfo.sourceType) == 0) {
325 if (audioEcManager_.GetSourceOpened() == SOURCE_TYPE_INVALID) {
326 // normal source is not opened before -- it should not be happen!!
327 AUDIO_WARNING_LOG("Record route should not be opened here!");
328 return SUCCESS;
329 }
330 sessionWithNormalSourceType_[sessionID] = sessionInfo;
331 } else if (sessionInfo.sourceType == SOURCE_TYPE_REMOTE_CAST) {
332 HandleRemoteCastDevice(true, streamInfo);
333 sessionWithSpecialSourceType_[sessionID] = sessionInfo;
334 } else {
335 sessionWithSpecialSourceType_[sessionID] = sessionInfo;
336 }
337 return SUCCESS;
338 }
339
OnCapturerSessionRemoved(uint64_t sessionID)340 void AudioCapturerSession::OnCapturerSessionRemoved(uint64_t sessionID)
341 {
342 std::lock_guard<std::mutex> lock(onCapturerSessionChangedMutex_);
343 AUDIO_INFO_LOG("sessionid:%{public}" PRIu64, sessionID);
344 if (sessionWithSpecialSourceType_.count(sessionID) > 0) {
345 if (sessionWithSpecialSourceType_[sessionID].sourceType == SOURCE_TYPE_REMOTE_CAST) {
346 HandleRemoteCastDevice(false);
347 }
348 sessionWithSpecialSourceType_.erase(sessionID);
349 return;
350 }
351
352 if (sessionWithNormalSourceType_.count(sessionID) > 0) {
353 if (sessionWithNormalSourceType_[sessionID].sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) {
354 audioEcManager_.ResetAudioEcInfo();
355 }
356 sessionWithNormalSourceType_.erase(sessionID);
357 if (!sessionWithNormalSourceType_.empty()) {
358 return;
359 }
360 // close source when all capturer sessions removed
361 audioEcManager_.CloseNormalSource();
362 return;
363 }
364
365 AUDIO_INFO_LOG("Sessionid:%{public}" PRIu64 " not added, directly placed into sessionIdisRemovedSet_", sessionID);
366 sessionIdisRemovedSet_.insert(sessionID);
367 }
368
ConstructWakeupAudioModuleInfo(const AudioStreamInfo & streamInfo,AudioModuleInfo & audioModuleInfo)369 bool AudioCapturerSession::ConstructWakeupAudioModuleInfo(const AudioStreamInfo &streamInfo,
370 AudioModuleInfo &audioModuleInfo)
371 {
372 if (!audioConfigManager_.GetAdapterInfoFlag()) {
373 return false;
374 }
375
376 std::shared_ptr<PolicyAdapterInfo> info;
377 AudioAdapterType type = static_cast<AudioAdapterType>(AudioPolicyUtils::portStrToEnum[std::string(PRIMARY_WAKEUP)]);
378 bool ret = audioConfigManager_.GetAdapterInfoByType(type, info);
379 if (!ret) {
380 AUDIO_ERR_LOG("can not find adapter info");
381 return false;
382 }
383
384 std::shared_ptr<AdapterPipeInfo> pipeInfo = info->GetPipeInfoByName(PIPE_WAKEUP_INPUT);
385 if (pipeInfo == nullptr) {
386 AUDIO_ERR_LOG("wakeup pipe info is nullptr");
387 return false;
388 }
389
390 if (!FillWakeupStreamPropInfo(streamInfo, pipeInfo, audioModuleInfo)) {
391 AUDIO_ERR_LOG("failed to fill pipe stream prop info");
392 return false;
393 }
394
395 audioModuleInfo.adapterName = info->adapterName;
396 audioModuleInfo.name = pipeInfo->paProp_.moduleName_;
397 audioModuleInfo.lib = pipeInfo->paProp_.lib_;
398 audioModuleInfo.networkId = "LocalDevice";
399 audioModuleInfo.className = "primary";
400 audioModuleInfo.fileName = "";
401 audioModuleInfo.OpenMicSpeaker = "1";
402 audioModuleInfo.sourceType = std::to_string(SourceType::SOURCE_TYPE_WAKEUP);
403
404 AUDIO_INFO_LOG("wakeup auido module info, adapter name:%{public}s, name:%{public}s, lib:%{public}s",
405 audioModuleInfo.adapterName.c_str(), audioModuleInfo.name.c_str(), audioModuleInfo.lib.c_str());
406 return true;
407 }
408
SetWakeUpAudioCapturer(InternalAudioCapturerOptions options)409 int32_t AudioCapturerSession::SetWakeUpAudioCapturer(InternalAudioCapturerOptions options)
410 {
411 AUDIO_INFO_LOG("set wakeup audio capturer start");
412 AudioModuleInfo moduleInfo = {};
413 if (!ConstructWakeupAudioModuleInfo(options.streamInfo, moduleInfo)) {
414 AUDIO_ERR_LOG("failed to construct wakeup audio module info");
415 return ERROR;
416 }
417 audioIOHandleMap_.OpenPortAndInsertIOHandle(moduleInfo.name, moduleInfo);
418
419 AUDIO_DEBUG_LOG("set wakeup audio capturer end");
420 return SUCCESS;
421 }
422
SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig & config)423 int32_t AudioCapturerSession::SetWakeUpAudioCapturerFromAudioServer(const AudioProcessConfig &config)
424 {
425 InternalAudioCapturerOptions capturerOptions;
426 capturerOptions.streamInfo = config.streamInfo;
427 return SetWakeUpAudioCapturer(capturerOptions);
428 }
429
CloseWakeUpAudioCapturer()430 int32_t AudioCapturerSession::CloseWakeUpAudioCapturer()
431 {
432 AUDIO_INFO_LOG("close wakeup audio capturer start");
433 return audioIOHandleMap_.ClosePortAndEraseIOHandle(std::string(PRIMARY_WAKEUP));
434 }
435
436 // private method
FillWakeupStreamPropInfo(const AudioStreamInfo & streamInfo,std::shared_ptr<AdapterPipeInfo> pipeInfo,AudioModuleInfo & audioModuleInfo)437 bool AudioCapturerSession::FillWakeupStreamPropInfo(const AudioStreamInfo &streamInfo,
438 std::shared_ptr<AdapterPipeInfo> pipeInfo, AudioModuleInfo &audioModuleInfo)
439 {
440 if (pipeInfo == nullptr) {
441 AUDIO_ERR_LOG("wakeup pipe info is nullptr");
442 return false;
443 }
444
445 if (pipeInfo->streamPropInfos_.size() == 0) {
446 AUDIO_ERR_LOG("no stream prop info");
447 return false;
448 }
449
450 auto targetIt = *pipeInfo->streamPropInfos_.begin();
451 for (auto it : pipeInfo->streamPropInfos_) {
452 if (it -> channels_ == static_cast<uint32_t>(streamInfo.channels)) {
453 targetIt = it;
454 break;
455 }
456 }
457
458 audioModuleInfo.format = AudioDefinitionPolicyUtils::enumToFormatStr[targetIt->format_];
459 audioModuleInfo.channels = std::to_string(targetIt->channels_);
460 audioModuleInfo.rate = std::to_string(targetIt->sampleRate_);
461 audioModuleInfo.bufferSize = std::to_string(targetIt->bufferSize_);
462
463 AUDIO_INFO_LOG("stream prop info, format:%{public}s, channels:%{public}s, rate:%{public}s, buffer size:%{public}s",
464 audioModuleInfo.format.c_str(), audioModuleInfo.channels.c_str(),
465 audioModuleInfo.rate.c_str(), audioModuleInfo.bufferSize.c_str());
466 return true;
467 }
468
IsVoipDeviceChanged(const AudioDeviceDescriptor & inputDevice,const AudioDeviceDescriptor & outputDevice)469 bool AudioCapturerSession::IsVoipDeviceChanged(const AudioDeviceDescriptor &inputDevice,
470 const AudioDeviceDescriptor &outputDevice)
471 {
472 AudioDeviceDescriptor realInputDevice = inputDevice;
473 AudioDeviceDescriptor realOutputDevice = outputDevice;
474 shared_ptr<AudioDeviceDescriptor> inputDesc =
475 audioRouterCenter_.FetchInputDevice(SOURCE_TYPE_VOICE_COMMUNICATION, -1);
476 if (inputDesc != nullptr) {
477 realInputDevice = *inputDesc;
478 }
479 vector<std::shared_ptr<AudioDeviceDescriptor>> outputDesc =
480 audioRouterCenter_.FetchOutputDevices(STREAM_USAGE_VOICE_COMMUNICATION, -1, "IsVoipDeviceChanged");
481 if (outputDesc.size() > 0 && outputDesc.front() != nullptr) {
482 realOutputDevice = *outputDesc.front();
483 }
484 if (!inputDevice.IsSameDeviceDesc(realInputDevice) || !outputDevice.IsSameDeviceDesc(realOutputDevice)) {
485 AUDIO_INFO_LOG("target device is not ready, so ignore reload");
486 return false;
487 }
488 AudioEcInfo lastEcInfo = audioEcManager_.GetAudioEcInfo();
489 AUDIO_INFO_LOG("curInDevice: %{public}d, curOutDevice: %{public}d", lastEcInfo.inputDevice.deviceType_,
490 lastEcInfo.outputDevice.deviceType_);
491 if (!lastEcInfo.inputDevice.IsSameDeviceDesc(realInputDevice) ||
492 !lastEcInfo.outputDevice.IsSameDeviceDesc(realOutputDevice)) {
493 return true;
494 }
495 return false;
496 }
497
ReloadSourceForDeviceChange(const AudioDeviceDescriptor & inputDevice,const AudioDeviceDescriptor & outputDevice,const std::string & caller)498 void AudioCapturerSession::ReloadSourceForDeviceChange(const AudioDeviceDescriptor &inputDevice,
499 const AudioDeviceDescriptor &outputDevice, const std::string &caller)
500 {
501 std::lock_guard<std::mutex> lock(onCapturerSessionChangedMutex_);
502 AUDIO_INFO_LOG("form caller: %{public}s, inDevice: %{public}d, outDevice: %{public}d", caller.c_str(),
503 inputDevice.deviceType_, outputDevice.deviceType_);
504 if (!audioEcManager_.GetEcFeatureEnable()) {
505 AUDIO_INFO_LOG("reload ignore for feature not enable");
506 return;
507 }
508 SourceType normalSourceOpened = audioEcManager_.GetSourceOpened();
509 if (normalSourceOpened != SOURCE_TYPE_VOICE_COMMUNICATION && normalSourceOpened != SOURCE_TYPE_MIC) {
510 AUDIO_INFO_LOG("reload ignore for source not voip or mic");
511 return;
512 }
513
514 if (normalSourceOpened == SOURCE_TYPE_VOICE_COMMUNICATION) {
515 if (!IsVoipDeviceChanged(inputDevice, outputDevice)) {
516 AUDIO_INFO_LOG("voip reload ignore for device not change");
517 return;
518 }
519 } else {
520 if (inputDevice.deviceType_ != DEVICE_TYPE_DEFAULT &&
521 GetInputDeviceTypeForReload().deviceType_ == DEVICE_TYPE_DEFAULT) {
522 SetInputDeviceTypeForReload(inputDevice);
523 AUDIO_INFO_LOG("mic source reload ignore for inputDeviceForReload_ not update");
524 return;
525 }
526 if (inputDevice.deviceType_ == DEVICE_TYPE_DEFAULT ||
527 inputDevice.IsSameDeviceDesc(GetInputDeviceTypeForReload())) {
528 AUDIO_INFO_LOG("mic source reload ignore for device not changed");
529 return;
530 }
531 }
532
533 // reload for device change, used session is not changed
534 uint64_t sessionId = audioEcManager_.GetOpenedNormalSourceSessionId();
535 if (sessionWithNormalSourceType_.find(sessionId) == sessionWithNormalSourceType_.end()) {
536 AUDIO_ERR_LOG("target session: %{public}" PRIu64 " not found", sessionId);
537 return;
538 }
539 SetInputDeviceTypeForReload(inputDevice);
540 AUDIO_INFO_LOG("start reload session: %{public}" PRIu64 " for device change", sessionId);
541 audioEcManager_.ReloadSourceForSession(sessionWithNormalSourceType_[sessionId]);
542 }
543
SetInputDeviceTypeForReload(const AudioDeviceDescriptor & inputDevice)544 void AudioCapturerSession::SetInputDeviceTypeForReload(const AudioDeviceDescriptor &inputDevice)
545 {
546 std::lock_guard<std::mutex> lock(inputDeviceReloadMutex_);
547 inputDeviceForReload_ = inputDevice;
548 }
549
GetInputDeviceTypeForReload()550 const AudioDeviceDescriptor& AudioCapturerSession::GetInputDeviceTypeForReload()
551 {
552 std::lock_guard<std::mutex> lock(inputDeviceReloadMutex_);
553 return inputDeviceForReload_;
554 }
555
GetEnhancePropByNameV3(const AudioEffectPropertyArrayV3 & propertyArray,const std::string & propName)556 std::string AudioCapturerSession::GetEnhancePropByNameV3(const AudioEffectPropertyArrayV3 &propertyArray,
557 const std::string &propName)
558 {
559 std::string propValue = "";
560 auto iter = std::find_if(propertyArray.property.begin(), propertyArray.property.end(),
561 [&propName](const AudioEffectPropertyV3 &prop) {
562 return prop.name == propName;
563 });
564 if (iter != propertyArray.property.end()) {
565 propValue = iter->category;
566 }
567 return propValue;
568 }
569
ReloadSourceForEffect(const AudioEffectPropertyArrayV3 & oldPropertyArray,const AudioEffectPropertyArrayV3 & newPropertyArray)570 void AudioCapturerSession::ReloadSourceForEffect(const AudioEffectPropertyArrayV3 &oldPropertyArray,
571 const AudioEffectPropertyArrayV3 &newPropertyArray)
572 {
573 if (!audioEcManager_.GetMicRefFeatureEnable()) {
574 AUDIO_INFO_LOG("reload ignore for feature not enable");
575 return;
576 }
577 if (audioEcManager_.GetSourceOpened() != SOURCE_TYPE_VOICE_COMMUNICATION &&
578 audioEcManager_.GetSourceOpened() != SOURCE_TYPE_MIC) {
579 AUDIO_INFO_LOG("reload ignore for source not voip or record");
580 return;
581 }
582 std::string oldRecordProp = GetEnhancePropByNameV3(oldPropertyArray, "record");
583 std::string oldVoipUpProp = GetEnhancePropByNameV3(oldPropertyArray, "voip_up");
584 std::string newRecordProp = GetEnhancePropByNameV3(newPropertyArray, "record");
585 std::string newVoipUpProp = GetEnhancePropByNameV3(newPropertyArray, "voip_up");
586 std::lock_guard<std::mutex> lock(onCapturerSessionChangedMutex_);
587 if ((!newVoipUpProp.empty() && ((oldVoipUpProp == "PNR") ^ (newVoipUpProp == "PNR"))) ||
588 (!newRecordProp.empty() && oldRecordProp != newRecordProp)) {
589 uint64_t sessionId = audioEcManager_.GetOpenedNormalSourceSessionId();
590 AUDIO_INFO_LOG("start reload session: %{public}" PRIu64 " for effect change", sessionId);
591 audioEcManager_.ReloadSourceForSession(sessionWithNormalSourceType_[sessionId]);
592 }
593 }
594
GetEnhancePropByName(const AudioEnhancePropertyArray & propertyArray,const std::string & propName)595 std::string AudioCapturerSession::GetEnhancePropByName(const AudioEnhancePropertyArray &propertyArray,
596 const std::string &propName)
597 {
598 std::string propValue = "";
599 auto iter = std::find_if(propertyArray.property.begin(), propertyArray.property.end(),
600 [&propName](const AudioEnhanceProperty &prop) {
601 return prop.enhanceClass == propName;
602 });
603 if (iter != propertyArray.property.end()) {
604 propValue = iter->enhanceProp;
605 }
606 return propValue;
607 }
608
ReloadSourceForEffect(const AudioEnhancePropertyArray & oldPropertyArray,const AudioEnhancePropertyArray & newPropertyArray)609 void AudioCapturerSession::ReloadSourceForEffect(const AudioEnhancePropertyArray &oldPropertyArray,
610 const AudioEnhancePropertyArray &newPropertyArray)
611 {
612 if (!audioEcManager_.GetMicRefFeatureEnable()) {
613 AUDIO_INFO_LOG("reload ignore for feature not enable");
614 return;
615 }
616 if (audioEcManager_.GetSourceOpened() != SOURCE_TYPE_VOICE_COMMUNICATION &&
617 audioEcManager_.GetSourceOpened() != SOURCE_TYPE_MIC) {
618 AUDIO_INFO_LOG("reload ignore for source not voip or record");
619 return;
620 }
621 std::string oldRecordProp = GetEnhancePropByName(oldPropertyArray, "record");
622 std::string oldVoipUpProp = GetEnhancePropByName(oldPropertyArray, "voip_up");
623 std::string newRecordProp = GetEnhancePropByName(newPropertyArray, "record");
624 std::string newVoipUpProp = GetEnhancePropByName(newPropertyArray, "voip_up");
625 std::lock_guard<std::mutex> lock(onCapturerSessionChangedMutex_);
626 if ((!newVoipUpProp.empty() && ((oldVoipUpProp == "PNR") ^ (newVoipUpProp == "PNR"))) ||
627 (!newRecordProp.empty() && oldRecordProp != newRecordProp)) {
628 uint64_t sessionId = audioEcManager_.GetOpenedNormalSourceSessionId();
629 AUDIO_INFO_LOG("start reload session: %{public}" PRIu64 " for enhance effect change", sessionId);
630 audioEcManager_.ReloadSourceForSession(sessionWithNormalSourceType_[sessionId]);
631 }
632 }
633
634 }
635 }
636