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_utils_c.h"
23 #include "standard_audio_policy_manager_listener_proxy.h"
24 #include "audio_policy_manager_listener_stub_impl.h"
25 #include "audio_policy_manager_listener.h"
26 #include "media_monitor_manager.h"
27 #include "audio_log.h"
28
29 #include "dfx_utils.h"
30 #include "app_mgr_client.h"
31 #include "dfx_msg_manager.h"
32 #include "audio_bundle_manager.h"
33 #include "istandard_audio_service.h"
34 #include "session_manager_lite.h"
35 #include "audio_zone_service.h"
36 #include "standalone_mode_manager.h"
37
38 namespace OHOS {
39 namespace AudioStandard {
40 constexpr uint32_t MEDIA_SA_UID = 1013;
41 constexpr uint32_t THP_EXTRA_SA_UID = 5000;
42 static const int32_t INTERRUPT_SERVICE_TIMEOUT = 10; // 10s
43 static sptr<IStandardAudioService> g_adProxy = nullptr;
44 const std::string DEFAULT_VOLUME_KEY = "default_volume_key_control";
45
46 static const map<InterruptHint, AudioFocuState> HINT_STATE_MAP = {
47 {INTERRUPT_HINT_PAUSE, PAUSE},
48 {INTERRUPT_HINT_DUCK, DUCK},
49 {INTERRUPT_HINT_NONE, ACTIVE},
50 {INTERRUPT_HINT_RESUME, ACTIVE},
51 {INTERRUPT_HINT_UNDUCK, ACTIVE},
52 {INTERRUPT_HINT_MUTE, MUTED}
53 };
54
55 static const map<InterruptHint, InterruptStage> HINT_STAGE_MAP = {
56 {INTERRUPT_HINT_PAUSE, INTERRUPT_STAGE_PAUSED},
57 {INTERRUPT_HINT_DUCK, INTERRUPT_STAGE_DUCK_BEGIN},
58 {INTERRUPT_HINT_STOP, INTERRUPT_STAGE_STOPPED},
59 {INTERRUPT_HINT_RESUME, INTERRUPT_STAGE_RESUMED},
60 {INTERRUPT_HINT_UNDUCK, INTERRUPT_STAGE_DUCK_END}
61 };
62
GetAudioSceneFromAudioInterrupt(const AudioInterrupt & audioInterrupt)63 inline AudioScene GetAudioSceneFromAudioInterrupt(const AudioInterrupt &audioInterrupt)
64 {
65 if (audioInterrupt.audioFocusType.streamType == STREAM_RING) {
66 return AUDIO_SCENE_RINGING;
67 } else if (audioInterrupt.audioFocusType.streamType == STREAM_VOICE_CALL ||
68 audioInterrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION) {
69 return audioInterrupt.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION ?
70 AUDIO_SCENE_PHONE_CALL : AUDIO_SCENE_PHONE_CHAT;
71 } else if (audioInterrupt.audioFocusType.streamType == STREAM_VOICE_RING) {
72 return AUDIO_SCENE_VOICE_RINGING;
73 }
74 return AUDIO_SCENE_DEFAULT;
75 }
76
77 static const std::unordered_map<const AudioScene, const int32_t> SCENE_PRIORITY = {
78 // from high to low
79 {AUDIO_SCENE_PHONE_CALL, 5},
80 {AUDIO_SCENE_VOICE_RINGING, 4},
81 {AUDIO_SCENE_PHONE_CHAT, 3},
82 {AUDIO_SCENE_RINGING, 2},
83 {AUDIO_SCENE_DEFAULT, 1}
84 };
85
86 static const unordered_map<AudioStreamType, int32_t> DEFAULT_STREAM_PRIORITY = {
87 {STREAM_VOICE_CALL, 0},
88 {STREAM_VOICE_CALL_ASSISTANT, 0},
89 {STREAM_VOICE_COMMUNICATION, 0},
90 {STREAM_VOICE_MESSAGE, 1},
91 {STREAM_NOTIFICATION, 2},
92 {STREAM_VOICE_ASSISTANT, 3},
93 {STREAM_RING, 4},
94 {STREAM_VOICE_RING, 4},
95 {STREAM_ALARM, 5},
96 {STREAM_NAVIGATION, 6},
97 {STREAM_MUSIC, 7},
98 {STREAM_MOVIE, 7},
99 {STREAM_SPEECH, 7},
100 {STREAM_GAME, 7},
101 {STREAM_DTMF, 8},
102 {STREAM_SYSTEM, 8},
103 {STREAM_SYSTEM_ENFORCED, 9},
104 };
105
GetAudioScenePriority(const AudioScene audioScene)106 inline int32_t GetAudioScenePriority(const AudioScene audioScene)
107 {
108 if (SCENE_PRIORITY.count(audioScene) == 0) {
109 return SCENE_PRIORITY.at(AUDIO_SCENE_DEFAULT);
110 }
111 return SCENE_PRIORITY.at(audioScene);
112 }
113
AudioInterruptService()114 AudioInterruptService::AudioInterruptService()
115 {
116 zoneManager_.InitService(this);
117 }
118
~AudioInterruptService()119 AudioInterruptService::~AudioInterruptService()
120 {
121 AUDIO_ERR_LOG("should not happen");
122 }
123
Init(sptr<AudioPolicyServer> server)124 void AudioInterruptService::Init(sptr<AudioPolicyServer> server)
125 {
126 std::lock_guard<std::mutex> lock(mutex_);
127
128 // load configuration
129 std::unique_ptr<AudioFocusParser> parser = make_unique<AudioFocusParser>();
130 int32_t ret = parser->LoadConfig(focusCfgMap_);
131 if (ret != SUCCESS) {
132 WriteServiceStartupError();
133 }
134 CHECK_AND_RETURN_LOG(!ret, "load fail");
135
136 AUDIO_DEBUG_LOG("configuration loaded. mapSize: %{public}zu", focusCfgMap_.size());
137
138 policyServer_ = server;
139 clientOnFocus_ = 0;
140 focussedAudioInterruptInfo_ = nullptr;
141
142 zoneManager_.CreateAudioInterruptZone(ZONEID_DEFAULT,
143 AudioZoneFocusStrategy::LOCAL_FOCUS_STRATEGY, false);
144
145 sessionService_ = AudioSessionService::GetAudioSessionService();
146 sessionService_->SetSessionTimeOutCallback(shared_from_this());
147 dfxCollector_ = std::make_unique<AudioInterruptDfxCollector>();
148 }
149
GetAudioServerProxy()150 const sptr<IStandardAudioService> AudioInterruptService::GetAudioServerProxy()
151 {
152 lock_guard<mutex> lock(audioServerProxyMutex_);
153
154 if (g_adProxy == nullptr) {
155 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
156 CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr, "Get samgr failed.");
157
158 sptr<IRemoteObject> object = samgr->GetSystemAbility(AUDIO_DISTRIBUTED_SERVICE_ID);
159 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr,
160 "audio service remote object is NULL.");
161
162 g_adProxy = iface_cast<IStandardAudioService>(object);
163 CHECK_AND_RETURN_RET_LOG(g_adProxy != nullptr, nullptr,
164 "init g_adProxy is NULL.");
165 }
166 const sptr<IStandardAudioService> gsp = g_adProxy;
167 return gsp;
168 }
169
OnSessionTimeout(const int32_t pid)170 void AudioInterruptService::OnSessionTimeout(const int32_t pid)
171 {
172 AUDIO_INFO_LOG("OnSessionTimeout pid %{public}d", pid);
173 AudioXCollie audioXCollie("AudioInterruptService::OnSessionTimeout", INTERRUPT_SERVICE_TIMEOUT,
174 [](void *) {
175 AUDIO_ERR_LOG("OnSessionTimeout timeout");
176 }, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
177 std::lock_guard<std::mutex> lock(mutex_);
178 HandleSessionTimeOutEvent(pid);
179 }
180
GetAudioSessionZoneidByPid(const int32_t pid)181 int32_t AudioInterruptService::GetAudioSessionZoneidByPid(const int32_t pid)
182 {
183 for (const auto &zonePair : zonesMap_) {
184 CHECK_AND_CONTINUE(zonePair.second != nullptr);
185 for (const auto &audioFocusPair : zonePair.second->audioFocusInfoList) {
186 if ((audioFocusPair.first.pid == pid) && (audioFocusPair.first.isAudioSessionInterrupt)) {
187 return zonePair.second->zoneId;
188 }
189 }
190 }
191 AUDIO_ERR_LOG("get audio session zoneid by pid failed!");
192 return ZONEID_INVALID;
193 }
194
HandleSessionTimeOutEvent(const int32_t pid)195 void AudioInterruptService::HandleSessionTimeOutEvent(const int32_t pid)
196 {
197 int32_t zoneId = GetAudioSessionZoneidByPid(pid);
198 if (sessionService_ != nullptr && zoneId != ZONEID_INVALID) {
199 // If there is a fake interrupt, it needs to be deactivated.
200 DeactivateAudioSessionFakeInterrupt(zoneId, pid, true);
201 if (handler_ != nullptr) {
202 // duckVolume = -1.0f, means timeout stop
203 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, INTERRUPT_FORCE, INTERRUPT_HINT_STOP, -1.0f};
204 AudioInterrupt audioInterrupt;
205 audioInterrupt.pid = pid;
206 handler_->SendInterruptEventCallbackForAudioSession(interruptEvent, audioInterrupt);
207 }
208 }
209
210 WriteSessionTimeoutDfxEvent(pid);
211 RemovePlaceholderInterruptForSession(pid, true);
212
213 AudioSessionDeactiveEvent deactiveEvent;
214 deactiveEvent.deactiveReason = AudioSessionDeactiveReason::TIMEOUT;
215 std::pair<int32_t, AudioSessionDeactiveEvent> sessionDeactivePair = {pid, deactiveEvent};
216 if (handler_ != nullptr) {
217 AUDIO_INFO_LOG("AudioSessionService::handler_ is not null. Send event!");
218 handler_->SendAudioSessionDeactiveCallback(sessionDeactivePair);
219 }
220 }
221
ActivateAudioSession(const int32_t zoneId,const int32_t callerPid,const AudioSessionStrategy & strategy,const bool isStandalone)222 int32_t AudioInterruptService::ActivateAudioSession(const int32_t zoneId, const int32_t callerPid,
223 const AudioSessionStrategy &strategy, const bool isStandalone)
224 {
225 AudioXCollie audioXCollie("AudioInterruptService::ActivateAudioSession", INTERRUPT_SERVICE_TIMEOUT,
226 [](void *) {
227 AUDIO_ERR_LOG("ActivateAudioSession timeout");
228 }, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
229 std::unique_lock<std::mutex> lock(mutex_);
230 if (sessionService_ == nullptr) {
231 AUDIO_ERR_LOG("sessionService_ is nullptr!");
232 return ERR_UNKNOWN;
233 }
234 bool isActivated = sessionService_->IsAudioSessionActivated(callerPid);
235 int32_t result = sessionService_->ActivateAudioSession(callerPid, strategy);
236 if (result != SUCCESS) {
237 AUDIO_ERR_LOG("Failed to activate audio session for pid %{public}d!", callerPid);
238 return result;
239 }
240 if (!isActivated) {
241 AUDIO_INFO_LOG("The audio session is activated for the first time. Add active streams");
242 AddActiveInterruptToSession(callerPid);
243 }
244
245 if (sessionService_->IsAudioSessionFocusMode(callerPid)) {
246 AUDIO_INFO_LOG("Enter audio session focus mode, pid = %{public}d", callerPid);
247 if (isStandalone) {
248 AUDIO_INFO_LOG("Current audio session focus mode is Standalone and return");
249 return SUCCESS;
250 }
251 bool updateScene = false;
252 result = ProcessFocusEntryForAudioSession(zoneId, callerPid, updateScene);
253 if (result != SUCCESS || !updateScene) {
254 AUDIO_INFO_LOG(
255 "Process focus for AudioSession, pid: %{public}d, result: %{public}d, updateScene: %{public}d",
256 callerPid,
257 result,
258 updateScene);
259 return result;
260 }
261
262 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
263 // If there is an event of (interrupt + set scene), ActivateAudioInterrupt and DeactivateAudioInterrupt may
264 // experience deadlocks, due to mutex_ and deviceStatusUpdateSharedMutex_ waiting for each other
265 lock.unlock();
266 UpdateAudioSceneFromInterrupt(targetAudioScene, ACTIVATE_AUDIO_INTERRUPT, zoneId);
267 return SUCCESS;
268 }
269
270 return SUCCESS;
271 }
272
IsSessionNeedToFetchOutputDevice(const int32_t callerPid)273 bool AudioInterruptService::IsSessionNeedToFetchOutputDevice(const int32_t callerPid)
274 {
275 std::lock_guard<std::mutex> lock(mutex_);
276 if (sessionService_ == nullptr) {
277 AUDIO_ERR_LOG("sessionService_ is nullptr!");
278 return false;
279 }
280
281 return sessionService_->IsSessionNeedToFetchOutputDevice(callerPid);
282 }
283
SetAudioSessionScene(int32_t callerPid,AudioSessionScene scene)284 int32_t AudioInterruptService::SetAudioSessionScene(int32_t callerPid, AudioSessionScene scene)
285 {
286 std::unique_lock<std::mutex> lock(mutex_);
287 if (sessionService_ == nullptr) {
288 AUDIO_ERR_LOG("sessionService_ is nullptr!");
289 return ERR_UNKNOWN;
290 }
291
292 return sessionService_->SetAudioSessionScene(callerPid, scene);
293 }
294
AddActiveInterruptToSession(const int32_t callerPid)295 void AudioInterruptService::AddActiveInterruptToSession(const int32_t callerPid)
296 {
297 if (sessionService_ == nullptr) {
298 AUDIO_ERR_LOG("sessionService_ is nullptr!");
299 return;
300 }
301 if (!sessionService_->IsAudioSessionActivated(callerPid)) {
302 AUDIO_ERR_LOG("The audio session for pid %{public}d is not active!", callerPid);
303 return;
304 }
305 auto audioSession = sessionService_->GetAudioSessionByPid(callerPid);
306
307 int32_t zoneId = zoneManager_.FindZoneByPid(callerPid);
308 auto itZone = zonesMap_.find(zoneId);
309 CHECK_AND_RETURN_LOG(itZone != zonesMap_.end(), "can not find zoneid");
310 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
311 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
312 audioFocusInfoList = itZone->second->audioFocusInfoList;
313 }
314 for (auto iterActive = audioFocusInfoList.begin(); iterActive != audioFocusInfoList.end(); ++iterActive) {
315 if ((iterActive->first).pid == callerPid && audioSession != nullptr) {
316 audioSession->AddStreamInfo(iterActive->first);
317 }
318 }
319 }
320
DeactivateAudioSession(const int32_t zoneId,const int32_t callerPid)321 int32_t AudioInterruptService::DeactivateAudioSession(const int32_t zoneId, const int32_t callerPid)
322 {
323 AudioXCollie audioXCollie("AudioInterruptService::DeactivateAudioSession", INTERRUPT_SERVICE_TIMEOUT,
324 [](void *) {
325 AUDIO_ERR_LOG("DeactivateAudioSession timeout");
326 }, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
327 std::unique_lock<std::mutex> lock(mutex_);
328 if (sessionService_ == nullptr) {
329 AUDIO_ERR_LOG("sessionService_ is nullptr!");
330 return ERR_UNKNOWN;
331 }
332
333 // audio session v2
334 if (HasAudioSessionFakeInterrupt(zoneId, callerPid)) {
335 std::vector<AudioInterrupt> streamsInSession = sessionService_->GetStreams(callerPid);
336 if (streamsInSession.size() > 0) {
337 // Wait for the streams managed by session to stop
338 DelayToDeactivateStreamsInAudioSession(zoneId, callerPid, streamsInSession);
339 } else {
340 // If there is a fake interrupt, it needs to be deactivated.
341 DeactivateAudioSessionFakeInterrupt(zoneId, callerPid);
342 }
343 }
344
345 int32_t result = sessionService_->DeactivateAudioSession(callerPid);
346 if (result != SUCCESS) {
347 AUDIO_INFO_LOG("Failed to deactivate audio session for pid %{public}d, result %{public}d", callerPid, result);
348 return result;
349 }
350
351 RemovePlaceholderInterruptForSession(callerPid);
352
353 return SUCCESS;
354 }
355
DelayToDeactivateStreamsInAudioSession(const int32_t zoneId,const int32_t callerPid,const std::vector<AudioInterrupt> & streamsInSession)356 void AudioInterruptService::DelayToDeactivateStreamsInAudioSession(
357 const int32_t zoneId, const int32_t callerPid, const std::vector<AudioInterrupt> &streamsInSession)
358 {
359 auto deactivateTask = [this, zoneId, callerPid, streamsInSession] {
360 std::this_thread::sleep_for(std::chrono::seconds(1));
361 std::unique_lock<std::mutex> lock(mutex_);
362 if (sessionService_ == nullptr) {
363 AUDIO_ERR_LOG("sessionService_ is nullptr!");
364 return;
365 }
366
367 // If the audio session is reactivated, there is no need to clean up the session resources.
368 if (sessionService_->IsAudioSessionActivated(callerPid)) {
369 AUDIO_ERR_LOG("Session is reactivated, no need to deactivate interrupt, pid %{public}d", callerPid);
370 return;
371 }
372
373 // If the application deactivates a session, the streams managed by session needs to be stoped.
374 if (handler_ != nullptr) {
375 AUDIO_INFO_LOG("Send InterruptCallbackEvent to all streams for pid %{public}d", callerPid);
376 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, INTERRUPT_FORCE, INTERRUPT_HINT_STOP, 1.0f};
377 for (auto &it : streamsInSession) {
378 handler_->SendInterruptEventWithStreamIdCallback(interruptEvent, it.streamId);
379 }
380 }
381
382 lock.unlock();
383
384 // Sleep for 50 milliseconds to allow streams in the session to stop.
385 std::this_thread::sleep_for(std::chrono::milliseconds(50));
386 // Before deactivating the fake interrupt, all stream interrupts within the session must be stopped.
387 lock.lock();
388 DeactivateAudioSessionFakeInterrupt(zoneId, callerPid);
389 };
390
391 std::thread(deactivateTask).detach();
392 AUDIO_INFO_LOG("Started deactivation thread for pid %{public}d with 1s delay", callerPid);
393 }
394
395 // Deactivate session when fake focus is stopped.
DeactivateAudioSessionInFakeFocusMode(const int32_t pid,InterruptHint hintType)396 void AudioInterruptService::DeactivateAudioSessionInFakeFocusMode(const int32_t pid, InterruptHint hintType)
397 {
398 if (sessionService_ == nullptr) {
399 AUDIO_ERR_LOG("sessionService_ is nullptr!");
400 return;
401 }
402
403 /*
404 Both stop and resume will delete the fake focus, so, need to deactivate audio session,
405 but only stop needs to trigger a callback to the streams managed by audio session.
406 */
407 std::vector<AudioInterrupt> streamsInSession = sessionService_->GetStreams(pid);
408 if (handler_ != nullptr && hintType == INTERRUPT_HINT_STOP) {
409 AUDIO_INFO_LOG("Send InterruptCallbackEvent to all streams for pid %{public}d", pid);
410 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, INTERRUPT_FORCE, INTERRUPT_HINT_STOP, 1.0f};
411 for (auto &it : streamsInSession) {
412 handler_->SendInterruptEventWithStreamIdCallback(interruptEvent, it.streamId);
413 }
414 }
415
416 int32_t result = sessionService_->DeactivateAudioSession(pid);
417 if (result != SUCCESS) {
418 AUDIO_INFO_LOG("Failed to deactivate audio session for pid %{public}d, result %{public}d", pid, result);
419 return;
420 }
421
422 RemovePlaceholderInterruptForSession(pid);
423
424 AudioSessionDeactiveEvent deactiveEvent;
425 deactiveEvent.deactiveReason = AudioSessionDeactiveReason::LOW_PRIORITY;
426 std::pair<int32_t, AudioSessionDeactiveEvent> sessionDeactivePair = {pid, deactiveEvent};
427 if (handler_ != nullptr) {
428 AUDIO_INFO_LOG("AudioSessionService::handler_ is not null. Send event!");
429 handler_->SendAudioSessionDeactiveCallback(sessionDeactivePair);
430 }
431 }
432
DeactivateAudioSessionFakeInterrupt(const int32_t zoneId,const int32_t callerPid,bool isSessionTimeout)433 void AudioInterruptService::DeactivateAudioSessionFakeInterrupt(
434 const int32_t zoneId, const int32_t callerPid, bool isSessionTimeout)
435 {
436 auto itZone = zonesMap_.find(zoneId);
437 CHECK_AND_RETURN_LOG((itZone != zonesMap_.end()) && (itZone->second != nullptr), "can not find zone");
438 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList = itZone->second->audioFocusInfoList;
439
440 auto isPresent = [callerPid] (const std::pair<AudioInterrupt, AudioFocuState> &pair) {
441 return pair.first.pid == callerPid && pair.first.isAudioSessionInterrupt;
442 };
443 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isPresent);
444 if (iter == audioFocusInfoList.end()) {
445 AUDIO_INFO_LOG("Can not find audio session fake interrupt for pid %{public}d", callerPid);
446 return;
447 }
448
449 DeactivateAudioInterruptInternal(zoneId, iter->first, isSessionTimeout);
450 }
451
HasAudioSessionFakeInterrupt(const int32_t zoneId,const int32_t callerPid)452 bool AudioInterruptService::HasAudioSessionFakeInterrupt(const int32_t zoneId, const int32_t callerPid)
453 {
454 auto itZone = zonesMap_.find(zoneId);
455 CHECK_AND_RETURN_RET_LOG((itZone != zonesMap_.end()) && (itZone->second != nullptr), false, "can not find zone");
456 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList = itZone->second->audioFocusInfoList;
457
458 auto isPresent = [callerPid] (const std::pair<AudioInterrupt, AudioFocuState> &pair) {
459 return pair.first.pid == callerPid && pair.first.isAudioSessionInterrupt;
460 };
461 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isPresent);
462 return iter != audioFocusInfoList.end();
463 }
464
RemovePlaceholderInterruptForSession(const int32_t callerPid,bool isSessionTimeout)465 void AudioInterruptService::RemovePlaceholderInterruptForSession(const int32_t callerPid, bool isSessionTimeout)
466 {
467 if (sessionService_ == nullptr) {
468 AUDIO_ERR_LOG("sessionService_ is nullptr!");
469 return;
470 }
471 if (sessionService_->IsAudioSessionActivated(callerPid)) {
472 AUDIO_ERR_LOG("The audio session for pid %{public}d is still active!", callerPid);
473 return;
474 }
475
476 int32_t zoneId = zoneManager_.FindZoneByPid(callerPid);
477 auto itZone = zonesMap_.find(zoneId);
478 CHECK_AND_RETURN_LOG(itZone != zonesMap_.end(), "can not find zoneid");
479 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
480 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
481 audioFocusInfoList = itZone->second->audioFocusInfoList;
482 }
483
484 for (auto iter = audioFocusInfoList.begin(); iter != audioFocusInfoList.end(); ++iter) {
485 if (iter->first.pid == callerPid && iter->second == PLACEHOLDER) {
486 AudioInterrupt placeholder = iter->first;
487 AUDIO_INFO_LOG("Remove stream id %{public}u (placeholder for pid%{public}d)",
488 placeholder.streamId, callerPid);
489 DeactivateAudioInterruptInternal(zoneId, placeholder, isSessionTimeout);
490 }
491 }
492 }
493
IsAudioSessionActivated(const int32_t callerPid)494 bool AudioInterruptService::IsAudioSessionActivated(const int32_t callerPid)
495 {
496 std::lock_guard<std::mutex> lock(mutex_);
497 if (sessionService_ == nullptr) {
498 AUDIO_ERR_LOG("sessionService_ is nullptr!");
499 return false;
500 }
501 return sessionService_->IsAudioSessionActivated(callerPid);
502 }
503
IsCanMixInterrupt(const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt)504 bool AudioInterruptService::IsCanMixInterrupt(const AudioInterrupt &incomingInterrupt,
505 const AudioInterrupt &activeInterrupt)
506 {
507 if (incomingInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID &&
508 (activeInterrupt.audioFocusType.streamType == STREAM_VOICE_CALL ||
509 activeInterrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION)) {
510 AUDIO_INFO_LOG("The capturer can not mix with voice call");
511 return false;
512 }
513 if ((incomingInterrupt.audioFocusType.streamType == STREAM_VOICE_CALL ||
514 incomingInterrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION) &&
515 activeInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID) {
516 AUDIO_INFO_LOG("The voice call can not mix with capturer");
517 return false;
518 }
519 if (incomingInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID &&
520 activeInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID) {
521 AUDIO_INFO_LOG("The capturer can not mix with another capturer");
522 return false;
523 }
524 return true;
525 }
526
CanMixForSession(const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt,const AudioFocusEntry & focusEntry)527 bool AudioInterruptService::CanMixForSession(const AudioInterrupt &incomingInterrupt,
528 const AudioInterrupt &activeInterrupt, const AudioFocusEntry &focusEntry)
529 {
530 if (focusEntry.isReject && incomingInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID) {
531 // The incoming stream is a capturer and the default policy is deny incoming.
532 AUDIO_INFO_LOG("The incoming audio capturer should be denied!");
533 return false;
534 }
535 if (!IsCanMixInterrupt(incomingInterrupt, activeInterrupt)) {
536 AUDIO_INFO_LOG("Two Stream Cannot Mix! incoming=%{public}d, active=%{public}d",
537 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
538 return false;
539 }
540 if (incomingInterrupt.audioFocusType.streamType == STREAM_INTERNAL_FORCE_STOP ||
541 activeInterrupt.audioFocusType.streamType == STREAM_INTERNAL_FORCE_STOP) {
542 AUDIO_INFO_LOG("STREAM_INTERNAL_FORCE_STOP! incomingInterrupt=%{public}d, activeInterrupt=%{public}d",
543 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
544 return false;
545 }
546 bool result = false;
547 result = CanMixForIncomingSession(incomingInterrupt, activeInterrupt, focusEntry);
548 if (result) {
549 AUDIO_INFO_LOG("Two streams can mix because of the incoming session. incoming %{public}d, active %{public}d",
550 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
551 return result;
552 }
553 result = CanMixForActiveSession(incomingInterrupt, activeInterrupt, focusEntry);
554 if (result) {
555 AUDIO_INFO_LOG("Two streams can mix because of the active session. incoming %{public}d, active %{public}d",
556 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
557 return result;
558 }
559 AUDIO_INFO_LOG("Two streams can not mix. incoming %{public}d, active %{public}d",
560 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
561 return result;
562 }
563
CanMixForIncomingSession(const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt,const AudioFocusEntry & focusEntry)564 bool AudioInterruptService::CanMixForIncomingSession(const AudioInterrupt &incomingInterrupt,
565 const AudioInterrupt &activeInterrupt, const AudioFocusEntry &focusEntry)
566 {
567 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(incomingInterrupt.pid)) {
568 // The strategy of activated AudioSession is the one with the highest priority.
569 std::shared_ptr<AudioSession> incomingSession = sessionService_->GetAudioSessionByPid(incomingInterrupt.pid);
570 if (incomingSession == nullptr) {
571 AUDIO_ERR_LOG("incomingSession is nullptr!");
572 return false;
573 }
574 AudioConcurrencyMode concurrencyMode = (incomingSession->GetSessionStrategy()).concurrencyMode;
575 if (concurrencyMode != AudioConcurrencyMode::MIX_WITH_OTHERS) {
576 AUDIO_INFO_LOG("The concurrency mode of incoming session is %{public}d",
577 static_cast<int32_t>(concurrencyMode));
578 return false;
579 }
580 // The concurrencyMode of incoming session is MIX_WITH_OTHERS. Need to check the priority.
581 if (IsIncomingStreamLowPriority(focusEntry)) {
582 bool isSameType = AudioSessionService::IsSameTypeForAudioSession(
583 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
584 AUDIO_INFO_LOG("The incoming stream is low priority. isSameType: %{public}d.", isSameType);
585 return isSameType;
586 }
587 AUDIO_INFO_LOG("The concurrency mode of incoming session is MIX_WITH_OTHERS. Skip the interrupt operation");
588 return true;
589 } else {
590 // There is no activated AudioSession for incoming stream. Check the strategy of AudioInterrupt.
591 AudioConcurrencyMode concurrencyMode = incomingInterrupt.sessionStrategy.concurrencyMode;
592 AUDIO_INFO_LOG("The concurrency mode of incoming interrupt: %{public}d", static_cast<int32_t>(concurrencyMode));
593 if (concurrencyMode == AudioConcurrencyMode::SILENT ||
594 concurrencyMode == AudioConcurrencyMode::MIX_WITH_OTHERS) {
595 AUDIO_INFO_LOG("incoming stream is explicitly SILENT or MIX_WITH_OTHERS.");
596 return true;
597 }
598 }
599 return false;
600 }
601
CanMixForActiveSession(const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt,const AudioFocusEntry & focusEntry)602 bool AudioInterruptService::CanMixForActiveSession(const AudioInterrupt &incomingInterrupt,
603 const AudioInterrupt &activeInterrupt, const AudioFocusEntry &focusEntry)
604 {
605 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(activeInterrupt.pid)) {
606 // The strategy of activated AudioSession is the one with the highest priority.
607 std::shared_ptr<AudioSession> activeSession = sessionService_->GetAudioSessionByPid(activeInterrupt.pid);
608 if (activeSession == nullptr) {
609 AUDIO_ERR_LOG("activeSession is nullptr!");
610 return false;
611 }
612 AudioConcurrencyMode concurrencyMode = (activeSession->GetSessionStrategy()).concurrencyMode;
613 if (concurrencyMode != AudioConcurrencyMode::MIX_WITH_OTHERS) {
614 AUDIO_INFO_LOG("The concurrency mode of active session is %{public}d",
615 static_cast<int32_t>(concurrencyMode));
616 return false;
617 }
618 // The concurrencyMode of active session is MIX_WITH_OTHERS. Need to check the priority.
619 if (IsActiveStreamLowPriority(focusEntry)) {
620 bool isSameType = AudioSessionService::IsSameTypeForAudioSession(
621 incomingInterrupt.audioFocusType.streamType, activeInterrupt.audioFocusType.streamType);
622 AUDIO_INFO_LOG("The active stream is low priority. isSameType: %{public}d.", isSameType);
623 return isSameType;
624 }
625 AUDIO_INFO_LOG("The concurrency mode of active session is MIX_WITH_OTHERS. Skip the interrupt operation");
626 return true;
627 } else {
628 // There is no active AudioSession for active stream. Check the strategy of AudioInterrupt.
629 AudioConcurrencyMode concurrencyMode = activeInterrupt.sessionStrategy.concurrencyMode;
630 AUDIO_INFO_LOG("The concurrency mode of active interrupt: %{public}d", static_cast<int32_t>(concurrencyMode));
631 if (concurrencyMode == AudioConcurrencyMode::SILENT ||
632 concurrencyMode == AudioConcurrencyMode::MIX_WITH_OTHERS) {
633 AUDIO_INFO_LOG("active stream is explicitly SILENT or MIX_WITH_OTHERS.");
634 return true;
635 }
636 }
637 return false;
638 }
639
IsIncomingStreamLowPriority(const AudioFocusEntry & focusEntry)640 bool AudioInterruptService::IsIncomingStreamLowPriority(const AudioFocusEntry &focusEntry)
641 {
642 if (focusEntry.isReject) {
643 return true;
644 }
645 if (focusEntry.actionOn == INCOMING) {
646 if (focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
647 focusEntry.hintType == INTERRUPT_HINT_STOP ||
648 focusEntry.hintType == INTERRUPT_HINT_DUCK) {
649 return true;
650 }
651 }
652 return false;
653 }
654
IsActiveStreamLowPriority(const AudioFocusEntry & focusEntry)655 bool AudioInterruptService::IsActiveStreamLowPriority(const AudioFocusEntry &focusEntry)
656 {
657 if (focusEntry.actionOn == CURRENT) {
658 if (focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
659 focusEntry.hintType == INTERRUPT_HINT_STOP ||
660 focusEntry.hintType == INTERRUPT_HINT_DUCK) {
661 return true;
662 }
663 }
664 return false;
665 }
666
WriteServiceStartupError()667 void AudioInterruptService::WriteServiceStartupError()
668 {
669 AUTO_CTRACE("SYSEVENT FAULT EVENT AUDIO_SERVICE_STARTUP_ERROR, SERVICE_ID: %d, ERROR_CODE: %d",
670 Media::MediaMonitor::AUDIO_POLICY_SERVICE_ID, Media::MediaMonitor::AUDIO_INTERRUPT_SERVER);
671 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
672 Media::MediaMonitor::AUDIO, Media::MediaMonitor::AUDIO_SERVICE_STARTUP_ERROR,
673 Media::MediaMonitor::FAULT_EVENT);
674 bean->Add("SERVICE_ID", static_cast<int32_t>(Media::MediaMonitor::AUDIO_POLICY_SERVICE_ID));
675 bean->Add("ERROR_CODE", static_cast<int32_t>(Media::MediaMonitor::AUDIO_INTERRUPT_SERVER));
676 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
677 }
678
AddDumpInfo(std::unordered_map<int32_t,std::shared_ptr<AudioInterruptZone>> & audioInterruptZonesMapDump)679 void AudioInterruptService::AddDumpInfo(std::unordered_map<int32_t, std::shared_ptr<AudioInterruptZone>>
680 &audioInterruptZonesMapDump)
681 {
682 std::lock_guard<std::mutex> lock(mutex_);
683
684 for (const auto&[zoneId, audioInterruptZone] : zonesMap_) {
685 std::shared_ptr<AudioInterruptZone> zoneDump = make_shared<AudioInterruptZone>();
686 zoneDump->zoneId = zoneId;
687 for (auto interruptCbInfo : audioInterruptZone->interruptCbsMap) {
688 zoneDump->interruptCbStreamIdsMap.insert(interruptCbInfo.first);
689 }
690 for (auto audioPolicyClientProxyCBInfo : audioInterruptZone->audioPolicyClientProxyCBMap) {
691 zoneDump->audioPolicyClientProxyCBClientPidMap.insert(audioPolicyClientProxyCBInfo.first);
692 }
693 zoneDump->audioFocusInfoList = audioInterruptZone->audioFocusInfoList;
694 audioInterruptZonesMapDump[zoneId] = zoneDump;
695 }
696 }
697
SetCallbackHandler(std::shared_ptr<AudioPolicyServerHandler> handler)698 void AudioInterruptService::SetCallbackHandler(std::shared_ptr<AudioPolicyServerHandler> handler)
699 {
700 handler_ = handler;
701 }
702
SetAudioManagerInterruptCallback(const sptr<IRemoteObject> & object)703 int32_t AudioInterruptService::SetAudioManagerInterruptCallback(const sptr<IRemoteObject> &object)
704 {
705 CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM,
706 "object is nullptr");
707
708 sptr<IStandardAudioPolicyManagerListener> listener = iface_cast<IStandardAudioPolicyManagerListener>(object);
709 CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM,
710 "obj cast failed");
711
712 std::shared_ptr<AudioInterruptCallback> callback = std::make_shared<AudioPolicyManagerListenerCallback>(listener);
713 CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM,
714 "create cb failed");
715
716 int32_t callerPid = IPCSkeleton::GetCallingPid();
717
718 if (handler_ != nullptr) {
719 handler_->AddExternInterruptCbsMap(callerPid, callback);
720 }
721
722 AUDIO_DEBUG_LOG("for client id %{public}d done", callerPid);
723
724 return SUCCESS;
725 }
726
UnsetAudioManagerInterruptCallback()727 int32_t AudioInterruptService::UnsetAudioManagerInterruptCallback()
728 {
729 int32_t callerPid = IPCSkeleton::GetCallingPid();
730 if (handler_ != nullptr) {
731 return handler_->RemoveExternInterruptCbsMap(callerPid);
732 }
733
734 return SUCCESS;
735 }
736
RequestAudioFocus(const int32_t clientId,const AudioInterrupt & audioInterrupt)737 int32_t AudioInterruptService::RequestAudioFocus(const int32_t clientId, const AudioInterrupt &audioInterrupt)
738 {
739 AUDIO_INFO_LOG("in");
740 std::lock_guard<std::mutex> lock(mutex_);
741
742 if (clientOnFocus_ == clientId) {
743 AUDIO_INFO_LOG("client already has focus");
744 NotifyFocusGranted(clientId, audioInterrupt);
745 return SUCCESS;
746 }
747
748 if (focussedAudioInterruptInfo_ != nullptr) {
749 AUDIO_INFO_LOG("Existing stream: %{public}d, incoming stream: %{public}d",
750 (focussedAudioInterruptInfo_->audioFocusType).streamType, audioInterrupt.audioFocusType.streamType);
751 NotifyFocusAbandoned(clientOnFocus_, *focussedAudioInterruptInfo_);
752 AbandonAudioFocusInternal(clientOnFocus_, *focussedAudioInterruptInfo_);
753 }
754
755 NotifyFocusGranted(clientId, audioInterrupt);
756
757 return SUCCESS;
758 }
759
AbandonAudioFocus(const int32_t clientId,const AudioInterrupt & audioInterrupt)760 int32_t AudioInterruptService::AbandonAudioFocus(const int32_t clientId, const AudioInterrupt &audioInterrupt)
761 {
762 AUDIO_INFO_LOG("in");
763 std::lock_guard<std::mutex> lock(mutex_);
764
765 return AbandonAudioFocusInternal(clientId, audioInterrupt);
766 }
767
SetAudioInterruptCallback(const int32_t zoneId,const uint32_t streamId,const sptr<IRemoteObject> & object,uint32_t uid)768 int32_t AudioInterruptService::SetAudioInterruptCallback(const int32_t zoneId, const uint32_t streamId,
769 const sptr<IRemoteObject> &object, uint32_t uid)
770 {
771 std::lock_guard<std::mutex> lock(mutex_);
772
773 // maybe add check session id validation here
774
775 CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM, "object is nullptr");
776
777 sptr<IStandardAudioPolicyManagerListener> listener = iface_cast<IStandardAudioPolicyManagerListener>(object);
778 CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM, "obj cast failed");
779
780 std::shared_ptr<AudioInterruptCallback> callback = std::make_shared<AudioPolicyManagerListenerCallback>(listener);
781 CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "create cb failed");
782
783 if (interruptClients_.find(streamId) == interruptClients_.end()) {
784 // Register client death recipient first
785 sptr<AudioInterruptDeathRecipient> deathRecipient =
786 new AudioInterruptDeathRecipient(shared_from_this(), streamId);
787 object->AddDeathRecipient(deathRecipient);
788
789 std::shared_ptr<AudioInterruptClient> client =
790 std::make_shared<AudioInterruptClient>(callback, object, deathRecipient);
791 uint32_t callingUid = static_cast<uint32_t>(IPCSkeleton::GetCallingUid());
792 if (callingUid == MEDIA_SA_UID) {
793 callingUid = uid;
794 }
795 client->SetCallingUid(callingUid);
796
797 interruptClients_[streamId] = client;
798
799 // just record in zone map, not used currently
800 auto it = zonesMap_.find(zoneId);
801 if (it != zonesMap_.end() && it->second != nullptr) {
802 it->second->interruptCbsMap[streamId] = callback;
803 zonesMap_[zoneId] = it->second;
804 }
805 } else {
806 AUDIO_ERR_LOG("%{public}u callback already exist", streamId);
807 return ERR_INVALID_PARAM;
808 }
809
810 return SUCCESS;
811 }
812
UnsetAudioInterruptCallback(const int32_t zoneId,const uint32_t streamId)813 int32_t AudioInterruptService::UnsetAudioInterruptCallback(const int32_t zoneId, const uint32_t streamId)
814 {
815 std::lock_guard<std::mutex> lock(mutex_);
816
817 if (interruptClients_.erase(streamId) == 0) {
818 AUDIO_ERR_LOG("streamId %{public}u not present", streamId);
819 return ERR_INVALID_PARAM;
820 }
821
822 auto it = zonesMap_.find(zoneId);
823 if (it != zonesMap_.end() && it->second != nullptr &&
824 it->second->interruptCbsMap.find(streamId) != it->second->interruptCbsMap.end()) {
825 it->second->interruptCbsMap.erase(it->second->interruptCbsMap.find(streamId));
826 zonesMap_[zoneId] = it->second;
827 }
828
829 return SUCCESS;
830 }
831
AudioInterruptIsActiveInFocusList(const int32_t zoneId,const uint32_t incomingStreamId)832 bool AudioInterruptService::AudioInterruptIsActiveInFocusList(const int32_t zoneId, const uint32_t incomingStreamId)
833 {
834 auto itZone = zonesMap_.find(zoneId);
835 if (itZone == zonesMap_.end()) {
836 AUDIO_ERR_LOG("Can not find zoneid");
837 return false;
838 }
839 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
840 audioFocusInfoList = itZone->second->audioFocusInfoList;
841 auto isPresent = [incomingStreamId] (const std::pair<AudioInterrupt, AudioFocuState> &pair) {
842 // If the stream id has been active or ducked, no need to activate audio interrupt again.
843 return pair.first.streamId == incomingStreamId && (pair.second == ACTIVE || pair.second == DUCK);
844 };
845 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isPresent);
846 if (iter != audioFocusInfoList.end()) {
847 return true;
848 }
849 return false;
850 }
851
HandleAppStreamType(const int32_t zoneId,AudioInterrupt & audioInterrupt)852 void AudioInterruptService::HandleAppStreamType(const int32_t zoneId, AudioInterrupt &audioInterrupt)
853 {
854 // In audio session mode, the focus policy is uniformly managed by the session and not handled separately here.
855 if (sessionService_ != nullptr && sessionService_->IsAudioSessionFocusMode(audioInterrupt.pid)) {
856 AUDIO_DEBUG_LOG(
857 "In audio session focus mode, no need to check app stream type. pid = %{public}d", audioInterrupt.pid);
858 return;
859 }
860
861 if (HasAudioSessionFakeInterrupt(zoneId, audioInterrupt.pid)) {
862 return;
863 }
864
865 // Force game app use game interrupt strategy, not affected by InterruptEventCallbackType.
866 // DO NOT use IsGameAvoidCallbackCase to replace it.
867 if (GetClientTypeByStreamId(audioInterrupt.streamId) != CLIENT_TYPE_GAME) {
868 return;
869 }
870
871 if (audioInterrupt.audioFocusType.streamType == STREAM_MUSIC) {
872 AUDIO_INFO_LOG("game create STREAM_MUSIC, turn into STREAM_GAME");
873 audioInterrupt.audioFocusType.streamType = STREAM_GAME;
874 }
875 }
876
ActivateAudioInterrupt(const int32_t zoneId,const AudioInterrupt & audioInterrupt,const bool isUpdatedAudioStrategy)877 int32_t AudioInterruptService::ActivateAudioInterrupt(
878 const int32_t zoneId, const AudioInterrupt &audioInterrupt, const bool isUpdatedAudioStrategy)
879 {
880 AudioXCollie audioXCollie("AudioInterruptService::ActivateAudioInterrupt", INTERRUPT_SERVICE_TIMEOUT,
881 [](void *) {
882 AUDIO_ERR_LOG("ActivateAudioInterrupt timeout");
883 }, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
884 std::unique_lock<std::mutex> lock(mutex_);
885 bool updateScene = false;
886 int32_t ret = ActivateAudioInterruptCoreProcedure(zoneId, audioInterrupt, isUpdatedAudioStrategy, updateScene);
887 if (ret != SUCCESS || !updateScene) {
888 return ret;
889 }
890
891 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
892 // If there is an event of (interrupt + set scene), ActivateAudioInterrupt and DeactivateAudioInterrupt may
893 // experience deadlocks, due to mutex_ and deviceStatusUpdateSharedMutex_ waiting for each other
894 lock.unlock();
895 UpdateAudioSceneFromInterrupt(targetAudioScene, ACTIVATE_AUDIO_INTERRUPT, zoneId);
896 return SUCCESS;
897 }
898
ActivateAudioInterruptCoreProcedure(const int32_t zoneId,const AudioInterrupt & audioInterrupt,const bool isUpdatedAudioStrategy,bool & updateScene)899 int32_t AudioInterruptService::ActivateAudioInterruptCoreProcedure(
900 const int32_t zoneId, const AudioInterrupt &audioInterrupt, const bool isUpdatedAudioStrategy, bool &updateScene)
901 {
902 PrintLogsOfFocusStrategyBaseMusic(audioInterrupt); // Print logs for automatic detection tools.
903 if (isPreemptMode_) {
904 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, INTERRUPT_FORCE, INTERRUPT_HINT_STOP, 1.0f};
905 SendInterruptEventToIncomingStream(interruptEvent, audioInterrupt);
906 return ERR_FOCUS_DENIED;
907 }
908
909 return ActivateAudioInterruptInternal(zoneId, audioInterrupt, isUpdatedAudioStrategy, updateScene);
910 }
911
ActivateAudioInterruptInternal(const int32_t zoneId,const AudioInterrupt & audioInterrupt,const bool isUpdatedAudioStrategy,bool & updateScene)912 int32_t AudioInterruptService::ActivateAudioInterruptInternal(const int32_t zoneId,
913 const AudioInterrupt &audioInterrupt, const bool isUpdatedAudioStrategy, bool &updateScene)
914 {
915 AudioInterrupt currAudioInterrupt = audioInterrupt;
916 HandleAppStreamType(zoneId, currAudioInterrupt);
917 AudioStreamType streamType = currAudioInterrupt.audioFocusType.streamType;
918 uint32_t incomingStreamId = currAudioInterrupt.streamId;
919 AUDIO_INFO_LOG("streamId: %{public}u pid: %{public}d streamType: %{public}d zoneId: %{public}d"\
920 "usage: %{public}d source: %{public}d",
921 incomingStreamId, currAudioInterrupt.pid, streamType, zoneId,
922 currAudioInterrupt.streamUsage, (currAudioInterrupt.audioFocusType).sourceType);
923
924 if (AudioInterruptIsActiveInFocusList(zoneId, incomingStreamId) && !isUpdatedAudioStrategy) {
925 AUDIO_INFO_LOG("Stream is active in focus list, no need to active audio interrupt.");
926 return SUCCESS;
927 }
928 ResetNonInterruptControl(currAudioInterrupt);
929 bool shouldReturnSuccess = false;
930 ProcessAudioScene(currAudioInterrupt, incomingStreamId, zoneId, shouldReturnSuccess);
931 if (shouldReturnSuccess) {
932 return SUCCESS;
933 }
934
935 if (ShouldBypassAudioSessionFocus(zoneId, audioInterrupt)) {
936 TryHandleStreamCallbackInSession(zoneId, audioInterrupt);
937 SendActiveVolumeTypeChangeEvent(zoneId);
938 updateScene = true;
939 AUDIO_INFO_LOG("Bypass Audio session focus, pid = %{public}d", audioInterrupt.pid);
940 return SUCCESS;
941 }
942
943 // Process ProcessFocusEntryTable for current audioFocusInfoList
944 int32_t ret = ProcessFocusEntry(zoneId, currAudioInterrupt);
945 CHECK_AND_RETURN_RET_LOG(!ret, ERR_FOCUS_DENIED, "request rejected");
946 if (zoneId == ZONEID_DEFAULT) {
947 updateScene = true;
948 }
949 return SUCCESS;
950 }
951
PrintLogsOfFocusStrategyBaseMusic(const AudioInterrupt & audioInterrupt)952 void AudioInterruptService::PrintLogsOfFocusStrategyBaseMusic(const AudioInterrupt &audioInterrupt)
953 {
954 // The log printed by this function is critical, so please do not modify it.
955 AudioFocusType audioFocusType;
956 audioFocusType.streamType = AudioStreamType::STREAM_MUSIC;
957 std::pair<AudioFocusType, AudioFocusType> focusPair =
958 std::make_pair(audioFocusType, audioInterrupt.audioFocusType);
959 CHECK_AND_RETURN_LOG(focusCfgMap_.find(focusPair) != focusCfgMap_.end(), "no focus cfg");
960 AudioFocusEntry focusEntry = focusCfgMap_[focusPair];
961 if (focusEntry.actionOn != CURRENT) {
962 AUDIO_WARNING_LOG("The audio focus strategy based on music: forceType: %{public}d, hintType: %{public}d, " \
963 "actionOn: %{public}d", focusEntry.forceType, focusEntry.hintType, focusEntry.actionOn);
964 return;
965 }
966 // Update focus strategy by audio session.
967 AudioConcurrencyMode concurrencyMode = AudioConcurrencyMode::INVALID;
968 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(audioInterrupt.pid)) {
969 std::shared_ptr<AudioSession> incomingSession = sessionService_->GetAudioSessionByPid(audioInterrupt.pid);
970 if (incomingSession != nullptr) {
971 concurrencyMode = (incomingSession->GetSessionStrategy()).concurrencyMode;
972 }
973 } else {
974 concurrencyMode = audioInterrupt.sessionStrategy.concurrencyMode;
975 }
976 switch (concurrencyMode) {
977 case AudioConcurrencyMode::MIX_WITH_OTHERS:
978 case AudioConcurrencyMode::SILENT:
979 if (focusEntry.hintType == INTERRUPT_HINT_DUCK ||
980 focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
981 focusEntry.hintType == INTERRUPT_HINT_STOP) {
982 focusEntry.hintType = INTERRUPT_HINT_NONE;
983 }
984 break;
985
986 case AudioConcurrencyMode::DUCK_OTHERS:
987 if (focusEntry.hintType == INTERRUPT_HINT_DUCK ||
988 focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
989 focusEntry.hintType == INTERRUPT_HINT_STOP) {
990 focusEntry.hintType = INTERRUPT_HINT_DUCK;
991 }
992 break;
993 case AudioConcurrencyMode::PAUSE_OTHERS:
994 if (focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
995 focusEntry.hintType == INTERRUPT_HINT_STOP) {
996 focusEntry.hintType = INTERRUPT_HINT_PAUSE;
997 }
998 break;
999 default:
1000 break;
1001 }
1002 AUDIO_WARNING_LOG("The audio focus strategy based on music: forceType: %{public}d, hintType: %{public}d, " \
1003 "actionOn: %{public}d", focusEntry.forceType, focusEntry.hintType, focusEntry.actionOn);
1004 return;
1005 }
1006
ResetNonInterruptControl(AudioInterrupt audioInterrupt)1007 void AudioInterruptService::ResetNonInterruptControl(AudioInterrupt audioInterrupt)
1008 {
1009 if (!IsGameAvoidCallbackCase(audioInterrupt)) {
1010 return;
1011 }
1012 AUDIO_INFO_LOG("Reset non-interrupt control for %{public}u", audioInterrupt.streamId);
1013 const sptr<IStandardAudioService> gsp = GetAudioServerProxy();
1014 std::string identity = IPCSkeleton::ResetCallingIdentity();
1015 CHECK_AND_RETURN_LOG(gsp != nullptr, "error for audio server proxy null");
1016 gsp->SetNonInterruptMute(audioInterrupt.streamId, false);
1017 IPCSkeleton::SetCallingIdentity(identity);
1018 }
1019
DeactivateAudioInterrupt(const int32_t zoneId,const AudioInterrupt & audioInterrupt)1020 int32_t AudioInterruptService::DeactivateAudioInterrupt(const int32_t zoneId, const AudioInterrupt &audioInterrupt)
1021 {
1022 AudioXCollie audioXCollie("AudioInterruptService::DeactivateAudioInterrupt", INTERRUPT_SERVICE_TIMEOUT,
1023 [](void *) {
1024 AUDIO_ERR_LOG("DeactivateAudioInterrupt timeout");
1025 }, nullptr, AUDIO_XCOLLIE_FLAG_LOG | AUDIO_XCOLLIE_FLAG_RECOVERY);
1026 std::unique_lock<std::mutex> lock(mutex_);
1027
1028 AudioInterrupt currAudioInterrupt = audioInterrupt;
1029 HandleAppStreamType(zoneId, currAudioInterrupt);
1030 AUDIO_INFO_LOG("streamId: %{public}u pid: %{public}d streamType: %{public}d "\
1031 "usage: %{public}d source: %{public}d",
1032 currAudioInterrupt.streamId, currAudioInterrupt.pid, (currAudioInterrupt.audioFocusType).streamType,
1033 currAudioInterrupt.streamUsage, (currAudioInterrupt.audioFocusType).sourceType);
1034
1035 DeactivateAudioInterruptInternal(zoneId, currAudioInterrupt);
1036
1037 if (HasAudioSessionFakeInterrupt(zoneId, currAudioInterrupt.pid)) {
1038 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
1039 // If there is an event of (interrupt + set scene), ActivateAudioInterrupt and DeactivateAudioInterrupt may
1040 // experience deadlocks, due to mutex_ and deviceStatusUpdateSharedMutex_ waiting for each other
1041 lock.unlock();
1042 UpdateAudioSceneFromInterrupt(targetAudioScene, DEACTIVATE_AUDIO_INTERRUPT, zoneId);
1043 }
1044
1045 return SUCCESS;
1046 }
1047
ClearAudioFocusInfoListOnAccountsChanged(const int32_t & id)1048 void AudioInterruptService::ClearAudioFocusInfoListOnAccountsChanged(const int32_t &id)
1049 {
1050 std::lock_guard<std::mutex> lock(mutex_);
1051 AUDIO_INFO_LOG("start DeactivateAudioInterrupt, current id:%{public}d", id);
1052 ClearAudioFocusInfoList();
1053 }
1054
ClearAudioFocusInfoList()1055 int32_t AudioInterruptService::ClearAudioFocusInfoList()
1056 {
1057 AUDIO_INFO_LOG("start clear audio focusInfo list");
1058 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, INTERRUPT_FORCE, INTERRUPT_HINT_STOP, 1.0f};
1059 for (const auto&[zoneId, audioInterruptZone] : zonesMap_) {
1060 CHECK_AND_CONTINUE_LOG(audioInterruptZone != nullptr, "audioInterruptZone is nullptr");
1061 std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator it =
1062 audioInterruptZone->audioFocusInfoList.begin();
1063 while (it != audioInterruptZone->audioFocusInfoList.end()) {
1064 if (!isPreemptMode_ &&
1065 ((*it).first.streamUsage == STREAM_USAGE_VOICE_MODEM_COMMUNICATION ||
1066 (*it).first.streamUsage == STREAM_USAGE_VOICE_RINGTONE)) {
1067 AUDIO_INFO_LOG("usage is voice modem communication or voice ring, skip");
1068 ++it;
1069 } else {
1070 CHECK_AND_RETURN_RET_LOG(handler_ != nullptr, ERROR, "handler is nullptr");
1071 SendInterruptEventCallback(interruptEvent, (*it).first.streamId, (*it).first);
1072 it = audioInterruptZone->audioFocusInfoList.erase(it);
1073 }
1074 }
1075 }
1076 return SUCCESS;
1077 }
1078
ActivatePreemptMode()1079 int32_t AudioInterruptService::ActivatePreemptMode()
1080 {
1081 AUDIO_INFO_LOG("start activate preempt mode");
1082 std::lock_guard<std::mutex> lock(mutex_);
1083 isPreemptMode_ = true;
1084 int32_t ret = ClearAudioFocusInfoList();
1085 if (ret) {
1086 isPreemptMode_ = false;
1087 }
1088 AUDIO_INFO_LOG("isPreemptMode_ = %{public}d", isPreemptMode_);
1089 return ret;
1090 }
1091
DeactivatePreemptMode()1092 int32_t AudioInterruptService::DeactivatePreemptMode()
1093 {
1094 AUDIO_INFO_LOG("start deactivate preempt mode");
1095 std::lock_guard<std::mutex> lock(mutex_);
1096 isPreemptMode_ = false;
1097 return SUCCESS;
1098 }
1099
CreateAudioInterruptZone(const int32_t zoneId,AudioZoneFocusStrategy focusStrategy)1100 int32_t AudioInterruptService::CreateAudioInterruptZone(const int32_t zoneId,
1101 AudioZoneFocusStrategy focusStrategy)
1102 {
1103 std::unique_lock<std::mutex> lock(mutex_);
1104 return zoneManager_.CreateAudioInterruptZone(zoneId, focusStrategy);
1105 }
1106
ReleaseAudioInterruptZone(const int32_t zoneId,GetZoneIdFunc func)1107 int32_t AudioInterruptService::ReleaseAudioInterruptZone(const int32_t zoneId, GetZoneIdFunc func)
1108 {
1109 std::unique_lock<std::mutex> lock(mutex_);
1110 int32_t ret = zoneManager_.ReleaseAudioInterruptZone(zoneId, func);
1111 if (ret != SUCCESS) {
1112 return ret;
1113 }
1114 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
1115 lock.unlock();
1116 UpdateAudioSceneFromInterrupt(targetAudioScene, ACTIVATE_AUDIO_INTERRUPT, zoneId);
1117 return SUCCESS;
1118 }
1119
MigrateAudioInterruptZone(const int32_t zoneId,GetZoneIdFunc func)1120 int32_t AudioInterruptService::MigrateAudioInterruptZone(const int32_t zoneId, GetZoneIdFunc func)
1121 {
1122 std::unique_lock<std::mutex> lock(mutex_);
1123 int32_t ret = zoneManager_.MigrateAudioInterruptZone(zoneId, func);
1124 if (ret != SUCCESS) {
1125 return ret;
1126 }
1127 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
1128 lock.unlock();
1129 UpdateAudioSceneFromInterrupt(targetAudioScene, ACTIVATE_AUDIO_INTERRUPT, zoneId);
1130 return SUCCESS;
1131 }
1132
InjectInterruptToAudioZone(const int32_t zoneId,const AudioFocusList & interrupts)1133 int32_t AudioInterruptService::InjectInterruptToAudioZone(const int32_t zoneId,
1134 const AudioFocusList &interrupts)
1135 {
1136 std::unique_lock<std::mutex> lock(mutex_);
1137 int32_t ret = zoneManager_.InjectInterruptToAudioZone(zoneId, interrupts);
1138 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InjectInterruptToAudioZone failed");
1139 CHECK_AND_RETURN_RET_LOG(zoneId != ZONEID_DEFAULT, SUCCESS, "zone id is default");
1140
1141 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
1142 lock.unlock();
1143 UpdateAudioSceneFromInterrupt(targetAudioScene, ACTIVATE_AUDIO_INTERRUPT, zoneId);
1144 return SUCCESS;
1145 }
1146
InjectInterruptToAudioZone(const int32_t zoneId,const std::string & deviceTag,const AudioFocusList & interrupts)1147 int32_t AudioInterruptService::InjectInterruptToAudioZone(const int32_t zoneId,
1148 const std::string &deviceTag, const AudioFocusList &interrupts)
1149 {
1150 std::unique_lock<std::mutex> lock(mutex_);
1151 int32_t ret = zoneManager_.InjectInterruptToAudioZone(zoneId, deviceTag, interrupts);
1152 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InjectInterruptToAudioZone failed");
1153 CHECK_AND_RETURN_RET_LOG(zoneId != ZONEID_DEFAULT, SUCCESS, "zone id is default");
1154
1155 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
1156 lock.unlock();
1157 UpdateAudioSceneFromInterrupt(targetAudioScene, ACTIVATE_AUDIO_INTERRUPT, zoneId);
1158 return SUCCESS;
1159 }
1160
GetAudioFocusInfoList(const int32_t zoneId,AudioFocusList & focusInfoList)1161 int32_t AudioInterruptService::GetAudioFocusInfoList(const int32_t zoneId, AudioFocusList &focusInfoList)
1162 {
1163 std::unique_lock<std::mutex> lock(mutex_);
1164 return zoneManager_.GetAudioFocusInfoList(zoneId, focusInfoList);
1165 }
1166
GetAudioFocusInfoList(const int32_t zoneId,const std::string & deviceTag,AudioFocusList & focusInfoList)1167 int32_t AudioInterruptService::GetAudioFocusInfoList(const int32_t zoneId, const std::string &deviceTag,
1168 AudioFocusList &focusInfoList)
1169 {
1170 std::unique_lock<std::mutex> lock(mutex_);
1171 return zoneManager_.GetAudioFocusInfoList(zoneId, deviceTag, focusInfoList);
1172 }
1173
GetStreamTypePriority(AudioStreamType streamType)1174 int32_t AudioInterruptService::GetStreamTypePriority(AudioStreamType streamType)
1175 {
1176 if (DEFAULT_STREAM_PRIORITY.find(streamType) != DEFAULT_STREAM_PRIORITY.end()) {
1177 return DEFAULT_STREAM_PRIORITY.at(streamType);
1178 }
1179 return STREAM_DEFAULT_PRIORITY;
1180 }
1181
GetStreamInFocus(const int32_t zoneId)1182 AudioStreamType AudioInterruptService::GetStreamInFocus(const int32_t zoneId)
1183 {
1184 std::lock_guard<std::mutex> lock(mutex_);
1185 return GetStreamInFocusInternal(0, zoneId);
1186 }
1187
GetStreamInFocusByUid(const int32_t uid,const int32_t zoneId)1188 AudioStreamType AudioInterruptService::GetStreamInFocusByUid(const int32_t uid, const int32_t zoneId)
1189 {
1190 std::lock_guard<std::mutex> lock(mutex_);
1191 return GetStreamInFocusInternal(uid, zoneId);
1192 }
1193
GetStreamInFocusInternal(const int32_t uid,const int32_t zoneId)1194 AudioStreamType AudioInterruptService::GetStreamInFocusInternal(const int32_t uid, const int32_t zoneId)
1195 {
1196 AudioStreamType streamInFocus = STREAM_DEFAULT;
1197
1198 auto itZone = zonesMap_.find(zoneId);
1199 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1200 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
1201 audioFocusInfoList = itZone->second->audioFocusInfoList;
1202 }
1203
1204 int32_t focusPriority = STREAM_DEFAULT_PRIORITY;
1205 for (auto iter = audioFocusInfoList.begin(); iter != audioFocusInfoList.end(); ++iter) {
1206 if ((iter->second != ACTIVE && iter->second != DUCK) ||
1207 (iter->first).audioFocusType.sourceType != SOURCE_TYPE_INVALID) {
1208 // if the steam is not active or the active stream is an audio capturer stream, skip it.
1209 continue;
1210 }
1211 if (uid != 0 && (iter->first).uid != uid) {
1212 continue;
1213 }
1214 if ((iter->first).audioFocusType.streamType == STREAM_VOICE_ASSISTANT &&
1215 !CheckoutSystemAppUtil::CheckoutSystemApp((iter->first).uid)) {
1216 (iter->first).audioFocusType.streamType = STREAM_MUSIC;
1217 }
1218 if (sessionService_ != nullptr && iter->first.isAudioSessionInterrupt) {
1219 std::vector<AudioInterrupt> sessionStreams = sessionService_->GetStreams(iter->first.pid);
1220 for (auto stream : sessionStreams) {
1221 int32_t curPriority = GetStreamTypePriority(stream.audioFocusType.streamType);
1222 if (curPriority < focusPriority) {
1223 focusPriority = curPriority;
1224 streamInFocus = stream.audioFocusType.streamType;
1225 }
1226 }
1227 } else {
1228 int32_t curPriority = GetStreamTypePriority((iter->first).audioFocusType.streamType);
1229 if (curPriority < focusPriority) {
1230 focusPriority = curPriority;
1231 streamInFocus = (iter->first).audioFocusType.streamType;
1232 }
1233 }
1234 }
1235 return streamInFocus == STREAM_DEFAULT ? defaultVolumeType_ : streamInFocus;
1236 }
1237
GetSessionInfoInFocus(AudioInterrupt & audioInterrupt,const int32_t zoneId)1238 int32_t AudioInterruptService::GetSessionInfoInFocus(AudioInterrupt &audioInterrupt, const int32_t zoneId)
1239 {
1240 uint32_t invalidStreamId = static_cast<uint32_t>(-1);
1241 audioInterrupt = {STREAM_USAGE_UNKNOWN, CONTENT_TYPE_UNKNOWN,
1242 {AudioStreamType::STREAM_DEFAULT, SourceType::SOURCE_TYPE_INVALID, true}, invalidStreamId};
1243
1244 std::unique_lock<std::mutex> lock(mutex_);
1245 auto itZone = zonesMap_.find(zoneId);
1246 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1247 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
1248 audioFocusInfoList = itZone->second->audioFocusInfoList;
1249 }
1250
1251 for (auto iter = audioFocusInfoList.begin(); iter != audioFocusInfoList.end(); ++iter) {
1252 if (iter->second == ACTIVE) {
1253 audioInterrupt = iter->first;
1254 }
1255 }
1256
1257 return SUCCESS;
1258 }
1259
NotifyFocusGranted(const int32_t clientId,const AudioInterrupt & audioInterrupt)1260 void AudioInterruptService::NotifyFocusGranted(const int32_t clientId, const AudioInterrupt &audioInterrupt)
1261 {
1262 AUDIO_INFO_LOG("Notify focus granted in: %{public}d", clientId);
1263
1264 InterruptEventInternal interruptEvent = {};
1265 interruptEvent.eventType = INTERRUPT_TYPE_END;
1266 interruptEvent.forceType = INTERRUPT_SHARE;
1267 interruptEvent.hintType = INTERRUPT_HINT_NONE;
1268 interruptEvent.duckVolume = 0;
1269
1270 if (handler_ != nullptr) {
1271 handler_->SendInterruptEventWithClientIdCallback(interruptEvent, clientId);
1272 unique_ptr<AudioInterrupt> tempAudioInterruptInfo = make_unique<AudioInterrupt>();
1273 tempAudioInterruptInfo->streamUsage = audioInterrupt.streamUsage;
1274 tempAudioInterruptInfo->contentType = audioInterrupt.contentType;
1275 (tempAudioInterruptInfo->audioFocusType).streamType = audioInterrupt.audioFocusType.streamType;
1276 tempAudioInterruptInfo->pauseWhenDucked = audioInterrupt.pauseWhenDucked;
1277 focussedAudioInterruptInfo_ = move(tempAudioInterruptInfo);
1278 clientOnFocus_ = clientId;
1279 }
1280 }
1281
NotifyFocusAbandoned(const int32_t clientId,const AudioInterrupt & audioInterrupt)1282 int32_t AudioInterruptService::NotifyFocusAbandoned(const int32_t clientId, const AudioInterrupt &audioInterrupt)
1283 {
1284 AUDIO_INFO_LOG("Notify focus abandoned in: %{public}d", clientId);
1285
1286 InterruptEventInternal interruptEvent = {};
1287 interruptEvent.eventType = INTERRUPT_TYPE_BEGIN;
1288 interruptEvent.forceType = INTERRUPT_SHARE;
1289 interruptEvent.hintType = INTERRUPT_HINT_STOP;
1290 interruptEvent.duckVolume = 0;
1291 if (handler_ != nullptr) {
1292 handler_->SendInterruptEventWithClientIdCallback(interruptEvent, clientId);
1293 }
1294
1295 return SUCCESS;
1296 }
1297
AbandonAudioFocusInternal(const int32_t clientId,const AudioInterrupt & audioInterrupt)1298 int32_t AudioInterruptService::AbandonAudioFocusInternal(const int32_t clientId, const AudioInterrupt &audioInterrupt)
1299 {
1300 if (clientId == clientOnFocus_) {
1301 AUDIO_INFO_LOG("remove app focus");
1302 focussedAudioInterruptInfo_.reset();
1303 focussedAudioInterruptInfo_ = nullptr;
1304 clientOnFocus_ = 0;
1305 }
1306
1307 return SUCCESS;
1308 }
1309
IsSameAppInShareMode(const AudioInterrupt incomingInterrupt,const AudioInterrupt activeInterrupt)1310 bool AudioInterruptService::IsSameAppInShareMode(const AudioInterrupt incomingInterrupt,
1311 const AudioInterrupt activeInterrupt)
1312 {
1313 if (incomingInterrupt.mode != SHARE_MODE || activeInterrupt.mode != SHARE_MODE) {
1314 return false;
1315 }
1316 if (incomingInterrupt.pid == DEFAULT_APP_PID || activeInterrupt.pid == DEFAULT_APP_PID) {
1317 return false;
1318 }
1319 return incomingInterrupt.pid == activeInterrupt.pid;
1320 }
1321
CheckAudioSessionExistence(const AudioInterrupt & incomingInterrupt,AudioFocusEntry & focusEntry)1322 bool AudioInterruptService::CheckAudioSessionExistence(const AudioInterrupt &incomingInterrupt,
1323 AudioFocusEntry &focusEntry)
1324 {
1325 if (sessionService_ == nullptr) {
1326 AUDIO_ERR_LOG("sessionService_ is nullptr!");
1327 return false;
1328 }
1329 if (!sessionService_->IsAudioSessionActivated(incomingInterrupt.pid)) {
1330 AUDIO_INFO_LOG("No active audio session for the pid of incomming stream");
1331 return false;
1332 }
1333 if (focusEntry.actionOn != CURRENT) {
1334 AUDIO_INFO_LOG("The interrupt event is not for the existed stream.");
1335 return false;
1336 }
1337 std::shared_ptr<AudioSession> incomingSession = sessionService_->GetAudioSessionByPid(incomingInterrupt.pid);
1338 if (incomingSession == nullptr) {
1339 AUDIO_ERR_LOG("incomingSession is nullptr!");
1340 return false;
1341 }
1342 return true;
1343 }
1344
UpdateHintTypeForExistingSession(const AudioInterrupt & incomingInterrupt,AudioFocusEntry & focusEntry)1345 void AudioInterruptService::UpdateHintTypeForExistingSession(const AudioInterrupt &incomingInterrupt,
1346 AudioFocusEntry &focusEntry)
1347 {
1348 AudioConcurrencyMode concurrencyMode = incomingInterrupt.sessionStrategy.concurrencyMode;
1349
1350 if (CheckAudioSessionExistence(incomingInterrupt, focusEntry)) {
1351 std::shared_ptr<AudioSession> incomingSession = sessionService_->GetAudioSessionByPid(incomingInterrupt.pid);
1352 concurrencyMode = (incomingSession->GetSessionStrategy()).concurrencyMode;
1353 }
1354 switch (concurrencyMode) {
1355 case AudioConcurrencyMode::DUCK_OTHERS:
1356 if (focusEntry.hintType == INTERRUPT_HINT_DUCK ||
1357 focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
1358 focusEntry.hintType == INTERRUPT_HINT_STOP) {
1359 AUDIO_INFO_LOG("The concurrency mode is DUCK_OTHERS. Use INTERRUPT_HINT_DUCK.");
1360 focusEntry.hintType = INTERRUPT_HINT_DUCK;
1361 }
1362 break;
1363 case AudioConcurrencyMode::PAUSE_OTHERS:
1364 if (focusEntry.hintType == INTERRUPT_HINT_PAUSE ||
1365 focusEntry.hintType == INTERRUPT_HINT_STOP) {
1366 AUDIO_INFO_LOG("The concurrency mode is PAUSE_OTHERS. Use INTERRUPT_HINT_PAUSE.");
1367 focusEntry.hintType = INTERRUPT_HINT_PAUSE;
1368 }
1369 break;
1370 default:
1371 AUDIO_INFO_LOG("The concurrency mode is %{public}d. No need to update hint type",
1372 static_cast<int32_t>(concurrencyMode));
1373 break;
1374 }
1375 }
1376
ProcessExistInterrupt(std::list<std::pair<AudioInterrupt,AudioFocuState>>::iterator & iterActive,AudioFocusEntry & focusEntry,const AudioInterrupt & incomingInterrupt,bool & removeFocusInfo,InterruptEventInternal & interruptEvent)1377 void AudioInterruptService::ProcessExistInterrupt(std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator
1378 &iterActive, AudioFocusEntry &focusEntry, const AudioInterrupt &incomingInterrupt,
1379 bool &removeFocusInfo, InterruptEventInternal &interruptEvent)
1380 {
1381 SourceType incomingSourceType = incomingInterrupt.audioFocusType.sourceType;
1382 std::vector<SourceType> incomingConcurrentSources = incomingInterrupt.currencySources.sourcesTypes;
1383 SourceType existSourceType = (iterActive->first).audioFocusType.sourceType;
1384 std::vector<SourceType> existConcurrentSources = (iterActive->first).currencySources.sourcesTypes;
1385
1386 // if the callerPid has an active audio session, the hint type need to be updated.
1387 if (IsCanMixInterrupt(incomingInterrupt, iterActive->first)) {
1388 UpdateHintTypeForExistingSession(incomingInterrupt, focusEntry);
1389 }
1390 switch (focusEntry.hintType) {
1391 case INTERRUPT_HINT_STOP:
1392 if (IsAudioSourceConcurrency(existSourceType, incomingSourceType, existConcurrentSources,
1393 incomingConcurrentSources)) {
1394 break;
1395 }
1396 interruptEvent.hintType = focusEntry.hintType;
1397 if (IsGameAvoidCallbackCase(iterActive->first)) {
1398 interruptEvent.hintType = INTERRUPT_HINT_PAUSE;
1399 iterActive->second = PAUSE;
1400 AUDIO_INFO_LOG("incomingInterrupt.hintType: %{public}d", interruptEvent.hintType);
1401 break;
1402 }
1403 removeFocusInfo = true;
1404 break;
1405 case INTERRUPT_HINT_PAUSE:
1406 if (IsAudioSourceConcurrency(existSourceType, incomingSourceType, existConcurrentSources,
1407 incomingConcurrentSources)) {
1408 break;
1409 }
1410 if (iterActive->second == ACTIVE || iterActive->second == DUCK) {
1411 iterActive->second = PAUSE;
1412 interruptEvent.hintType = focusEntry.hintType;
1413 }
1414 break;
1415 case INTERRUPT_HINT_DUCK:
1416 if (iterActive->second == ACTIVE) {
1417 iterActive->second = DUCK;
1418 interruptEvent.duckVolume = DUCK_FACTOR;
1419 interruptEvent.hintType = focusEntry.hintType;
1420 }
1421 break;
1422 case INTERRUPT_HINT_MUTE:
1423 if (iterActive->second == ACTIVE) {
1424 iterActive->second = MUTED;
1425 interruptEvent.hintType = focusEntry.hintType;
1426 }
1427 break;
1428 default:
1429 break;
1430 }
1431 }
1432
SwitchHintType(std::list<std::pair<AudioInterrupt,AudioFocuState>>::iterator & iterActive,InterruptEventInternal & interruptEvent,std::list<std::pair<AudioInterrupt,AudioFocuState>> & tmpFocusInfoList)1433 bool AudioInterruptService::SwitchHintType(std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator &iterActive,
1434 InterruptEventInternal &interruptEvent, std::list<std::pair<AudioInterrupt, AudioFocuState>> &tmpFocusInfoList)
1435 {
1436 bool needRemoveCurIter = false;
1437 switch (interruptEvent.hintType) {
1438 case INTERRUPT_HINT_STOP:
1439 if (IsGameAvoidCallbackCase(iterActive->first)) {
1440 iterActive->second = PAUSEDBYREMOTE;
1441 break;
1442 }
1443 needRemoveCurIter = true;
1444 break;
1445 case INTERRUPT_HINT_PAUSE:
1446 if (iterActive->second == ACTIVE || iterActive->second == DUCK) {
1447 iterActive->second = PAUSEDBYREMOTE;
1448 }
1449 break;
1450 case INTERRUPT_HINT_RESUME:
1451 if (iterActive->second == PAUSEDBYREMOTE) {
1452 needRemoveCurIter = true;
1453 }
1454 break;
1455 default:
1456 break;
1457 }
1458 return needRemoveCurIter;
1459 }
1460
GetStreamIdsForAudioSessionByStreamUsage(const int32_t zoneId,const std::set<StreamUsage> & streamUsageSet)1461 std::set<int32_t> AudioInterruptService::GetStreamIdsForAudioSessionByStreamUsage(
1462 const int32_t zoneId, const std::set<StreamUsage> &streamUsageSet)
1463 {
1464 std::set<int32_t> streamIds;
1465
1466 std::unique_lock<std::mutex> lock(mutex_);
1467 auto targetZoneIt = zonesMap_.find(zoneId);
1468 CHECK_AND_RETURN_RET_LOG(targetZoneIt != zonesMap_.end(), streamIds, "can not find zone id");
1469 auto &tmpFocusInfoList = targetZoneIt->second->audioFocusInfoList;
1470 for (auto focusIter = tmpFocusInfoList.begin(); focusIter != tmpFocusInfoList.end(); ++focusIter) {
1471 const auto &audioInterrupt = focusIter->first;
1472 if (audioInterrupt.isAudioSessionInterrupt &&
1473 streamUsageSet.find(audioInterrupt.streamUsage) != streamUsageSet.end()) {
1474 streamIds.insert(static_cast<int32_t>(audioInterrupt.streamId));
1475 }
1476 }
1477 return streamIds;
1478 }
1479
GetStreamIdsForAudioSessionByDeviceType(const int32_t zoneId,DeviceType deviceType)1480 std::set<int32_t> AudioInterruptService::GetStreamIdsForAudioSessionByDeviceType(
1481 const int32_t zoneId, DeviceType deviceType)
1482 {
1483 std::set<int32_t> streamIds;
1484
1485 std::unique_lock<std::mutex> lock(mutex_);
1486 CHECK_AND_RETURN_RET_LOG(sessionService_ != nullptr, streamIds, "sessionService_ is nullptr");
1487 auto targetZoneIt = zonesMap_.find(zoneId);
1488 CHECK_AND_RETURN_RET_LOG(targetZoneIt != zonesMap_.end(), streamIds, "can not find zone id");
1489 auto &tmpFocusInfoList = targetZoneIt->second->audioFocusInfoList;
1490 for (auto focusIter = tmpFocusInfoList.begin(); focusIter != tmpFocusInfoList.end(); ++focusIter) {
1491 const auto &audioInterrupt = focusIter->first;
1492 if (audioInterrupt.isAudioSessionInterrupt &&
1493 sessionService_->HasStreamForDeviceType(audioInterrupt.pid, deviceType)) {
1494 streamIds.insert(static_cast<int32_t>(audioInterrupt.streamId));
1495 }
1496 }
1497
1498 return streamIds;
1499 }
1500
GetAudioSessionUidList(int32_t zoneId)1501 std::vector<int32_t> AudioInterruptService::GetAudioSessionUidList(int32_t zoneId)
1502 {
1503 std::vector<int32_t> uidList;
1504 std::lock_guard<std::mutex> lock(mutex_);
1505 AUDIO_INFO_LOG("start to find audio session uid in zone %{public}d", zoneId);
1506 auto itZone = zonesMap_.find(zoneId);
1507 CHECK_AND_RETURN_RET_LOG((itZone != zonesMap_.end()) && (itZone->second != nullptr),
1508 uidList, "cannot find zoneid in zonesMap");
1509
1510 auto audioFocusInfoList = itZone->second->audioFocusInfoList;
1511 for (const auto &iter : audioFocusInfoList) {
1512 if (iter.first.isAudioSessionInterrupt) {
1513 AUDIO_INFO_LOG("find uid : %{public}d", iter.first.uid);
1514 uidList.push_back(iter.first.uid);
1515 }
1516 }
1517 return uidList;
1518 }
1519
GetAudioSessionStreamUsage(int32_t callerPid)1520 StreamUsage AudioInterruptService::GetAudioSessionStreamUsage(int32_t callerPid)
1521 {
1522 std::lock_guard<std::mutex> lock(mutex_);
1523 CHECK_AND_RETURN_RET_LOG(sessionService_ != nullptr, STREAM_USAGE_INVALID, "sessionService_ is nullptr!");
1524 return sessionService_->GetAudioSessionStreamUsage(callerPid);
1525 }
1526
ProcessRemoteInterrupt(std::set<int32_t> streamIds,InterruptEventInternal interruptEvent)1527 void AudioInterruptService::ProcessRemoteInterrupt(std::set<int32_t> streamIds, InterruptEventInternal interruptEvent)
1528 {
1529 std::unique_lock<std::mutex> lock(mutex_);
1530 auto targetZoneIt = zonesMap_.find(0);
1531 CHECK_AND_RETURN_LOG(targetZoneIt != zonesMap_.end(), "can not find zone id");
1532
1533 std::list<std::pair<AudioInterrupt, AudioFocuState>> tmpFocusInfoList {};
1534 if (targetZoneIt != zonesMap_.end()) {
1535 tmpFocusInfoList = targetZoneIt->second->audioFocusInfoList;
1536 targetZoneIt->second->zoneId = 0;
1537 }
1538 for (auto iterActive = tmpFocusInfoList.begin(); iterActive != tmpFocusInfoList.end();) {
1539 bool needRemoveCurIter = false;
1540 for (auto streamId : streamIds) {
1541 if (streamId != static_cast<int32_t> (iterActive->first.streamId)) {
1542 continue;
1543 }
1544 AudioInterrupt currentInterrupt = iterActive->first;
1545 needRemoveCurIter = SwitchHintType(iterActive, interruptEvent, tmpFocusInfoList);
1546 SendInterruptEventCallback(interruptEvent, streamId, currentInterrupt);
1547 if (interruptEvent.hintType == INTERRUPT_HINT_PAUSE || interruptEvent.hintType == INTERRUPT_HINT_STOP) {
1548 SendFocusChangeEvent(ZONEID_DEFAULT, AudioPolicyServerHandler::ABANDON_CALLBACK_CATEGORY,
1549 currentInterrupt);
1550 }
1551 }
1552 if (needRemoveCurIter) {
1553 iterActive = tmpFocusInfoList.erase(iterActive);
1554 } else {
1555 ++iterActive;
1556 }
1557 }
1558 targetZoneIt->second->audioFocusInfoList = tmpFocusInfoList;
1559 }
1560
ProcessActiveInterrupt(const int32_t zoneId,const AudioInterrupt & incomingInterrupt)1561 void AudioInterruptService::ProcessActiveInterrupt(const int32_t zoneId, const AudioInterrupt &incomingInterrupt)
1562 {
1563 // Use local variable to record target focus info list, can be optimized
1564 auto targetZoneIt = zonesMap_.find(zoneId);
1565 CHECK_AND_RETURN_LOG(targetZoneIt != zonesMap_.end(), "can not find zone id");
1566 CHECK_AND_RETURN_LOG(policyServer_ != nullptr, "policyServer nullptr");
1567 std::list<std::pair<AudioInterrupt, AudioFocuState>> tmpFocusInfoList {};
1568 if (targetZoneIt != zonesMap_.end()) {
1569 tmpFocusInfoList = targetZoneIt->second->audioFocusInfoList;
1570 targetZoneIt->second->zoneId = zoneId;
1571 }
1572
1573 std::list<int32_t> removeFocusInfoPidList = {};
1574 InterruptDfxBuilder dfxBuilder;
1575 for (auto iterActive = tmpFocusInfoList.begin(); iterActive != tmpFocusInfoList.end();) {
1576 AudioFocusEntry focusEntry =
1577 focusCfgMap_[std::make_pair((iterActive->first).audioFocusType, incomingInterrupt.audioFocusType)];
1578 UpdateAudioFocusStrategy(iterActive->first, incomingInterrupt, focusEntry);
1579 if (focusEntry.actionOn != CURRENT || IsSameAppInShareMode(incomingInterrupt, iterActive->first) ||
1580 iterActive->second == PLACEHOLDER || CanMixForSession(incomingInterrupt, iterActive->first, focusEntry) ||
1581 // incomming peeling should not stop/pause/duck other playing instances
1582 (IsLowestPriorityRecording(incomingInterrupt) && !IsRecordingInterruption(iterActive->first))) {
1583 ++iterActive;
1584 continue;
1585 }
1586
1587 // other new recording should stop the existing peeling anyway
1588 if (IsLowestPriorityRecording(iterActive->first) && IsRecordingInterruption(incomingInterrupt)) {
1589 focusEntry.actionOn = CURRENT;
1590 focusEntry.forceType = INTERRUPT_FORCE;
1591 focusEntry.hintType = INTERRUPT_HINT_STOP;
1592 }
1593
1594 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, focusEntry.forceType, INTERRUPT_HINT_NONE, 1.0f};
1595 uint32_t activeStreamId = (iterActive->first).streamId;
1596 bool removeFocusInfo = false;
1597 ProcessExistInterrupt(iterActive, focusEntry, incomingInterrupt, removeFocusInfo, interruptEvent);
1598 AudioInterrupt currentInterrupt = iterActive->first;
1599 if (removeFocusInfo) {
1600 RemoveFocusInfo(iterActive, tmpFocusInfoList, targetZoneIt->second, removeFocusInfoPidList);
1601 } else {
1602 ++iterActive;
1603 }
1604 uint8_t appstate = GetAppState(currentInterrupt.pid);
1605 auto info = AudioBundleManager::GetBundleInfoFromUid(currentInterrupt.uid);
1606 dfxBuilder.WriteEffectMsg(appstate, info.name, currentInterrupt, interruptEvent.hintType);
1607 SendActiveInterruptEvent(activeStreamId, interruptEvent, incomingInterrupt, currentInterrupt);
1608 }
1609
1610 WriteStartDfxMsg(dfxBuilder, incomingInterrupt);
1611 targetZoneIt->second->audioFocusInfoList = tmpFocusInfoList;
1612 zonesMap_[zoneId] = targetZoneIt->second;
1613 SendActiveVolumeTypeChangeEvent(zoneId);
1614 RemoveAllPlaceholderInterrupt(removeFocusInfoPidList);
1615 }
1616
RemoveAllPlaceholderInterrupt(std::list<int32_t> & removeFocusInfoPidList)1617 void AudioInterruptService::RemoveAllPlaceholderInterrupt(std::list<int32_t> &removeFocusInfoPidList)
1618 {
1619 for (auto pid : removeFocusInfoPidList) {
1620 RemovePlaceholderInterruptForSession(pid);
1621 }
1622 }
1623
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)1624 void AudioInterruptService::RemoveFocusInfo(std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator &iterActive,
1625 std::list<std::pair<AudioInterrupt, AudioFocuState>> &tmpFocusInfoList,
1626 std::shared_ptr<AudioInterruptZone> &zoneInfo,
1627 std::list<int32_t> &removeFocusInfoPidList)
1628 {
1629 int32_t pidToRemove = (iterActive->first).pid;
1630 uint32_t streamId = (iterActive->first).streamId;
1631 iterActive = tmpFocusInfoList.erase(iterActive);
1632 zoneInfo->audioFocusInfoList = tmpFocusInfoList;
1633 bool isAudioSessionDeactivated = false;
1634 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(pidToRemove)) {
1635 isAudioSessionDeactivated = HandleLowPriorityEvent(pidToRemove, streamId);
1636 }
1637 if (isAudioSessionDeactivated) {
1638 removeFocusInfoPidList.push_back(pidToRemove);
1639 }
1640 }
1641
HandleLowPriorityEvent(const int32_t pid,const uint32_t streamId)1642 bool AudioInterruptService::HandleLowPriorityEvent(const int32_t pid, const uint32_t streamId)
1643 {
1644 // If AudioSession is deactivated, return true, otherwise, return false.
1645 if (sessionService_ == nullptr) {
1646 AUDIO_ERR_LOG("sessionService_ is nullptr!");
1647 return false;
1648 }
1649 auto audioSession = sessionService_->GetAudioSessionByPid(pid);
1650 if (audioSession == nullptr) {
1651 AUDIO_ERR_LOG("audioSession is nullptr!");
1652 return false;
1653 }
1654
1655 audioSession->RemoveStreamInfo(streamId);
1656 if (audioSession->IsAudioSessionEmpty()) {
1657 AUDIO_INFO_LOG("The audio session is empty because the last one stream is interruptted!");
1658 sessionService_->DeactivateAudioSession(pid);
1659
1660 AudioSessionDeactiveEvent deactiveEvent;
1661 deactiveEvent.deactiveReason = AudioSessionDeactiveReason::LOW_PRIORITY;
1662 std::pair<int32_t, AudioSessionDeactiveEvent> sessionDeactivePair = {pid, deactiveEvent};
1663 if (handler_ != nullptr) {
1664 AUDIO_INFO_LOG("AudioSessionService::handler_ is not null. Send event!");
1665 handler_->SendAudioSessionDeactiveCallback(sessionDeactivePair);
1666 }
1667 return true;
1668 }
1669 return false;
1670 }
1671
SendActiveInterruptEvent(const uint32_t activeStreamId,const InterruptEventInternal & interruptEvent,const AudioInterrupt & incomingInterrupt,const AudioInterrupt & activeInterrupt)1672 void AudioInterruptService::SendActiveInterruptEvent(const uint32_t activeStreamId,
1673 const InterruptEventInternal &interruptEvent, const AudioInterrupt &incomingInterrupt,
1674 const AudioInterrupt &activeInterrupt)
1675 {
1676 if (interruptEvent.hintType != INTERRUPT_HINT_NONE) {
1677 AUDIO_INFO_LOG("OnInterrupt for active streamId:%{public}d, hintType:%{public}d. By streamId:%{public}d",
1678 activeStreamId, interruptEvent.hintType, incomingInterrupt.streamId);
1679 SendInterruptEventCallback(interruptEvent, activeStreamId, activeInterrupt);
1680 // focus remove or state change
1681 SendFocusChangeEvent(ZONEID_DEFAULT, AudioPolicyServerHandler::NONE_CALLBACK_CATEGORY,
1682 incomingInterrupt);
1683 }
1684 }
1685
ProcessAudioScene(const AudioInterrupt & audioInterrupt,const uint32_t & incomingStreamId,const int32_t & zoneId,bool & shouldReturnSuccess)1686 void AudioInterruptService::ProcessAudioScene(const AudioInterrupt &audioInterrupt, const uint32_t &incomingStreamId,
1687 const int32_t &zoneId, bool &shouldReturnSuccess)
1688 {
1689 auto itZone = zonesMap_.find(zoneId);
1690 CHECK_AND_RETURN_LOG(itZone != zonesMap_.end(), "can not find zoneId");
1691
1692 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1693 if ((itZone != zonesMap_.end()) && (itZone->second != nullptr)) {
1694 audioFocusInfoList = itZone->second->audioFocusInfoList;
1695 itZone->second->zoneId = zoneId;
1696 }
1697 int32_t pid = audioInterrupt.pid;
1698
1699 if (!audioFocusInfoList.empty() && (itZone->second != nullptr)) {
1700 // If the session is present in audioFocusInfoList and the placeholder's stream type is not VoIP communication,
1701 // and the incoming stream type is not Capturer, remove and treat it as a new request
1702 AUDIO_DEBUG_LOG("audioFocusInfoList is not empty");
1703 audioFocusInfoList.remove_if(
1704 [&audioInterrupt, this](const std::pair<AudioInterrupt, AudioFocuState> &audioFocus) {
1705 return AudioFocusInfoListRemovalCondition(audioInterrupt, audioFocus);
1706 });
1707
1708 itZone->second->audioFocusInfoList = audioFocusInfoList;
1709 zonesMap_[zoneId] = itZone->second;
1710 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(pid)) {
1711 std::shared_ptr<AudioSession> tempSession = sessionService_->GetAudioSessionByPid(pid);
1712 CHECK_AND_RETURN_LOG(tempSession != nullptr, "audio session is null");
1713 tempSession->RemoveStreamInfo(incomingStreamId);
1714 }
1715 }
1716
1717 if (audioFocusInfoList.empty()) {
1718 InterruptDfxBuilder dfxBuilder;
1719 WriteStartDfxMsg(dfxBuilder, audioInterrupt);
1720 AUDIO_INFO_LOG("audioFocusInfoList is empty");
1721 if (itZone->second != nullptr) {
1722 itZone->second->audioFocusInfoList.emplace_back(std::make_pair(audioInterrupt, ACTIVE));
1723 zonesMap_[zoneId] = itZone->second;
1724 }
1725 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(pid)) {
1726 std::shared_ptr<AudioSession> tempAudioSession = sessionService_->GetAudioSessionByPid(pid);
1727 CHECK_AND_RETURN_LOG(tempAudioSession != nullptr, "audio session is null");
1728 tempAudioSession->AddStreamInfo(audioInterrupt);
1729 }
1730 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::REQUEST_CALLBACK_CATEGORY, audioInterrupt);
1731 SendActiveVolumeTypeChangeEvent(zoneId);
1732 AudioScene targetAudioScene = GetHighestPriorityAudioScene(zoneId);
1733 UpdateAudioSceneFromInterrupt(targetAudioScene, ACTIVATE_AUDIO_INTERRUPT, zoneId);
1734 shouldReturnSuccess = true;
1735 return;
1736 }
1737 shouldReturnSuccess = false;
1738 }
1739
AudioFocusInfoListRemovalCondition(const AudioInterrupt & audioInterrupt,const std::pair<AudioInterrupt,AudioFocuState> & audioFocus)1740 bool AudioInterruptService::AudioFocusInfoListRemovalCondition(const AudioInterrupt &audioInterrupt,
1741 const std::pair<AudioInterrupt, AudioFocuState> &audioFocus)
1742 {
1743 return audioFocus.first.streamId == audioInterrupt.streamId ||
1744 (audioFocus.first.pid == audioInterrupt.pid && audioFocus.second == PLACEHOLDER &&
1745 audioInterrupt.audioFocusType.sourceType == SOURCE_TYPE_INVALID &&
1746 audioFocus.first.audioFocusType.streamType != STREAM_VOICE_COMMUNICATION);
1747 }
1748
IsAudioSourceConcurrency(const SourceType & existSourceType,const SourceType & incomingSourceType,const std::vector<SourceType> & existConcurrentSources,const std::vector<SourceType> & incomingConcurrentSources)1749 bool AudioInterruptService::IsAudioSourceConcurrency(const SourceType &existSourceType,
1750 const SourceType &incomingSourceType, const std::vector<SourceType> &existConcurrentSources,
1751 const std::vector<SourceType> &incomingConcurrentSources)
1752 {
1753 if ((incomingConcurrentSources.size() > 0 && existSourceType >= 0 && find(incomingConcurrentSources.begin(),
1754 incomingConcurrentSources.end(), existSourceType) != incomingConcurrentSources.end()) ||
1755 (existConcurrentSources.size() > 0 && incomingSourceType >= 0 && find(existConcurrentSources.begin(),
1756 existConcurrentSources.end(), incomingSourceType) != existConcurrentSources.end())) {
1757 return true;
1758 }
1759 return false;
1760 }
1761
IsMediaStream(AudioStreamType audioStreamType)1762 bool AudioInterruptService::IsMediaStream(AudioStreamType audioStreamType)
1763 {
1764 if (audioStreamType == STREAM_MUSIC || audioStreamType == STREAM_MOVIE || audioStreamType == STREAM_SPEECH) {
1765 return true;
1766 }
1767 return false;
1768 }
1769
SetQueryBundleNameListCallback(const sptr<IRemoteObject> & object)1770 int32_t AudioInterruptService::SetQueryBundleNameListCallback(const sptr<IRemoteObject> &object)
1771 {
1772 AUDIO_INFO_LOG("Set query bundle name list callback");
1773 queryBundleNameListCallback_ = iface_cast<IStandardAudioPolicyManagerListener>(object);
1774 if (queryBundleNameListCallback_ == nullptr) {
1775 AUDIO_ERR_LOG("Client type callback is null");
1776 return ERR_CALLBACK_NOT_REGISTERED;
1777 }
1778 return SUCCESS;
1779 }
1780
GetRealBundleName(uint32_t uid)1781 std::string AudioInterruptService::GetRealBundleName(uint32_t uid)
1782 {
1783 CHECK_AND_RETURN_RET_LOG(policyServer_ != nullptr, "", "policyServer nullptr");
1784 if (IPCSkeleton::GetCallingUid() == MEDIA_SA_UID) {
1785 auto info = AudioBundleManager::GetBundleInfoFromUid(uid);
1786 return info.name;
1787 }
1788 return AudioBundleManager::GetBundleName();
1789 }
1790
UpdateAudioFocusStrategy(const AudioInterrupt & currentInterrupt,const AudioInterrupt & incomingInterrupt,AudioFocusEntry & focusEntry)1791 void AudioInterruptService::UpdateAudioFocusStrategy(const AudioInterrupt ¤tInterrupt,
1792 const AudioInterrupt &incomingInterrupt, AudioFocusEntry &focusEntry)
1793 {
1794 int32_t uid = incomingInterrupt.uid;
1795 int32_t currentPid = currentInterrupt.pid;
1796 int32_t incomingPid = incomingInterrupt.pid;
1797 AudioFocusType incomingAudioFocusType = incomingInterrupt.audioFocusType;
1798 AudioFocusType existAudioFocusType = currentInterrupt.audioFocusType;
1799 std::string bundleName = GetRealBundleName(static_cast<uint32_t>(uid));
1800 CHECK_AND_RETURN_LOG(!bundleName.empty(), "bundleName is empty");
1801 AudioStreamType existStreamType = existAudioFocusType.streamType;
1802 AudioStreamType incomingStreamType = incomingAudioFocusType.streamType;
1803 SourceType existSourceType = existAudioFocusType.sourceType;
1804 SourceType incomingSourceType = incomingAudioFocusType.sourceType;
1805 UpdateFocusStrategy(bundleName, focusEntry, IsMediaStream(existStreamType), IsMediaStream(incomingStreamType));
1806 if (uid == static_cast<int32_t>(AUDIO_ID)) {
1807 AUDIO_INFO_LOG("lake app:%{public}s access", std::to_string(uid).c_str());
1808 UpdateMicFocusStrategy(existSourceType, incomingSourceType, std::to_string(uid), focusEntry);
1809 } else {
1810 UpdateMicFocusStrategy(existSourceType, incomingSourceType, bundleName, focusEntry);
1811 }
1812 UpdateWindowFocusStrategy(currentPid, incomingPid, existStreamType, incomingStreamType, focusEntry);
1813 UpdateMuteAudioFocusStrategy(currentInterrupt, incomingInterrupt, focusEntry);
1814 }
1815
UpdateFocusStrategy(const std::string & bundleName,AudioFocusEntry & focusEntry,bool isExistMediaStream,bool isIncomingMediaStream)1816 void AudioInterruptService::UpdateFocusStrategy(const std::string &bundleName,
1817 AudioFocusEntry &focusEntry, bool isExistMediaStream, bool isIncomingMediaStream)
1818 {
1819 bool ret = false;
1820 if (queryBundleNameListCallback_ != nullptr) {
1821 queryBundleNameListCallback_->OnQueryBundleNameIsInList(bundleName, "audio_param", ret);
1822 }
1823 if (isExistMediaStream && isIncomingMediaStream && ret &&
1824 focusEntry.hintType == INTERRUPT_HINT_STOP) {
1825 focusEntry.hintType = INTERRUPT_HINT_PAUSE;
1826 AUDIO_INFO_LOG("%{public}s update audio focus strategy", bundleName.c_str());
1827 }
1828 }
1829
UpdateMicFocusStrategy(SourceType existSourceType,SourceType incomingSourceType,const std::string & bundleName,AudioFocusEntry & focusEntry)1830 void AudioInterruptService::UpdateMicFocusStrategy(SourceType existSourceType,
1831 SourceType incomingSourceType, const std::string &bundleName, AudioFocusEntry &focusEntry)
1832 {
1833 if (incomingSourceType == SOURCE_TYPE_INVALID || existSourceType == SOURCE_TYPE_INVALID) {
1834 AUDIO_INFO_LOG("Not a recording stream access");
1835 return;
1836 }
1837 bool ret = false;
1838 if (queryBundleNameListCallback_ != nullptr) {
1839 queryBundleNameListCallback_->OnQueryBundleNameIsInList(bundleName, "audio_micfocus_list", ret);
1840 }
1841 if (existSourceType == SOURCE_TYPE_MIC && IsMicSource(incomingSourceType) && ret) {
1842 focusEntry.hintType = INTERRUPT_HINT_NONE;
1843 AUDIO_INFO_LOG("audio_micfocus_list : %{public}s update mic focus strategy", bundleName.c_str());
1844 }
1845 }
1846
IsMicSource(SourceType sourceType)1847 bool AudioInterruptService::IsMicSource(SourceType sourceType)
1848 {
1849 return (sourceType == SOURCE_TYPE_VOICE_CALL ||
1850 sourceType == SOURCE_TYPE_VOICE_TRANSCRIPTION||
1851 sourceType == SOURCE_TYPE_VOICE_COMMUNICATION);
1852 }
1853
CheckWindowState(const int32_t pid)1854 bool AudioInterruptService::CheckWindowState(const int32_t pid)
1855 {
1856 auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy();
1857 if (sceneSessionManager == nullptr) {
1858 AUDIO_INFO_LOG("AudioInterruptService null manager");
1859 return false;
1860 }
1861 std::vector<Rosen::MainWindowState> windowStates;
1862 Rosen::WSError ret = sceneSessionManager->GetMainWindowStatesByPid(pid, windowStates);
1863 if (ret != Rosen::WSError::WS_OK || windowStates.empty()) {
1864 AUDIO_INFO_LOG("AudioInterruptService fail GetWindow");
1865 return false;
1866 }
1867 for (auto &windowState : windowStates) {
1868 if (windowState.isVisible_ && (windowState.state_ == (int32_t) Rosen::SessionState::STATE_ACTIVE ||
1869 windowState.state_ == (int32_t) Rosen::SessionState::STATE_FOREGROUND)) {
1870 AUDIO_INFO_LOG("AudioInterruptService app window front desk");
1871 return true;
1872 }
1873 }
1874 return false;
1875 }
1876
UpdateWindowFocusStrategy(const int32_t & currentPid,const int32_t & incomingPid,const AudioStreamType & existStreamType,const AudioStreamType & incomingStreamType,AudioFocusEntry & focusEntry)1877 void AudioInterruptService::UpdateWindowFocusStrategy(const int32_t ¤tPid, const int32_t &incomingPid,
1878 const AudioStreamType &existStreamType, const AudioStreamType &incomingStreamType, AudioFocusEntry &focusEntry)
1879 {
1880 if (!CheckWindowState(currentPid) || !CheckWindowState(incomingPid)) {
1881 AUDIO_INFO_LOG("currentWindowState: %{public}d incomingWindowState: %{public}d"
1882 " Not all front desk audio access", CheckWindowState(currentPid), CheckWindowState(incomingPid));
1883 return;
1884 }
1885 if ((existStreamType == STREAM_MUSIC ||
1886 existStreamType == STREAM_MOVIE || existStreamType == STREAM_SPEECH) &&
1887 (incomingStreamType == STREAM_MUSIC || incomingStreamType == STREAM_MOVIE ||
1888 incomingStreamType == STREAM_SPEECH)) {
1889 focusEntry.hintType = INTERRUPT_HINT_NONE;
1890 focusEntry.actionOn = INCOMING;
1891 AUDIO_INFO_LOG("The media windowStates concurrent");
1892 return;
1893 }
1894 }
1895
FocusEntryContinue(std::list<std::pair<AudioInterrupt,AudioFocuState>>::iterator & iterActive,AudioFocusEntry & focusEntry,const AudioInterrupt & incomingInterrupt)1896 bool AudioInterruptService::FocusEntryContinue(std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator
1897 &iterActive, AudioFocusEntry &focusEntry, const AudioInterrupt &incomingInterrupt)
1898 {
1899 SourceType incomingSourceType = incomingInterrupt.audioFocusType.sourceType;
1900 std::vector<SourceType> incomingConcurrentSources = incomingInterrupt.currencySources.sourcesTypes;
1901 if (focusEntry.actionOn == CURRENT || iterActive->second == PLACEHOLDER ||
1902 CanMixForSession(incomingInterrupt, iterActive->first, focusEntry)) {
1903 return true;
1904 }
1905 if (((focusEntry.actionOn == INCOMING && focusEntry.hintType == INTERRUPT_HINT_PAUSE) || focusEntry.isReject) &&
1906 (IsAudioSourceConcurrency((iterActive->first).audioFocusType.sourceType, incomingSourceType,
1907 (iterActive->first).currencySources.sourcesTypes, incomingConcurrentSources) ||
1908 // if the rejection is caused by the existing peeling recording, just ignore it
1909 IsLowestPriorityRecording(iterActive->first))) {
1910 return true;
1911 }
1912 return false;
1913 }
1914
ProcessFocusEntry(const int32_t zoneId,const AudioInterrupt & incomingInterrupt)1915 int32_t AudioInterruptService::ProcessFocusEntry(const int32_t zoneId, const AudioInterrupt &incomingInterrupt)
1916 {
1917 AudioFocuState incomingState = ACTIVE;
1918 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_BEGIN, INTERRUPT_FORCE, INTERRUPT_HINT_NONE, 1.0f};
1919 auto itZone = zonesMap_.find(zoneId);
1920 CHECK_AND_RETURN_RET_LOG(itZone != zonesMap_.end(), ERROR, "can not find zoneid");
1921 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
1922 if (itZone != zonesMap_.end()) { audioFocusInfoList = itZone->second->audioFocusInfoList; }
1923
1924 std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator activeInterrupt = audioFocusInfoList.end();
1925 int32_t res = ProcessActiveStreamFocus(audioFocusInfoList, incomingInterrupt, incomingState, activeInterrupt);
1926 if ((incomingState >= PAUSE || res != SUCCESS) && activeInterrupt != audioFocusInfoList.end()) {
1927 ReportRecordGetFocusFail(incomingInterrupt, activeInterrupt->first,
1928 res == SUCCESS ? RECORD_ERROR_GET_FOCUS_FAIL : RECORD_ERROR_NO_FOCUS_CFG);
1929 }
1930 CHECK_AND_RETURN_RET_LOG(res == SUCCESS, res, "ProcessActiveStreamFocus fail");
1931 HandleIncomingState(zoneId, incomingState, interruptEvent, incomingInterrupt);
1932 AddToAudioFocusInfoList(itZone->second, zoneId, incomingInterrupt, incomingState);
1933 SendInterruptEventToIncomingStream(interruptEvent, incomingInterrupt);
1934 if (IsGameAvoidCallbackCase(incomingInterrupt) && incomingState == PAUSE) {
1935 return SUCCESS;
1936 }
1937 return incomingState >= PAUSE ? ERR_FOCUS_DENIED : SUCCESS;
1938 }
1939
ProcessFocusEntryForAudioSession(const int32_t zoneId,const int32_t callerPid,bool & updateScene)1940 int32_t AudioInterruptService::ProcessFocusEntryForAudioSession(
1941 const int32_t zoneId, const int32_t callerPid, bool &updateScene)
1942 {
1943 if (sessionService_ == nullptr) {
1944 AUDIO_ERR_LOG("sessionService_ is nullptr!");
1945 return ERR_UNKNOWN;
1946 }
1947
1948 auto itZone = zonesMap_.find(zoneId);
1949 CHECK_AND_RETURN_RET_LOG((itZone != zonesMap_.end()) && (itZone->second != nullptr), ERROR, "can not find zone");
1950 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList = itZone->second->audioFocusInfoList;
1951
1952 auto isAudioSessionFocusPresent = [callerPid] (const std::pair<AudioInterrupt, AudioFocuState> &pair) {
1953 return pair.first.pid == callerPid && pair.first.isAudioSessionInterrupt;
1954 };
1955
1956 AudioInterrupt audioInterrupt = sessionService_->GenerateFakeAudioInterrupt(callerPid);
1957 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isAudioSessionFocusPresent);
1958 // It is possible that the reactivation of the audio session was caused by changing the session scene or strategy.
1959 bool isFirstTimeActiveAudioSession = true;
1960 if (iter != audioFocusInfoList.end()) {
1961 audioFocusInfoList.erase(iter);
1962 isFirstTimeActiveAudioSession = false;
1963 }
1964
1965 itZone->second->audioFocusInfoList = audioFocusInfoList;
1966
1967 bool tempUpdateScene = false;
1968 int32_t ret = ActivateAudioInterruptCoreProcedure(zoneId, audioInterrupt, false, tempUpdateScene);
1969 if (tempUpdateScene) {
1970 updateScene = true;
1971 }
1972 if (ret == SUCCESS) {
1973 ResumeAudioFocusList(zoneId, false);
1974 } else {
1975 return ret;
1976 }
1977
1978 if (isFirstTimeActiveAudioSession) {
1979 sessionService_->ClearStreamInfo(callerPid);
1980 return HandleExistStreamsForSession(zoneId, callerPid, updateScene);
1981 }
1982
1983 return SUCCESS;
1984 }
1985
HandleExistStreamsForSession(const int32_t zoneId,const int32_t callerPid,bool & updateScene)1986 int32_t AudioInterruptService::HandleExistStreamsForSession(
1987 const int32_t zoneId, const int32_t callerPid, bool &updateScene)
1988 {
1989 auto itZone = zonesMap_.find(zoneId);
1990 CHECK_AND_RETURN_RET_LOG((itZone != zonesMap_.end()) && (itZone->second != nullptr), ERROR, "can not find zone");
1991 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList = itZone->second->audioFocusInfoList;
1992
1993 /* The focus of a single stream should be managed by audio session focus.
1994 1. This mainly handles streams that already exist before audio session activation.
1995 2. and to handle the state transition when the audio session resumes from a paused state.
1996 */
1997 auto isStreamFocusPresent = [&](const std::pair<AudioInterrupt, AudioFocuState> &pair) {
1998 return pair.first.pid == callerPid &&
1999 !pair.first.isAudioSessionInterrupt &&
2000 !sessionService_->ShouldExcludeStreamType(pair.first);
2001 };
2002
2003 bool tempUpdateScene = false;
2004 for (const auto &it : audioFocusInfoList) {
2005 if (isStreamFocusPresent(it)) {
2006 updateScene = true;
2007 int32_t ret = ActivateAudioInterruptCoreProcedure(zoneId, it.first, true, tempUpdateScene);
2008 if (ret != SUCCESS) {
2009 return ret;
2010 }
2011 }
2012 }
2013
2014 return SUCCESS;
2015 }
2016
ShouldBypassAudioSessionFocus(const int32_t zoneId,const AudioInterrupt & incomingInterrupt)2017 bool AudioInterruptService::ShouldBypassAudioSessionFocus(const int32_t zoneId, const AudioInterrupt &incomingInterrupt)
2018 {
2019 AUDIO_INFO_LOG("incomingInterrupt info: pid = %{public}d, isAudioSessionInterrupt = %{public}d,"
2020 "streamId = %{public}u, streamType = %{public}d",
2021 incomingInterrupt.pid,
2022 incomingInterrupt.isAudioSessionInterrupt,
2023 incomingInterrupt.streamId,
2024 incomingInterrupt.audioFocusType.streamType);
2025 if (!HasAudioSessionFakeInterrupt(zoneId, incomingInterrupt.pid)) {
2026 return false;
2027 }
2028
2029 if (incomingInterrupt.isAudioSessionInterrupt) {
2030 return false;
2031 }
2032
2033 if (sessionService_ != nullptr && sessionService_->ShouldBypassFocusForStream(incomingInterrupt)) {
2034 return true;
2035 }
2036
2037 return false;
2038 }
2039
TryHandleStreamCallbackInSession(const int32_t zoneId,const AudioInterrupt & incomingInterrupt)2040 void AudioInterruptService::TryHandleStreamCallbackInSession(
2041 const int32_t zoneId, const AudioInterrupt &incomingInterrupt)
2042 {
2043 if (handler_ == nullptr) {
2044 AUDIO_ERR_LOG("AudioPolicyServerHandler is nullptr");
2045 return;
2046 }
2047
2048 auto itZone = zonesMap_.find(zoneId);
2049 CHECK_AND_RETURN_LOG((itZone != zonesMap_.end()) && (itZone->second != nullptr), "can not find zone");
2050 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList = itZone->second->audioFocusInfoList;
2051
2052 auto isAudioSessionFocusPresent = [&incomingInterrupt](const std::pair<AudioInterrupt, AudioFocuState> &pair) {
2053 return pair.first.pid == incomingInterrupt.pid && pair.first.isAudioSessionInterrupt &&
2054 (pair.second == AudioFocuState::PAUSE || pair.second == AudioFocuState::DUCK);
2055 };
2056 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isAudioSessionFocusPresent);
2057 if (iter == audioFocusInfoList.end()) {
2058 return;
2059 }
2060
2061 if (iter->second == AudioFocuState::DUCK) {
2062 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_DUCK, DUCK_FACTOR};
2063 handler_->SendInterruptEventWithStreamIdCallback(interruptEvent, incomingInterrupt.streamId);
2064 }
2065
2066 if (iter->second == AudioFocuState::PAUSE) {
2067 InterruptEventInternal interruptEvent {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_PAUSE, 1.0f};
2068 handler_->SendInterruptEventWithStreamIdCallback(interruptEvent, incomingInterrupt.streamId);
2069 }
2070 }
2071
GetNewIncomingState(InterruptHint hintType,AudioFocuState oldState)2072 AudioFocuState AudioInterruptService::GetNewIncomingState(InterruptHint hintType, AudioFocuState oldState)
2073 {
2074 auto pos = HINT_STATE_MAP.find(hintType);
2075 AudioFocuState newState = (pos == HINT_STATE_MAP.end()) ? ACTIVE : pos->second;
2076 return (newState > oldState) ? newState : oldState;
2077 }
2078
IsLowestPriorityRecording(const AudioInterrupt & audioInterrupt)2079 bool AudioInterruptService::IsLowestPriorityRecording(const AudioInterrupt &audioInterrupt)
2080 {
2081 if (audioInterrupt.currencySources.sourcesTypes.size() == 1 &&
2082 audioInterrupt.currencySources.sourcesTypes[0] == SOURCE_TYPE_INVALID) {
2083 AUDIO_INFO_LOG("PEELING AUDIO IsLowestPriorityRecording:%{public}d", audioInterrupt.streamId);
2084 return true;
2085 }
2086 return false;
2087 }
2088
IsRecordingInterruption(const AudioInterrupt & audioInterrupt)2089 bool AudioInterruptService::IsRecordingInterruption(const AudioInterrupt &audioInterrupt)
2090 {
2091 return audioInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID ? true : false;
2092 }
2093
CheckIncommingFoucsValidity(AudioFocusEntry & focusEntry,const AudioInterrupt & incomingInterrupt,std::vector<SourceType> incomingConcurrentSources)2094 void AudioInterruptService::CheckIncommingFoucsValidity(AudioFocusEntry &focusEntry,
2095 const AudioInterrupt &incomingInterrupt, std::vector<SourceType> incomingConcurrentSources)
2096 {
2097 CHECK_AND_RETURN_LOG(interruptClients_.find(incomingInterrupt.streamId) != interruptClients_.end(),
2098 "interruptClients is nullptr");
2099 auto uid = interruptClients_[incomingInterrupt.streamId]->GetCallingUid();
2100 if (IsRecordingInterruption(incomingInterrupt) && incomingConcurrentSources.size() != 0 &&
2101 (uid == THP_EXTRA_SA_UID || uid == MEDIA_SA_UID)) {
2102 focusEntry.actionOn = INCOMING;
2103 focusEntry.isReject = true;
2104 }
2105 }
2106
SendInterruptEventToIncomingStream(InterruptEventInternal & interruptEvent,const AudioInterrupt & incomingInterrupt)2107 void AudioInterruptService::SendInterruptEventToIncomingStream(InterruptEventInternal &interruptEvent,
2108 const AudioInterrupt &incomingInterrupt)
2109 {
2110 if (interruptEvent.hintType != INTERRUPT_HINT_NONE) {
2111 AUDIO_INFO_LOG("OnInterrupt for incoming streamId: %{public}d, hintType: %{public}d",
2112 incomingInterrupt.streamId, interruptEvent.hintType);
2113 SendInterruptEventCallback(interruptEvent, incomingInterrupt.streamId, incomingInterrupt);
2114 }
2115 }
2116
AddToAudioFocusInfoList(std::shared_ptr<AudioInterruptZone> & audioInterruptZone,const int32_t & zoneId,const AudioInterrupt & incomingInterrupt,const AudioFocuState & incomingState)2117 void AudioInterruptService::AddToAudioFocusInfoList(std::shared_ptr<AudioInterruptZone> &audioInterruptZone,
2118 const int32_t &zoneId, const AudioInterrupt &incomingInterrupt, const AudioFocuState &incomingState)
2119 {
2120 if (incomingState == STOP) {
2121 // Deny incoming. No need to add it.
2122 return;
2123 }
2124
2125 audioInterruptZone->zoneId = zoneId;
2126 audioInterruptZone->audioFocusInfoList.emplace_back(std::make_pair(incomingInterrupt, incomingState));
2127 zonesMap_[zoneId] = audioInterruptZone;
2128 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::REQUEST_CALLBACK_CATEGORY, incomingInterrupt);
2129 SendActiveVolumeTypeChangeEvent(zoneId);
2130 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(incomingInterrupt.pid)) {
2131 auto audioSession = sessionService_->GetAudioSessionByPid(incomingInterrupt.pid);
2132 if (audioSession == nullptr) {
2133 AUDIO_ERR_LOG("audioSession is nullptr!");
2134 return;
2135 }
2136 audioSession->AddStreamInfo(incomingInterrupt);
2137 }
2138 }
2139
HandleIncomingState(const int32_t & zoneId,const AudioFocuState & incomingState,InterruptEventInternal & interruptEvent,const AudioInterrupt & incomingInterrupt)2140 void AudioInterruptService::HandleIncomingState(const int32_t &zoneId, const AudioFocuState &incomingState,
2141 InterruptEventInternal &interruptEvent, const AudioInterrupt &incomingInterrupt)
2142 {
2143 if (incomingState == STOP) {
2144 interruptEvent.hintType = INTERRUPT_HINT_STOP;
2145 } else {
2146 if (incomingState == PAUSE) {
2147 interruptEvent.hintType = INTERRUPT_HINT_PAUSE;
2148 } else if (incomingState == DUCK) {
2149 interruptEvent.hintType = INTERRUPT_HINT_DUCK;
2150 interruptEvent.duckVolume = DUCK_FACTOR;
2151 } else if (incomingState == MUTED) {
2152 interruptEvent.hintType = INTERRUPT_HINT_MUTE;
2153 }
2154 // Handle existing focus state
2155 ProcessActiveInterrupt(zoneId, incomingInterrupt);
2156 }
2157 }
2158
GetHighestPriorityAudioScene(const int32_t zoneId) const2159 AudioScene AudioInterruptService::GetHighestPriorityAudioScene(const int32_t zoneId) const
2160 {
2161 AudioScene audioScene = AUDIO_SCENE_DEFAULT;
2162 int32_t audioScenePriority = GetAudioScenePriority(audioScene);
2163
2164 auto itZone = zonesMap_.find(zoneId);
2165 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
2166 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
2167 audioFocusInfoList = itZone->second->audioFocusInfoList;
2168 }
2169 for (const auto &[interrupt, focuState] : audioFocusInfoList) {
2170 if (interrupt.isAudioSessionInterrupt) {
2171 audioScene = GetHighestPriorityAudioSceneFromAudioSession(interrupt, audioScene);
2172 continue;
2173 }
2174 AudioScene itAudioScene = GetAudioSceneFromAudioInterrupt(interrupt);
2175 int32_t itAudioScenePriority = GetAudioScenePriority(itAudioScene);
2176 if (itAudioScenePriority >= audioScenePriority) {
2177 audioScene = itAudioScene;
2178 audioScenePriority = itAudioScenePriority;
2179 ownerPid_ = interrupt.pid;
2180 ownerUid_ = interrupt.uid;
2181 }
2182 }
2183
2184 return audioScene;
2185 }
2186
GetHighestPriorityAudioSceneFromAudioSession(const AudioInterrupt & audioInterrupt,const AudioScene & audioScene) const2187 AudioScene AudioInterruptService::GetHighestPriorityAudioSceneFromAudioSession(
2188 const AudioInterrupt &audioInterrupt, const AudioScene &audioScene) const
2189 {
2190 if (sessionService_ == nullptr) {
2191 return audioScene;
2192 }
2193
2194 int32_t audioScenePriority = GetAudioScenePriority(audioScene);
2195 AudioScene finalAudioScene = audioScene;
2196 bool hasRingtoneInVoip = false;
2197
2198 // Handle streams in audio session
2199 const auto &streamsInSession = sessionService_->GetStreams(audioInterrupt.pid);
2200 for (auto &it : streamsInSession) {
2201 AudioScene innerAudioScene = GetAudioSceneFromAudioInterrupt(it);
2202 int32_t innerAudioScenePriority = GetAudioScenePriority(innerAudioScene);
2203 if (innerAudioScenePriority >= audioScenePriority) {
2204 finalAudioScene = innerAudioScene;
2205 audioScenePriority = innerAudioScenePriority;
2206 ownerPid_ = audioInterrupt.pid;
2207 ownerUid_ = audioInterrupt.uid;
2208 }
2209
2210 // In the VoIP session scene, the STREAM_VOICE_RING AudioScene should be kept independent
2211 if (it.audioFocusType.streamType == STREAM_RING &&
2212 audioInterrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION) {
2213 hasRingtoneInVoip = true;
2214 }
2215 }
2216
2217 if (hasRingtoneInVoip) {
2218 return finalAudioScene;
2219 }
2220
2221 // Update audio scene for audio session fake audioInterrupt
2222 AudioScene itAudioScene = GetAudioSceneFromAudioInterrupt(audioInterrupt);
2223 int32_t itAudioScenePriority = GetAudioScenePriority(itAudioScene);
2224 if (itAudioScenePriority >= audioScenePriority) {
2225 finalAudioScene = itAudioScene;
2226 audioScenePriority = itAudioScenePriority;
2227 ownerPid_ = audioInterrupt.pid;
2228 ownerUid_ = audioInterrupt.uid;
2229 }
2230
2231 return finalAudioScene;
2232 }
2233
HadVoipStatus(const AudioInterrupt & audioInterrupt,const std::list<std::pair<AudioInterrupt,AudioFocuState>> & audioFocusInfoList)2234 bool AudioInterruptService::HadVoipStatus(const AudioInterrupt &audioInterrupt,
2235 const std::list<std::pair<AudioInterrupt, AudioFocuState>> &audioFocusInfoList)
2236 {
2237 for (const auto &[interrupt, focusState] : audioFocusInfoList) {
2238 if (audioInterrupt.pid == interrupt.pid && focusState == PLACEHOLDER &&
2239 interrupt.audioFocusType.streamType == STREAM_VOICE_COMMUNICATION &&
2240 interrupt.streamId != audioInterrupt.streamId) {
2241 AUDIO_WARNING_LOG("The audio session pid: %{public}d had voip status", audioInterrupt.pid);
2242 return true;
2243 }
2244 }
2245 return false;
2246 }
2247
2248 // LCOV_EXCL_STOP
DeactivateAudioInterruptInternal(const int32_t zoneId,const AudioInterrupt & audioInterrupt,bool isSessionTimeout)2249 void AudioInterruptService::DeactivateAudioInterruptInternal(const int32_t zoneId,
2250 const AudioInterrupt &audioInterrupt, bool isSessionTimeout)
2251 {
2252 auto itZone = zonesMap_.find(zoneId);
2253 CHECK_AND_RETURN_LOG((itZone != zonesMap_.end()) && (itZone->second != nullptr), "can not find zone");
2254 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList = itZone->second->audioFocusInfoList;
2255
2256 bool needPlaceHolder = false;
2257 if (sessionService_ != nullptr && sessionService_->IsAudioSessionActivated(audioInterrupt.pid)) {
2258 // if this stream is the last renderer for audio session, change the state to PLACEHOLDER.
2259 auto audioSession = sessionService_->GetAudioSessionByPid(audioInterrupt.pid);
2260 if (audioSession != nullptr) {
2261 audioSession->RemoveStreamInfo(audioInterrupt.streamId);
2262 needPlaceHolder = !audioInterrupt.isAudioSessionInterrupt &&
2263 audioInterrupt.audioFocusType.streamType != STREAM_DEFAULT &&
2264 audioSession->IsAudioRendererEmpty() &&
2265 !HadVoipStatus(audioInterrupt, audioFocusInfoList);
2266 }
2267 }
2268
2269 WriteStopDfxMsg(audioInterrupt);
2270 auto isPresent = [audioInterrupt] (const std::pair<AudioInterrupt, AudioFocuState> &pair) {
2271 return pair.first.streamId == audioInterrupt.streamId;
2272 };
2273 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), isPresent);
2274 if (iter != audioFocusInfoList.end()) {
2275 if (needPlaceHolder) {
2276 // Change the state to PLACEHOLDER because of the active audio session.
2277 // No need to release interrupt until the audio session is deactivated.
2278 iter->second = PLACEHOLDER;
2279 itZone->second->audioFocusInfoList = audioFocusInfoList;
2280 zonesMap_[zoneId] = itZone->second;
2281 SendActiveVolumeTypeChangeEvent(zoneId);
2282 AUDIO_INFO_LOG("Change the state of streamId %{public}u to PLACEHOLDER! (pid %{public}d)",
2283 audioInterrupt.streamId, audioInterrupt.pid);
2284 return;
2285 }
2286 ResetNonInterruptControl(audioInterrupt);
2287 audioFocusInfoList.erase(iter);
2288 itZone->second->zoneId = zoneId;
2289 itZone->second->audioFocusInfoList = audioFocusInfoList;
2290 zonesMap_[zoneId] = itZone->second;
2291 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::ABANDON_CALLBACK_CATEGORY, audioInterrupt);
2292 SendActiveVolumeTypeChangeEvent(zoneId);
2293 } else {
2294 // If it was not in the audioFocusInfoList, no need to take any action on other sessions, just return.
2295 AUDIO_DEBUG_LOG("stream (streamId %{public}u) is not active now", audioInterrupt.streamId);
2296 return;
2297 }
2298
2299 if (itZone->second->focusStrategy == AudioZoneFocusStrategy::DISTRIBUTED_FOCUS_STRATEGY) {
2300 AUDIO_INFO_LOG("zone: %{public}d distributed focus strategy not resume when deactivate interrupt",
2301 itZone->first);
2302 return;
2303 }
2304 // resume if other session was forced paused or ducked
2305 ResumeAudioFocusList(zoneId, isSessionTimeout);
2306
2307 return;
2308 }
2309
UpdateAudioSceneFromInterrupt(const AudioScene audioScene,AudioInterruptChangeType changeType,int32_t zoneId)2310 void AudioInterruptService::UpdateAudioSceneFromInterrupt(const AudioScene audioScene,
2311 AudioInterruptChangeType changeType, int32_t zoneId)
2312 {
2313 CHECK_AND_RETURN_LOG(policyServer_ != nullptr, "policyServer nullptr");
2314 CHECK_AND_RETURN_LOG(zoneId == ZONEID_DEFAULT, "zoneId %{public}d is not default", zoneId);
2315 int32_t scene = AUDIO_SCENE_INVALID;
2316 policyServer_->GetAudioScene(scene);
2317 AudioScene currentAudioScene = static_cast<AudioScene>(scene);
2318 if (currentAudioScene != audioScene) {
2319 AUDIO_PRERELEASE_LOGI("currentScene: %{public}d, targetScene: %{public}d, changeType: %{public}d",
2320 currentAudioScene, audioScene, changeType);
2321 }
2322
2323 switch (changeType) {
2324 case ACTIVATE_AUDIO_INTERRUPT:
2325 break;
2326 case DEACTIVATE_AUDIO_INTERRUPT:
2327 if (GetAudioScenePriority(audioScene) >= GetAudioScenePriority(currentAudioScene)) {
2328 AudioStateManager::GetAudioStateManager().SetAudioSceneOwnerUid(audioScene == 0 ? 0 : ownerUid_);
2329 return;
2330 }
2331 break;
2332 default:
2333 AUDIO_ERR_LOG("unexpected changeType: %{public}d", changeType);
2334 return;
2335 }
2336 policyServer_->SetAudioSceneInternal(audioScene, ownerUid_, ownerPid_);
2337 }
2338
EvaluateWhetherContinue(const AudioInterrupt & incoming,const AudioInterrupt & inprocessing,AudioFocusEntry & focusEntry,bool bConcurrency)2339 bool AudioInterruptService::EvaluateWhetherContinue(const AudioInterrupt &incoming, const AudioInterrupt
2340 &inprocessing, AudioFocusEntry &focusEntry, bool bConcurrency)
2341 {
2342 if (focusEntry.hintType == INTERRUPT_HINT_MUTE) {
2343 AUDIO_INFO_LOG("sessionId: %{public}u can not skip", inprocessing.streamId);
2344 return false;
2345 }
2346
2347 if (CanMixForSession(incoming, inprocessing, focusEntry) ||
2348 ((focusEntry.hintType == INTERRUPT_HINT_PAUSE || focusEntry.hintType == INTERRUPT_HINT_STOP) && bConcurrency)) {
2349 return true;
2350 }
2351 UpdateHintTypeForExistingSession(incoming, focusEntry);
2352 if (IsGameAvoidCallbackCase(incoming) &&
2353 focusEntry.hintType == INTERRUPT_HINT_STOP) {
2354 focusEntry.hintType = INTERRUPT_HINT_PAUSE;
2355 AUDIO_INFO_LOG("focusEntry.hintType: %{public}d", focusEntry.hintType);
2356 }
2357 return false;
2358 }
2359
SimulateFocusEntry(const int32_t zoneId)2360 std::list<std::pair<AudioInterrupt, AudioFocuState>> AudioInterruptService::SimulateFocusEntry(const int32_t zoneId)
2361 {
2362 AUDIO_INFO_LOG("Simulate in");
2363 std::list<std::pair<AudioInterrupt, AudioFocuState>> newAudioFocuInfoList;
2364 auto itZone = zonesMap_.find(zoneId);
2365 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
2366 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
2367 audioFocusInfoList = itZone->second->audioFocusInfoList;
2368 }
2369
2370 for (auto iterActive = audioFocusInfoList.begin(); iterActive != audioFocusInfoList.end(); ++iterActive) {
2371 AudioInterrupt incoming = iterActive->first;
2372 AudioFocuState incomingState = ACTIVE;
2373 SourceType incomingSourceType = incoming.audioFocusType.sourceType;
2374 std::vector<SourceType> incomingConcurrentSources = incoming.currencySources.sourcesTypes;
2375 std::list<std::pair<AudioInterrupt, AudioFocuState>> tmpAudioFocuInfoList = newAudioFocuInfoList;
2376 for (auto iter = newAudioFocuInfoList.begin(); iter != newAudioFocuInfoList.end(); ++iter) {
2377 AudioInterrupt inprocessing = iter->first;
2378 if (IsSameAppInShareMode(incoming, inprocessing) || iter->second == PLACEHOLDER) { continue; }
2379 auto audioFocusTypePair = std::make_pair(inprocessing.audioFocusType, incoming.audioFocusType);
2380 if (focusCfgMap_.find(audioFocusTypePair) == focusCfgMap_.end()) {
2381 AUDIO_WARNING_LOG("focus type is invalid");
2382 incomingState = iterActive->second;
2383 break;
2384 }
2385 AudioFocusEntry focusEntry = focusCfgMap_[audioFocusTypePair];
2386 UpdateAudioFocusStrategy(inprocessing, incoming, focusEntry);
2387 SourceType existSourceType = inprocessing.audioFocusType.sourceType;
2388 std::vector<SourceType> existConcurrentSources = inprocessing.currencySources.sourcesTypes;
2389 bool bConcurrency = IsAudioSourceConcurrency(existSourceType, incomingSourceType,
2390 existConcurrentSources, incomingConcurrentSources);
2391 if (EvaluateWhetherContinue(incoming, inprocessing, focusEntry, bConcurrency)) { continue; }
2392 if (focusEntry.hintType == INTERRUPT_HINT_STOP &&
2393 IsGameAvoidCallbackCase(inprocessing)) {
2394 focusEntry.hintType = INTERRUPT_HINT_PAUSE;
2395 }
2396 auto pos = HINT_STATE_MAP.find(focusEntry.hintType);
2397 if (pos == HINT_STATE_MAP.end()) { continue; }
2398 if (focusEntry.actionOn == CURRENT) {
2399 iter->second = (pos->second > iter->second) ? pos->second : iter->second;
2400 } else if (focusEntry.actionOn == INCOMING) {
2401 AudioFocuState newState = pos->second;
2402 incomingState = (newState > incomingState) ? newState : incomingState;
2403 }
2404 }
2405
2406 if (incomingState == PAUSE) { newAudioFocuInfoList = tmpAudioFocuInfoList; }
2407 if (iterActive->second == PLACEHOLDER) { incomingState = PLACEHOLDER; }
2408 newAudioFocuInfoList.emplace_back(std::make_pair(incoming, incomingState));
2409 }
2410
2411 return newAudioFocuInfoList;
2412 }
2413
SendInterruptEvent(AudioFocuState oldState,AudioFocuState newState,std::list<std::pair<AudioInterrupt,AudioFocuState>>::iterator & iterActive,bool & removeFocusInfo)2414 void AudioInterruptService::SendInterruptEvent(AudioFocuState oldState, AudioFocuState newState,
2415 std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator &iterActive, bool &removeFocusInfo)
2416 {
2417 AudioInterrupt audioInterrupt = iterActive->first;
2418 uint32_t streamId = audioInterrupt.streamId;
2419
2420 CHECK_AND_RETURN_LOG(handler_ != nullptr, "handler is nullptr");
2421
2422 InterruptEventInternal forceActive {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_RESUME, 1.0f};
2423 // RESUME event should be INTERRUPT_SHARE. But mark it as INTERRUPT_FORCE here for state checking.
2424 // The force type will be changed to INTERRUPT_SHARE in client.
2425 InterruptEventInternal forceUnduck {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_UNDUCK, 1.0f};
2426 InterruptEventInternal forceDuck {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_DUCK, DUCK_FACTOR};
2427 InterruptEventInternal forcePause {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_PAUSE, 1.0f};
2428 InterruptEventInternal forceUnmute {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_UNMUTE, 1.0f};
2429 switch (newState) {
2430 case ACTIVE:
2431 if (oldState == PAUSE) {
2432 SendInterruptEventCallback(forceActive, streamId, audioInterrupt);
2433 removeFocusInfo = true;
2434 } else if (oldState == DUCK) {
2435 SendInterruptEventCallback(forceUnduck, streamId, audioInterrupt);
2436 } else if (oldState == MUTED) {
2437 SendInterruptEventCallback(forceUnmute, streamId, audioInterrupt);
2438 }
2439 break;
2440 case DUCK:
2441 if (oldState == PAUSE) {
2442 SendInterruptEventCallback(forceActive, streamId, audioInterrupt);
2443 removeFocusInfo = true;
2444 } else if (oldState == ACTIVE) {
2445 SendInterruptEventCallback(forceDuck, streamId, audioInterrupt);
2446 }
2447 break;
2448 case PAUSE:
2449 if (oldState == DUCK) {
2450 SendInterruptEventCallback(forceUnduck, streamId, audioInterrupt);
2451 }
2452 SendInterruptEventCallback(forcePause, streamId, audioInterrupt);
2453 break;
2454 default:
2455 break;
2456 }
2457 iterActive->second = newState;
2458 }
2459
SendInterruptEventCallback(const InterruptEventInternal & interruptEvent,const uint32_t & streamId,const AudioInterrupt & audioInterrupt)2460 void AudioInterruptService::SendInterruptEventCallback(const InterruptEventInternal &interruptEvent,
2461 const uint32_t &streamId, const AudioInterrupt &audioInterrupt)
2462 {
2463 CHECK_AND_RETURN_LOG(dfxCollector_ != nullptr, "dfxCollector is null");
2464 AUDIO_INFO_LOG("hintType= %{public}d", interruptEvent.hintType);
2465 InterruptDfxBuilder dfxBuilder;
2466 auto& [infoIdx, effectIdx] = dfxCollector_->GetDfxIndexes(audioInterrupt.streamId);
2467
2468 auto pos = HINT_STAGE_MAP.find(interruptEvent.hintType);
2469 auto stage = (pos == HINT_STAGE_MAP.end()) ? INTERRUPT_STAGE_STOPPED : pos->second;
2470 dfxBuilder.WriteActionMsg(infoIdx, effectIdx, stage);
2471 dfxCollector_->AddDfxMsg(audioInterrupt.streamId, dfxBuilder.GetResult());
2472
2473 if (audioInterrupt.strategy == InterruptStrategy::MUTE) {
2474 SetLatestMuteState(interruptEvent, streamId);
2475 }
2476
2477 if (handler_ == nullptr) {
2478 AUDIO_ERR_LOG("AudioPolicyServerHandler is nullptr");
2479 return;
2480 }
2481
2482 if (audioInterrupt.isAudioSessionInterrupt) {
2483 SendAudioSessionInterruptEventCallback(interruptEvent, audioInterrupt);
2484 } else {
2485 handler_->SendInterruptEventWithStreamIdCallback(interruptEvent, streamId);
2486 }
2487 }
2488
SendAudioSessionInterruptEventCallback(const InterruptEventInternal & interruptEvent,const AudioInterrupt & audioInterrupt)2489 void AudioInterruptService::SendAudioSessionInterruptEventCallback(
2490 const InterruptEventInternal &interruptEvent, const AudioInterrupt &audioInterrupt)
2491 {
2492 if (handler_ == nullptr) {
2493 AUDIO_ERR_LOG("AudioPolicyServerHandler is nullptr");
2494 return;
2495 }
2496
2497 /*
2498 For audio session focus, the session's callbacks must be processed first,
2499 then process all stream callbacks managed under that session.
2500 */
2501 if (sessionService_ == nullptr) {
2502 AUDIO_ERR_LOG("sessionService_ is nullptr");
2503 return;
2504 }
2505
2506 // Processes the situation where the audio session fake interrupt is preempted by other applications.
2507 if (sessionService_->ShouldAudioSessionProcessHintType(interruptEvent.hintType)) {
2508 handler_->SendInterruptEventCallbackForAudioSession(interruptEvent, audioInterrupt);
2509 // Simulate the deactivation of the audio session.
2510 if (interruptEvent.hintType == INTERRUPT_HINT_STOP || interruptEvent.hintType == INTERRUPT_HINT_RESUME) {
2511 DeactivateAudioSessionInFakeFocusMode(audioInterrupt.pid, interruptEvent.hintType);
2512 }
2513 }
2514 /*
2515 Callback for all streams when the audio session's fake interrupt state changes.
2516 INTERRUPT_HINT_STOP should not be processed here, because the audio session has been deactivated.
2517 */
2518 if (sessionService_->ShouldAudioStreamProcessHintType(interruptEvent.hintType)) {
2519 const auto &audioInterrupts = sessionService_->GetStreams(audioInterrupt.pid);
2520 for (auto &it : audioInterrupts) {
2521 handler_->SendInterruptEventWithStreamIdCallback(interruptEvent, it.streamId);
2522 }
2523 }
2524 }
2525
IsHandleIter(std::list<std::pair<AudioInterrupt,AudioFocuState>>::iterator & iterActive,AudioFocuState oldState,std::list<std::pair<AudioInterrupt,AudioFocuState>>::iterator & iterNew)2526 bool AudioInterruptService::IsHandleIter(
2527 std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator &iterActive, AudioFocuState oldState,
2528 std::list<std::pair<AudioInterrupt, AudioFocuState>>::iterator &iterNew)
2529 {
2530 if (oldState == PAUSEDBYREMOTE) {
2531 AUDIO_INFO_LOG("old State is PAUSEDBYREMOTE");
2532 ++iterActive;
2533 ++iterNew;
2534 return true;
2535 }
2536 return false;
2537 }
2538
ResumeAudioFocusList(const int32_t zoneId,bool isSessionTimeout)2539 void AudioInterruptService::ResumeAudioFocusList(const int32_t zoneId, bool isSessionTimeout)
2540 {
2541 AudioScene highestPriorityAudioScene = AUDIO_SCENE_DEFAULT;
2542
2543 auto itZone = zonesMap_.find(zoneId);
2544 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
2545 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
2546 audioFocusInfoList = itZone->second->audioFocusInfoList;
2547 }
2548 std::list<std::pair<AudioInterrupt, AudioFocuState>> newAudioFocuInfoList = SimulateFocusEntry(zoneId);
2549 for (auto iterActive = audioFocusInfoList.begin(), iterNew = newAudioFocuInfoList.begin();
2550 iterActive != audioFocusInfoList.end() && iterNew != newAudioFocuInfoList.end();) {
2551 AudioFocuState oldState = iterActive->second;
2552 if (IsHandleIter(iterActive, oldState, iterNew)) {
2553 continue;
2554 }
2555 AudioFocuState newState = iterNew->second;
2556 bool removeFocusInfo = false;
2557 if (oldState != newState) {
2558 if (isSessionTimeout && oldState == PAUSE && (newState == ACTIVE || newState == DUCK)) {
2559 // When the audio session is timeout, just send unduck event and skip resume event.
2560 AudioInterrupt interruptToRemove = iterActive->first;
2561 iterActive = audioFocusInfoList.erase(iterActive);
2562 iterNew = newAudioFocuInfoList.erase(iterNew);
2563 AUDIO_INFO_LOG("Audio session time out. Treat resume event as stop event. streamId %{public}d",
2564 interruptToRemove.streamId);
2565 SendSessionTimeOutStopEvent(zoneId, interruptToRemove, audioFocusInfoList);
2566 continue;
2567 }
2568 AUDIO_INFO_LOG("State change: streamId %{public}d, oldstate %{public}d, "\
2569 "newState %{public}d", (iterActive->first).streamId, oldState, newState);
2570 SendInterruptEvent(oldState, newState, iterActive, removeFocusInfo);
2571 }
2572
2573 if (removeFocusInfo && !IsGameAvoidCallbackCase(iterActive->first)) {
2574 AudioInterrupt interruptToRemove = iterActive->first;
2575 iterActive = audioFocusInfoList.erase(iterActive);
2576 iterNew = newAudioFocuInfoList.erase(iterNew);
2577 AUDIO_INFO_LOG("Remove focus info from focus list, streamId: %{public}d", interruptToRemove.streamId);
2578 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::ABANDON_CALLBACK_CATEGORY, interruptToRemove);
2579 } else {
2580 highestPriorityAudioScene =
2581 RefreshAudioSceneFromAudioInterrupt(iterActive->first, highestPriorityAudioScene);
2582 ++iterActive;
2583 ++iterNew;
2584 }
2585 }
2586
2587 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
2588 itZone->second->audioFocusInfoList = audioFocusInfoList;
2589 SendActiveVolumeTypeChangeEvent(zoneId);
2590 }
2591 UpdateAudioSceneFromInterrupt(highestPriorityAudioScene, DEACTIVATE_AUDIO_INTERRUPT, zoneId);
2592 }
2593
RefreshAudioSceneFromAudioInterrupt(const AudioInterrupt & audioInterrupt,AudioScene & highestPriorityAudioScene)2594 AudioScene AudioInterruptService::RefreshAudioSceneFromAudioInterrupt(const AudioInterrupt &audioInterrupt,
2595 AudioScene &highestPriorityAudioScene)
2596 {
2597 if (audioInterrupt.isAudioSessionInterrupt) {
2598 return GetHighestPriorityAudioSceneFromAudioSession(audioInterrupt, highestPriorityAudioScene);
2599 }
2600
2601 AudioScene targetAudioScene = GetAudioSceneFromAudioInterrupt(audioInterrupt);
2602 if (GetAudioScenePriority(targetAudioScene) >= GetAudioScenePriority(highestPriorityAudioScene)) {
2603 highestPriorityAudioScene = targetAudioScene;
2604 ownerPid_ = audioInterrupt.pid;
2605 ownerUid_ = audioInterrupt.uid;
2606 }
2607 return highestPriorityAudioScene;
2608 }
2609
SendSessionTimeOutStopEvent(const int32_t zoneId,const AudioInterrupt & audioInterrupt,const std::list<std::pair<AudioInterrupt,AudioFocuState>> & audioFocusInfoList)2610 void AudioInterruptService::SendSessionTimeOutStopEvent(const int32_t zoneId, const AudioInterrupt &audioInterrupt,
2611 const std::list<std::pair<AudioInterrupt, AudioFocuState>> &audioFocusInfoList)
2612 {
2613 // When the audio session is timeout, change resume event to stop event and delete the interttupt.
2614 InterruptEventInternal stopEvent {INTERRUPT_TYPE_END, INTERRUPT_FORCE, INTERRUPT_HINT_STOP, 1.0f};
2615 SendInterruptEventCallback(stopEvent, audioInterrupt.streamId, audioInterrupt);
2616
2617 auto itZone = zonesMap_.find(zoneId);
2618 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
2619 itZone->second->zoneId = zoneId;
2620 itZone->second->audioFocusInfoList = audioFocusInfoList;
2621 zonesMap_[zoneId] = itZone->second;
2622 }
2623 SendFocusChangeEvent(zoneId, AudioPolicyServerHandler::ABANDON_CALLBACK_CATEGORY, audioInterrupt);
2624 SendActiveVolumeTypeChangeEvent(zoneId);
2625 }
2626
SendActiveVolumeTypeChangeEvent(const int32_t zoneId)2627 void AudioInterruptService::SendActiveVolumeTypeChangeEvent(const int32_t zoneId)
2628 {
2629 CHECK_AND_RETURN_LOG(handler_ != nullptr, "handler is null");
2630
2631 const uint32_t DEFAUFT_UID = 0;
2632 AudioStreamType streamInFocus = GetStreamInFocusInternal(DEFAUFT_UID, zoneId);
2633 streamInFocus = VolumeUtils::GetVolumeTypeFromStreamType(streamInFocus);
2634 if (activeStreamType_ != streamInFocus) {
2635 AUDIO_INFO_LOG("activeStreamType_: %{public}d, streamInFocus: %{public}d",
2636 activeStreamType_, streamInFocus);
2637
2638 activeStreamType_ = streamInFocus;
2639 handler_->SendActiveVolumeTypeChangeCallback(activeStreamType_);
2640 }
2641 }
2642
SendFocusChangeEvent(const int32_t zoneId,int32_t callbackCategory,const AudioInterrupt & audioInterrupt)2643 void AudioInterruptService::SendFocusChangeEvent(const int32_t zoneId, int32_t callbackCategory,
2644 const AudioInterrupt &audioInterrupt)
2645 {
2646 CHECK_AND_RETURN_LOG(handler_ != nullptr, "handler is null");
2647 CHECK_AND_RETURN_LOG(zoneId == ZONEID_DEFAULT, "zoneId %{public}d is not default", zoneId);
2648
2649 auto itZone = zonesMap_.find(zoneId);
2650 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList {};
2651 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
2652 audioFocusInfoList = itZone->second->audioFocusInfoList;
2653 }
2654
2655 if (IsRecordingInterruption(audioInterrupt)) {
2656 if (callbackCategory == static_cast<int32_t>(AudioPolicyServerHandler::REQUEST_CALLBACK_CATEGORY)) {
2657 SetSessionMuteState(audioInterrupt.streamId, true, audioInterrupt.strategy != InterruptStrategy::DEFAULT);
2658 } else if (callbackCategory == static_cast<int32_t>(AudioPolicyServerHandler::ABANDON_CALLBACK_CATEGORY)) {
2659 SetSessionMuteState(audioInterrupt.streamId, false, audioInterrupt.strategy != InterruptStrategy::DEFAULT);
2660 }
2661 }
2662
2663 handler_->SendAudioFocusInfoChangeCallback(callbackCategory, audioInterrupt, audioFocusInfoList);
2664 }
2665
RemoveExistingFocus(const int32_t appUid,std::unordered_set<int32_t> & uidActivedSessions)2666 void AudioInterruptService::RemoveExistingFocus(
2667 const int32_t appUid, std::unordered_set<int32_t> &uidActivedSessions)
2668 {
2669 std::lock_guard<std::mutex> lock(mutex_);
2670 if (zonesMap_.empty()) {
2671 AUDIO_ERR_LOG("zonesMap is empty");
2672 return;
2673 }
2674
2675 for (auto itZone : zonesMap_) {
2676 bool isNeedRefresh = false;
2677 auto audioFocusInfoList = itZone.second->audioFocusInfoList;
2678 for (auto iter = audioFocusInfoList.begin(); iter != audioFocusInfoList.end();) {
2679 if (iter->first.uid != appUid) {
2680 iter++;
2681 continue;
2682 }
2683 AUDIO_INFO_LOG("itZone = %{public}d, streamId = %{public}d",
2684 itZone.first, iter->first.streamId);
2685 uidActivedSessions.insert(iter->first.streamId);
2686 iter = audioFocusInfoList.erase(iter);
2687 isNeedRefresh = true;
2688 }
2689 if (isNeedRefresh) {
2690 zonesMap_[itZone.first]->audioFocusInfoList = audioFocusInfoList;
2691 ResumeAudioFocusList(itZone.first, false);
2692 }
2693 }
2694 }
2695
ResumeFocusByStreamId(const int32_t streamId,const InterruptEventInternal interruptEventResume)2696 void AudioInterruptService::ResumeFocusByStreamId(
2697 const int32_t streamId, const InterruptEventInternal interruptEventResume)
2698 {
2699 std::lock_guard<std::mutex> lock(mutex_);
2700 AUDIO_INFO_LOG("Remove Focus By StreamId = %{public}d", streamId);
2701 if (interruptClients_.find(streamId) != interruptClients_.end() && handler_ != nullptr) {
2702 handler_->SendInterruptEventWithStreamIdCallback(interruptEventResume, streamId);
2703 }
2704 }
2705
2706 // LCOV_EXCL_START
DispatchInterruptEventWithStreamId(uint32_t streamId,InterruptEventInternal & interruptEvent)2707 void AudioInterruptService::DispatchInterruptEventWithStreamId(uint32_t streamId,
2708 InterruptEventInternal &interruptEvent)
2709 {
2710 CHECK_AND_RETURN_LOG(streamId >= MIN_STREAMID && streamId <= MAX_STREAMID,
2711 "EntryPoint Taint Mark:arg streamId: %{public}u is tained", streamId);
2712 std::lock_guard<std::mutex> lock(mutex_);
2713
2714 // call all clients
2715 if (streamId == 0) {
2716 for (auto &it : interruptClients_) {
2717 (it.second)->OnInterrupt(interruptEvent);
2718 }
2719 return;
2720 }
2721
2722 if (interruptClients_.find(streamId) != interruptClients_.end()) {
2723 #ifdef FEATURE_APPGALLERY
2724 if (ShouldCallbackToClient(interruptClients_[streamId]->GetCallingUid(), streamId, interruptEvent)) {
2725 interruptClients_[streamId]->OnInterrupt(interruptEvent);
2726 }
2727 #else
2728 interruptClients_[streamId]->OnInterrupt(interruptEvent);
2729 #endif
2730 }
2731 }
2732
DispatchInterruptEventForAudioSession(InterruptEventInternal & interruptEvent,const AudioInterrupt & audioInterrupt)2733 void AudioInterruptService::DispatchInterruptEventForAudioSession(
2734 InterruptEventInternal &interruptEvent, const AudioInterrupt &audioInterrupt)
2735 {
2736 std::lock_guard<std::mutex> lock(mutex_);
2737 if (sessionService_ == nullptr) {
2738 AUDIO_ERR_LOG("[sessionService_ is null");
2739 return;
2740 }
2741
2742 std::vector<AudioInterrupt> sessionStreams = sessionService_->GetStreams(audioInterrupt.pid);
2743 for (auto it : sessionStreams) {
2744 if (interruptClients_.find(it.streamId) != interruptClients_.end() &&
2745 interruptClients_[it.streamId] != nullptr) {
2746 interruptClients_[it.streamId]->OnInterrupt(interruptEvent);
2747 }
2748 }
2749 }
2750
IsGameAvoidCallbackCase(const AudioInterrupt & audioInterrupt)2751 bool AudioInterruptService::IsGameAvoidCallbackCase(const AudioInterrupt &audioInterrupt)
2752 {
2753 return GetClientTypeByStreamId(audioInterrupt.streamId) == CLIENT_TYPE_GAME &&
2754 audioInterrupt.callbackType != INTERRUPT_EVENT_CALLBACK_SEPERATED;
2755 }
2756
GetClientTypeByStreamId(int32_t streamId)2757 ClientType AudioInterruptService::GetClientTypeByStreamId(int32_t streamId)
2758 {
2759 #ifdef FEATURE_APPGALLERY
2760 uint32_t uid = 0;
2761 if (interruptClients_.find(streamId) != interruptClients_.end()) {
2762 uid = interruptClients_[streamId]->GetCallingUid();
2763 }
2764 if (uid == 0) {
2765 AUDIO_ERR_LOG("Cannot find streamId %{public}d", streamId);
2766 return CLIENT_TYPE_OTHERS;
2767 }
2768 return ClientTypeManager::GetInstance()->GetClientTypeByUid(uid);
2769 #else
2770 return CLIENT_TYPE_OTHERS;
2771 #endif
2772 }
2773
ShouldCallbackToClient(uint32_t uid,int32_t streamId,InterruptEventInternal & interruptEvent)2774 bool AudioInterruptService::ShouldCallbackToClient(uint32_t uid, int32_t streamId,
2775 InterruptEventInternal &interruptEvent)
2776 {
2777 AUDIO_INFO_LOG("uid: %{public}u, streamId: %{public}d, hintType: %{public}d", uid, streamId,
2778 interruptEvent.hintType);
2779 ClientType clientType = ClientTypeManager::GetInstance()->GetClientTypeByUid(uid);
2780 if (clientType != CLIENT_TYPE_GAME) {
2781 return true;
2782 }
2783 if (interruptEvent.hintType == INTERRUPT_HINT_DUCK || interruptEvent.hintType == INTERRUPT_HINT_UNDUCK) {
2784 interruptEvent.callbackToApp = false;
2785 return true;
2786 }
2787
2788 bool muteFlag = true;
2789 switch (interruptEvent.hintType) {
2790 case INTERRUPT_HINT_RESUME:
2791 muteFlag = false;
2792 policyServer_->UpdateDefaultOutputDeviceWhenStarting(streamId);
2793 break;
2794 case INTERRUPT_HINT_PAUSE:
2795 case INTERRUPT_HINT_STOP:
2796 policyServer_->UpdateDefaultOutputDeviceWhenStopping(streamId);
2797 break;
2798 default:
2799 return false;
2800 }
2801 const sptr<IStandardAudioService> gsp = GetAudioServerProxy();
2802 std::string identity = IPCSkeleton::ResetCallingIdentity();
2803 CHECK_AND_RETURN_RET_LOG(gsp != nullptr, true, "error for g_adProxy null");
2804 AUDIO_INFO_LOG("mute flag is: %{public}d", muteFlag);
2805 gsp->SetNonInterruptMute(streamId, muteFlag);
2806 IPCSkeleton::SetCallingIdentity(identity);
2807 return false;
2808 }
2809
2810 // called when the client remote object dies
RemoveClient(const int32_t zoneId,uint32_t streamId)2811 void AudioInterruptService::RemoveClient(const int32_t zoneId, uint32_t streamId)
2812 {
2813 std::lock_guard<std::mutex> lock(mutex_);
2814
2815 AUDIO_INFO_LOG("Remove session: %{public}u in audioFocusInfoList", streamId);
2816
2817 auto itActiveZone = zonesMap_.find(ZONEID_DEFAULT);
2818
2819 auto isSessionPresent = [&streamId] (const std::pair<AudioInterrupt, AudioFocuState> &audioFocusInfo) {
2820 return audioFocusInfo.first.streamId == streamId;
2821 };
2822 auto iterActive = std::find_if((itActiveZone->second->audioFocusInfoList).begin(),
2823 (itActiveZone->second->audioFocusInfoList).end(), isSessionPresent);
2824 if (iterActive != (itActiveZone->second->audioFocusInfoList).end()) {
2825 AudioInterrupt interruptToRemove = iterActive->first;
2826 DeactivateAudioInterruptInternal(ZONEID_DEFAULT, interruptToRemove);
2827 }
2828
2829 interruptClients_.erase(streamId);
2830
2831 // callback in zones map also need to be removed
2832 auto it = zonesMap_.find(zoneId);
2833 if (it != zonesMap_.end() && it->second != nullptr &&
2834 it->second->interruptCbsMap.find(streamId) != it->second->interruptCbsMap.end()) {
2835 it->second->interruptCbsMap.erase(it->second->interruptCbsMap.find(streamId));
2836 zonesMap_[zoneId] = it->second;
2837 }
2838 }
2839
WriteFocusMigrateEvent(const int32_t & toZoneId)2840 void AudioInterruptService::WriteFocusMigrateEvent(const int32_t &toZoneId)
2841 {
2842 auto uid = IPCSkeleton::GetCallingUid();
2843 std::string deviceDesc = (toZoneId == 1) ? REMOTE_NETWORK_ID : LOCAL_NETWORK_ID;
2844 AUTO_CTRACE("SYSEVENT BEHAVIOR EVENT AUDIO_FOCUS_MIGRATE, CLIENT_UID: %d, MIGRATE_DIRECTION: %d, DEVICE_DESC: %s",
2845 static_cast<int32_t>(uid), toZoneId, deviceDesc.c_str());
2846 std::shared_ptr<Media::MediaMonitor::EventBean> bean = std::make_shared<Media::MediaMonitor::EventBean>(
2847 Media::MediaMonitor::AUDIO, Media::MediaMonitor::AUDIO_FOCUS_MIGRATE,
2848 Media::MediaMonitor::BEHAVIOR_EVENT);
2849 bean->Add("CLIENT_UID", static_cast<int32_t>(uid));
2850 bean->Add("MIGRATE_DIRECTION", toZoneId);
2851 bean->Add("DEVICE_DESC", deviceDesc);
2852 Media::MediaMonitor::MediaMonitorManager::GetInstance().WriteLogMsg(bean);
2853 }
2854
GetAppState(int32_t appPid)2855 uint8_t AudioInterruptService::GetAppState(int32_t appPid)
2856 {
2857 OHOS::AppExecFwk::AppMgrClient appManager;
2858 OHOS::AppExecFwk::RunningProcessInfo infos;
2859 uint8_t state = 0;
2860 appManager.GetRunningProcessInfoByPid(appPid, infos);
2861 state = static_cast<uint8_t>(infos.state_);
2862 if (state == 0) {
2863 AUDIO_WARNING_LOG("GetAppState failed, appPid=%{public}d", appPid);
2864 }
2865 return state;
2866 }
2867
WriteStartDfxMsg(InterruptDfxBuilder & dfxBuilder,const AudioInterrupt & audioInterrupt)2868 void AudioInterruptService::WriteStartDfxMsg(InterruptDfxBuilder &dfxBuilder, const AudioInterrupt &audioInterrupt)
2869 {
2870 CHECK_AND_RETURN_LOG(dfxCollector_ != nullptr, "dfxCollector is null");
2871 auto& [infoIdx, effectIdx] = dfxCollector_->GetDfxIndexes(audioInterrupt.streamId);
2872 if (!dfxBuilder.GetResult().interruptEffectVec.empty()) {
2873 ++effectIdx;
2874 }
2875
2876 if (audioInterrupt.state == State::PREPARED) {
2877 auto &manager = DfxMsgManager::GetInstance();
2878 DfxAppState appStartState = static_cast<AppExecFwk::AppProcessState>(GetAppState(audioInterrupt.pid)) ==
2879 AppExecFwk::AppProcessState::APP_STATE_BACKGROUND ?
2880 DFX_APP_STATE_BACKGROUND : DFX_APP_STATE_FOREGROUND;
2881 manager.UpdateAppState(audioInterrupt.uid, appStartState, true);
2882 }
2883
2884 InterruptStage stage = dfxCollector_->IsExist(audioInterrupt.streamId) ?
2885 INTERRUPT_STAGE_RESTART : INTERRUPT_STAGE_START;
2886
2887 AudioSessionStrategy strategy = audioInterrupt.sessionStrategy;
2888 auto audioSession = sessionService_->GetAudioSessionByPid(audioInterrupt.pid);
2889 InterruptRole interruptType = InterruptRole::INTERRUPT_ROLE_DEFAULT;
2890 if (audioSession != nullptr) {
2891 strategy = audioSession->GetSessionStrategy();
2892 interruptType = INTERRUPT_ROLE_AUDIO_SESSION;
2893 }
2894
2895 dfxBuilder.WriteActionMsg(++infoIdx, effectIdx, stage).WriteInfoMsg(audioInterrupt, strategy, interruptType);
2896 dfxCollector_->AddDfxMsg(audioInterrupt.streamId, dfxBuilder.GetResult());
2897 }
2898
WriteSessionTimeoutDfxEvent(const int32_t pid)2899 void AudioInterruptService::WriteSessionTimeoutDfxEvent(const int32_t pid)
2900 {
2901 CHECK_AND_RETURN_LOG(dfxCollector_ != nullptr, "dfxCollector is null");
2902 auto itZone = zonesMap_.find(ZONEID_DEFAULT);
2903 CHECK_AND_RETURN_LOG(itZone != zonesMap_.end(), "can not find zoneid");
2904 std::list<std::pair<AudioInterrupt, AudioFocuState>> audioFocusInfoList{};
2905 if (itZone != zonesMap_.end() && itZone->second != nullptr) {
2906 audioFocusInfoList = itZone->second->audioFocusInfoList;
2907 }
2908
2909 auto iter = std::find_if(audioFocusInfoList.begin(), audioFocusInfoList.end(), [pid](const auto &item) {
2910 return pid == item.first.pid;
2911 });
2912 if (iter == audioFocusInfoList.end()) {
2913 AUDIO_WARNING_LOG("audioFocusInfoList have no match object");
2914 return;
2915 }
2916
2917 auto audioInterrupt = iter->first;
2918 InterruptDfxBuilder dfxBuilder;
2919 auto& [infoIdx, effectIdx] = dfxCollector_->GetDfxIndexes(audioInterrupt.streamId);
2920 dfxBuilder.WriteActionMsg(infoIdx, effectIdx, INTERRUPT_STAGE_TIMEOUT);
2921 dfxCollector_->AddDfxMsg(audioInterrupt.streamId, dfxBuilder.GetResult());
2922 }
2923
WriteStopDfxMsg(const AudioInterrupt & audioInterrupt)2924 void AudioInterruptService::WriteStopDfxMsg(const AudioInterrupt &audioInterrupt)
2925 {
2926 CHECK_AND_RETURN_LOG((dfxCollector_ != nullptr && policyServer_ != nullptr), "WriteStopDfxMsg nullptr");
2927 InterruptDfxBuilder dfxBuilder;
2928 auto& [infoIdx, effectIdx] = dfxCollector_->GetDfxIndexes(audioInterrupt.streamId);
2929 dfxBuilder.WriteActionMsg(infoIdx, effectIdx, INTERRUPT_STAGE_STOP);
2930 dfxCollector_->AddDfxMsg(audioInterrupt.streamId, dfxBuilder.GetResult());
2931
2932 if (audioInterrupt.state == State::RELEASED) {
2933 dfxCollector_->FlushDfxMsg(audioInterrupt.streamId, audioInterrupt.uid);
2934 }
2935 }
2936
RegisterDefaultVolumeTypeListener()2937 void AudioInterruptService::RegisterDefaultVolumeTypeListener()
2938 {
2939 AudioSettingProvider &settingProvider = AudioSettingProvider::GetInstance(AUDIO_POLICY_SERVICE_ID);
2940 AudioSettingObserver::UpdateFunc updateFuncMono = [this, &settingProvider](const std::string &key) {
2941 int32_t currentValueType = STREAM_MUSIC;
2942 ErrCode ret = settingProvider.GetIntValue(DEFAULT_VOLUME_KEY, currentValueType, "system");
2943 CHECK_AND_RETURN_LOG(ret == SUCCESS, "DEFAULT_VOLUME_KEY get mono value failed");
2944 if (currentValueType == STREAM_RING) {
2945 defaultVolumeType_ = STREAM_RING;
2946 } else {
2947 defaultVolumeType_ = STREAM_MUSIC;
2948 }
2949 AUDIO_INFO_LOG("Get defaultVolumeType: %{public}d", defaultVolumeType_);
2950 };
2951 sptr observer = settingProvider.CreateObserver(DEFAULT_VOLUME_KEY, updateFuncMono);
2952 ErrCode ret = settingProvider.RegisterObserver(observer, "system");
2953 if (ret != ERR_OK) {
2954 AUDIO_ERR_LOG("RegisterDefaultVolumeTypeListener mono failed");
2955 }
2956 updateFuncMono(DEFAULT_VOLUME_KEY);
2957 AUDIO_INFO_LOG("DefaultVolumeTypeListener mono successfully, defaultVolumeType:%{public}d", defaultVolumeType_);
2958 }
2959
2960 // LCOV_EXCL_STOP
2961 } // namespace AudioStandard
2962 } // namespace OHOS
2963