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> ¶ms, T param, FilterMode mode)285 bool isFilterMatched(const std::vector<T> ¶ms, 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