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