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