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