• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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