1 /*
2 * Copyright (c) 2024 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 "AudioInterruptService"
17 #endif
18
19 #include "audio_interrupt_service.h"
20
21 #include "audio_focus_parser.h"
22 #include "audio_policy_manager_listener_proxy.h"
23 #include "audio_utils.h"
24 #include "media_monitor_manager.h"
25
26 namespace OHOS {
27 namespace AudioStandard {
28 const int32_t DEFAULT_ZONE_ID = 0;
29 constexpr uint32_t MEDIA_SA_UID = 1013;
30 static sptr<IStandardAudioService> g_adProxy = nullptr;
31
32 static const map<InterruptHint, AudioFocuState> HINT_STATE_MAP = {
33 {INTERRUPT_HINT_PAUSE, PAUSE},
34 {INTERRUPT_HINT_DUCK, DUCK},
35 {INTERRUPT_HINT_NONE, ACTIVE},
36 {INTERRUPT_HINT_RESUME, ACTIVE},
37 {INTERRUPT_HINT_UNDUCK, ACTIVE}
38 };
39
GetAudioSceneFromAudioInterrupt(const AudioInterrupt & audioInterrupt)40 inline AudioScene GetAudioSceneFromAudioInterrupt(const AudioInterrupt &audioInterrupt)
41 {
42 if (audioInterrupt.audioFocusType.streamType == STREAM_RING) {
43 return AUDIO_SCENE_RINGING;
44 } else if (audioInterrupt.audioFocusType.streamType == STREAM_VOICE_CALL ||
45 audioInterrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION) {
46 return audioInterrupt.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION ?
47 AUDIO_SCENE_PHONE_CALL : AUDIO_SCENE_PHONE_CHAT;
48 } else if (audioInterrupt.audioFocusType.streamType == STREAM_VOICE_RING) {
49 return AUDIO_SCENE_VOICE_RINGING;
50 }
51 return AUDIO_SCENE_DEFAULT;
52 }
53
54 static const std::unordered_map<const AudioScene, const int> SCENE_PRIORITY = {
55 // from high to low
56 {AUDIO_SCENE_PHONE_CALL, 5},
57 {AUDIO_SCENE_VOICE_RINGING, 4},
58 {AUDIO_SCENE_PHONE_CHAT, 3},
59 {AUDIO_SCENE_RINGING, 2},
60 {AUDIO_SCENE_DEFAULT, 1}
61 };
62
63 static const unordered_map<AudioStreamType, int> DEFAULT_STREAM_PRIORITY = {
64 {STREAM_VOICE_CALL, 0},
65 {STREAM_VOICE_COMMUNICATION, 0},
66 {STREAM_VOICE_MESSAGE, 1},
67 {STREAM_NOTIFICATION, 2},
68 {STREAM_VOICE_ASSISTANT, 3},
69 {STREAM_RING, 4},
70 {STREAM_VOICE_RING, 4},
71 {STREAM_ALARM, 5},
72 {STREAM_NAVIGATION, 6},
73 {STREAM_MUSIC, 7},
74 {STREAM_MOVIE, 7},
75 {STREAM_SPEECH, 7},
76 {STREAM_GAME, 7},
77 {STREAM_DTMF, 8},
78 {STREAM_SYSTEM, 8},
79 {STREAM_SYSTEM_ENFORCED, 9},
80 };
81
GetAudioScenePriority(const AudioScene audioScene)82 inline int GetAudioScenePriority(const AudioScene audioScene)
83 {
84 if (SCENE_PRIORITY.count(audioScene) == 0) {
85 return SCENE_PRIORITY.at(AUDIO_SCENE_DEFAULT);
86 }
87 return SCENE_PRIORITY.at(audioScene);
88 }
89
AudioInterruptService()90 AudioInterruptService::AudioInterruptService()
91 {
92 }
93
~AudioInterruptService()94 AudioInterruptService::~AudioInterruptService()
95 {
96 AUDIO_ERR_LOG("should not happen");
97 }
98
Init(sptr<AudioPolicyServer> server)99 void AudioInterruptService::Init(sptr<AudioPolicyServer> server)
100 {
101 std::lock_guard<std::mutex> lock(mutex_);
102
103 // load configuration
104 std::unique_ptr<AudioFocusParser> parser = make_unique<AudioFocusParser>();
105 if (parser == nullptr) {
106 WriteServiceStartupError();
107 }
108
109 int32_t ret = parser->LoadConfig(focusCfgMap_);
110 if (ret != SUCCESS) {
111 WriteServiceStartupError();
112 }
113 CHECK_AND_RETURN_LOG(!ret, "load fail");
114
115 AUDIO_DEBUG_LOG("configuration loaded. mapSize: %{public}zu", focusCfgMap_.size());
116
117 policyServer_ = server;
118 clientOnFocus_ = 0;
119 focussedAudioInterruptInfo_ = nullptr;
120
121 CreateAudioInterruptZoneInternal(ZONEID_DEFAULT, {});
122
123 sessionService_ = std::make_shared<AudioSessionService>();
124 sessionService_->Init();
125 sessionService_->SetSessionTimeOutCallback(shared_from_this());
126 }
127
GetAudioServerProxy()128 const sptr<IStandardAudioService> AudioInterruptService::GetAudioServerProxy()
129 {
130 lock_guard<mutex> lock(audioServerProxyMutex_);
131
132 if (g_adProxy == nullptr) {
133 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
134 CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr, "Get samgr failed.");
135
136 sptr<IRemoteObject> object = samgr->GetSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID);
137 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr,
138 "audio service remote object is NULL.");
139
140 g_adProxy = iface_cast<IStandardAudioService>(object);
141 CHECK_AND_RETURN_RET_LOG(g_adProxy != nullptr, nullptr,
142 "init g_adProxy is NULL.");
143 }
144 const sptr<IStandardAudioService> gsp = g_adProxy;
145 return gsp;
146 }
147
OnSessionTimeout(const int32_t pid)148 void AudioInterruptService::OnSessionTimeout(const int32_t pid)
149 {
150 AUDIO_INFO_LOG("OnSessionTimeout pid %{public}d", pid);
151 std::lock_guard<std::mutex> lock(mutex_);
152 HandleSessionTimeOutEvent(pid);
153 }
154
HandleSessionTimeOutEvent(const int32_t pid)155 void AudioInterruptService::HandleSessionTimeOutEvent(const int32_t pid)
156 {
157 RemovePlaceholderInterruptForSession(pid, true);
158
159 AudioSessionDeactiveEvent deactiveEvent;
160 deactiveEvent.deactiveReason = AudioSessionDeactiveReason::TIMEOUT;
161 std::pair<int32_t, AudioSessionDeactiveEvent> sessionDeactivePair = {pid, deactiveEvent};
162 if (handler_ != nullptr) {
163 AUDIO_INFO_LOG("AudioSessionService::handler_ is not null. Send event!");
164 handler_->SendAudioSessionDeactiveCallback(sessionDeactivePair);
165 }
166 }
167
ActivateAudioSession(const int32_t callerPid,const AudioSessionStrategy & strategy)168 int32_t AudioInterruptService::ActivateAudioSession(const int32_t callerPid, const AudioSessionStrategy &strategy)
169 {
170 std::lock_guard<std::mutex> lock(mutex_);
171 if (sessionService_ == nullptr) {
172 AUDIO_ERR_LOG("sessionService_ is nullptr!");
173 return ERR_UNKNOWN;
174 }
175 int32_t result = sessionService_->ActivateAudioSession(callerPid, strategy);
176 if (result != SUCCESS) {
177 AUDIO_ERR_LOG("Failed to activate audio session for pid %{public}d!", callerPid);
178 return result;
179 }
180
181 AddActiveInterruptToSession(callerPid);
182 return SUCCESS;
183 }
184
AddActiveInterruptToSession(const int32_t callerPid)185 void AudioInterruptService::AddActiveInterruptToSession(const int32_t callerPid)
186 {
187 if (sessionService_ == nullptr) {
188 AUDIO_ERR_LOG("sessionService_ is nullptr!");
189 return;
190 }
191 if (!sessionService_->IsAudioSessionActivated(callerPid)) {
192 AUDIO_ERR_LOG("The audio session for pid %{public}d is not active!", callerPid);
193 return;
194 }
195 auto audioSession = sessionService_->GetAudioSessionByPid(callerPid);
196
197 auto itZone = zonesMap_.find(DEFAULT_ZONE_ID);
198 CHECK_AND_RETURN_LOG(itZone != zonesMap_.end(), "can not find zoneid");
199 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
200 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
201 audioFocusInfoList = itZone->second->audioFocusInfoList;
202 }
203 for (auto iterActive = audioFocusInfoList.begin(); iterActive != audioFocusInfoList.end(); ++iterActive) {
204 if ((iterActive->first).pid == callerPid && audioSession != nullptr) {
205 audioSession->AddAudioInterrpt(*iterActive);
206 }
207 }
208 }
209
DeactivateAudioSession(const int32_t callerPid)210 int32_t AudioInterruptService::DeactivateAudioSession(const int32_t callerPid)
211 {
212 std::lock_guard<std::mutex> lock(mutex_);
213 if (sessionService_ == nullptr) {
214 AUDIO_ERR_LOG("sessionService_ is nullptr!");
215 return ERR_UNKNOWN;
216 }
217
218 int32_t result = sessionService_->DeactivateAudioSession(callerPid);
219 if (result != SUCCESS) {
220 AUDIO_ERR_LOG("Failed to deactivate audio session for pid %{public}d!", callerPid);
221 return result;
222 }
223
224 RemovePlaceholderInterruptForSession(callerPid);
225 return SUCCESS;
226 }
227
RemovePlaceholderInterruptForSession(const int32_t callerPid,bool isSessionTimeout)228 void AudioInterruptService::RemovePlaceholderInterruptForSession(const int32_t callerPid, bool isSessionTimeout)
229 {
230 if (sessionService_ == nullptr) {
231 AUDIO_ERR_LOG("sessionService_ is nullptr!");
232 return;
233 }
234 if (sessionService_->IsAudioSessionActivated(callerPid)) {
235 AUDIO_ERR_LOG("The audio session for pid %{public}d is still active!", callerPid);
236 return;
237 }
238
239 auto itZone = zonesMap_.find(DEFAULT_ZONE_ID);
240 CHECK_AND_RETURN_LOG(itZone != zonesMap_.end(), "can not find zoneid");
241 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
242 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
243 audioFocusInfoList = itZone->second->audioFocusInfoList;
244 }
245
246 auto isPresent = [callerPid] (std::pair<AudioInterrupt, AudioFocuState> &pair) {
247 return pair.first.pid == callerPid && pair.second == PLACEHOLDER;
248 };
249 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isPresent);
250 if (iter != audioFocusInfoList.end()) {
251 AudioInterrupt placeholder = iter->first;
252 AUDIO_INFO_LOG("Remove stream id %{public}u (placeholder for pid%{public}d)", placeholder.sessionId, callerPid);
253 DeactivateAudioInterruptInternal(DEFAULT_ZONE_ID, placeholder, isSessionTimeout);
254 }
255 }
256
IsAudioSessionActivated(const int32_t callerPid)257 bool AudioInterruptService::IsAudioSessionActivated(const int32_t callerPid)
258 {
259 std::lock_guard<std::mutex> lock(mutex_);
260 if (sessionService_ == nullptr) {
261 AUDIO_ERR_LOG("sessionService_ is nullptr!");
262 return ERR_UNKNOWN;
263 }
264 return sessionService_->IsAudioSessionActivated(callerPid);
265 }
266
IsCanMixInterrupt(const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt)267 bool AudioInterruptService::IsCanMixInterrupt(const AudioInterrupt &incomingInterrupt,
268 const AudioInterrupt &activeInterrupt)
269 {
270 if (incomingInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID &&
271 (activeInterrupt.audioFocusType.streamType == STREAM_VOICE_CALL ||
272 activeInterrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION)) {
273 AUDIO_INFO_LOG("The capturer can not mix with voice call");
274 return false;
275 }
276 if ((incomingInterrupt.audioFocusType.streamType == STREAM_VOICE_CALL ||
277 incomingInterrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION) &&
278 activeInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID) {
279 AUDIO_INFO_LOG("The voice call can not mix with capturer");
280 return false;
281 }
282 if (incomingInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID &&
283 activeInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID) {
284 AUDIO_INFO_LOG("The capturer can not mix with another capturer");
285 return false;
286 }
287 return true;
288 }
289
CanMixForSession(const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt,const AudioFocusEntry & focusEntry)290 bool AudioInterruptService::CanMixForSession(const AudioInterrupt &incomingInterrupt,
291 const AudioInterrupt &activeInterrupt, const AudioFocusEntry &focusEntry)
292 {
293 if (focusEntry.isReject && incomingInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID) {
294 // The incoming stream is a capturer and the default policy is deny incoming.
295 AUDIO_INFO_LOG("The incoming audio capturer should be denied!");
296 return false;
297 }
298 if (!IsCanMixInterrupt(incomingInterrupt, activeInterrupt)) {
299 AUDIO_INFO_LOG("Two Stream Cannot Mix! incoming=%{public}d, active=%{public}d",
300 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
301 return false;
302 }
303 if (incomingInterrupt.audioFocusType.streamType == STREAM_INTERNAL_FORCE_STOP ||
304 activeInterrupt.audioFocusType.streamType == STREAM_INTERNAL_FORCE_STOP) {
305 AUDIO_INFO_LOG("STREAM_INTERNAL_FORCE_STOP! incomingInterrupt=%{public}d, activeInterrupt=%{public}d",
306 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
307 return false;
308 }
309 bool result = false;
310 result = CanMixForIncomingSession(incomingInterrupt, activeInterrupt, focusEntry);
311 if (result) {
312 AUDIO_INFO_LOG("Two streams can mix because of the incoming session. incoming %{public}d, active %{public}d",
313 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
314 return result;
315 }
316 result = CanMixForActiveSession(incomingInterrupt, activeInterrupt, focusEntry);
317 if (result) {
318 AUDIO_INFO_LOG("Two streams can mix because of the active session. incoming %{public}d, active %{public}d",
319 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
320 return result;
321 }
322 AUDIO_INFO_LOG("Two streams can not mix. incoming %{public}d, active %{public}d",
323 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
324 return result;
325 }
326
CanMixForIncomingSession(const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt,const AudioFocusEntry & focusEntry)327 bool AudioInterruptService::CanMixForIncomingSession(const AudioInterrupt &incomingInterrupt,
328 const AudioInterrupt &activeInterrupt, const AudioFocusEntry &focusEntry)
329 {
330 if (sessionService_ == nullptr) {
331 AUDIO_ERR_LOG("sessionService_ is nullptr!");
332 return false;
333 }
334 if (incomingInterrupt.sessionStrategy.concurrencyMode == AudioConcurrencyMode::SLIENT) {
335 AUDIO_INFO_LOG("incoming stream is explicitly SLIENT");
336 return true;
337 }
338 if (incomingInterrupt.sessionStrategy.concurrencyMode == AudioConcurrencyMode::MIX_WITH_OTHERS) {
339 AUDIO_INFO_LOG("incoming stream is explicitly MIX_WITH_OTHERS");
340 return true;
341 }
342 if (!sessionService_->IsAudioSessionActivated(incomingInterrupt.pid)) {
343 AUDIO_INFO_LOG("No active audio session for the pid of incomming stream");
344 return false;
345 }
346
347 std::shared_ptr<AudioSession> incomingSession = sessionService_->GetAudioSessionByPid(incomingInterrupt.pid);
348 if (incomingSession == nullptr) {
349 AUDIO_ERR_LOG("incomingSession is nullptr!");
350 return false;
351 }
352 AudioConcurrencyMode concurrencyMode = (incomingSession->GetSessionStrategy()).concurrencyMode;
353 if (concurrencyMode != AudioConcurrencyMode::MIX_WITH_OTHERS) {
354 AUDIO_INFO_LOG("The concurrency mode of incoming session is not MIX_WITH_OTHERS");
355 return false;
356 }
357
358 if (IsIncomingStreamLowPriority(focusEntry)) {
359 bool isSameType = AudioSessionService::IsSameTypeForAudioSession(
360 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
361 AUDIO_INFO_LOG("The incoming stream is low priority. isSameType: %{public}d.", isSameType);
362 return isSameType;
363 } else {
364 AUDIO_INFO_LOG("The concurrency mode of incoming session is MIX_WITH_OTHERS. Skip the interrupt operation");
365 return true;
366 }
367 }
368
CanMixForActiveSession(const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt,const AudioFocusEntry & focusEntry)369 bool AudioInterruptService::CanMixForActiveSession(const AudioInterrupt &incomingInterrupt,
370 const AudioInterrupt &activeInterrupt, const AudioFocusEntry &focusEntry)
371 {
372 if (sessionService_ == nullptr) {
373 AUDIO_ERR_LOG("sessionService_ is nullptr!");
374 return false;
375 }
376 if (activeInterrupt.sessionStrategy.concurrencyMode == AudioConcurrencyMode::SLIENT) {
377 AUDIO_INFO_LOG("The concurrency mode of active session is SLIENT");
378 return true;
379 }
380 if (!sessionService_->IsAudioSessionActivated(activeInterrupt.pid)) {
381 AUDIO_INFO_LOG("No active audio session for the pid of active stream");
382 return false;
383 }
384
385 std::shared_ptr<AudioSession> activeSession = sessionService_->GetAudioSessionByPid(activeInterrupt.pid);
386 if (activeSession == nullptr) {
387 AUDIO_ERR_LOG("activeSession is nullptr!");
388 return false;
389 }
390 AudioConcurrencyMode concurrencyMode = (activeSession->GetSessionStrategy()).concurrencyMode;
391 if (concurrencyMode != AudioConcurrencyMode::MIX_WITH_OTHERS) {
392 AUDIO_INFO_LOG("The concurrency mode of active session is not MIX_WITH_OTHERS");
393 return false;
394 }
395
396 if (IsActiveStreamLowPriority(focusEntry)) {
397 bool isSameType = AudioSessionService::IsSameTypeForAudioSession(
398 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
399 AUDIO_INFO_LOG("The active stream is low priority. isSameType: %{public}d.", isSameType);
400 return isSameType;
401 } else {
402 AUDIO_INFO_LOG("The concurrency mode of active session is MIX_WITH_OTHERS. Skip the interrupt operation");
403 return true;
404 }
405 }
406
IsIncomingStreamLowPriority(const AudioFocusEntry & focusEntry)407 bool AudioInterruptService::IsIncomingStreamLowPriority(const AudioFocusEntry &focusEntry)
408 {
409 if (focusEntry.isReject) {
410 return true;
411 }
412 if (focusEntry.actionOn == INCOMING) {
413 if (focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
414 focusEntry.hintType == INTERRUPT_HINT_STOP ||
415 focusEntry.hintType == INTERRUPT_HINT_DUCK) {
416 return true;
417 }
418 }
419 return false;
420 }
421
IsActiveStreamLowPriority(const AudioFocusEntry & focusEntry)422 bool AudioInterruptService::IsActiveStreamLowPriority(const AudioFocusEntry &focusEntry)
423 {
424 if (focusEntry.actionOn == CURRENT) {
425 if (focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
426 focusEntry.hintType == INTERRUPT_HINT_STOP ||
427 focusEntry.hintType == INTERRUPT_HINT_DUCK) {
428 return true;
429 }
430 }
431 return false;
432 }
433
WriteServiceStartupError()434 void AudioInterruptService::WriteServiceStartupError()
435 {
436 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
437 Media::MediaMonitor::AUDIO, Media::MediaMonitor::AUDIO_SERVICE_STARTUP_ERROR,
438 Media::MediaMonitor::FAULT_EVENT);
439 bean->Add("SERVICE_ID", static_cast<int32_t>(Media::MediaMonitor::AUDIO_POLICY_SERVICE_ID));
440 bean->Add("ERROR_CODE", static_cast<int32_t>(Media::MediaMonitor::AUDIO_INTERRUPT_SERVER));
441 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
442 }
443
AddDumpInfo(std::unordered_map<int32_t,std::shared_ptr<AudioInterruptZone>> & audioInterruptZonesMapDump)444 void AudioInterruptService::AddDumpInfo(std::unordered_map<int32_t, std::shared_ptr<AudioInterruptZone>>
445 &audioInterruptZonesMapDump)
446 {
447 std::lock_guard<std::mutex> lock(mutex_);
448
449 for (const auto&[zoneId, audioInterruptZone] : zonesMap_) {
450 std::shared_ptr<AudioInterruptZone> zoneDump = make_shared<AudioInterruptZone>();
451 zoneDump->zoneId = zoneId;
452 zoneDump->pids = audioInterruptZone->pids;
453 for (auto interruptCbInfo : audioInterruptZone->interruptCbsMap) {
454 zoneDump->interruptCbSessionIdsMap.insert(interruptCbInfo.first);
455 }
456 for (auto audioPolicyClientProxyCBInfo : audioInterruptZone->audioPolicyClientProxyCBMap) {
457 zoneDump->audioPolicyClientProxyCBClientPidMap.insert(audioPolicyClientProxyCBInfo.first);
458 }
459 zoneDump->audioFocusInfoList = audioInterruptZone->audioFocusInfoList;
460 audioInterruptZonesMapDump[zoneId] = zoneDump;
461 }
462 }
463
SetCallbackHandler(std::shared_ptr<AudioPolicyServerHandler> handler)464 void AudioInterruptService::SetCallbackHandler(std::shared_ptr<AudioPolicyServerHandler> handler)
465 {
466 handler_ = handler;
467 }
468
SetAudioManagerInterruptCallback(const sptr<IRemoteObject> & object)469 int32_t AudioInterruptService::SetAudioManagerInterruptCallback(const sptr<IRemoteObject> &object)
470 {
471 CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM,
472 "object is nullptr");
473
474 sptr<IStandardAudioPolicyManagerListener> listener = iface_cast<IStandardAudioPolicyManagerListener>(object);
475 CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM,
476 "obj cast failed");
477
478 std::shared_ptr<AudioInterruptCallback> callback = std::make_shared<AudioPolicyManagerListenerCallback>(listener);
479 CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM,
480 "create cb failed");
481
482 int32_t callerPid = IPCSkeleton::GetCallingPid();
483
484 if (handler_ != nullptr) {
485 handler_->AddExternInterruptCbsMap(callerPid, callback);
486 }
487
488 AUDIO_DEBUG_LOG("for client id %{public}d done", callerPid);
489
490 return SUCCESS;
491 }
492
UnsetAudioManagerInterruptCallback()493 int32_t AudioInterruptService::UnsetAudioManagerInterruptCallback()
494 {
495 int32_t callerPid = IPCSkeleton::GetCallingPid();
496 if (handler_ != nullptr) {
497 return handler_->RemoveExternInterruptCbsMap(callerPid);
498 }
499
500 return SUCCESS;
501 }
502
RequestAudioFocus(const int32_t clientId,const AudioInterrupt & audioInterrupt)503 int32_t AudioInterruptService::RequestAudioFocus(const int32_t clientId, const AudioInterrupt &audioInterrupt)
504 {
505 AUDIO_INFO_LOG("in");
506 std::lock_guard<std::mutex> lock(mutex_);
507
508 if (clientOnFocus_ == clientId) {
509 AUDIO_INFO_LOG("client already has focus");
510 NotifyFocusGranted(clientId, audioInterrupt);
511 return SUCCESS;
512 }
513
514 if (focussedAudioInterruptInfo_ != nullptr) {
515 AUDIO_INFO_LOG("Existing stream: %{public}d, incoming stream: %{public}d",
516 (focussedAudioInterruptInfo_->audioFocusType).streamType, audioInterrupt.audioFocusType.streamType);
517 NotifyFocusAbandoned(clientOnFocus_, *focussedAudioInterruptInfo_);
518 AbandonAudioFocusInternal(clientOnFocus_, *focussedAudioInterruptInfo_);
519 }
520
521 NotifyFocusGranted(clientId, audioInterrupt);
522
523 return SUCCESS;
524 }
525
AbandonAudioFocus(const int32_t clientId,const AudioInterrupt & audioInterrupt)526 int32_t AudioInterruptService::AbandonAudioFocus(const int32_t clientId, const AudioInterrupt &audioInterrupt)
527 {
528 AUDIO_INFO_LOG("in");
529 std::lock_guard<std::mutex> lock(mutex_);
530
531 return AbandonAudioFocusInternal(clientId, audioInterrupt);
532 }
533
SetAudioInterruptCallback(const int32_t zoneId,const uint32_t sessionId,const sptr<IRemoteObject> & object,uint32_t uid)534 int32_t AudioInterruptService::SetAudioInterruptCallback(const int32_t zoneId, const uint32_t sessionId,
535 const sptr<IRemoteObject> &object, uint32_t uid)
536 {
537 std::lock_guard<std::mutex> lock(mutex_);
538
539 // maybe add check session id validation here
540
541 CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM, "object is nullptr");
542
543 sptr<IStandardAudioPolicyManagerListener> listener = iface_cast<IStandardAudioPolicyManagerListener>(object);
544 CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM, "obj cast failed");
545
546 std::shared_ptr<AudioInterruptCallback> callback = std::make_shared<AudioPolicyManagerListenerCallback>(listener);
547 CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "create cb failed");
548
549 if (interruptClients_.find(sessionId) == interruptClients_.end()) {
550 // Register client death recipient first
551 sptr<AudioInterruptDeathRecipient> deathRecipient =
552 new AudioInterruptDeathRecipient(shared_from_this(), sessionId);
553 object->AddDeathRecipient(deathRecipient);
554
555 std::shared_ptr<AudioInterruptClient> client =
556 std::make_shared<AudioInterruptClient>(callback, object, deathRecipient);
557 uint32_t callingUid = static_cast<uint32_t>(IPCSkeleton::GetCallingUid());
558 if (callingUid == MEDIA_SA_UID) {
559 callingUid = uid;
560 }
561 client->SetCallingUid(callingUid);
562
563 interruptClients_[sessionId] = client;
564
565 // just record in zone map, not used currently
566 auto it = zonesMap_.find(zoneId);
567 if (it != zonesMap_.end() && it->second != nullptr) {
568 it->second->interruptCbsMap[sessionId] = callback;
569 zonesMap_[zoneId] = it->second;
570 }
571 } else {
572 AUDIO_ERR_LOG("%{public}u callback already exist", sessionId);
573 return ERR_INVALID_PARAM;
574 }
575
576 return SUCCESS;
577 }
578
UnsetAudioInterruptCallback(const int32_t zoneId,const uint32_t sessionId)579 int32_t AudioInterruptService::UnsetAudioInterruptCallback(const int32_t zoneId, const uint32_t sessionId)
580 {
581 std::lock_guard<std::mutex> lock(mutex_);
582
583 if (interruptClients_.erase(sessionId) == 0) {
584 AUDIO_ERR_LOG("session %{public}u not present", sessionId);
585 return ERR_INVALID_PARAM;
586 }
587
588 auto it = zonesMap_.find(zoneId);
589 if (it != zonesMap_.end() && it->second != nullptr &&
590 it->second->interruptCbsMap.find(sessionId) != it->second->interruptCbsMap.end()) {
591 it->second->interruptCbsMap.erase(it->second->interruptCbsMap.find(sessionId));
592 zonesMap_[zoneId] = it->second;
593 }
594
595 return SUCCESS;
596 }
597
AudioInterruptIsActiveInFocusList(const int32_t zoneId,const uint32_t incomingSessionId)598 bool AudioInterruptService::AudioInterruptIsActiveInFocusList(const int32_t zoneId, const uint32_t incomingSessionId)
599 {
600 auto itZone = zonesMap_.find(zoneId);
601 if (itZone == zonesMap_.end()) {
602 AUDIO_ERR_LOG("Can not find zoneid");
603 return false;
604 }
605 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
606 if (itZone != zonesMap_.end()) { audioFocusInfoList = itZone->second->audioFocusInfoList; }
607 auto isPresent = [incomingSessionId] (const std::pair<AudioInterrupt, AudioFocuState> &pair) {
608 return pair.first.sessionId == incomingSessionId && pair.second == ACTIVE;
609 };
610 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isPresent);
611 if (iter != audioFocusInfoList.end()) {
612 return true;
613 }
614 return false;
615 }
616
ActivateAudioInterrupt(const int32_t zoneId,const AudioInterrupt & audioInterrupt,const bool isUpdatedAudioStrategy)617 int32_t AudioInterruptService::ActivateAudioInterrupt(
618 const int32_t zoneId, const AudioInterrupt &audioInterrupt, const bool isUpdatedAudioStrategy)
619 {
620 std::unique_lock<std::mutex> lock(mutex_);
621
622 AudioStreamType streamType = audioInterrupt.audioFocusType.streamType;
623 uint32_t incomingSessionId = audioInterrupt.sessionId;
624 AUDIO_INFO_LOG("sessionId: %{public}u pid: %{public}d streamType: %{public}d "\
625 "usage: %{public}d source: %{public}d",
626 incomingSessionId, audioInterrupt.pid, streamType,
627 audioInterrupt.streamUsage, (audioInterrupt.audioFocusType).sourceType);
628
629 if (AudioInterruptIsActiveInFocusList(zoneId, incomingSessionId) && !isUpdatedAudioStrategy) {
630 AUDIO_INFO_LOG("Stream is active in focus list, no need to active audio interrupt.");
631 return SUCCESS;
632 }
633
634 if (audioInterrupt.parallelPlayFlag) {
635 AUDIO_PRERELEASE_LOGI("allow parallel play");
636 return SUCCESS;
637 }
638 ResetNonInterruptControl(incomingSessionId);
639
640 policyServer_->CheckStreamMode(incomingSessionId);
641 policyServer_->OffloadStreamCheck(incomingSessionId, OFFLOAD_NO_SESSION_ID);
642
643 bool shouldReturnSuccess = false;
644 ProcessAudioScene(audioInterrupt, incomingSessionId, zoneId, shouldReturnSuccess);
645 if (shouldReturnSuccess) {
646 return SUCCESS;
647 }
648
649 // Process ProcessFocusEntryTable for current audioFocusInfoList
650 int32_t ret = ProcessFocusEntry(zoneId, audioInterrupt);
651 CHECK_AND_RETURN_RET_LOG(!ret, ERR_FOCUS_DENIED, "request rejected");
652
653 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
654
655 // If there is an event of (interrupt + set scene), ActivateAudioInterrupt and DeactivateAudioInterrupt may
656 // experience deadlocks, due to mutex_ and deviceStatusUpdateSharedMutex_ waiting for each other
657 lock.unlock();
658 UpdateAudioSceneFromInterrupt(targetAudioScene, ACTIVATE_AUDIO_INTERRUPT);
659 return SUCCESS;
660 }
661
ResetNonInterruptControl(uint32_t sessionId)662 void AudioInterruptService::ResetNonInterruptControl(uint32_t sessionId)
663 {
664 if (GetClientTypeBySessionId(sessionId) != CLIENT_TYPE_GAME) {
665 return;
666 }
667 AUDIO_INFO_LOG("Reset non-interrupt control for %{public}u", sessionId);
668 const sptr<IStandardAudioService> gsp = GetAudioServerProxy();
669 std::string identity = IPCSkeleton::ResetCallingIdentity();
670 CHECK_AND_RETURN_LOG(gsp != nullptr, "error for audio server proxy null");
671 gsp->SetNonInterruptMute(sessionId, false);
672 IPCSkeleton::SetCallingIdentity(identity);
673 }
674
DeactivateAudioInterrupt(const int32_t zoneId,const AudioInterrupt & audioInterrupt)675 int32_t AudioInterruptService::DeactivateAudioInterrupt(const int32_t zoneId, const AudioInterrupt &audioInterrupt)
676 {
677 std::lock_guard<std::mutex> lock(mutex_);
678
679 AUDIO_INFO_LOG("sessionId: %{public}u pid: %{public}d streamType: %{public}d "\
680 "usage: %{public}d source: %{public}d",
681 audioInterrupt.sessionId, audioInterrupt.pid, (audioInterrupt.audioFocusType).streamType,
682 audioInterrupt.streamUsage, (audioInterrupt.audioFocusType).sourceType);
683
684 if (audioInterrupt.parallelPlayFlag) {
685 AUDIO_PRERELEASE_LOGI("allow parallel play");
686 return SUCCESS;
687 }
688
689 DeactivateAudioInterruptInternal(zoneId, audioInterrupt);
690
691 return SUCCESS;
692 }
693
ClearAudioFocusInfoListOnAccountsChanged(const int & id)694 void AudioInterruptService::ClearAudioFocusInfoListOnAccountsChanged(const int &id)
695 {
696 std::lock_guard<std::mutex> lock(mutex_);
697 AUDIO_INFO_LOG("start DeactivateAudioInterrupt, current id:%{public}d", id);
698 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, INTERRUPT_FORCE, INTERRUPT_HINT_STOP, 1.0f};
699 for (const auto&[zoneId, audioInterruptZone] : zonesMap_) {
700 CHECK_AND_CONTINUE_LOG(audioInterruptZone != nullptr, "audioInterruptZone is nullptr");
701 std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator it =
702 audioInterruptZone->audioFocusInfoList.begin();
703 while (it != audioInterruptZone->audioFocusInfoList.end()) {
704 if ((*it).first.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION ||
705 (*it).first.streamUsage == STREAM_USAGE_VOICE_RINGTONE) {
706 AUDIO_INFO_LOG("usage is voice modem communication or voice ring, skip");
707 ++it;
708 } else {
709 CHECK_AND_RETURN_LOG(handler_ != nullptr, "handler is nullptr");
710 handler_->SendInterruptEventWithSessionIdCallback(interruptEvent, (*it).first.sessionId);
711 it = audioInterruptZone->audioFocusInfoList.erase(it);
712 }
713 }
714 }
715 }
716
CreateAudioInterruptZone(const int32_t zoneId,const std::set<int32_t> & pids)717 int32_t AudioInterruptService::CreateAudioInterruptZone(const int32_t zoneId, const std::set<int32_t> &pids)
718 {
719 std::lock_guard<std::mutex> lock(mutex_);
720
721 CHECK_AND_RETURN_RET_LOG(CheckAudioInterruptZonePermission(), ERR_INVALID_PARAM, "permission deny");
722
723 return CreateAudioInterruptZoneInternal(zoneId, pids);
724 }
725
ReleaseAudioInterruptZone(const int32_t zoneId)726 int32_t AudioInterruptService::ReleaseAudioInterruptZone(const int32_t zoneId)
727 {
728 std::lock_guard<std::mutex> lock(mutex_);
729
730 CHECK_AND_RETURN_RET_LOG(CheckAudioInterruptZonePermission(), ERR_INVALID_PARAM,
731 "permission deny");
732
733 if (zonesMap_.find(zoneId) == zonesMap_.end()) {
734 AUDIO_INFO_LOG("no such zone:%{public}d, do not release", zoneId);
735 return SUCCESS;
736 }
737
738 auto it = zonesMap_.find(zoneId);
739 if (it->second == nullptr) {
740 zonesMap_.erase(it);
741 AUDIO_INFO_LOG("zoneId:(%{public}d) invalid, do not release", zoneId);
742 return SUCCESS;
743 }
744 ArchiveToNewAudioInterruptZone(zoneId, ZONEID_DEFAULT);
745 return SUCCESS;
746 }
747
AddAudioInterruptZonePids(const int32_t zoneId,const std::set<int32_t> & pids)748 int32_t AudioInterruptService::AddAudioInterruptZonePids(const int32_t zoneId, const std::set<int32_t> &pids)
749 {
750 std::lock_guard<std::mutex> lock(mutex_);
751
752 CHECK_AND_RETURN_RET_LOG(CheckAudioInterruptZonePermission(), ERR_INVALID_PARAM,
753 "permission deny");
754
755 bool shouldCreateNew = true;
756 auto it = zonesMap_.find(zoneId);
757 std::shared_ptr<AudioInterruptZone> audioInterruptZone = nullptr;
758 if (it != zonesMap_.end()) {
759 shouldCreateNew = false;
760 audioInterruptZone = it->second;
761 if (audioInterruptZone == nullptr) {
762 zonesMap_.erase(it);
763 shouldCreateNew = true;
764 }
765 }
766
767 if (shouldCreateNew) {
768 CreateAudioInterruptZoneInternal(zoneId, pids);
769 return SUCCESS;
770 }
771
772 CHECK_AND_RETURN_RET_LOG(audioInterruptZone != nullptr, ERROR, "Invalid audio interrupt zone.");
773 for (int32_t pid : pids) {
774 std::pair<set<int32_t>::iterator, bool> ret = audioInterruptZone->pids.insert(pid);
775 if (!ret.second) {
776 AUDIO_ERR_LOG("Add the same pid:%{public}d, add new pid failed.", pid);
777 }
778 }
779
780 int32_t hitZoneId;
781 HitZoneIdHaveTheSamePidsZone(audioInterruptZone->pids, hitZoneId);
782
783 NewAudioInterruptZoneByPids(audioInterruptZone, audioInterruptZone->pids, zoneId);
784
785 ArchiveToNewAudioInterruptZone(hitZoneId, zoneId);
786
787 return SUCCESS;
788 }
789
RemoveAudioInterruptZonePids(const int32_t zoneId,const std::set<int32_t> & pids)790 int32_t AudioInterruptService::RemoveAudioInterruptZonePids(const int32_t zoneId, const std::set<int32_t> &pids)
791 {
792 std::lock_guard<std::mutex> lock(mutex_);
793
794 CHECK_AND_RETURN_RET_LOG(CheckAudioInterruptZonePermission(), ERR_INVALID_PARAM,
795 "permission deny");
796
797 if (zonesMap_.find(zoneId) == zonesMap_.end()) {
798 AUDIO_INFO_LOG("no such zone:%{public}d, no need to remove", zoneId);
799 return SUCCESS;
800 }
801
802 auto it = zonesMap_.find(zoneId);
803 if (it->second == nullptr) {
804 zonesMap_.erase(it);
805 AUDIO_INFO_LOG("zoneId:(%{public}d) invalid, no need to remove", zoneId);
806 return SUCCESS;
807 }
808
809 for (int32_t pid : pids) {
810 auto pidIt = it->second->pids.find(pid);
811 if (pidIt != it->second->pids.end()) {
812 it->second->pids.erase(pidIt);
813 } else {
814 AUDIO_ERR_LOG("no pid:%{public}d, no need to remove", pid);
815 }
816
817 if (it->second->audioPolicyClientProxyCBMap.find(pid) != it->second->audioPolicyClientProxyCBMap.end()) {
818 it->second->audioPolicyClientProxyCBMap.erase(it->second->audioPolicyClientProxyCBMap.find(pid));
819 }
820 }
821
822 std::shared_ptr<AudioInterruptZone> audioInterruptZone = make_shared<AudioInterruptZone>();
823 audioInterruptZone = it->second;
824 zonesMap_.insert_or_assign(zoneId, audioInterruptZone);
825
826 ArchiveToNewAudioInterruptZone(zoneId, ZONEID_DEFAULT);
827 return SUCCESS;
828 }
829
830 // LCOV_EXCL_START
GetAudioFocusInfoList(const int32_t zoneId,std::list<std::pair<AudioInterrupt,AudioFocuState>> & focusInfoList)831 int32_t AudioInterruptService::GetAudioFocusInfoList(const int32_t zoneId,
832 std::list<std::pair<AudioInterrupt, AudioFocuState>> &focusInfoList)
833 {
834 std::lock_guard<std::mutex> lock(mutex_);
835
836 auto itZone = zonesMap_.find(zoneId);
837 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
838 focusInfoList = itZone->second->audioFocusInfoList;
839 } else {
840 focusInfoList = {};
841 }
842
843 return SUCCESS;
844 }
845
GetStreamTypePriority(AudioStreamType streamType)846 int32_t AudioInterruptService::GetStreamTypePriority(AudioStreamType streamType)
847 {
848 const std::unordered_map<AudioStreamType, int> &priorityMap = GetStreamPriorityMap();
849 if (priorityMap.find(streamType) != priorityMap.end()) {
850 return priorityMap.at(streamType);
851 }
852 return STREAM_DEFAULT_PRIORITY;
853 }
854
GetStreamPriorityMap() const855 unordered_map<AudioStreamType, int> AudioInterruptService::GetStreamPriorityMap() const
856 {
857 return DEFAULT_STREAM_PRIORITY;
858 }
859
GetStreamInFocus(const int32_t zoneId)860 AudioStreamType AudioInterruptService::GetStreamInFocus(const int32_t zoneId)
861 {
862 AudioStreamType streamInFocus = STREAM_DEFAULT;
863
864 auto itZone = zonesMap_.find(zoneId);
865 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
866 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
867 audioFocusInfoList = itZone->second->audioFocusInfoList;
868 }
869
870 int32_t focusPriority = STREAM_DEFAULT_PRIORITY;
871 for (auto iter = audioFocusInfoList.begin(); iter != audioFocusInfoList.end(); ++iter) {
872 if ((iter->second != ACTIVE && iter->second != DUCK) ||
873 (iter->first).audioFocusType.sourceType != SOURCE_TYPE_INVALID) {
874 // if the steam is not active or the active stream is an audio capturer stream, skip it.
875 continue;
876 }
877 int32_t curPriority = GetStreamTypePriority((iter->first).audioFocusType.streamType);
878 if (curPriority < focusPriority) {
879 focusPriority = curPriority;
880 streamInFocus = (iter->first).audioFocusType.streamType;
881 }
882 }
883 return streamInFocus == STREAM_DEFAULT ? STREAM_MUSIC : streamInFocus;
884 }
885
GetSessionInfoInFocus(AudioInterrupt & audioInterrupt,const int32_t zoneId)886 int32_t AudioInterruptService::GetSessionInfoInFocus(AudioInterrupt &audioInterrupt, const int32_t zoneId)
887 {
888 uint32_t invalidSessionId = static_cast<uint32_t>(-1);
889 audioInterrupt = {STREAM_USAGE_UNKNOWN, CONTENT_TYPE_UNKNOWN,
890 {AudioStreamType::STREAM_DEFAULT, SourceType::SOURCE_TYPE_INVALID, true}, invalidSessionId};
891
892 auto itZone = zonesMap_.find(zoneId);
893 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
894 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
895 audioFocusInfoList = itZone->second->audioFocusInfoList;
896 }
897
898 for (auto iter = audioFocusInfoList.begin(); iter != audioFocusInfoList.end(); ++iter) {
899 if (iter->second == ACTIVE) {
900 audioInterrupt = iter->first;
901 }
902 }
903
904 return SUCCESS;
905 }
906
NotifyFocusGranted(const int32_t clientId,const AudioInterrupt & audioInterrupt)907 void AudioInterruptService::NotifyFocusGranted(const int32_t clientId, const AudioInterrupt &audioInterrupt)
908 {
909 AUDIO_INFO_LOG("Notify focus granted in: %{public}d", clientId);
910
911 InterruptEventInternal interruptEvent = {};
912 interruptEvent.eventType = INTERRUPT_TYPE_END;
913 interruptEvent.forceType = INTERRUPT_SHARE;
914 interruptEvent.hintType = INTERRUPT_HINT_NONE;
915 interruptEvent.duckVolume = 0;
916
917 if (handler_ != nullptr) {
918 handler_->SendInterruptEventWithClientIdCallback(interruptEvent, clientId);
919 unique_ptr<AudioInterrupt> tempAudioInterruptInfo = make_unique<AudioInterrupt>();
920 tempAudioInterruptInfo->streamUsage = audioInterrupt.streamUsage;
921 tempAudioInterruptInfo->contentType = audioInterrupt.contentType;
922 (tempAudioInterruptInfo->audioFocusType).streamType = audioInterrupt.audioFocusType.streamType;
923 tempAudioInterruptInfo->pauseWhenDucked = audioInterrupt.pauseWhenDucked;
924 focussedAudioInterruptInfo_ = move(tempAudioInterruptInfo);
925 clientOnFocus_ = clientId;
926 }
927 }
928
NotifyFocusAbandoned(const int32_t clientId,const AudioInterrupt & audioInterrupt)929 int32_t AudioInterruptService::NotifyFocusAbandoned(const int32_t clientId, const AudioInterrupt &audioInterrupt)
930 {
931 AUDIO_INFO_LOG("Notify focus abandoned in: %{public}d", clientId);
932
933 InterruptEventInternal interruptEvent = {};
934 interruptEvent.eventType = INTERRUPT_TYPE_BEGIN;
935 interruptEvent.forceType = INTERRUPT_SHARE;
936 interruptEvent.hintType = INTERRUPT_HINT_STOP;
937 interruptEvent.duckVolume = 0;
938 if (handler_ != nullptr) {
939 handler_->SendInterruptEventWithClientIdCallback(interruptEvent, clientId);
940 }
941
942 return SUCCESS;
943 }
944
AbandonAudioFocusInternal(const int32_t clientId,const AudioInterrupt & audioInterrupt)945 int32_t AudioInterruptService::AbandonAudioFocusInternal(const int32_t clientId, const AudioInterrupt &audioInterrupt)
946 {
947 if (clientId == clientOnFocus_) {
948 AUDIO_INFO_LOG("remove app focus");
949 focussedAudioInterruptInfo_.reset();
950 focussedAudioInterruptInfo_ = nullptr;
951 clientOnFocus_ = 0;
952 }
953
954 return SUCCESS;
955 }
956
IsSameAppInShareMode(const AudioInterrupt incomingInterrupt,const AudioInterrupt activeInterrupt)957 bool AudioInterruptService::IsSameAppInShareMode(const AudioInterrupt incomingInterrupt,
958 const AudioInterrupt activeInterrupt)
959 {
960 if (incomingInterrupt.mode != SHARE_MODE || activeInterrupt.mode != SHARE_MODE) {
961 return false;
962 }
963 if (incomingInterrupt.pid == DEFAULT_APP_PID || activeInterrupt.pid == DEFAULT_APP_PID) {
964 return false;
965 }
966 return incomingInterrupt.pid == activeInterrupt.pid;
967 }
968
UpdateHintTypeForExistingSession(const AudioInterrupt & incomingInterrupt,AudioFocusEntry & focusEntry)969 void AudioInterruptService::UpdateHintTypeForExistingSession(const AudioInterrupt &incomingInterrupt,
970 AudioFocusEntry &focusEntry)
971 {
972 if (sessionService_ == nullptr) {
973 AUDIO_ERR_LOG("sessionService_ is nullptr!");
974 return;
975 }
976 if (!sessionService_->IsAudioSessionActivated(incomingInterrupt.pid)) {
977 AUDIO_INFO_LOG("No active audio session for the pid of incomming stream");
978 return;
979 }
980 if (focusEntry.actionOn != CURRENT) {
981 AUDIO_INFO_LOG("The interrupt event is not for the existed stream.");
982 return;
983 }
984
985 std::shared_ptr<AudioSession> incomingSession = sessionService_->GetAudioSessionByPid(incomingInterrupt.pid);
986 if (incomingSession == nullptr) {
987 AUDIO_ERR_LOG("incomingSession is nullptr!");
988 return;
989 }
990 AudioConcurrencyMode concurrencyMode = (incomingSession->GetSessionStrategy()).concurrencyMode;
991 switch (concurrencyMode) {
992 case AudioConcurrencyMode::DUCK_OTHERS:
993 if (focusEntry.hintType == INTERRUPT_HINT_DUCK ||
994 focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
995 focusEntry.hintType == INTERRUPT_HINT_STOP) {
996 AUDIO_INFO_LOG("The concurrency mode of incoming session is DUCK_OTHERS. Use INTERRUPT_HINT_DUCK.");
997 focusEntry.hintType = INTERRUPT_HINT_DUCK;
998 }
999 break;
1000 case AudioConcurrencyMode::PAUSE_OTHERS:
1001 if (focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
1002 focusEntry.hintType == INTERRUPT_HINT_STOP) {
1003 AUDIO_INFO_LOG("The concurrency mode of incoming session is PAUSE_OTHERS. Use INTERRUPT_HINT_PAUSE.");
1004 focusEntry.hintType = INTERRUPT_HINT_PAUSE;
1005 }
1006 break;
1007 default:
1008 AUDIO_INFO_LOG("The concurrency mode of incoming session is %{public}d. No need to update hint type",
1009 static_cast<int32_t>(concurrencyMode));
1010 break;
1011 }
1012 }
1013
ProcessExistInterrupt(std::list<std::pair<AudioInterrupt,AudioFocuState>>::iterator & iterActive,AudioFocusEntry & focusEntry,const AudioInterrupt & incomingInterrupt,bool & removeFocusInfo,InterruptEventInternal & interruptEvent)1014 void AudioInterruptService::ProcessExistInterrupt(std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator
1015 &iterActive, AudioFocusEntry &focusEntry, const AudioInterrupt &incomingInterrupt,
1016 bool &removeFocusInfo, InterruptEventInternal &interruptEvent)
1017 {
1018 SourceType incomingSourceType = incomingInterrupt.audioFocusType.sourceType;
1019 std::vector<SourceType> incomingConcurrentSources = incomingInterrupt.currencySources.sourcesTypes;
1020 SourceType existSourceType = (iterActive->first).audioFocusType.sourceType;
1021 std::vector<SourceType> existConcurrentSources = (iterActive->first).currencySources.sourcesTypes;
1022
1023 // if the callerPid has an active audio session, the hint type need to be updated.
1024 if (IsCanMixInterrupt(incomingInterrupt, iterActive->first)) {
1025 UpdateHintTypeForExistingSession(incomingInterrupt, focusEntry);
1026 }
1027 switch (focusEntry.hintType) {
1028 case INTERRUPT_HINT_STOP:
1029 if (IsAudioSourceConcurrency(existSourceType, incomingSourceType, existConcurrentSources,
1030 incomingConcurrentSources)) {
1031 break;
1032 }
1033 interruptEvent.hintType = focusEntry.hintType;
1034 if (GetClientTypeBySessionId((iterActive->first).sessionId) == CLIENT_TYPE_GAME) {
1035 interruptEvent.hintType = INTERRUPT_HINT_PAUSE;
1036 iterActive->second = PAUSE;
1037 AUDIO_INFO_LOG("incomingInterrupt.hintType: %{public}d", interruptEvent.hintType);
1038 break;
1039 }
1040 removeFocusInfo = true;
1041 break;
1042 case INTERRUPT_HINT_PAUSE:
1043 if (IsAudioSourceConcurrency(existSourceType, incomingSourceType, existConcurrentSources,
1044 incomingConcurrentSources)) {
1045 break;
1046 }
1047 if (iterActive->second == ACTIVE || iterActive->second == DUCK) {
1048 iterActive->second = PAUSE;
1049 interruptEvent.hintType = focusEntry.hintType;
1050 }
1051 break;
1052 case INTERRUPT_HINT_DUCK:
1053 if (iterActive->second == ACTIVE) {
1054 iterActive->second = DUCK;
1055 interruptEvent.duckVolume = DUCK_FACTOR;
1056 interruptEvent.hintType = focusEntry.hintType;
1057 }
1058 break;
1059 default:
1060 break;
1061 }
1062 }
1063
ProcessActiveInterrupt(const int32_t zoneId,const AudioInterrupt & incomingInterrupt)1064 void AudioInterruptService::ProcessActiveInterrupt(const int32_t zoneId, const AudioInterrupt &incomingInterrupt)
1065 {
1066 // Use local variable to record target focus info list, can be optimized
1067 auto targetZoneIt = zonesMap_.find(zoneId);
1068 CHECK_AND_RETURN_LOG(targetZoneIt != zonesMap_.end(), "can not find zone id");
1069 std::list<std::pair<AudioInterrupt, AudioFocuState>> tmpFocusInfoList {};
1070 if (targetZoneIt != zonesMap_.end()) {
1071 tmpFocusInfoList = targetZoneIt->second->audioFocusInfoList;
1072 targetZoneIt->second->zoneId = zoneId;
1073 }
1074
1075 for (auto iterActive = tmpFocusInfoList.begin(); iterActive != tmpFocusInfoList.end();) {
1076 AudioFocusEntry focusEntry =
1077 focusCfgMap_[std::make_pair((iterActive->first).audioFocusType, incomingInterrupt.audioFocusType)];
1078 if (focusEntry.actionOn != CURRENT || IsSameAppInShareMode(incomingInterrupt, iterActive->first) ||
1079 iterActive->second == PLACEHOLDER || CanMixForSession(incomingInterrupt, iterActive->first, focusEntry)) {
1080 ++iterActive;
1081 continue;
1082 }
1083
1084 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, focusEntry.forceType, INTERRUPT_HINT_NONE, 1.0f};
1085 uint32_t activeSessionId = (iterActive->first).sessionId;
1086 bool removeFocusInfo = false;
1087 ProcessExistInterrupt(iterActive, focusEntry, incomingInterrupt, removeFocusInfo, interruptEvent);
1088 if (removeFocusInfo) {
1089 // execute remove from list, iter move to next by erase
1090 int32_t pidToRemove = (iterActive->first).pid;
1091 uint32_t streamId = (iterActive->first).sessionId;
1092 auto pidIt = targetZoneIt->second->pids.find(pidToRemove);
1093 if (pidIt != targetZoneIt->second->pids.end()) {
1094 targetZoneIt->second->pids.erase(pidIt);
1095 }
1096 iterActive = tmpFocusInfoList.erase(iterActive);
1097 targetZoneIt->second->audioFocusInfoList = tmpFocusInfoList;
1098 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(pidToRemove)) {
1099 HandleLowPriorityEvent(pidToRemove, streamId);
1100 }
1101 } else {
1102 ++iterActive;
1103 }
1104
1105 SendActiveInterruptEvent(activeSessionId, interruptEvent, incomingInterrupt);
1106 }
1107
1108 targetZoneIt->second->audioFocusInfoList = tmpFocusInfoList;
1109 zonesMap_[zoneId] = targetZoneIt->second;
1110 }
1111
HandleLowPriorityEvent(const int32_t pid,const uint32_t streamId)1112 void AudioInterruptService::HandleLowPriorityEvent(const int32_t pid, const uint32_t streamId)
1113 {
1114 if (sessionService_ == nullptr) {
1115 AUDIO_ERR_LOG("sessionService_ is nullptr!");
1116 return;
1117 }
1118 auto audioSession = sessionService_->GetAudioSessionByPid(pid);
1119 if (audioSession == nullptr) {
1120 AUDIO_ERR_LOG("audioSession is nullptr!");
1121 return;
1122 }
1123
1124 audioSession->RemoveAudioInterrptByStreamId(streamId);
1125 if (audioSession->IsAudioSessionEmpty()) {
1126 AUDIO_INFO_LOG("The audio session is empty because the last one stream is interruptted!");
1127 sessionService_->DeactivateAudioSession(pid);
1128
1129 AudioSessionDeactiveEvent deactiveEvent;
1130 deactiveEvent.deactiveReason = AudioSessionDeactiveReason::LOW_PRIORITY;
1131 std::pair<int32_t, AudioSessionDeactiveEvent> sessionDeactivePair = {pid, deactiveEvent};
1132 if (handler_ != nullptr) {
1133 AUDIO_INFO_LOG("AudioSessionService::handler_ is not null. Send event!");
1134 handler_->SendAudioSessionDeactiveCallback(sessionDeactivePair);
1135 }
1136 }
1137 }
1138
SendActiveInterruptEvent(const uint32_t activeSessionId,const InterruptEventInternal & interruptEvent,const AudioInterrupt & incomingInterrupt)1139 void AudioInterruptService::SendActiveInterruptEvent(const uint32_t activeSessionId,
1140 const InterruptEventInternal &interruptEvent, const AudioInterrupt &incomingInterrupt)
1141 {
1142 if (interruptEvent.hintType != INTERRUPT_HINT_NONE) {
1143 AUDIO_INFO_LOG("OnInterrupt for active sessionId:%{public}d, hintType:%{public}d. By sessionId:%{public}d",
1144 activeSessionId, interruptEvent.hintType, incomingInterrupt.sessionId);
1145 if (handler_ != nullptr) {
1146 handler_->SendInterruptEventWithSessionIdCallback(interruptEvent, activeSessionId);
1147 }
1148 // focus remove or state change
1149 SendFocusChangeEvent(ZONEID_DEFAULT, AudioPolicyServerHandler::NONE_CALLBACK_CATEGORY,
1150 incomingInterrupt);
1151 }
1152 }
1153
ProcessAudioScene(const AudioInterrupt & audioInterrupt,const uint32_t & incomingSessionId,const int32_t & zoneId,bool & shouldReturnSuccess)1154 void AudioInterruptService::ProcessAudioScene(const AudioInterrupt &audioInterrupt, const uint32_t &incomingSessionId,
1155 const int32_t &zoneId, bool &shouldReturnSuccess)
1156 {
1157 auto itZone = zonesMap_.find(zoneId);
1158 CHECK_AND_RETURN_LOG(itZone != zonesMap_.end(), "can not find zoneId");
1159
1160 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1161 if ((itZone != zonesMap_.end()) && (itZone->second != nullptr)) {
1162 audioFocusInfoList = itZone->second->audioFocusInfoList;
1163 itZone->second->zoneId = zoneId;
1164 }
1165 int32_t pid = audioInterrupt.pid;
1166 if (!audioFocusInfoList.empty() && (itZone->second != nullptr)) {
1167 // If the session is present in audioFocusInfoList and not Capturer, remove and treat it as a new request
1168 AUDIO_DEBUG_LOG("audioFocusInfoList is not empty, check whether the session is present");
1169 audioFocusInfoList.remove_if(
1170 [&audioInterrupt, &pid](const std::pair<AudioInterrupt, AudioFocuState> &audioFocus) {
1171 return audioFocus.first.sessionId == audioInterrupt.sessionId ||
1172 (audioFocus.first.pid == pid && audioFocus.second == PLACEHOLDER &&
1173 audioInterrupt.audioFocusType.sourceType == SOURCE_TYPE_INVALID &&
1174 audioFocus.first.audioFocusType.streamType != STREAM_VOICE_COMMUNICATION);
1175 });
1176
1177 if (itZone->second->pids.find(pid) != itZone->second->pids.end()) {
1178 itZone->second->pids.erase(itZone->second->pids.find(pid));
1179 }
1180 itZone->second->audioFocusInfoList = audioFocusInfoList;
1181 zonesMap_[zoneId] = itZone->second;
1182 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(pid)) {
1183 std::shared_ptr<AudioSession> session = sessionService_->GetAudioSessionByPid(pid);
1184 if (session != nullptr) {
1185 sessionService_->GetAudioSessionByPid(pid)->RemoveAudioInterrptByStreamId(incomingSessionId);
1186 }
1187 }
1188 }
1189 if (audioFocusInfoList.empty()) {
1190 // If audioFocusInfoList is empty, directly activate interrupt
1191 AUDIO_INFO_LOG("audioFocusInfoList is empty, add the session into it directly");
1192 if (itZone->second != nullptr) {
1193 itZone->second->pids.insert(pid);
1194 itZone->second->audioFocusInfoList.emplace_back(std::make_pair(audioInterrupt, ACTIVE));
1195 zonesMap_[zoneId] = itZone->second;
1196 }
1197 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(pid)) {
1198 std::shared_ptr<AudioSession> tempAudioSession = sessionService_->GetAudioSessionByPid(pid);
1199 if (tempAudioSession != nullptr) {
1200 tempAudioSession->AddAudioInterrpt(std::make_pair(audioInterrupt, ACTIVE));
1201 }
1202 }
1203 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::REQUEST_CALLBACK_CATEGORY, audioInterrupt);
1204 UpdateAudioSceneFromInterrupt(GetHighestPriorityAudioScene(zoneId), ACTIVATE_AUDIO_INTERRUPT);
1205 shouldReturnSuccess = true;
1206 return;
1207 }
1208 shouldReturnSuccess = false;
1209 }
1210
IsAudioSourceConcurrency(const SourceType & existSourceType,const SourceType & incomingSourceType,const std::vector<SourceType> & existConcurrentSources,const std::vector<SourceType> & incomingConcurrentSources)1211 bool AudioInterruptService::IsAudioSourceConcurrency(const SourceType &existSourceType,
1212 const SourceType &incomingSourceType, const std::vector<SourceType> &existConcurrentSources,
1213 const std::vector<SourceType> &incomingConcurrentSources)
1214 {
1215 if ((incomingConcurrentSources.size() > 0 && existSourceType >= 0 && find(incomingConcurrentSources.begin(),
1216 incomingConcurrentSources.end(), existSourceType) != incomingConcurrentSources.end()) ||
1217 (existConcurrentSources.size() > 0 && incomingSourceType >= 0 && find(existConcurrentSources.begin(),
1218 existConcurrentSources.end(), incomingSourceType) != existConcurrentSources.end())) {
1219 return true;
1220 }
1221 return false;
1222 }
1223
ProcessFocusEntry(const int32_t zoneId,const AudioInterrupt & incomingInterrupt)1224 int32_t AudioInterruptService::ProcessFocusEntry(const int32_t zoneId, const AudioInterrupt &incomingInterrupt)
1225 {
1226 AudioFocuState incomingState = ACTIVE;
1227 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, INTERRUPT_FORCE, INTERRUPT_HINT_NONE, 1.0f};
1228 auto itZone = zonesMap_.find(zoneId);
1229 CHECK_AND_RETURN_RET_LOG(itZone != zonesMap_.end(), ERROR, "can not find zoneid");
1230 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1231 if (itZone != zonesMap_.end()) { audioFocusInfoList = itZone->second->audioFocusInfoList; }
1232
1233 SourceType incomingSourceType = incomingInterrupt.audioFocusType.sourceType;
1234 std::vector<SourceType> incomingConcurrentSources = incomingInterrupt.currencySources.sourcesTypes;
1235 for (auto iterActive = audioFocusInfoList.begin(); iterActive != audioFocusInfoList.end(); ++iterActive) {
1236 if (IsSameAppInShareMode(incomingInterrupt, iterActive->first)) { continue; }
1237 std::pair<AudioFocusType, AudioFocusType> audioFocusTypePair =
1238 std::make_pair((iterActive->first).audioFocusType, incomingInterrupt.audioFocusType);
1239 CHECK_AND_RETURN_RET_LOG(focusCfgMap_.find(audioFocusTypePair) != focusCfgMap_.end(), ERR_INVALID_PARAM,
1240 "audio focus type pair is invalid");
1241 AudioFocusEntry focusEntry = focusCfgMap_[audioFocusTypePair];
1242 if (focusEntry.actionOn == CURRENT || iterActive->second == PLACEHOLDER ||
1243 CanMixForSession(incomingInterrupt, iterActive->first, focusEntry)) {
1244 continue;
1245 }
1246 if ((focusEntry.actionOn == INCOMING && focusEntry.hintType == INTERRUPT_HINT_PAUSE) || focusEntry.isReject) {
1247 SourceType existSourceType = (iterActive->first).audioFocusType.sourceType;
1248 std::vector<SourceType> existConcurrentSources = (iterActive->first).currencySources.sourcesTypes;
1249 if (IsAudioSourceConcurrency(existSourceType, incomingSourceType, existConcurrentSources,
1250 incomingConcurrentSources)) {
1251 continue;
1252 }
1253 }
1254 if (focusEntry.isReject) {
1255 if (GetClientTypeBySessionId((iterActive->first).sessionId) == CLIENT_TYPE_GAME) {
1256 incomingState = PAUSE;
1257 AUDIO_INFO_LOG("incomingState: %{public}d", incomingState);
1258 continue;
1259 }
1260
1261 AUDIO_INFO_LOG("the incoming stream is rejected by sessionId:%{public}d, pid:%{public}d",
1262 (iterActive->first).sessionId, (iterActive->first).pid);
1263 incomingState = STOP;
1264 break;
1265 }
1266 auto pos = HINT_STATE_MAP.find(focusEntry.hintType);
1267 AudioFocuState newState = (pos == HINT_STATE_MAP.end()) ? ACTIVE : pos->second;
1268 incomingState = (newState > incomingState) ? newState : incomingState;
1269 }
1270 HandleIncomingState(zoneId, incomingState, interruptEvent, incomingInterrupt);
1271 AddToAudioFocusInfoList(itZone->second, zoneId, incomingInterrupt, incomingState);
1272 SendInterruptEventToIncomingStream(interruptEvent, incomingInterrupt);
1273 return incomingState >= PAUSE ? ERR_FOCUS_DENIED : SUCCESS;
1274 }
1275
SendInterruptEventToIncomingStream(InterruptEventInternal & interruptEvent,const AudioInterrupt & incomingInterrupt)1276 void AudioInterruptService::SendInterruptEventToIncomingStream(InterruptEventInternal &interruptEvent,
1277 const AudioInterrupt &incomingInterrupt)
1278 {
1279 if (interruptEvent.hintType != INTERRUPT_HINT_NONE && handler_ != nullptr) {
1280 AUDIO_INFO_LOG("OnInterrupt for incoming sessionId: %{public}d, hintType: %{public}d",
1281 incomingInterrupt.sessionId, interruptEvent.hintType);
1282 handler_->SendInterruptEventWithSessionIdCallback(interruptEvent, incomingInterrupt.sessionId);
1283 }
1284 }
1285
AddToAudioFocusInfoList(std::shared_ptr<AudioInterruptZone> & audioInterruptZone,const int32_t & zoneId,const AudioInterrupt & incomingInterrupt,const AudioFocuState & incomingState)1286 void AudioInterruptService::AddToAudioFocusInfoList(std::shared_ptr<AudioInterruptZone> &audioInterruptZone,
1287 const int32_t &zoneId, const AudioInterrupt &incomingInterrupt, const AudioFocuState &incomingState)
1288 {
1289 if (incomingState == STOP) {
1290 // Deny incoming. No need to add it.
1291 return;
1292 }
1293
1294 int32_t inComingPid = incomingInterrupt.pid;
1295 audioInterruptZone->zoneId = zoneId;
1296 audioInterruptZone->pids.insert(inComingPid);
1297 audioInterruptZone->audioFocusInfoList.emplace_back(std::make_pair(incomingInterrupt, incomingState));
1298 zonesMap_[zoneId] = audioInterruptZone;
1299 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::REQUEST_CALLBACK_CATEGORY, incomingInterrupt);
1300 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(incomingInterrupt.pid)) {
1301 auto audioSession = sessionService_->GetAudioSessionByPid(incomingInterrupt.pid);
1302 if (audioSession == nullptr) {
1303 AUDIO_ERR_LOG("audioSession is nullptr!");
1304 return;
1305 }
1306 audioSession->AddAudioInterrpt(std::make_pair(incomingInterrupt, incomingState));
1307 }
1308 }
1309
HandleIncomingState(const int32_t & zoneId,AudioFocuState & incomingState,InterruptEventInternal & interruptEvent,const AudioInterrupt & incomingInterrupt)1310 void AudioInterruptService::HandleIncomingState(const int32_t &zoneId, AudioFocuState &incomingState,
1311 InterruptEventInternal &interruptEvent, const AudioInterrupt &incomingInterrupt)
1312 {
1313 if (incomingState == STOP) {
1314 interruptEvent.hintType = INTERRUPT_HINT_STOP;
1315 } else {
1316 if (incomingState == PAUSE) {
1317 interruptEvent.hintType = INTERRUPT_HINT_PAUSE;
1318 } else if (incomingState == DUCK) {
1319 interruptEvent.hintType = INTERRUPT_HINT_DUCK;
1320 interruptEvent.duckVolume = DUCK_FACTOR;
1321 }
1322 // Handle existing focus state
1323 ProcessActiveInterrupt(zoneId, incomingInterrupt);
1324 }
1325 }
1326
GetHighestPriorityAudioScene(const int32_t zoneId) const1327 AudioScene AudioInterruptService::GetHighestPriorityAudioScene(const int32_t zoneId) const
1328 {
1329 AudioScene audioScene = AUDIO_SCENE_DEFAULT;
1330 int audioScenePriority = GetAudioScenePriority(audioScene);
1331
1332 auto itZone = zonesMap_.find(zoneId);
1333 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1334 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
1335 audioFocusInfoList = itZone->second->audioFocusInfoList;
1336 }
1337 for (const auto&[interrupt, focuState] : audioFocusInfoList) {
1338 AudioScene itAudioScene = GetAudioSceneFromAudioInterrupt(interrupt);
1339 int itAudioScenePriority = GetAudioScenePriority(itAudioScene);
1340 if (itAudioScenePriority > audioScenePriority) {
1341 audioScene = itAudioScene;
1342 audioScenePriority = itAudioScenePriority;
1343 }
1344 }
1345 return audioScene;
1346 }
1347
HadVoipStatus(const AudioInterrupt & audioInterrupt,const std::list<std::pair<AudioInterrupt,AudioFocuState>> & audioFocusInfoList)1348 bool AudioInterruptService::HadVoipStatus(const AudioInterrupt &audioInterrupt,
1349 const std::list<std::pair<AudioInterrupt, AudioFocuState>> &audioFocusInfoList)
1350 {
1351 for (const auto &[interrupt, focusState] : audioFocusInfoList) {
1352 if (audioInterrupt.pid == interrupt.pid && focusState == PLACEHOLDER &&
1353 interrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION &&
1354 interrupt.sessionId != audioInterrupt.sessionId) {
1355 AUDIO_WARNING_LOG("The audio session pid: %{public}d had voip status", audioInterrupt.pid);
1356 return true;
1357 }
1358 }
1359 return false;
1360 }
1361
1362 // LCOV_EXCL_STOP
DeactivateAudioInterruptInternal(const int32_t zoneId,const AudioInterrupt & audioInterrupt,bool isSessionTimeout)1363 void AudioInterruptService::DeactivateAudioInterruptInternal(const int32_t zoneId,
1364 const AudioInterrupt &audioInterrupt, bool isSessionTimeout)
1365 {
1366 auto itZone = zonesMap_.find(zoneId);
1367 CHECK_AND_RETURN_LOG((itZone != zonesMap_.end()) && (itZone->second != nullptr), "can not find zone");
1368 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList = itZone->second->audioFocusInfoList;
1369
1370 bool needPlaceHolder = false;
1371 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(audioInterrupt.pid)) {
1372 auto audioSession = sessionService_->GetAudioSessionByPid(audioInterrupt.pid);
1373 if (audioSession != nullptr) {
1374 audioSession->RemoveAudioInterrptByStreamId(audioInterrupt.sessionId);
1375 needPlaceHolder = audioSession->IsAudioRendererEmpty() &&
1376 !HadVoipStatus(audioInterrupt, audioFocusInfoList);
1377 }
1378 }
1379
1380 auto isPresent = [audioInterrupt] (std::pair<AudioInterrupt, AudioFocuState> &pair) {
1381 return pair.first.sessionId == audioInterrupt.sessionId;
1382 };
1383 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isPresent);
1384 if (iter != audioFocusInfoList.end()) {
1385 if (needPlaceHolder) {
1386 // Change the state to PLACEHOLDER because of the active audio session.
1387 // No need to release interrupt until the audio session is deactivated.
1388 iter->second = PLACEHOLDER;
1389 itZone->second->audioFocusInfoList = audioFocusInfoList;
1390 zonesMap_[zoneId] = itZone->second;
1391 return;
1392 }
1393 ResetNonInterruptControl(audioInterrupt.sessionId);
1394 int32_t deactivePid = audioInterrupt.pid;
1395 audioFocusInfoList.erase(iter);
1396 itZone->second->zoneId = zoneId;
1397 if (itZone->second->pids.find(deactivePid) != itZone->second->pids.end()) {
1398 itZone->second->pids.erase(itZone->second->pids.find(deactivePid));
1399 }
1400 itZone->second->audioFocusInfoList = audioFocusInfoList;
1401 zonesMap_[zoneId] = itZone->second;
1402 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::ABANDON_CALLBACK_CATEGORY, audioInterrupt);
1403 } else {
1404 // If it was not in the audioFocusInfoList, no need to take any action on other sessions, just return.
1405 AUDIO_DEBUG_LOG("stream (sessionId %{public}d) is not active now", audioInterrupt.sessionId);
1406 return;
1407 }
1408
1409 policyServer_->OffloadStreamCheck(OFFLOAD_NO_SESSION_ID, audioInterrupt.sessionId);
1410 policyServer_->OffloadStopPlaying(audioInterrupt);
1411
1412 // resume if other session was forced paused or ducked
1413 ResumeAudioFocusList(zoneId, isSessionTimeout);
1414
1415 return;
1416 }
1417
UpdateAudioSceneFromInterrupt(const AudioScene audioScene,AudioInterruptChangeType changeType)1418 void AudioInterruptService::UpdateAudioSceneFromInterrupt(const AudioScene audioScene,
1419 AudioInterruptChangeType changeType)
1420 {
1421 AudioScene currentAudioScene = policyServer_->GetAudioScene();
1422
1423 AUDIO_PRERELEASE_LOGI("currentScene: %{public}d, targetScene: %{public}d, changeType: %{public}d",
1424 currentAudioScene, audioScene, changeType);
1425
1426 switch (changeType) {
1427 case ACTIVATE_AUDIO_INTERRUPT:
1428 break;
1429 case DEACTIVATE_AUDIO_INTERRUPT:
1430 if (GetAudioScenePriority(audioScene) >= GetAudioScenePriority(currentAudioScene)) {
1431 return;
1432 }
1433 break;
1434 default:
1435 AUDIO_ERR_LOG("unexpected changeType: %{public}d", changeType);
1436 return;
1437 }
1438 policyServer_->SetAudioSceneInternal(audioScene);
1439 }
1440
EvaluateWhetherContinue(const AudioInterrupt & incoming,const AudioInterrupt & inprocessing,AudioFocusEntry & focusEntry,bool bConcurrency)1441 bool AudioInterruptService::EvaluateWhetherContinue(const AudioInterrupt &incoming, const AudioInterrupt
1442 &inprocessing, AudioFocusEntry &focusEntry, bool bConcurrency)
1443 {
1444 if (CanMixForSession(incoming, inprocessing, focusEntry) ||
1445 ((focusEntry.hintType == INTERRUPT_HINT_PAUSE || focusEntry.hintType == INTERRUPT_HINT_STOP) && bConcurrency)) {
1446 return true;
1447 }
1448 UpdateHintTypeForExistingSession(incoming, focusEntry);
1449 if (GetClientTypeBySessionId(incoming.sessionId) == CLIENT_TYPE_GAME &&
1450 focusEntry.hintType == INTERRUPT_HINT_STOP) {
1451 focusEntry.hintType = INTERRUPT_HINT_PAUSE;
1452 AUDIO_INFO_LOG("focusEntry.hintType: %{public}d", focusEntry.hintType);
1453 }
1454 return false;
1455 }
1456
SimulateFocusEntry(const int32_t zoneId)1457 std::list<std::pair<AudioInterrupt, AudioFocuState>> AudioInterruptService::SimulateFocusEntry(const int32_t zoneId)
1458 {
1459 std::list<std::pair<AudioInterrupt, AudioFocuState>> newAudioFocuInfoList;
1460 auto itZone = zonesMap_.find(zoneId);
1461 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1462 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
1463 audioFocusInfoList = itZone->second->audioFocusInfoList;
1464 }
1465
1466 for (auto iterActive = audioFocusInfoList.begin(); iterActive != audioFocusInfoList.end(); ++iterActive) {
1467 AudioInterrupt incoming = iterActive->first;
1468 AudioFocuState incomingState = ACTIVE;
1469 SourceType incomingSourceType = incoming.audioFocusType.sourceType;
1470 std::vector<SourceType> incomingConcurrentSources = incoming.currencySources.sourcesTypes;
1471 std::list<std::pair<AudioInterrupt, AudioFocuState>> tmpAudioFocuInfoList = newAudioFocuInfoList;
1472 for (auto iter = newAudioFocuInfoList.begin(); iter != newAudioFocuInfoList.end(); ++iter) {
1473 AudioInterrupt inprocessing = iter->first;
1474 if (IsSameAppInShareMode(incoming, inprocessing) || iter->second == PLACEHOLDER) { continue; }
1475 auto audioFocusTypePair = std::make_pair(inprocessing.audioFocusType, incoming.audioFocusType);
1476 if (focusCfgMap_.find(audioFocusTypePair) == focusCfgMap_.end()) {
1477 AUDIO_WARNING_LOG("focus type is invalid");
1478 incomingState = iterActive->second;
1479 break;
1480 }
1481 AudioFocusEntry focusEntry = focusCfgMap_[audioFocusTypePair];
1482 SourceType existSourceType = inprocessing.audioFocusType.sourceType;
1483 std::vector<SourceType> existConcurrentSources = inprocessing.currencySources.sourcesTypes;
1484 bool bConcurrency = IsAudioSourceConcurrency(existSourceType, incomingSourceType,
1485 existConcurrentSources, incomingConcurrentSources);
1486 if (EvaluateWhetherContinue(incoming, inprocessing, focusEntry, bConcurrency)) { continue; }
1487 auto pos = HINT_STATE_MAP.find(focusEntry.hintType);
1488 if (pos == HINT_STATE_MAP.end()) { continue; }
1489 if (focusEntry.actionOn == CURRENT && pos->second > iter->second) {
1490 iter->second = pos->second;
1491 } else {
1492 AudioFocuState newState = pos->second;
1493 incomingState = newState > incomingState ? newState : incomingState;
1494 }
1495 }
1496
1497 if (incomingState == PAUSE) { newAudioFocuInfoList = tmpAudioFocuInfoList; }
1498 if (iterActive->second == PLACEHOLDER) { incomingState = PLACEHOLDER; }
1499 newAudioFocuInfoList.emplace_back(std::make_pair(incoming, incomingState));
1500 }
1501
1502 return newAudioFocuInfoList;
1503 }
1504
SendInterruptEvent(AudioFocuState oldState,AudioFocuState newState,std::list<std::pair<AudioInterrupt,AudioFocuState>>::iterator & iterActive,bool & removeFocusInfo)1505 void AudioInterruptService::SendInterruptEvent(AudioFocuState oldState, AudioFocuState newState,
1506 std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator &iterActive, bool &removeFocusInfo)
1507 {
1508 AudioInterrupt audioInterrupt = iterActive->first;
1509 uint32_t sessionId = audioInterrupt.sessionId;
1510
1511 CHECK_AND_RETURN_LOG(handler_ != nullptr, "handler is nullptr");
1512
1513 InterruptEventInternal forceActive {INTERRUPT_TYPE_END, INTERRUPT_SHARE, INTERRUPT_HINT_RESUME, 1.0f};
1514 InterruptEventInternal forceUnduck {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_UNDUCK, 1.0f};
1515 InterruptEventInternal forceDuck {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_DUCK, DUCK_FACTOR};
1516 InterruptEventInternal forcePause {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_PAUSE, 1.0f};
1517 switch (newState) {
1518 case ACTIVE:
1519 if (oldState == PAUSE) {
1520 handler_->SendInterruptEventWithSessionIdCallback(forceActive, sessionId);
1521 removeFocusInfo = true;
1522 }
1523 if (oldState == DUCK) {
1524 handler_->SendInterruptEventWithSessionIdCallback(forceUnduck, sessionId);
1525 }
1526 break;
1527 case DUCK:
1528 if (oldState == PAUSE) {
1529 handler_->SendInterruptEventWithSessionIdCallback(forceActive, sessionId);
1530 removeFocusInfo = true;
1531 } else if (oldState == ACTIVE) {
1532 handler_->SendInterruptEventWithSessionIdCallback(forceDuck, sessionId);
1533 }
1534 break;
1535 case PAUSE:
1536 if (oldState == DUCK) {
1537 handler_->SendInterruptEventWithSessionIdCallback(forceUnduck, sessionId);
1538 }
1539 handler_->SendInterruptEventWithSessionIdCallback(forcePause, sessionId);
1540 break;
1541 default:
1542 break;
1543 }
1544 iterActive->second = newState;
1545 }
1546
ResumeAudioFocusList(const int32_t zoneId,bool isSessionTimeout)1547 void AudioInterruptService::ResumeAudioFocusList(const int32_t zoneId, bool isSessionTimeout)
1548 {
1549 AudioScene highestPriorityAudioScene = AUDIO_SCENE_DEFAULT;
1550
1551 auto itZone = zonesMap_.find(zoneId);
1552 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1553 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
1554 audioFocusInfoList = itZone->second->audioFocusInfoList;
1555 }
1556
1557 std::list<std::pair<AudioInterrupt, AudioFocuState>> newAudioFocuInfoList = SimulateFocusEntry(zoneId);
1558 for (auto iterActive = audioFocusInfoList.begin(), iterNew = newAudioFocuInfoList.begin();
1559 iterActive != audioFocusInfoList.end() && iterNew != newAudioFocuInfoList.end();) {
1560 AudioFocuState oldState = iterActive->second;
1561 AudioFocuState newState = iterNew->second;
1562 bool removeFocusInfo = false;
1563 if (oldState != newState) {
1564 if (isSessionTimeout && oldState == PAUSE && (newState == ACTIVE || newState == DUCK)) {
1565 // When the audio session is timeout, just send unduck event and skip resume event.
1566 AudioInterrupt interruptToRemove = iterActive->first;
1567 iterActive = audioFocusInfoList.erase(iterActive);
1568 iterNew = newAudioFocuInfoList.erase(iterNew);
1569 AUDIO_INFO_LOG("Audio session time out. Treat resume event as stop event. streamId %{public}d",
1570 interruptToRemove.sessionId);
1571 SendSessionTimeOutStopEvent(zoneId, interruptToRemove, audioFocusInfoList);
1572 continue;
1573 }
1574 AUDIO_INFO_LOG("State change: sessionId %{public}d, oldstate %{public}d, "\
1575 "newState %{public}d", (iterActive->first).sessionId, oldState, newState);
1576 SendInterruptEvent(oldState, newState, iterActive, removeFocusInfo);
1577 }
1578
1579 if (removeFocusInfo && GetClientTypeBySessionId((iterActive->first).sessionId) != CLIENT_TYPE_GAME) {
1580 AudioInterrupt interruptToRemove = iterActive->first;
1581 iterActive = audioFocusInfoList.erase(iterActive);
1582 iterNew = newAudioFocuInfoList.erase(iterNew);
1583 AUDIO_INFO_LOG("Remove focus info from focus list, streamId: %{public}d", interruptToRemove.sessionId);
1584 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::ABANDON_CALLBACK_CATEGORY, interruptToRemove);
1585 } else {
1586 AudioScene targetAudioScene = GetAudioSceneFromAudioInterrupt(iterActive->first);
1587 if (GetAudioScenePriority(targetAudioScene) > GetAudioScenePriority(highestPriorityAudioScene)) {
1588 highestPriorityAudioScene = targetAudioScene;
1589 }
1590 ++iterActive;
1591 ++iterNew;
1592 }
1593 }
1594
1595 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
1596 itZone->second->audioFocusInfoList = audioFocusInfoList;
1597 }
1598
1599 UpdateAudioSceneFromInterrupt(highestPriorityAudioScene, DEACTIVATE_AUDIO_INTERRUPT);
1600 }
1601
SendSessionTimeOutStopEvent(const int32_t zoneId,const AudioInterrupt & audioInterrupt,const std::list<std::pair<AudioInterrupt,AudioFocuState>> & audioFocusInfoList)1602 void AudioInterruptService::SendSessionTimeOutStopEvent(const int32_t zoneId, const AudioInterrupt &audioInterrupt,
1603 const std::list<std::pair<AudioInterrupt, AudioFocuState>> &audioFocusInfoList)
1604 {
1605 // When the audio session is timeout, change resume event to stop event and delete the interttupt.
1606 InterruptEventInternal stopEvent {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_STOP, 1.0f};
1607 if (handler_ != nullptr) {
1608 handler_->SendInterruptEventWithSessionIdCallback(stopEvent, audioInterrupt.sessionId);
1609 }
1610
1611 auto itZone = zonesMap_.find(zoneId);
1612 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
1613 itZone->second->zoneId = zoneId;
1614 if (itZone->second->pids.find(audioInterrupt.pid) != itZone->second->pids.end()) {
1615 itZone->second->pids.erase(itZone->second->pids.find(audioInterrupt.pid));
1616 }
1617 itZone->second->audioFocusInfoList = audioFocusInfoList;
1618 zonesMap_[zoneId] = itZone->second;
1619 }
1620 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::ABANDON_CALLBACK_CATEGORY, audioInterrupt);
1621 }
1622
SendFocusChangeEvent(const int32_t zoneId,int32_t callbackCategory,const AudioInterrupt & audioInterrupt)1623 void AudioInterruptService::SendFocusChangeEvent(const int32_t zoneId, int32_t callbackCategory,
1624 const AudioInterrupt &audioInterrupt)
1625 {
1626 CHECK_AND_RETURN_LOG(handler_ != nullptr, "handler is null");
1627 auto itZone = zonesMap_.find(zoneId);
1628 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1629 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
1630 audioFocusInfoList = itZone->second->audioFocusInfoList;
1631 }
1632
1633 handler_->SendAudioFocusInfoChangeCallback(callbackCategory, audioInterrupt, audioFocusInfoList);
1634 }
1635
1636 // LCOV_EXCL_START
CheckAudioInterruptZonePermission()1637 bool AudioInterruptService::CheckAudioInterruptZonePermission()
1638 {
1639 auto callerUid = IPCSkeleton::GetCallingUid();
1640 if (callerUid == UID_AUDIO) {
1641 return true;
1642 }
1643 return false;
1644 }
1645
CreateAudioInterruptZoneInternal(const int32_t zoneId,const std::set<int32_t> & pids)1646 int32_t AudioInterruptService::CreateAudioInterruptZoneInternal(const int32_t zoneId, const std::set<int32_t> &pids)
1647 {
1648 if (zonesMap_.find(zoneId) != zonesMap_.end()) {
1649 AUDIO_INFO_LOG("zone:(%{public}d) already exists.", zoneId);
1650 return SUCCESS;
1651 }
1652
1653 int32_t hitZoneId;
1654 HitZoneIdHaveTheSamePidsZone(pids, hitZoneId);
1655
1656 std::shared_ptr<AudioInterruptZone> audioInterruptZone = make_shared<AudioInterruptZone>();
1657 NewAudioInterruptZoneByPids(audioInterruptZone, pids, zoneId);
1658
1659 ArchiveToNewAudioInterruptZone(hitZoneId, zoneId);
1660
1661 return SUCCESS;
1662 }
1663
HitZoneId(const std::set<int32_t> & pids,const std::shared_ptr<AudioInterruptZone> & audioInterruptZone,const int32_t & zoneId,int32_t & hitZoneId,bool & haveSamePids)1664 int32_t AudioInterruptService::HitZoneId(const std::set<int32_t> &pids,
1665 const std::shared_ptr<AudioInterruptZone> &audioInterruptZone,
1666 const int32_t &zoneId, int32_t &hitZoneId, bool &haveSamePids)
1667 {
1668 for (int32_t pid : pids) {
1669 for (int32_t pidTmp : audioInterruptZone->pids) {
1670 if (pid != pidTmp) {
1671 haveSamePids = false;
1672 break;
1673 }
1674 }
1675 if (!haveSamePids) {
1676 break;
1677 } else {
1678 hitZoneId = zoneId;
1679 }
1680 }
1681 return SUCCESS;
1682 }
1683
HitZoneIdHaveTheSamePidsZone(const std::set<int32_t> & pids,int32_t & hitZoneId)1684 int32_t AudioInterruptService::HitZoneIdHaveTheSamePidsZone(const std::set<int32_t> &pids,
1685 int32_t &hitZoneId)
1686 {
1687 for (const auto&[zoneId, audioInterruptZone] : zonesMap_) {
1688 if (zoneId == ZONEID_DEFAULT) {
1689 continue;
1690 }
1691 // Find the same count pid's zone
1692 bool haveSamePids = true;
1693 if (audioInterruptZone != nullptr && pids.size() == audioInterruptZone->pids.size()) {
1694 HitZoneId(pids, audioInterruptZone, zoneId, hitZoneId, haveSamePids);
1695 }
1696 if (haveSamePids) {
1697 break;
1698 }
1699 }
1700 return SUCCESS;
1701 }
1702
DealAudioInterruptZoneData(const int32_t pid,const std::shared_ptr<AudioInterruptZone> & audioInterruptZoneTmp,std::shared_ptr<AudioInterruptZone> & audioInterruptZone)1703 int32_t AudioInterruptService::DealAudioInterruptZoneData(const int32_t pid,
1704 const std::shared_ptr<AudioInterruptZone> &audioInterruptZoneTmp,
1705 std::shared_ptr<AudioInterruptZone> &audioInterruptZone)
1706 {
1707 if (audioInterruptZoneTmp == nullptr || audioInterruptZone == nullptr) {
1708 return SUCCESS;
1709 }
1710
1711 for (auto audioFocusInfoTmp : audioInterruptZoneTmp->audioFocusInfoList) {
1712 int32_t audioFocusInfoPid = (audioFocusInfoTmp.first).pid;
1713 uint32_t audioFocusInfoSessionId = (audioFocusInfoTmp.first).sessionId;
1714 if (audioFocusInfoPid == pid) {
1715 audioInterruptZone->audioFocusInfoList.emplace_back(audioFocusInfoTmp);
1716 }
1717 if (audioInterruptZoneTmp->interruptCbsMap.find(audioFocusInfoSessionId) !=
1718 audioInterruptZoneTmp->interruptCbsMap.end()) {
1719 audioInterruptZone->interruptCbsMap.emplace(audioFocusInfoSessionId,
1720 audioInterruptZoneTmp->interruptCbsMap.find(audioFocusInfoSessionId)->second);
1721 }
1722 }
1723 if (audioInterruptZoneTmp->audioPolicyClientProxyCBMap.find(pid) !=
1724 audioInterruptZoneTmp->audioPolicyClientProxyCBMap.end()) {
1725 audioInterruptZone->audioPolicyClientProxyCBMap.emplace(pid,
1726 audioInterruptZoneTmp->audioPolicyClientProxyCBMap.find(pid)->second);
1727 }
1728
1729 return SUCCESS;
1730 }
1731
NewAudioInterruptZoneByPids(std::shared_ptr<AudioInterruptZone> & audioInterruptZone,const std::set<int32_t> & pids,const int32_t & zoneId)1732 int32_t AudioInterruptService::NewAudioInterruptZoneByPids(std::shared_ptr<AudioInterruptZone> &audioInterruptZone,
1733 const std::set<int32_t> &pids, const int32_t &zoneId)
1734 {
1735 audioInterruptZone->zoneId = zoneId;
1736 audioInterruptZone->pids = pids;
1737
1738 for (int32_t pid : pids) {
1739 for (const auto&[zoneIdTmp, audioInterruptZoneTmp] : zonesMap_) {
1740 if (audioInterruptZoneTmp != nullptr) {
1741 DealAudioInterruptZoneData(pid, audioInterruptZoneTmp, audioInterruptZone);
1742 }
1743 }
1744 }
1745 zonesMap_.insert_or_assign(zoneId, audioInterruptZone);
1746 return SUCCESS;
1747 }
1748
ArchiveToNewAudioInterruptZone(const int32_t & fromZoneId,const int32_t & toZoneId)1749 int32_t AudioInterruptService::ArchiveToNewAudioInterruptZone(const int32_t &fromZoneId, const int32_t &toZoneId)
1750 {
1751 if (fromZoneId == toZoneId || fromZoneId == ZONEID_DEFAULT) {
1752 AUDIO_ERR_LOG("From zone:%{public}d == To zone:%{public}d, dont archive.", fromZoneId, toZoneId);
1753 return SUCCESS;
1754 }
1755 auto fromZoneIt = zonesMap_.find(fromZoneId);
1756 if (fromZoneIt == zonesMap_.end()) {
1757 AUDIO_ERR_LOG("From zone invalid. -- fromZoneId:%{public}d, toZoneId:(%{public}d).", fromZoneId, toZoneId);
1758 return SUCCESS;
1759 }
1760 std::shared_ptr<AudioInterruptZone> fromZoneAudioInterruptZone = fromZoneIt->second;
1761 if (fromZoneAudioInterruptZone == nullptr) {
1762 AUDIO_ERR_LOG("From zone element invalid. -- fromZoneId:%{public}d, toZoneId:(%{public}d).",
1763 fromZoneId, toZoneId);
1764 zonesMap_.erase(fromZoneIt);
1765 return SUCCESS;
1766 }
1767 auto toZoneIt = zonesMap_.find(toZoneId);
1768 if (toZoneIt == zonesMap_.end()) {
1769 AUDIO_ERR_LOG("To zone invalid. -- fromZoneId:%{public}d, toZoneId:(%{public}d).", fromZoneId, toZoneId);
1770 return SUCCESS;
1771 }
1772 std::shared_ptr<AudioInterruptZone> toZoneAudioInterruptZone = toZoneIt->second;
1773 if (toZoneAudioInterruptZone != nullptr) {
1774 for (auto pid : fromZoneAudioInterruptZone->pids) {
1775 toZoneAudioInterruptZone->pids.insert(pid);
1776 }
1777 for (auto fromZoneAudioPolicyClientProxyCb : fromZoneAudioInterruptZone->audioPolicyClientProxyCBMap) {
1778 toZoneAudioInterruptZone->audioPolicyClientProxyCBMap.insert_or_assign(
1779 fromZoneAudioPolicyClientProxyCb.first, fromZoneAudioPolicyClientProxyCb.second);
1780 }
1781 for (auto fromZoneInterruptCb : fromZoneAudioInterruptZone->interruptCbsMap) {
1782 toZoneAudioInterruptZone->interruptCbsMap.insert_or_assign(
1783 fromZoneInterruptCb.first, fromZoneInterruptCb.second);
1784 }
1785 for (auto fromAudioFocusInfo : fromZoneAudioInterruptZone->audioFocusInfoList) {
1786 toZoneAudioInterruptZone->audioFocusInfoList.emplace_back(fromAudioFocusInfo);
1787 }
1788 std::shared_ptr<AudioInterruptZone> audioInterruptZone = make_shared<AudioInterruptZone>();
1789 audioInterruptZone->zoneId = toZoneId;
1790 toZoneAudioInterruptZone->pids.swap(audioInterruptZone->pids);
1791 toZoneAudioInterruptZone->interruptCbsMap.swap(audioInterruptZone->interruptCbsMap);
1792 toZoneAudioInterruptZone->audioPolicyClientProxyCBMap.swap(audioInterruptZone->audioPolicyClientProxyCBMap);
1793 toZoneAudioInterruptZone->audioFocusInfoList.swap(audioInterruptZone->audioFocusInfoList);
1794 zonesMap_.insert_or_assign(toZoneId, audioInterruptZone);
1795 zonesMap_.erase(fromZoneIt);
1796 }
1797 WriteFocusMigrateEvent(toZoneId);
1798 return SUCCESS;
1799 }
1800
WriteFocusMigrateEvent(const int32_t & toZoneId)1801 void AudioInterruptService::WriteFocusMigrateEvent(const int32_t &toZoneId)
1802 {
1803 auto uid = IPCSkeleton::GetCallingUid();
1804 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
1805 Media::MediaMonitor::AUDIO, Media::MediaMonitor::AUDIO_FOCUS_MIGRATE,
1806 Media::MediaMonitor::BEHAVIOR_EVENT);
1807 bean->Add("CLIENT_UID", static_cast<int32_t>(uid));
1808 bean->Add("MIGRATE_DIRECTION", toZoneId);
1809 bean->Add("DEVICE_DESC", (toZoneId == 1) ? REMOTE_NETWORK_ID : LOCAL_NETWORK_ID);
1810 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
1811 }
1812
DispatchInterruptEventWithSessionId(uint32_t sessionId,InterruptEventInternal & interruptEvent)1813 void AudioInterruptService::DispatchInterruptEventWithSessionId(uint32_t sessionId,
1814 InterruptEventInternal &interruptEvent)
1815 {
1816 std::lock_guard<std::mutex> lock(mutex_);
1817
1818 // call all clients
1819 if (sessionId == 0) {
1820 for (auto &it : interruptClients_) {
1821 (it.second)->OnInterrupt(interruptEvent);
1822 }
1823 return;
1824 }
1825
1826 if (interruptClients_.find(sessionId) != interruptClients_.end()) {
1827 #ifdef FEATURE_APPGALLERY
1828 if (ShouldCallbackToClient(interruptClients_[sessionId]->GetCallingUid(), sessionId, interruptEvent)) {
1829 interruptClients_[sessionId]->OnInterrupt(interruptEvent);
1830 }
1831 #else
1832 interruptClients_[sessionId]->OnInterrupt(interruptEvent);
1833 #endif
1834 }
1835 }
1836
GetClientTypeBySessionId(int32_t sessionId)1837 ClientType AudioInterruptService::GetClientTypeBySessionId(int32_t sessionId)
1838 {
1839 #ifdef FEATURE_APPGALLERY
1840 uint32_t uid = 0;
1841 if (interruptClients_.find(sessionId) != interruptClients_.end()) {
1842 uid = interruptClients_[sessionId]->GetCallingUid();
1843 }
1844 if (uid == 0) {
1845 AUDIO_ERR_LOG("Cannot find sessionid %{public}d", sessionId);
1846 return CLIENT_TYPE_OTHERS;
1847 }
1848 return ClientTypeManager::GetInstance()->GetClientTypeByUid(uid);
1849 #else
1850 return CLIENT_TYPE_OTHERS;
1851 #endif
1852 }
1853
ShouldCallbackToClient(uint32_t uid,int32_t sessionId,InterruptEventInternal & interruptEvent)1854 bool AudioInterruptService::ShouldCallbackToClient(uint32_t uid, int32_t sessionId,
1855 InterruptEventInternal &interruptEvent)
1856 {
1857 AUDIO_INFO_LOG("uid: %{public}u, sessionId: %{public}d, hintType: %{public}d", uid, sessionId,
1858 interruptEvent.hintType);
1859 ClientType clientType = ClientTypeManager::GetInstance()->GetClientTypeByUid(uid);
1860 if (clientType != CLIENT_TYPE_GAME) {
1861 return true;
1862 }
1863 if (interruptEvent.hintType == INTERRUPT_HINT_DUCK || interruptEvent.hintType == INTERRUPT_HINT_UNDUCK) {
1864 interruptEvent.callbackToApp = false;
1865 return true;
1866 }
1867
1868 bool muteFlag = true;
1869 const sptr<IStandardAudioService> gsp = GetAudioServerProxy();
1870 std::string identity = IPCSkeleton::ResetCallingIdentity();
1871 CHECK_AND_RETURN_RET_LOG(gsp != nullptr, true, "error for g_adProxy null");
1872 switch (interruptEvent.hintType) {
1873 case INTERRUPT_HINT_RESUME:
1874 muteFlag = false;
1875 [[fallthrough]];
1876 case INTERRUPT_HINT_PAUSE:
1877 case INTERRUPT_HINT_STOP:
1878 AUDIO_INFO_LOG("mute flag is: %{public}d", muteFlag);
1879 gsp->SetNonInterruptMute(sessionId, muteFlag);
1880 break;
1881 default:
1882 break;
1883 }
1884 IPCSkeleton::SetCallingIdentity(identity);
1885 return false;
1886 }
1887
1888 // called when the client remote object dies
RemoveClient(const int32_t zoneId,uint32_t sessionId)1889 void AudioInterruptService::RemoveClient(const int32_t zoneId, uint32_t sessionId)
1890 {
1891 std::lock_guard<std::mutex> lock(mutex_);
1892
1893 AUDIO_INFO_LOG("Remove session: %{public}u in audioFocusInfoList", sessionId);
1894
1895 auto itActiveZone = zonesMap_.find(ZONEID_DEFAULT);
1896
1897 auto isSessionPresent = [&sessionId] (const std::pair<AudioInterrupt, AudioFocuState> &audioFocusInfo) {
1898 return audioFocusInfo.first.sessionId == sessionId;
1899 };
1900 auto iterActive = std::find_if((itActiveZone->second->audioFocusInfoList).begin(),
1901 (itActiveZone->second->audioFocusInfoList).end(), isSessionPresent);
1902 if (iterActive != (itActiveZone->second->audioFocusInfoList).end()) {
1903 AudioInterrupt interruptToRemove = iterActive->first;
1904 DeactivateAudioInterruptInternal(ZONEID_DEFAULT, interruptToRemove);
1905 }
1906
1907 interruptClients_.erase(sessionId);
1908
1909 // callback in zones map also need to be removed
1910 auto it = zonesMap_.find(zoneId);
1911 if (it != zonesMap_.end() && it->second != nullptr &&
1912 it->second->interruptCbsMap.find(sessionId) != it->second->interruptCbsMap.end()) {
1913 it->second->interruptCbsMap.erase(it->second->interruptCbsMap.find(sessionId));
1914 zonesMap_[zoneId] = it->second;
1915 }
1916 }
1917
1918 // AudioInterruptDeathRecipient impl begin
AudioInterruptDeathRecipient(const std::shared_ptr<AudioInterruptService> & service,uint32_t sessionId)1919 AudioInterruptService::AudioInterruptDeathRecipient::AudioInterruptDeathRecipient(
1920 const std::shared_ptr<AudioInterruptService> &service,
1921 uint32_t sessionId)
1922 : service_(service), sessionId_(sessionId)
1923 {
1924 }
1925
OnRemoteDied(const wptr<IRemoteObject> & remote)1926 void AudioInterruptService::AudioInterruptDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
1927 {
1928 std::shared_ptr<AudioInterruptService> service = service_.lock();
1929 if (service != nullptr) {
1930 service->RemoveClient(ZONEID_DEFAULT, sessionId_);
1931 }
1932 }
1933
1934 // AudioInterruptClient impl begin
AudioInterruptClient(const std::shared_ptr<AudioInterruptCallback> & callback,const sptr<IRemoteObject> & object,const sptr<AudioInterruptDeathRecipient> & deathRecipient)1935 AudioInterruptService::AudioInterruptClient::AudioInterruptClient(
1936 const std::shared_ptr<AudioInterruptCallback> &callback,
1937 const sptr<IRemoteObject> &object,
1938 const sptr<AudioInterruptDeathRecipient> &deathRecipient)
1939 : callback_(callback), object_(object), deathRecipient_(deathRecipient)
1940 {
1941 }
1942
~AudioInterruptClient()1943 AudioInterruptService::AudioInterruptClient::~AudioInterruptClient()
1944 {
1945 if (object_ != nullptr) {
1946 object_->RemoveDeathRecipient(deathRecipient_);
1947 }
1948 }
1949
OnInterrupt(const InterruptEventInternal & interruptEvent)1950 void AudioInterruptService::AudioInterruptClient::OnInterrupt(const InterruptEventInternal &interruptEvent)
1951 {
1952 if (callback_ != nullptr) {
1953 callback_->OnInterrupt(interruptEvent);
1954 }
1955 }
1956
AudioInterruptZoneDump(std::string & dumpString)1957 void AudioInterruptService::AudioInterruptZoneDump(std::string &dumpString)
1958 {
1959 std::unordered_map<int32_t, std::shared_ptr<AudioInterruptZone>> audioInterruptZonesMapDump;
1960 AddDumpInfo(audioInterruptZonesMapDump);
1961 dumpString += "\nAudioInterrupt Zone:\n";
1962 AppendFormat(dumpString, "- %zu AudioInterruptZoneDump (s) available:\n",
1963 zonesMap_.size());
1964 for (const auto&[zoneID, audioInterruptZoneDump] : audioInterruptZonesMapDump) {
1965 if (zoneID < 0) {
1966 continue;
1967 }
1968 AppendFormat(dumpString, " - Zone ID: %d\n", zoneID);
1969 AppendFormat(dumpString, " - Pids size: %zu\n", audioInterruptZoneDump->pids.size());
1970 for (auto pid : audioInterruptZoneDump->pids) {
1971 AppendFormat(dumpString, " - pid: %d\n", pid);
1972 }
1973
1974 AppendFormat(dumpString, " - Interrupt callback size: %zu\n",
1975 audioInterruptZoneDump->interruptCbSessionIdsMap.size());
1976 AppendFormat(dumpString, " - The sessionIds as follow:\n");
1977 for (auto sessionId : audioInterruptZoneDump->interruptCbSessionIdsMap) {
1978 AppendFormat(dumpString, " - SessionId: %u -- have interrupt callback.\n", sessionId);
1979 }
1980
1981 AppendFormat(dumpString, " - Audio policy client proxy callback size: %zu\n",
1982 audioInterruptZoneDump->audioPolicyClientProxyCBClientPidMap.size());
1983 AppendFormat(dumpString, " - The clientPids as follow:\n");
1984 for (auto pid : audioInterruptZoneDump->audioPolicyClientProxyCBClientPidMap) {
1985 AppendFormat(dumpString, " - ClientPid: %d -- have audiopolicy client proxy callback.\n", pid);
1986 }
1987
1988 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList
1989 = audioInterruptZoneDump->audioFocusInfoList;
1990 AppendFormat(dumpString, " - %zu Audio Focus Info (s) available:\n", audioFocusInfoList.size());
1991 uint32_t invalidSessionId = static_cast<uint32_t>(-1);
1992 for (auto iter = audioFocusInfoList.begin(); iter != audioFocusInfoList.end(); ++iter) {
1993 if ((iter->first).sessionId == invalidSessionId) {
1994 continue;
1995 }
1996 AppendFormat(dumpString, " - Pid: %d\n", (iter->first).pid);
1997 AppendFormat(dumpString, " - SessionId: %u\n", (iter->first).sessionId);
1998 AppendFormat(dumpString, " - Audio Focus isPlay Id: %d\n", (iter->first).audioFocusType.isPlay);
1999 AppendFormat(dumpString, " - Stream Name: %s\n",
2000 AudioInfoDumpUtils::GetStreamName((iter->first).audioFocusType.streamType).c_str());
2001 AppendFormat(dumpString, " - Source Name: %s\n",
2002 AudioInfoDumpUtils::GetSourceName((iter->first).audioFocusType.sourceType).c_str());
2003 AppendFormat(dumpString, " - Audio Focus State: %d\n", iter->second);
2004 dumpString += "\n";
2005 }
2006 dumpString += "\n";
2007 }
2008 return;
2009 }
2010
SetCallingUid(uint32_t uid)2011 void AudioInterruptService::AudioInterruptClient::SetCallingUid(uint32_t uid)
2012 {
2013 AUDIO_INFO_LOG("uid: %{public}u", uid);
2014 callingUid_ = uid;
2015 }
2016
GetCallingUid()2017 uint32_t AudioInterruptService::AudioInterruptClient::GetCallingUid()
2018 {
2019 AUDIO_INFO_LOG("callingUid_: %{public}u", callingUid_);
2020 return callingUid_;
2021 }
2022 // LCOV_EXCL_STOP
2023 } // namespace AudioStandard
2024 } // namespace OHOS
2025