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