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