• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "AudioService"
17 #endif
18 
19 #include "audio_service.h"
20 
21 #include <thread>
22 
23 #include "ipc_skeleton.h"
24 #include "audio_errors.h"
25 #include "audio_common_log.h"
26 #include "audio_utils.h"
27 #include "policy_handler.h"
28 #include "ipc_stream_in_server.h"
29 #include "audio_capturer_source.h"
30 #include "audio_volume.h"
31 
32 namespace OHOS {
33 namespace AudioStandard {
34 
35 static uint64_t g_id = 1;
36 static const uint32_t NORMAL_ENDPOINT_RELEASE_DELAY_TIME = 10000; // 10ms
37 static const uint32_t A2DP_ENDPOINT_RELEASE_DELAY_TIME = 3000; // 3ms
38 static const uint32_t VOIP_ENDPOINT_RELEASE_DELAY_TIME = 200; // 200ms
39 static const uint32_t A2DP_ENDPOINT_RE_CREATE_RELEASE_DELAY_TIME = 200; // 200ms
40 static const int32_t INVALID_APP_UID = -1;
41 static const int32_t INVALID_APP_CREATED_AUDIO_STREAM_NUM = -1;
42 static const int32_t MEDIA_SERVICE_UID = 1013;
43 
GetInstance()44 AudioService *AudioService::GetInstance()
45 {
46     static AudioService AudioService;
47 
48     return &AudioService;
49 }
50 
AudioService()51 AudioService::AudioService()
52 {
53     AUDIO_INFO_LOG("AudioService()");
54 }
55 
~AudioService()56 AudioService::~AudioService()
57 {
58     AUDIO_INFO_LOG("~AudioService()");
59 }
60 
OnProcessRelease(IAudioProcessStream * process,bool isSwitchStream)61 int32_t AudioService::OnProcessRelease(IAudioProcessStream *process, bool isSwitchStream)
62 {
63     std::lock_guard<std::mutex> processListLock(processListMutex_);
64     bool isFind = false;
65     int32_t ret = ERROR;
66     auto paired = linkedPairedList_.begin();
67     std::string endpointName;
68     bool needRelease = false;
69     int32_t delayTime = NORMAL_ENDPOINT_RELEASE_DELAY_TIME;
70     while (paired != linkedPairedList_.end()) {
71         if ((*paired).first == process) {
72             AUDIO_INFO_LOG("SessionId %{public}u", (*paired).first->GetSessionId());
73             auto processConfig = process->GetAudioProcessConfig();
74             if (processConfig.audioMode == AUDIO_MODE_PLAYBACK) {
75                 SetDecMaxRendererStreamCnt();
76                 CleanAppUseNumMap(processConfig.appInfo.appUid);
77             }
78             if (!isSwitchStream) {
79                 AUDIO_INFO_LOG("is not switch stream, remove from mutedSessions_");
80                 RemoveIdFromMuteControlSet((*paired).first->GetSessionId());
81             }
82             ret = UnlinkProcessToEndpoint((*paired).first, (*paired).second);
83             if ((*paired).second->GetStatus() == AudioEndpoint::EndpointStatus::UNLINKED) {
84                 needRelease = true;
85                 endpointName = (*paired).second->GetEndpointName();
86                 delayTime = GetReleaseDelayTime((*paired).second, isSwitchStream);
87             }
88             linkedPairedList_.erase(paired);
89             isFind = true;
90             break;
91         } else {
92             paired++;
93         }
94     }
95     if (isFind) {
96         AUDIO_INFO_LOG("find and release process result %{public}d", ret);
97     } else {
98         AUDIO_INFO_LOG("can not find target process, maybe already released.");
99     }
100 
101     if (needRelease) {
102         ReleaseProcess(endpointName, delayTime);
103     }
104 
105     return SUCCESS;
106 }
107 
ReleaseProcess(const std::string endpointName,const int32_t delayTime)108 void AudioService::ReleaseProcess(const std::string endpointName, const int32_t delayTime)
109 {
110     AUDIO_INFO_LOG("find endpoint unlink, call delay release.");
111     std::unique_lock<std::mutex> lock(releaseEndpointMutex_);
112     releasingEndpointSet_.insert(endpointName);
113     auto releaseMidpointThread = [this, endpointName, delayTime] () {
114         this->DelayCallReleaseEndpoint(endpointName, delayTime);
115     };
116     std::thread releaseEndpointThread(releaseMidpointThread);
117     releaseEndpointThread.detach();
118 }
119 
GetReleaseDelayTime(std::shared_ptr<AudioEndpoint> endpoint,bool isSwitchStream)120 int32_t AudioService::GetReleaseDelayTime(std::shared_ptr<AudioEndpoint> endpoint, bool isSwitchStream)
121 {
122     if (endpoint->GetEndpointType()  == AudioEndpoint::EndpointType::TYPE_VOIP_MMAP) {
123         return VOIP_ENDPOINT_RELEASE_DELAY_TIME;
124     }
125 
126     if (endpoint->GetDeviceInfo().deviceType != DEVICE_TYPE_BLUETOOTH_A2DP) {
127         return NORMAL_ENDPOINT_RELEASE_DELAY_TIME;
128     }
129     if (!isSwitchStream) {
130         return A2DP_ENDPOINT_RELEASE_DELAY_TIME;
131     }
132     // The delay for destruction and reconstruction cannot be set to 0, otherwise there may be a problem:
133     // An endpoint exists at check process, but it may be destroyed immediately - during the re-create process
134     return A2DP_ENDPOINT_RE_CREATE_RELEASE_DELAY_TIME;
135 }
136 
GetIpcStream(const AudioProcessConfig & config,int32_t & ret)137 sptr<IpcStreamInServer> AudioService::GetIpcStream(const AudioProcessConfig &config, int32_t &ret)
138 {
139     Trace trace("AudioService::GetIpcStream");
140     if (innerCapturerMgr_ == nullptr) {
141         innerCapturerMgr_ = PlaybackCapturerManager::GetInstance(); // As mgr is a singleton, lock is needless here.
142         innerCapturerMgr_->RegisterCapturerFilterListener(this);
143     }
144 
145     // in plan: GetDeviceInfoForProcess(config) and stream limit check
146     // in plan: call GetProcessDeviceInfo to load inner-cap-sink
147     sptr<IpcStreamInServer> ipcStreamInServer = IpcStreamInServer::Create(config, ret);
148 
149     // in plan: Put playback into list, check if EnableInnerCap is need.
150     if (ipcStreamInServer != nullptr && config.audioMode == AUDIO_MODE_PLAYBACK) {
151         uint32_t sessionId = 0;
152         std::shared_ptr<RendererInServer> renderer = ipcStreamInServer->GetRenderer();
153         if (renderer != nullptr && renderer->GetSessionId(sessionId) == SUCCESS) {
154             InsertRenderer(sessionId, renderer); // for all renderers
155             CheckInnerCapForRenderer(sessionId, renderer);
156             CheckRenderSessionMuteState(sessionId, renderer);
157         }
158     }
159     if (ipcStreamInServer != nullptr && config.audioMode == AUDIO_MODE_RECORD) {
160         uint32_t sessionId = 0;
161         std::shared_ptr<CapturerInServer> capturer = ipcStreamInServer->GetCapturer();
162         if (capturer != nullptr && capturer->GetSessionId(sessionId) == SUCCESS) {
163             InsertCapturer(sessionId, capturer); // for all renderers
164             CheckCaptureSessionMuteState(sessionId, capturer);
165         }
166     }
167 
168     return ipcStreamInServer;
169 }
170 
UpdateMuteControlSet(uint32_t sessionId,bool muteFlag)171 void AudioService::UpdateMuteControlSet(uint32_t sessionId, bool muteFlag)
172 {
173     if (sessionId < MIN_SESSIONID || sessionId > MAX_SESSIONID) {
174         AUDIO_WARNING_LOG("Invalid sessionid %{public}u", sessionId);
175         return;
176    }
177     std::lock_guard<std::mutex> lock(mutedSessionsMutex_);
178     if (muteFlag) {
179         mutedSessions_.insert(sessionId);
180         return;
181     }
182     if (mutedSessions_.find(sessionId) != mutedSessions_.end()) {
183         mutedSessions_.erase(sessionId);
184     } else {
185         AUDIO_WARNING_LOG("Session id %{public}u not in the set", sessionId);
186     }
187 }
188 
RemoveIdFromMuteControlSet(uint32_t sessionId)189 void AudioService::RemoveIdFromMuteControlSet(uint32_t sessionId)
190 {
191     std::lock_guard<std::mutex> mutedSessionsLock(mutedSessionsMutex_);
192     if (mutedSessions_.find(sessionId) != mutedSessions_.end()) {
193         mutedSessions_.erase(sessionId);
194     } else {
195         AUDIO_WARNING_LOG("Session id %{public}u not in the set", sessionId);
196     }
197 }
198 
CheckRenderSessionMuteState(uint32_t sessionId,std::shared_ptr<RendererInServer> renderer)199 void AudioService::CheckRenderSessionMuteState(uint32_t sessionId, std::shared_ptr<RendererInServer> renderer)
200 {
201     std::unique_lock<std::mutex> mutedSessionsLock(mutedSessionsMutex_);
202     if (mutedSessions_.find(sessionId) != mutedSessions_.end()) {
203         mutedSessionsLock.unlock();
204         AUDIO_INFO_LOG("Session %{public}u is in control", sessionId);
205         renderer->SetNonInterruptMute(true);
206     }
207 }
208 
CheckCaptureSessionMuteState(uint32_t sessionId,std::shared_ptr<CapturerInServer> capturer)209 void AudioService::CheckCaptureSessionMuteState(uint32_t sessionId, std::shared_ptr<CapturerInServer> capturer)
210 {
211     std::unique_lock<std::mutex> mutedSessionsLock(mutedSessionsMutex_);
212     if (mutedSessions_.find(sessionId) != mutedSessions_.end()) {
213         mutedSessionsLock.unlock();
214         AUDIO_INFO_LOG("Session %{public}u is in control", sessionId);
215         capturer->SetNonInterruptMute(true);
216     }
217 }
CheckFastSessionMuteState(uint32_t sessionId,sptr<AudioProcessInServer> process)218 void AudioService::CheckFastSessionMuteState(uint32_t sessionId, sptr<AudioProcessInServer> process)
219 {
220     std::unique_lock<std::mutex> mutedSessionsLock(mutedSessionsMutex_);
221     if (mutedSessions_.find(sessionId) != mutedSessions_.end()) {
222         mutedSessionsLock.unlock();
223         AUDIO_INFO_LOG("Session %{public}u is in control", sessionId);
224         process->SetNonInterruptMute(true);
225     }
226 }
227 
InsertRenderer(uint32_t sessionId,std::shared_ptr<RendererInServer> renderer)228 void AudioService::InsertRenderer(uint32_t sessionId, std::shared_ptr<RendererInServer> renderer)
229 {
230     std::unique_lock<std::mutex> lock(rendererMapMutex_);
231     AUDIO_INFO_LOG("Insert renderer:%{public}u into map", sessionId);
232     allRendererMap_[sessionId] = renderer;
233 }
234 
RemoveRenderer(uint32_t sessionId)235 void AudioService::RemoveRenderer(uint32_t sessionId)
236 {
237     std::unique_lock<std::mutex> lock(rendererMapMutex_);
238     AUDIO_INFO_LOG("Renderer:%{public}u will be removed.", sessionId);
239     if (!allRendererMap_.count(sessionId)) {
240         AUDIO_WARNING_LOG("Renderer in not in map!");
241         return;
242     }
243     allRendererMap_.erase(sessionId);
244     RemoveIdFromMuteControlSet(sessionId);
245 }
246 
InsertCapturer(uint32_t sessionId,std::shared_ptr<CapturerInServer> capturer)247 void AudioService::InsertCapturer(uint32_t sessionId, std::shared_ptr<CapturerInServer> capturer)
248 {
249     std::unique_lock<std::mutex> lock(capturerMapMutex_);
250     AUDIO_INFO_LOG("Insert capturer:%{public}u into map", sessionId);
251     allCapturerMap_[sessionId] = capturer;
252 }
253 
RemoveCapturer(uint32_t sessionId)254 void AudioService::RemoveCapturer(uint32_t sessionId)
255 {
256     std::unique_lock<std::mutex> lock(capturerMapMutex_);
257     AUDIO_INFO_LOG("Capturer: %{public}u will be removed.", sessionId);
258     if (!allCapturerMap_.count(sessionId)) {
259         AUDIO_WARNING_LOG("Capturer in not in map!");
260         return;
261     }
262     allCapturerMap_.erase(sessionId);
263     RemoveIdFromMuteControlSet(sessionId);
264 }
265 
CheckInnerCapForRenderer(uint32_t sessionId,std::shared_ptr<RendererInServer> renderer)266 void AudioService::CheckInnerCapForRenderer(uint32_t sessionId, std::shared_ptr<RendererInServer> renderer)
267 {
268     CHECK_AND_RETURN_LOG(renderer != nullptr, "renderer is null.");
269 
270     std::unique_lock<std::mutex> lock(rendererMapMutex_);
271 
272     // inner-cap not working
273     if (workingInnerCapId_ == 0) {
274         return;
275     }
276     // in plan: check if meet with the workingConfig_
277     if (ShouldBeInnerCap(renderer->processConfig_)) {
278         filteredRendererMap_.push_back(renderer);
279         renderer->EnableInnerCap(); // for debug
280     }
281 }
282 
GetInnerCapFilterPolicy()283 InnerCapFilterPolicy AudioService::GetInnerCapFilterPolicy()
284 {
285     auto usagesSize = workingConfig_.filterOptions.usages.size();
286     auto pidsSize = workingConfig_.filterOptions.pids.size();
287     if (usagesSize == 0 && pidsSize == 0) {
288         AUDIO_ERR_LOG("error, invalid usages and pids");
289         return POLICY_INVALID;
290     }
291     if (usagesSize > 0 && pidsSize == 0) {
292         AUDIO_INFO_LOG("usages only");
293         return POLICY_USAGES_ONLY;
294     }
295     return POLICY_USAGES_AND_PIDS;
296 }
297 
298 template<typename T>
isFilterMatched(const std::vector<T> & params,T param,FilterMode mode)299 bool isFilterMatched(const std::vector<T> &params, T param, FilterMode mode)
300 {
301     bool isFound = std::count(params.begin(), params.end(), param) != 0;
302     return (mode == FilterMode::INCLUDE && isFound) || (mode == FilterMode::EXCLUDE && !isFound);
303 }
304 
ShouldBeInnerCap(const AudioProcessConfig & rendererConfig)305 bool AudioService::ShouldBeInnerCap(const AudioProcessConfig &rendererConfig)
306 {
307     bool canBeCaptured = rendererConfig.privacyType == AudioPrivacyType::PRIVACY_TYPE_PUBLIC;
308     if (!canBeCaptured) {
309         AUDIO_WARNING_LOG("%{public}d privacy is not public!", rendererConfig.appInfo.appPid);
310         return false;
311     }
312     InnerCapFilterPolicy filterPolicy = GetInnerCapFilterPolicy();
313     bool res = false;
314     switch (filterPolicy) {
315         case POLICY_INVALID:
316             return false;
317         case POLICY_USAGES_ONLY:
318             res = isFilterMatched(workingConfig_.filterOptions.usages,
319                 rendererConfig.rendererInfo.streamUsage, workingConfig_.filterOptions.usageFilterMode);
320             break;
321         case POLICY_USAGES_AND_PIDS:
322             res = isFilterMatched(workingConfig_.filterOptions.usages, rendererConfig.rendererInfo.streamUsage,
323                 workingConfig_.filterOptions.usageFilterMode) &&
324                 isFilterMatched(workingConfig_.filterOptions.pids, rendererConfig.appInfo.appPid,
325                 workingConfig_.filterOptions.pidFilterMode);
326             break;
327         default:
328             break;
329     }
330 
331     AUDIO_INFO_LOG("pid:%{public}d usage:%{public}d result:%{public}s", rendererConfig.appInfo.appPid,
332         rendererConfig.rendererInfo.streamUsage, res ? "true" : "false");
333     return res;
334 }
335 
ShouldBeDualTone(const AudioProcessConfig & config)336 bool AudioService::ShouldBeDualTone(const AudioProcessConfig &config)
337 {
338     CHECK_AND_RETURN_RET_LOG(Util::IsRingerOrAlarmerStreamUsage(config.rendererInfo.streamUsage), false,
339         "Wrong usage ,should not be dualtone");
340     DeviceInfo deviceInfo;
341     bool ret = PolicyHandler::GetInstance().GetProcessDeviceInfo(config, false, deviceInfo);
342     if (!ret) {
343         AUDIO_WARNING_LOG("GetProcessDeviceInfo from audio policy server failed!");
344         return false;
345     }
346     if (config.audioMode != AUDIO_MODE_PLAYBACK) {
347         AUDIO_WARNING_LOG("No playback mode!");
348         return false;
349     }
350     AUDIO_INFO_LOG("Get DeviceInfo from policy server success, deviceType: %{public}d, "
351         "supportLowLatency: %{public}d", deviceInfo.deviceType, deviceInfo.isLowLatencyDevice);
352     if (deviceInfo.deviceType == DEVICE_TYPE_WIRED_HEADSET || deviceInfo.deviceType == DEVICE_TYPE_WIRED_HEADPHONES ||
353         deviceInfo.deviceType == DEVICE_TYPE_BLUETOOTH_A2DP || deviceInfo.deviceType == DEVICE_TYPE_USB_HEADSET ||
354         deviceInfo.deviceType == DEVICE_TYPE_USB_ARM_HEADSET) {
355         switch (config.rendererInfo.streamUsage) {
356             case STREAM_USAGE_ALARM:
357             case STREAM_USAGE_VOICE_RINGTONE:
358             case STREAM_USAGE_RINGTONE:
359                 AUDIO_WARNING_LOG("Should DualTone.");
360                 return true;
361             default:
362                 return false;
363         }
364     }
365     return false;
366 }
367 
FilterAllFastProcess()368 void AudioService::FilterAllFastProcess()
369 {
370     std::unique_lock<std::mutex> lock(processListMutex_);
371     if (linkedPairedList_.size() == 0) {
372         return;
373     }
374     for (auto paired : linkedPairedList_) {
375         AudioProcessConfig temp = paired.first->processConfig_;
376         if (temp.audioMode == AUDIO_MODE_PLAYBACK && ShouldBeInnerCap(temp)) {
377             paired.first->SetInnerCapState(true);
378             paired.second->EnableFastInnerCap();
379         } else {
380             paired.first->SetInnerCapState(false);
381         }
382     }
383 
384     for (auto pair : endpointList_) {
385         if (pair.second->GetDeviceRole() == OUTPUT_DEVICE && !pair.second->ShouldInnerCap()) {
386             pair.second->DisableFastInnerCap();
387         }
388     }
389 }
390 
OnInitInnerCapList()391 int32_t AudioService::OnInitInnerCapList()
392 {
393     AUDIO_INFO_LOG("workingInnerCapId_ is %{public}d", workingInnerCapId_);
394     FilterAllFastProcess();
395 
396     // strong ref to prevent destruct before unlock
397     std::vector<std::shared_ptr<RendererInServer>> renderers;
398 
399     {
400         std::unique_lock<std::mutex> lock(rendererMapMutex_);
401         for (auto it = allRendererMap_.begin(); it != allRendererMap_.end(); it++) {
402             std::shared_ptr<RendererInServer> renderer = it->second.lock();
403             if (renderer == nullptr) {
404                 AUDIO_WARNING_LOG("Renderer is already released!");
405                 continue;
406             }
407             if (ShouldBeInnerCap(renderer->processConfig_)) {
408                 renderer->EnableInnerCap();
409                 filteredRendererMap_.push_back(renderer);
410             }
411             renderers.push_back(std::move(renderer));
412         }
413     }
414 
415     return SUCCESS;
416 }
417 
OnUpdateInnerCapList()418 int32_t AudioService::OnUpdateInnerCapList()
419 {
420     AUDIO_INFO_LOG("workingInnerCapId_ is %{public}d", workingInnerCapId_);
421 
422     std::unique_lock<std::mutex> lock(rendererMapMutex_);
423     for (size_t i = 0; i < filteredRendererMap_.size(); i++) {
424         std::shared_ptr<RendererInServer> renderer = filteredRendererMap_[i].lock();
425         if (renderer == nullptr) {
426             AUDIO_WARNING_LOG("Renderer is already released!");
427             continue;
428         }
429         if (!ShouldBeInnerCap(renderer->processConfig_)) {
430             renderer->DisableInnerCap();
431         }
432     }
433     filteredRendererMap_.clear();
434     lock.unlock();
435     // EnableInnerCap will be called twice as it's already in filteredRendererMap_.
436     return OnInitInnerCapList();
437 }
438 
EnableDualToneList(uint32_t sessionId)439 int32_t AudioService::EnableDualToneList(uint32_t sessionId)
440 {
441     workingDualToneId_ = sessionId;
442     AUDIO_INFO_LOG("EnableDualToneList sessionId is %{public}d", sessionId);
443     std::unique_lock<std::mutex> lock(rendererMapMutex_);
444     for (auto it = allRendererMap_.begin(); it != allRendererMap_.end(); it++) {
445         std::shared_ptr<RendererInServer> renderer = it->second.lock();
446         if (renderer == nullptr) {
447             AUDIO_WARNING_LOG("Renderer is already released!");
448             continue;
449         }
450         if (ShouldBeDualTone(renderer->processConfig_)) {
451             renderer->EnableDualTone();
452             filteredDualToneRendererMap_.push_back(renderer);
453         }
454     }
455     return SUCCESS;
456 }
457 
DisableDualToneList(uint32_t sessionId)458 int32_t AudioService::DisableDualToneList(uint32_t sessionId)
459 {
460     AUDIO_INFO_LOG("disable dual tone, sessionId is %{public}d", sessionId);
461     std::unique_lock<std::mutex> lock(rendererMapMutex_);
462     for (size_t i = 0; i < filteredDualToneRendererMap_.size(); i++) {
463         std::shared_ptr<RendererInServer> renderer = filteredDualToneRendererMap_[i].lock();
464         if (renderer == nullptr) {
465             AUDIO_WARNING_LOG("Renderer is already released!");
466             continue;
467         }
468         renderer->DisableDualTone();
469     }
470     filteredDualToneRendererMap_.clear();
471     return SUCCESS;
472 }
473 
474 // Only one session is working at the same time.
OnCapturerFilterChange(uint32_t sessionId,const AudioPlaybackCaptureConfig & newConfig)475 int32_t AudioService::OnCapturerFilterChange(uint32_t sessionId, const AudioPlaybackCaptureConfig &newConfig)
476 {
477     Trace trace("AudioService::OnCapturerFilterChange");
478     // in plan:
479     // step 1: if sessionId is not added before, add the sessionId and enbale the filter in allRendererMap_
480     // step 2: if sessionId is already in using, this means the config is changed. Check the filtered renderer before,
481     // call disable inner-cap for those not meet with the new config, than filter all allRendererMap_.
482     if (workingInnerCapId_ == 0) {
483         workingInnerCapId_ = sessionId;
484         workingConfig_ = newConfig;
485         return OnInitInnerCapList();
486     }
487 
488     if (workingInnerCapId_ == sessionId) {
489         workingConfig_ = newConfig;
490         return OnUpdateInnerCapList();
491     }
492 
493     AUDIO_WARNING_LOG("%{public}u is working, comming %{public}u will not work!", workingInnerCapId_, sessionId);
494     return ERR_OPERATION_FAILED;
495 }
496 
OnCapturerFilterRemove(uint32_t sessionId)497 int32_t AudioService::OnCapturerFilterRemove(uint32_t sessionId)
498 {
499     if (workingInnerCapId_ != sessionId) {
500         AUDIO_WARNING_LOG("%{public}u is working, remove %{public}u will not work!", workingInnerCapId_, sessionId);
501         return SUCCESS;
502     }
503     workingInnerCapId_ = 0;
504     workingConfig_ = {};
505 
506     std::unique_lock<std::mutex> lockEndpoint(processListMutex_);
507     for (auto pair : endpointList_) {
508         if (pair.second->GetDeviceRole() == OUTPUT_DEVICE) {
509             pair.second->DisableFastInnerCap();
510         }
511     }
512     lockEndpoint.unlock();
513 
514     // strong ref to prevent destruct before unlock
515     std::vector<std::shared_ptr<RendererInServer>> renderers;
516 
517     {
518         std::lock_guard<std::mutex> lock(rendererMapMutex_);
519         for (size_t i = 0; i < filteredRendererMap_.size(); i++) {
520             std::shared_ptr<RendererInServer> renderer = filteredRendererMap_[i].lock();
521             if (renderer == nullptr) {
522                 AUDIO_WARNING_LOG("Find renderer is already released!");
523                 continue;
524             }
525             renderer->DisableInnerCap();
526             renderers.push_back(std::move(renderer));
527         }
528         AUDIO_INFO_LOG("Filter removed, clear %{public}zu filtered renderer.", filteredRendererMap_.size());
529 
530         filteredRendererMap_.clear();
531     }
532 
533     return SUCCESS;
534 }
535 
IsEndpointTypeVoip(const AudioProcessConfig & config,DeviceInfo & deviceInfo)536 bool AudioService::IsEndpointTypeVoip(const AudioProcessConfig &config, DeviceInfo &deviceInfo)
537 {
538     if (config.rendererInfo.streamUsage == STREAM_USAGE_VOICE_COMMUNICATION ||
539         config.rendererInfo.streamUsage == STREAM_USAGE_VIDEO_COMMUNICATION) {
540         return config.rendererInfo.originalFlag == AUDIO_FLAG_VOIP_FAST || deviceInfo.networkId != LOCAL_NETWORK_ID;
541     }
542 
543     if (config.capturerInfo.sourceType == SOURCE_TYPE_VOICE_COMMUNICATION) {
544         return config.capturerInfo.originalFlag == AUDIO_FLAG_VOIP_FAST || deviceInfo.networkId != LOCAL_NETWORK_ID;
545     }
546     return false;
547 }
548 
GetAudioProcess(const AudioProcessConfig & config)549 sptr<AudioProcessInServer> AudioService::GetAudioProcess(const AudioProcessConfig &config)
550 {
551     AudioPipeType incomingPipe = config.audioMode == AUDIO_MODE_PLAYBACK ?
552         PIPE_TYPE_LOWLATENCY_OUT : PIPE_TYPE_LOWLATENCY_IN;
553     int32_t ret = PolicyHandler::GetInstance().ActivateConcurrencyFromServer(incomingPipe);
554     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, nullptr, "Concede incoming lowlatency stream from server");
555     Trace trace("AudioService::GetAudioProcess for " + std::to_string(config.appInfo.appPid));
556     AUDIO_INFO_LOG("GetAudioProcess dump %{public}s", ProcessConfig::DumpProcessConfig(config).c_str());
557     DeviceInfo deviceInfo = GetDeviceInfoForProcess(config);
558     std::lock_guard<std::mutex> lock(processListMutex_);
559     std::shared_ptr<AudioEndpoint> audioEndpoint = GetAudioEndpointForDevice(deviceInfo, config,
560         IsEndpointTypeVoip(config, deviceInfo));
561     CHECK_AND_RETURN_RET_LOG(audioEndpoint != nullptr, nullptr, "no endpoint found for the process");
562 
563     uint32_t totalSizeInframe = 0;
564     uint32_t spanSizeInframe = 0;
565     audioEndpoint->GetPreferBufferInfo(totalSizeInframe, spanSizeInframe);
566     CHECK_AND_RETURN_RET_LOG(*deviceInfo.audioStreamInfo.samplingRate.rbegin() > 0, nullptr,
567         "Sample rate in server is invalid.");
568 
569     sptr<AudioProcessInServer> process = AudioProcessInServer::Create(config, this);
570     CHECK_AND_RETURN_RET_LOG(process != nullptr, nullptr, "AudioProcessInServer create failed.");
571     CheckFastSessionMuteState(process->GetSessionId(), process);
572 
573     std::shared_ptr<OHAudioBuffer> buffer = audioEndpoint->GetEndpointType()
574          == AudioEndpoint::TYPE_INDEPENDENT ? audioEndpoint->GetBuffer() : nullptr;
575     ret = process->ConfigProcessBuffer(totalSizeInframe, spanSizeInframe, deviceInfo.audioStreamInfo, buffer);
576     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, nullptr, "ConfigProcessBuffer failed");
577 
578     ret = LinkProcessToEndpoint(process, audioEndpoint);
579     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, nullptr, "LinkProcessToEndpoint failed");
580 
581     linkedPairedList_.push_back(std::make_pair(process, audioEndpoint));
582     CheckInnerCapForProcess(process, audioEndpoint);
583     return process;
584 }
585 
ResetAudioEndpoint()586 void AudioService::ResetAudioEndpoint()
587 {
588     std::lock_guard<std::mutex> lock(processListMutex_);
589 
590     std::vector<std::string> audioEndpointNames;
591     for (auto paired = linkedPairedList_.begin(); paired != linkedPairedList_.end(); paired++) {
592         if (paired->second->GetEndpointType() == AudioEndpoint::TYPE_MMAP) {
593             // unlink old link
594             if (UnlinkProcessToEndpoint(paired->first, paired->second) != SUCCESS) {
595                 AUDIO_ERR_LOG("Unlink process to old endpoint failed");
596             }
597             audioEndpointNames.push_back(paired->second->GetEndpointName());
598         }
599     }
600 
601     // release old endpoint
602     for (auto &endpointName : audioEndpointNames) {
603         if (endpointList_.count(endpointName) > 0) {
604             endpointList_[endpointName]->Release();
605             AUDIO_INFO_LOG("Erase endpoint %{public}s from endpointList_", endpointName.c_str());
606             endpointList_.erase(endpointName);
607         }
608     }
609 
610     ReLinkProcessToEndpoint();
611 }
612 
ReLinkProcessToEndpoint()613 void AudioService::ReLinkProcessToEndpoint()
614 {
615     using LinkPair = std::pair<sptr<AudioProcessInServer>, std::shared_ptr<AudioEndpoint>>;
616     std::vector<std::vector<LinkPair>::iterator> errorLinkedPaireds;
617     for (auto paired = linkedPairedList_.begin(); paired != linkedPairedList_.end(); paired++) {
618         if (paired->second->GetEndpointType() == AudioEndpoint::TYPE_MMAP) {
619             AUDIO_INFO_LOG("Session id %{public}u", paired->first->GetSessionId());
620 
621             // get new endpoint
622             const AudioProcessConfig &config = paired->first->processConfig_;
623             DeviceInfo deviceInfo = GetDeviceInfoForProcess(config);
624             std::shared_ptr<AudioEndpoint> audioEndpoint = GetAudioEndpointForDevice(deviceInfo, config,
625                 IsEndpointTypeVoip(config, deviceInfo));
626             if (audioEndpoint == nullptr) {
627                 AUDIO_ERR_LOG("Get new endpoint failed");
628                 errorLinkedPaireds.push_back(paired);
629                 continue;
630             }
631             // link new endpoint
632             if (LinkProcessToEndpoint(paired->first, audioEndpoint) != SUCCESS) {
633                 AUDIO_ERR_LOG("LinkProcessToEndpoint failed");
634                 errorLinkedPaireds.push_back(paired);
635                 continue;
636             }
637             // reset shared_ptr before to new
638             paired->second.reset();
639             paired->second = audioEndpoint;
640             CheckInnerCapForProcess(paired->first, audioEndpoint);
641         }
642     }
643 
644     for (auto &paired : errorLinkedPaireds) {
645         linkedPairedList_.erase(paired);
646     }
647 }
648 
CheckInnerCapForProcess(sptr<AudioProcessInServer> process,std::shared_ptr<AudioEndpoint> endpoint)649 void AudioService::CheckInnerCapForProcess(sptr<AudioProcessInServer> process, std::shared_ptr<AudioEndpoint> endpoint)
650 {
651     Trace trace("AudioService::CheckInnerCapForProcess:" + std::to_string(process->processConfig_.appInfo.appPid));
652     // inner-cap not working
653     if (workingInnerCapId_ == 0) {
654         return;
655     }
656 
657     if (ShouldBeInnerCap(process->processConfig_)) {
658         process->SetInnerCapState(true);
659         endpoint->EnableFastInnerCap();
660     } else {
661         process->SetInnerCapState(false);
662     }
663 }
664 
NotifyStreamVolumeChanged(AudioStreamType streamType,float volume)665 int32_t AudioService::NotifyStreamVolumeChanged(AudioStreamType streamType, float volume)
666 {
667     int32_t ret = SUCCESS;
668     for (auto item : endpointList_) {
669         std::string endpointName = item.second->GetEndpointName();
670         if (endpointName == item.first) {
671             ret = ret != SUCCESS ? ret : item.second->SetVolume(streamType, volume);
672         }
673     }
674     return ret;
675 }
676 
LinkProcessToEndpoint(sptr<AudioProcessInServer> process,std::shared_ptr<AudioEndpoint> endpoint)677 int32_t AudioService::LinkProcessToEndpoint(sptr<AudioProcessInServer> process,
678     std::shared_ptr<AudioEndpoint> endpoint)
679 {
680     int32_t ret = endpoint->LinkProcessStream(process);
681     if (ret != SUCCESS && endpoint->GetLinkedProcessCount() == 0 &&
682         endpointList_.count(endpoint->GetEndpointName())) {
683         std::string endpointToErase = endpoint->GetEndpointName();
684         endpointList_.erase(endpoint->GetEndpointName());
685         AUDIO_ERR_LOG("LinkProcessStream failed, erase endpoint %{public}s", endpointToErase.c_str());
686         return ERR_OPERATION_FAILED;
687     }
688     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "LinkProcessStream to endpoint %{public}s failed",
689         endpoint->GetEndpointName().c_str());
690 
691     ret = process->AddProcessStatusListener(endpoint);
692     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "AddProcessStatusListener failed");
693 
694     std::unique_lock<std::mutex> lock(releaseEndpointMutex_);
695     if (releasingEndpointSet_.count(endpoint->GetEndpointName())) {
696         AUDIO_INFO_LOG("LinkProcessToEndpoint find endpoint is releasing, call break.");
697         releasingEndpointSet_.erase(endpoint->GetEndpointName());
698         releaseEndpointCV_.notify_all();
699     }
700     return SUCCESS;
701 }
702 
UnlinkProcessToEndpoint(sptr<AudioProcessInServer> process,std::shared_ptr<AudioEndpoint> endpoint)703 int32_t AudioService::UnlinkProcessToEndpoint(sptr<AudioProcessInServer> process,
704     std::shared_ptr<AudioEndpoint> endpoint)
705 {
706     int32_t ret = endpoint->UnlinkProcessStream(process);
707     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "UnlinkProcessStream failed");
708 
709     ret = process->RemoveProcessStatusListener(endpoint);
710     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "RemoveProcessStatusListener failed");
711 
712     return SUCCESS;
713 }
714 
DelayCallReleaseEndpoint(std::string endpointName,int32_t delayInMs)715 void AudioService::DelayCallReleaseEndpoint(std::string endpointName, int32_t delayInMs)
716 {
717     AUDIO_INFO_LOG("Delay release endpoint [%{public}s] start, delayInMs %{public}d.", endpointName.c_str(), delayInMs);
718     CHECK_AND_RETURN_LOG(endpointList_.count(endpointName),
719         "Find no such endpoint: %{public}s", endpointName.c_str());
720     std::unique_lock<std::mutex> lock(releaseEndpointMutex_);
721     if (delayInMs != 0) {
722         releaseEndpointCV_.wait_for(lock, std::chrono::milliseconds(delayInMs), [this, endpointName] {
723             if (releasingEndpointSet_.count(endpointName)) {
724                 AUDIO_DEBUG_LOG("Wake up but keep release endpoint %{public}s in delay", endpointName.c_str());
725                 return false;
726             }
727             AUDIO_DEBUG_LOG("Delay release endpoint break when reuse: %{public}s", endpointName.c_str());
728             return true;
729         });
730     }
731 
732     if (!releasingEndpointSet_.count(endpointName)) {
733         AUDIO_DEBUG_LOG("Timeout or not need to release: %{public}s", endpointName.c_str());
734         return;
735     }
736     releasingEndpointSet_.erase(endpointName);
737 
738     std::shared_ptr<AudioEndpoint> temp = nullptr;
739     CHECK_AND_RETURN_LOG(endpointList_.find(endpointName) != endpointList_.end() &&
740         endpointList_[endpointName] != nullptr, "Endpoint %{public}s not available, stop call release",
741         endpointName.c_str());
742     temp = endpointList_[endpointName];
743     if (temp->GetStatus() == AudioEndpoint::EndpointStatus::UNLINKED) {
744         AUDIO_INFO_LOG("%{public}s not in use anymore, call release!", endpointName.c_str());
745         temp->Release();
746         temp = nullptr;
747         endpointList_.erase(endpointName);
748         return;
749     }
750     AUDIO_WARNING_LOG("%{public}s is not unlinked, stop call release", endpointName.c_str());
751     return;
752 }
753 
GetDeviceInfoForProcess(const AudioProcessConfig & config)754 DeviceInfo AudioService::GetDeviceInfoForProcess(const AudioProcessConfig &config)
755 {
756     // send the config to AudioPolicyServera and get the device info.
757     DeviceInfo deviceInfo;
758     bool ret = PolicyHandler::GetInstance().GetProcessDeviceInfo(config, false, deviceInfo);
759     if (ret) {
760         AUDIO_INFO_LOG("Get DeviceInfo from policy server success, deviceType: %{public}d, "
761             "supportLowLatency: %{public}d", deviceInfo.deviceType, deviceInfo.isLowLatencyDevice);
762         return deviceInfo;
763     } else {
764         AUDIO_WARNING_LOG("GetProcessDeviceInfo from audio policy server failed!");
765     }
766 
767     if (config.audioMode == AUDIO_MODE_RECORD) {
768         deviceInfo.deviceId = 1;
769         deviceInfo.networkId = LOCAL_NETWORK_ID;
770         deviceInfo.deviceRole = INPUT_DEVICE;
771         deviceInfo.deviceType = DEVICE_TYPE_MIC;
772     } else {
773         deviceInfo.deviceId = 6; // 6 for test
774         deviceInfo.networkId = LOCAL_NETWORK_ID;
775         deviceInfo.deviceRole = OUTPUT_DEVICE;
776         deviceInfo.deviceType = DEVICE_TYPE_SPEAKER;
777     }
778     AudioStreamInfo targetStreamInfo = {SAMPLE_RATE_48000, ENCODING_PCM, SAMPLE_S16LE, STEREO}; // note: read from xml
779     deviceInfo.audioStreamInfo = targetStreamInfo;
780     deviceInfo.deviceName = "mmap_device";
781     return deviceInfo;
782 }
783 
GetAudioEndpointForDevice(DeviceInfo & deviceInfo,const AudioProcessConfig & clientConfig,bool isVoipStream)784 std::shared_ptr<AudioEndpoint> AudioService::GetAudioEndpointForDevice(DeviceInfo &deviceInfo,
785     const AudioProcessConfig &clientConfig, bool isVoipStream)
786 {
787     int32_t endpointSeparateFlag = -1;
788     GetSysPara("persist.multimedia.audioflag.fast.disableseparate", endpointSeparateFlag);
789     uint32_t uid = static_cast<uint32_t>(IPCSkeleton::GetCallingUid());
790     if (deviceInfo.deviceRole == INPUT_DEVICE || deviceInfo.networkId != LOCAL_NETWORK_ID || uid != 0 ||
791         endpointSeparateFlag == 1) {
792         // Create shared stream.
793         int32_t endpointFlag = AUDIO_FLAG_MMAP;
794         if (isVoipStream) {
795             endpointFlag = AUDIO_FLAG_VOIP_FAST;
796         }
797         std::string deviceKey = AudioEndpoint::GenerateEndpointKey(deviceInfo, endpointFlag);
798         if (endpointList_.find(deviceKey) != endpointList_.end()) {
799             AUDIO_INFO_LOG("AudioService find endpoint already exist for deviceKey:%{public}s", deviceKey.c_str());
800             return endpointList_[deviceKey];
801         } else {
802             std::shared_ptr<AudioEndpoint> endpoint = AudioEndpoint::CreateEndpoint(isVoipStream ?
803                 AudioEndpoint::TYPE_VOIP_MMAP : AudioEndpoint::TYPE_MMAP, endpointFlag, clientConfig, deviceInfo);
804             CHECK_AND_RETURN_RET_LOG(endpoint != nullptr, nullptr, "Create mmap AudioEndpoint failed.");
805             AUDIO_INFO_LOG("Add endpoint %{public}s to endpointList_", deviceKey.c_str());
806             endpointList_[deviceKey] = endpoint;
807             return endpoint;
808         }
809     } else {
810         // Create Independent stream.
811         std::string deviceKey = deviceInfo.networkId + std::to_string(deviceInfo.deviceId) + "_" + std::to_string(g_id);
812         std::shared_ptr<AudioEndpoint> endpoint = AudioEndpoint::CreateEndpoint(AudioEndpoint::TYPE_INDEPENDENT,
813             g_id, clientConfig, deviceInfo);
814         CHECK_AND_RETURN_RET_LOG(endpoint != nullptr, nullptr, "Create independent AudioEndpoint failed.");
815         g_id++;
816         AUDIO_INFO_LOG("Add endpointSeperate %{public}s to endpointList_", deviceKey.c_str());
817         endpointList_[deviceKey] = endpoint;
818         return endpoint;
819     }
820 }
821 
Dump(std::string & dumpString)822 void AudioService::Dump(std::string &dumpString)
823 {
824     AUDIO_INFO_LOG("AudioService dump begin");
825     if (workingInnerCapId_ != 0) {
826         AppendFormat(dumpString, "  - InnerCap filter: %s\n",
827             ProcessConfig::DumpInnerCapConfig(workingConfig_).c_str());
828     }
829     // dump process
830     for (auto paired : linkedPairedList_) {
831         paired.first->Dump(dumpString);
832     }
833     // dump endpoint
834     for (auto item : endpointList_) {
835         AppendFormat(dumpString, "  - Endpoint device id: %s\n", item.first.c_str());
836         item.second->Dump(dumpString);
837     }
838     // dump voip and direct
839     {
840         std::lock_guard<std::mutex> lock(rendererMapMutex_);
841         for (const auto &item : allRendererMap_) {
842             std::shared_ptr<RendererInServer> renderer = item.second.lock();
843             if (renderer) {
844                 renderer->Dump(dumpString);
845             }
846         }
847     }
848 
849     // dump appUseNumMap_ and currentRendererStreamCnt_
850     {
851         std::lock_guard<std::mutex> lock(streamLifeCycleMutex_);
852         AppendFormat(dumpString, " - currentRendererStreamCnt is %d\n", currentRendererStreamCnt_);
853         for (auto it : appUseNumMap_) {
854             AppendFormat(dumpString, "  - appUseNumMap_ appUid: %d\n", it.first);
855             AppendFormat(dumpString, "  - appUseNumMap_ appUid created stream: %d\n", it.second);
856         }
857     }
858     PolicyHandler::GetInstance().Dump(dumpString);
859     AudioVolume::GetInstance()->Dump(dumpString);
860 }
861 
GetMaxAmplitude(bool isOutputDevice)862 float AudioService::GetMaxAmplitude(bool isOutputDevice)
863 {
864     std::lock_guard<std::mutex> lock(processListMutex_);
865 
866     if (linkedPairedList_.size() == 0) {
867         return 0;
868     }
869 
870     float fastAudioMaxAmplitude = 0;
871     for (auto paired : linkedPairedList_) {
872         if (isOutputDevice && (paired.second->GetDeviceRole() == OUTPUT_DEVICE)) {
873             float curFastAudioMaxAmplitude = paired.second->GetMaxAmplitude();
874             if (curFastAudioMaxAmplitude > fastAudioMaxAmplitude) {
875                 fastAudioMaxAmplitude = curFastAudioMaxAmplitude;
876             }
877         }
878         if (!isOutputDevice && (paired.second->GetDeviceRole() == INPUT_DEVICE)) {
879             float curFastAudioMaxAmplitude = paired.second->GetMaxAmplitude();
880             if (curFastAudioMaxAmplitude > fastAudioMaxAmplitude) {
881                 fastAudioMaxAmplitude = curFastAudioMaxAmplitude;
882             }
883         }
884     }
885     return fastAudioMaxAmplitude;
886 }
887 
GetRendererBySessionID(const uint32_t & sessionID)888 std::shared_ptr<RendererInServer> AudioService::GetRendererBySessionID(const uint32_t &sessionID)
889 {
890     std::lock_guard<std::mutex> lock(rendererMapMutex_);
891     if (allRendererMap_.count(sessionID)) {
892         return allRendererMap_[sessionID].lock();
893     } else {
894         return nullptr;
895     }
896 }
897 
SetNonInterruptMute(const uint32_t sessionId,const bool muteFlag)898 void AudioService::SetNonInterruptMute(const uint32_t sessionId, const bool muteFlag)
899 {
900     AUDIO_INFO_LOG("SessionId: %{public}u, muteFlag: %{public}d", sessionId, muteFlag);
901     std::unique_lock<std::mutex> rendererLock(rendererMapMutex_);
902     if (allRendererMap_.count(sessionId)) {
903         std::shared_ptr<RendererInServer> renderer = allRendererMap_[sessionId].lock();
904         if (renderer == nullptr) {
905             AUDIO_ERR_LOG("rendererinserver is null");
906             rendererLock.unlock();
907             return;
908         }
909         renderer->SetNonInterruptMute(muteFlag);
910         AUDIO_INFO_LOG("allRendererMap_ has sessionId");
911         rendererLock.unlock();
912         return;
913     }
914     rendererLock.unlock();
915     std::unique_lock<std::mutex> capturerLock(capturerMapMutex_);
916     if (allCapturerMap_.count(sessionId)) {
917         std::shared_ptr<CapturerInServer> capturer = allCapturerMap_[sessionId].lock();
918         if (capturer == nullptr) {
919             AUDIO_ERR_LOG("capturerinserver is null");
920             capturerLock.unlock();
921             return;
922         }
923         capturer->SetNonInterruptMute(muteFlag);
924         AUDIO_INFO_LOG("allCapturerMap_ has sessionId");
925         capturerLock.unlock();
926         return;
927     }
928     capturerLock.unlock();
929     std::unique_lock<std::mutex> processListLock(processListMutex_);
930     for (auto paired : linkedPairedList_) {
931         if (paired.first == nullptr) {
932             AUDIO_ERR_LOG("processInServer is nullptr");
933             processListLock.unlock();
934             return;
935         }
936         if (paired.first->GetSessionId() == sessionId) {
937             AUDIO_INFO_LOG("linkedPairedList_ has sessionId");
938             paired.first->SetNonInterruptMute(muteFlag);
939             processListLock.unlock();
940             return;
941         }
942     }
943     processListLock.unlock();
944     AUDIO_INFO_LOG("Cannot find sessionId");
945 }
946 
UpdateSourceType(SourceType sourceType)947 int32_t AudioService::UpdateSourceType(SourceType sourceType)
948 {
949     // specialSourceType need not updateaudioroute
950     if (specialSourceTypeSet_.contains(sourceType)) {
951         return SUCCESS;
952     }
953 
954     AudioCapturerSource *audioCapturerSourceInstance = AudioCapturerSource::GetInstance("primary");
955     CHECK_AND_RETURN_RET_LOG(audioCapturerSourceInstance != nullptr, ERROR, "source is null");
956 
957     return audioCapturerSourceInstance->UpdateSourceType(sourceType);
958 }
959 
SetIncMaxRendererStreamCnt(AudioMode audioMode)960 void AudioService::SetIncMaxRendererStreamCnt(AudioMode audioMode)
961 {
962     if (audioMode == AUDIO_MODE_PLAYBACK) {
963         currentRendererStreamCnt_++;
964     }
965 }
966 
SetDecMaxRendererStreamCnt()967 void AudioService::SetDecMaxRendererStreamCnt()
968 {
969     std::lock_guard<std::mutex> lock(streamLifeCycleMutex_);
970     currentRendererStreamCnt_--;
971 }
972 
CleanAppUseNumMap(int32_t appUid)973 void AudioService::CleanAppUseNumMap(int32_t appUid)
974 {
975     std::lock_guard<std::mutex> lock(streamLifeCycleMutex_);
976     auto appUseNum = appUseNumMap_.find(appUid);
977     if (appUseNum != appUseNumMap_.end()) {
978         appUseNumMap_[appUid] = --appUseNum->second;
979     }
980 }
981 
GetCurrentRendererStreamCnt()982 int32_t AudioService::GetCurrentRendererStreamCnt()
983 {
984     return currentRendererStreamCnt_;
985 }
986 
987 // need call with streamLifeCycleMutex_ lock
IsExceedingMaxStreamCntPerUid(int32_t callingUid,int32_t appUid,int32_t maxStreamCntPerUid)988 bool AudioService::IsExceedingMaxStreamCntPerUid(int32_t callingUid, int32_t appUid,
989     int32_t maxStreamCntPerUid)
990 {
991     if (callingUid != MEDIA_SERVICE_UID) {
992         appUid = callingUid;
993     }
994 
995     auto appUseNum = appUseNumMap_.find(appUid);
996     if (appUseNum != appUseNumMap_.end()) {
997         ++appUseNum->second;
998     } else {
999         int32_t initValue = 1;
1000         appUseNumMap_.emplace(appUid, initValue);
1001     }
1002 
1003     if (appUseNumMap_[appUid] > maxStreamCntPerUid) {
1004         --appUseNumMap_[appUid]; // actual created stream num is stream num decrease one
1005         return true;
1006     }
1007     return false;
1008 }
1009 
GetCreatedAudioStreamMostUid()1010 int32_t AudioService::GetCreatedAudioStreamMostUid()
1011 {
1012     int32_t mostAppUid = INVALID_APP_UID;
1013     int32_t mostAppNum = INVALID_APP_CREATED_AUDIO_STREAM_NUM;
1014     for (auto it = appUseNumMap_.begin(); it != appUseNumMap_.end(); it++) {
1015         mostAppNum = it->second > mostAppNum ? it->second : mostAppNum;
1016         mostAppUid = it->first;
1017     }
1018     return mostAppUid;
1019 }
1020 } // namespace AudioStandard
1021 } // namespace OHOS
1022