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