• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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