1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #undef LOG_TAG
16 #define LOG_TAG "AudioSessionService"
17
18 #include "audio_session_service.h"
19
20 #include "audio_errors.h"
21 #include "audio_policy_log.h"
22 #include "audio_utils.h"
23 #include "audio_stream_id_allocator.h"
24 #include "audio_stream_collector.h"
25 #include "ipc_skeleton.h"
26
27 namespace OHOS {
28 namespace AudioStandard {
29
30 static constexpr time_t AUDIO_SESSION_TIME_OUT_DURATION_S = 60; // Audio session timeout duration : 60 seconds
31 static constexpr time_t AUDIO_SESSION_SCENE_TIME_OUT_DURATION_S = 10; // Audio sessionV2 timeout duration : 10 seconds
32
33 static const std::unordered_map<AudioStreamType, AudioSessionType> SESSION_TYPE_MAP = {
34 {STREAM_ALARM, AudioSessionType::SONIFICATION},
35 {STREAM_RING, AudioSessionType::SONIFICATION},
36 {STREAM_MUSIC, AudioSessionType::MEDIA},
37 {STREAM_MOVIE, AudioSessionType::MEDIA},
38 {STREAM_GAME, AudioSessionType::MEDIA},
39 {STREAM_SPEECH, AudioSessionType::MEDIA},
40 {STREAM_NAVIGATION, AudioSessionType::MEDIA},
41 {STREAM_VOICE_MESSAGE, AudioSessionType::MEDIA},
42 {STREAM_VOICE_CALL, AudioSessionType::CALL},
43 {STREAM_VOICE_CALL_ASSISTANT, AudioSessionType::CALL},
44 {STREAM_VOICE_COMMUNICATION, AudioSessionType::VOIP},
45 {STREAM_SYSTEM, AudioSessionType::SYSTEM},
46 {STREAM_SYSTEM_ENFORCED, AudioSessionType::SYSTEM},
47 {STREAM_ACCESSIBILITY, AudioSessionType::SYSTEM},
48 {STREAM_ULTRASONIC, AudioSessionType::SYSTEM},
49 {STREAM_NOTIFICATION, AudioSessionType::NOTIFICATION},
50 {STREAM_DTMF, AudioSessionType::DTMF},
51 {STREAM_VOICE_ASSISTANT, AudioSessionType::VOICE_ASSISTANT},
52 };
53
AudioSessionService()54 AudioSessionService::AudioSessionService()
55 {
56 }
57
~AudioSessionService()58 AudioSessionService::~AudioSessionService()
59 {
60 }
61
GetAudioSessionService()62 std::shared_ptr<AudioSessionService> AudioSessionService::GetAudioSessionService()
63 {
64 static std::shared_ptr<AudioSessionService> audioSessionService = std::make_shared<AudioSessionService>();
65 return audioSessionService;
66 }
67
IsSameTypeForAudioSession(const AudioStreamType incomingType,const AudioStreamType existedType)68 bool AudioSessionService::IsSameTypeForAudioSession(const AudioStreamType incomingType,
69 const AudioStreamType existedType)
70 {
71 if (SESSION_TYPE_MAP.count(incomingType) == 0 || SESSION_TYPE_MAP.count(existedType) == 0) {
72 AUDIO_WARNING_LOG("The stream type (new:%{public}d or old:%{public}d) is invalid!", incomingType, existedType);
73 return false;
74 }
75 return SESSION_TYPE_MAP.at(incomingType) == SESSION_TYPE_MAP.at(existedType);
76 }
77
ActivateAudioSession(const int32_t callerPid,const AudioSessionStrategy & strategy)78 int32_t AudioSessionService::ActivateAudioSession(const int32_t callerPid, const AudioSessionStrategy &strategy)
79 {
80 AUDIO_INFO_LOG("ActivateAudioSession: callerPid %{public}d, concurrencyMode %{public}d",
81 callerPid, static_cast<int32_t>(strategy.concurrencyMode));
82 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
83
84 if (sessionMap_.count(callerPid) != 0) {
85 // The audio session of the callerPid is already created. The strategy will be updated.
86 AUDIO_INFO_LOG("The audio seesion of pid %{public}d has already been created! Update strategy.", callerPid);
87 } else {
88 sessionMap_[callerPid] = std::make_shared<AudioSession>(callerPid, strategy, shared_from_this());
89 }
90
91 if (sessionMap_[callerPid] == nullptr) {
92 AUDIO_ERR_LOG("Create audio seesion fail, pid: %{public}d!", callerPid);
93 return ERROR;
94 }
95
96 if (sessionMap_[callerPid]->IsSceneParameterSet()) {
97 GenerateFakeStreamId(callerPid);
98 }
99
100 sessionMap_[callerPid]->Activate(strategy);
101
102 StopMonitor(callerPid);
103 if (sessionMap_[callerPid]->IsAudioSessionEmpty()) {
104 // session v1 60s
105 if (!sessionMap_[callerPid]->IsSceneParameterSet()) {
106 StartMonitor(callerPid, AUDIO_SESSION_TIME_OUT_DURATION_S);
107 }
108
109 // session v2 background 10s
110 if (sessionMap_[callerPid]->IsSceneParameterSet() && sessionMap_[callerPid]->IsBackGroundApp()) {
111 StartMonitor(callerPid, AUDIO_SESSION_SCENE_TIME_OUT_DURATION_S);
112 }
113 }
114
115 return SUCCESS;
116 }
117
DeactivateAudioSession(const int32_t callerPid)118 int32_t AudioSessionService::DeactivateAudioSession(const int32_t callerPid)
119 {
120 AUDIO_INFO_LOG("DeactivateAudioSession: callerPid %{public}d", callerPid);
121 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
122 return DeactivateAudioSessionInternal(callerPid);
123 }
124
DeactivateAudioSessionInternal(const int32_t callerPid,bool isSessionTimeout)125 int32_t AudioSessionService::DeactivateAudioSessionInternal(const int32_t callerPid, bool isSessionTimeout)
126 {
127 AUDIO_INFO_LOG("DeactivateAudioSessionInternal: callerPid %{public}d", callerPid);
128 if (sessionMap_.count(callerPid) == 0) {
129 // The audio session of the callerPid is not existed or has been released.
130 AUDIO_ERR_LOG("The audio seesion of pid %{public}d is not found!", callerPid);
131 return ERR_ILLEGAL_STATE;
132 }
133
134 if (sessionMap_[callerPid] == nullptr) {
135 AUDIO_ERR_LOG("The audio seesion obj of pid %{public}d is nullptr!", callerPid);
136 return ERR_ILLEGAL_STATE;
137 }
138
139 sessionMap_[callerPid]->Deactivate();
140 sessionMap_.erase(callerPid);
141
142 if (!isSessionTimeout) {
143 StopMonitor(callerPid);
144 }
145
146 return SUCCESS;
147 }
148
IsAudioSessionActivated(const int32_t callerPid)149 bool AudioSessionService::IsAudioSessionActivated(const int32_t callerPid)
150 {
151 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
152 if (sessionMap_.count(callerPid) == 0 || sessionMap_[callerPid] == nullptr) {
153 // The audio session of the callerPid is not existed or has been released.
154 AUDIO_WARNING_LOG("The audio seesion of pid %{public}d is not found!", callerPid);
155 return false;
156 }
157 return sessionMap_[callerPid]->IsActivated();
158 }
159
SetSessionTimeOutCallback(const std::shared_ptr<SessionTimeOutCallback> & timeOutCallback)160 int32_t AudioSessionService::SetSessionTimeOutCallback(
161 const std::shared_ptr<SessionTimeOutCallback> &timeOutCallback)
162 {
163 AUDIO_INFO_LOG("SetSessionTimeOutCallback is nullptr!");
164 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
165 if (timeOutCallback == nullptr) {
166 AUDIO_ERR_LOG("timeOutCallback is nullptr!");
167 return AUDIO_INVALID_PARAM;
168 }
169 timeOutCallback_ = timeOutCallback;
170 return SUCCESS;
171 }
172
GetAudioSessionByPid(const int32_t callerPid)173 std::shared_ptr<AudioSession> AudioSessionService::GetAudioSessionByPid(const int32_t callerPid)
174 {
175 AUDIO_INFO_LOG("GetAudioSessionByPid: callerPid %{public}d", callerPid);
176 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
177 if (sessionMap_.count(callerPid) == 0) {
178 AUDIO_ERR_LOG("The audio seesion of pid %{public}d is not found!", callerPid);
179 return nullptr;
180 }
181 return sessionMap_[callerPid];
182 }
183
184 // Audio session monitor callback
OnAudioSessionTimeOut(int32_t callerPid)185 void AudioSessionService::OnAudioSessionTimeOut(int32_t callerPid)
186 {
187 AUDIO_INFO_LOG("OnAudioSessionTimeOut: callerPid %{public}d", callerPid);
188 std::unique_lock<std::mutex> lock(sessionServiceMutex_);
189 DeactivateAudioSessionInternal(callerPid, true);
190 lock.unlock();
191
192 auto cb = timeOutCallback_.lock();
193 if (cb == nullptr) {
194 AUDIO_ERR_LOG("timeOutCallback_ is nullptr!");
195 return;
196 }
197 cb->OnSessionTimeout(callerPid);
198 }
199
GetSelfSharedPtr()200 std::shared_ptr<AudioSessionStateMonitor> AudioSessionService::GetSelfSharedPtr()
201 {
202 return shared_from_this();
203 }
204
SetAudioSessionScene(int32_t callerPid,AudioSessionScene scene)205 int32_t AudioSessionService::SetAudioSessionScene(int32_t callerPid, AudioSessionScene scene)
206 {
207 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
208 if (sessionMap_.count(callerPid) != 0 && sessionMap_[callerPid] != nullptr) {
209 // The audio session of the callerPid is already created. The strategy will be updated.
210 AUDIO_INFO_LOG("The audio seesion of pid %{public}d has already been created! Update scene.", callerPid);
211 } else {
212 AudioSessionStrategy strategy;
213 strategy.concurrencyMode = AudioConcurrencyMode::DEFAULT;
214 sessionMap_[callerPid] = std::make_shared<AudioSession>(callerPid, strategy, shared_from_this());
215 CHECK_AND_RETURN_RET_LOG(sessionMap_[callerPid] != nullptr, ERROR, "Create AudioSession fail");
216 }
217
218 return sessionMap_[callerPid]->SetAudioSessionScene(scene);
219 }
220
GetAudioSessionStreamUsage(int32_t callerPid)221 StreamUsage AudioSessionService::GetAudioSessionStreamUsage(int32_t callerPid)
222 {
223 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
224 auto session = sessionMap_.find(callerPid);
225 if (session != sessionMap_.end() && sessionMap_[callerPid] != nullptr) {
226 return sessionMap_[callerPid]->GetSessionStreamUsage();
227 }
228
229 return STREAM_USAGE_INVALID;
230 }
231
IsAudioSessionFocusMode(int32_t callerPid)232 bool AudioSessionService::IsAudioSessionFocusMode(int32_t callerPid)
233 {
234 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
235 auto session = sessionMap_.find(callerPid);
236 return session != sessionMap_.end() && sessionMap_[callerPid] != nullptr &&
237 sessionMap_[callerPid]->IsSceneParameterSet() && sessionMap_[callerPid]->IsActivated();
238 }
239
240 // For audio session v2
ShouldExcludeStreamType(const AudioInterrupt & audioInterrupt)241 bool AudioSessionService::ShouldExcludeStreamType(const AudioInterrupt &audioInterrupt)
242 {
243 bool isExcludedStream = audioInterrupt.audioFocusType.streamType == STREAM_NOTIFICATION ||
244 audioInterrupt.audioFocusType.streamType == STREAM_DTMF ||
245 audioInterrupt.audioFocusType.streamType == STREAM_ALARM ||
246 audioInterrupt.audioFocusType.streamType == STREAM_VOICE_CALL_ASSISTANT ||
247 audioInterrupt.audioFocusType.streamType == STREAM_ULTRASONIC ||
248 audioInterrupt.audioFocusType.streamType == STREAM_ACCESSIBILITY;
249 if (isExcludedStream) {
250 return true;
251 }
252
253 bool isExcludedStreamType = audioInterrupt.audioFocusType.sourceType != SOURCE_TYPE_INVALID;
254 if (isExcludedStreamType) {
255 return true;
256 }
257
258 return false;
259 }
260
ShouldBypassFocusForStream(const AudioInterrupt & audioInterrupt)261 bool AudioSessionService::ShouldBypassFocusForStream(const AudioInterrupt &audioInterrupt)
262 {
263 if (!IsAudioSessionFocusMode(audioInterrupt.pid)) {
264 return false;
265 }
266
267 if (ShouldExcludeStreamType(audioInterrupt)) {
268 return false;
269 }
270
271 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
272 auto session = sessionMap_.find(audioInterrupt.pid);
273 if (session != sessionMap_.end() && sessionMap_[audioInterrupt.pid] != nullptr) {
274 sessionMap_[audioInterrupt.pid]->AddStreamInfo(audioInterrupt);
275 }
276
277 return true;
278 }
279
ShouldAudioSessionProcessHintType(InterruptHint hintType)280 bool AudioSessionService::ShouldAudioSessionProcessHintType(InterruptHint hintType)
281 {
282 return hintType == INTERRUPT_HINT_RESUME ||
283 hintType == INTERRUPT_HINT_PAUSE ||
284 hintType == INTERRUPT_HINT_STOP ||
285 hintType == INTERRUPT_HINT_DUCK ||
286 hintType == INTERRUPT_HINT_UNDUCK;
287 }
288
ShouldAudioStreamProcessHintType(InterruptHint hintType)289 bool AudioSessionService::ShouldAudioStreamProcessHintType(InterruptHint hintType)
290 {
291 return hintType == INTERRUPT_HINT_PAUSE ||
292 hintType == INTERRUPT_HINT_STOP ||
293 hintType == INTERRUPT_HINT_DUCK ||
294 hintType == INTERRUPT_HINT_UNDUCK;
295 }
296
GetStreams(int32_t callerPid)297 std::vector<AudioInterrupt> AudioSessionService::GetStreams(int32_t callerPid)
298 {
299 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
300 auto session = sessionMap_.find(callerPid);
301 if (session == sessionMap_.end()) {
302 return {};
303 }
304 return session->second->GetStreams();
305 }
306
GenerateFakeAudioInterrupt(int32_t callerPid)307 AudioInterrupt AudioSessionService::GenerateFakeAudioInterrupt(int32_t callerPid)
308 {
309 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
310 AudioInterrupt fakeAudioInterrupt;
311 fakeAudioInterrupt.pid = callerPid;
312 fakeAudioInterrupt.uid = IPCSkeleton::GetCallingUid();
313 fakeAudioInterrupt.isAudioSessionInterrupt = true;
314 auto session = sessionMap_.find(callerPid);
315 if (session != sessionMap_.end() && sessionMap_[callerPid] != nullptr) {
316 fakeAudioInterrupt.streamId = sessionMap_[callerPid]->GetFakeStreamId();
317 fakeAudioInterrupt.audioFocusType.streamType = sessionMap_[callerPid]->GetFakeStreamType();
318 fakeAudioInterrupt.streamUsage = sessionMap_[callerPid]->GetSessionStreamUsage();
319 } else {
320 AUDIO_ERR_LOG("This failure should not have occurred, possibly due to calling the function incorrectly!");
321 }
322
323 return fakeAudioInterrupt;
324 }
325
HasStreamForDeviceType(int32_t callerPid,DeviceType deviceType)326 bool AudioSessionService::HasStreamForDeviceType(int32_t callerPid, DeviceType deviceType)
327 {
328 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
329 auto session = sessionMap_.find(callerPid);
330 if (session == sessionMap_.end()) {
331 return false;
332 }
333
334 if (session->second == nullptr) {
335 return false;
336 }
337
338 if (session->second->IsAudioSessionEmpty()) {
339 return false;
340 }
341
342 std::set<int32_t> streamIds =
343 AudioStreamCollector::GetAudioStreamCollector().GetSessionIdsOnRemoteDeviceByDeviceType(deviceType);
344
345 std::vector<AudioInterrupt> streamsInSession = session->second->GetStreams();
346 for (const auto &stream : streamsInSession) {
347 if (streamIds.find(stream.streamId) != streamIds.end()) {
348 return true;
349 }
350 }
351
352 return false;
353 }
354
GenerateFakeStreamId(int32_t callerPid)355 void AudioSessionService::GenerateFakeStreamId(int32_t callerPid)
356 {
357 uint32_t fakeStreamId = AudioStreamIdAllocator::GetAudioStreamIdAllocator().GenerateStreamId();
358
359 auto session = sessionMap_.find(callerPid);
360 if (session != sessionMap_.end() && sessionMap_[callerPid] != nullptr) {
361 sessionMap_[callerPid]->SaveFakeStreamId(fakeStreamId);
362 }
363 }
364
RemoveStreamInfo(const AudioInterrupt & audioInterrupt)365 void AudioSessionService::RemoveStreamInfo(const AudioInterrupt &audioInterrupt)
366 {
367 // No need to handle fake focus.
368 if (audioInterrupt.isAudioSessionInterrupt) {
369 return;
370 }
371
372 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
373 auto session = sessionMap_.find(audioInterrupt.pid);
374 if (session == sessionMap_.end()) {
375 return;
376 }
377 return session->second->RemoveStreamInfo(audioInterrupt.streamId);
378 }
379
ClearStreamInfo(const int32_t callerPid)380 void AudioSessionService::ClearStreamInfo(const int32_t callerPid)
381 {
382 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
383 if ((sessionMap_.count(callerPid) == 0) || (sessionMap_[callerPid] == nullptr)) {
384 return;
385 }
386
387 sessionMap_[callerPid]->ClearStreamInfo();
388 }
389
AudioSessionInfoDump(std::string & dumpString)390 void AudioSessionService::AudioSessionInfoDump(std::string &dumpString)
391 {
392 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
393 if (sessionMap_.empty()) {
394 AppendFormat(dumpString, " - The AudioSessionMap is empty.\n");
395 return;
396 }
397 for (auto iterAudioSession = sessionMap_.begin(); iterAudioSession != sessionMap_.end(); ++iterAudioSession) {
398 dumpString += "\n";
399 int32_t pid = iterAudioSession->first;
400 std::shared_ptr<AudioSession> audioSession = iterAudioSession->second;
401 if (audioSession == nullptr) {
402 AppendFormat(dumpString, " - pid: %d, AudioSession is null.\n", pid);
403 continue;
404 }
405 audioSession->Dump(dumpString);
406 }
407 dumpString += "\n";
408 }
409
SetSessionDefaultOutputDevice(const int32_t callerPid,const DeviceType & deviceType)410 int32_t AudioSessionService::SetSessionDefaultOutputDevice(const int32_t callerPid, const DeviceType &deviceType)
411 {
412 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
413 if ((sessionMap_.count(callerPid) > 0) && (sessionMap_[callerPid] != nullptr)) {
414 AUDIO_INFO_LOG("SetSessionDefaultOutputDevice: callerPid %{public}d, deviceType %{public}d",
415 callerPid, static_cast<int32_t>(deviceType));
416 } else {
417 AudioSessionStrategy strategy;
418 strategy.concurrencyMode = AudioConcurrencyMode::DEFAULT;
419 sessionMap_[callerPid] = std::make_shared<AudioSession>(callerPid, strategy, shared_from_this());
420 CHECK_AND_RETURN_RET_LOG(sessionMap_[callerPid] != nullptr, ERROR, "Create AudioSession fail");
421 }
422
423 return sessionMap_[callerPid]->SetSessionDefaultOutputDevice(deviceType);
424 }
425
GetSessionDefaultOutputDevice(const int32_t callerPid)426 DeviceType AudioSessionService::GetSessionDefaultOutputDevice(const int32_t callerPid)
427 {
428 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
429 if ((sessionMap_.count(callerPid) > 0) && (sessionMap_[callerPid] != nullptr)) {
430 DeviceType deviceType;
431 sessionMap_[callerPid]->GetSessionDefaultOutputDevice(deviceType);
432 return deviceType;
433 }
434
435 return DEVICE_TYPE_INVALID;
436 }
437
IsStreamAllowedToSetDevice(const uint32_t streamId)438 bool AudioSessionService::IsStreamAllowedToSetDevice(const uint32_t streamId)
439 {
440 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
441 for (const auto& pair : sessionMap_) {
442 if ((pair.second != nullptr) && (pair.second->IsStreamContainedInCurrentSession(streamId))) {
443 // for inactivate session, its default device cannot be used, so set it to DEVICE_TYPE_INVALID
444 if (!pair.second->IsActivated()) {
445 return true;
446 } else {
447 DeviceType deviceType;
448 pair.second->GetSessionDefaultOutputDevice(deviceType);
449 return deviceType == DEVICE_TYPE_INVALID;
450 }
451 return true;
452 }
453 }
454
455 return true;
456 }
457
IsSessionNeedToFetchOutputDevice(const int32_t callerPid)458 bool AudioSessionService::IsSessionNeedToFetchOutputDevice(const int32_t callerPid)
459 {
460 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
461 if ((sessionMap_.count(callerPid) != 0) && (sessionMap_[callerPid] != nullptr)) {
462 return sessionMap_[callerPid]->GetAndClearNeedToFetchFlag();
463 }
464
465 return false;
466 }
467
NotifyAppStateChange(const int32_t pid,bool isBackState)468 void AudioSessionService::NotifyAppStateChange(const int32_t pid, bool isBackState)
469 {
470 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
471 if (sessionMap_.count(pid) == 0) {
472 return;
473 }
474
475 if (sessionMap_[pid] == nullptr) {
476 AUDIO_WARNING_LOG("audio session is nullptr, pid: %{public}d!", pid);
477 return;
478 }
479
480 // v2 foreground
481 if (!isBackState && sessionMap_[pid]->IsSceneParameterSet()) {
482 StopMonitor(pid);
483 return;
484 }
485
486 // v2 background
487 if (sessionMap_[pid]->IsActivated() &&
488 sessionMap_[pid]->IsSceneParameterSet() &&
489 sessionMap_[pid]->IsAudioSessionEmpty()) {
490 StartMonitor(pid, AUDIO_SESSION_SCENE_TIME_OUT_DURATION_S);
491 }
492 }
493
494 } // namespace AudioStandard
495 } // namespace OHOS
496