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_log.h"
22
23 namespace OHOS {
24 namespace AudioStandard {
25 static const std::unordered_map<AudioStreamType, AudioSessionType> SESSION_TYPE_MAP = {
26 {STREAM_ALARM, AudioSessionType::SONIFICATION},
27 {STREAM_RING, AudioSessionType::SONIFICATION},
28 {STREAM_MUSIC, AudioSessionType::MEDIA},
29 {STREAM_MOVIE, AudioSessionType::MEDIA},
30 {STREAM_GAME, AudioSessionType::MEDIA},
31 {STREAM_SPEECH, AudioSessionType::MEDIA},
32 {STREAM_NAVIGATION, AudioSessionType::MEDIA},
33 {STREAM_VOICE_MESSAGE, AudioSessionType::MEDIA},
34 {STREAM_VOICE_CALL, AudioSessionType::CALL},
35 {STREAM_VOICE_CALL_ASSISTANT, AudioSessionType::CALL},
36 {STREAM_VOICE_COMMUNICATION, AudioSessionType::VOIP},
37 {STREAM_SYSTEM, AudioSessionType::SYSTEM},
38 {STREAM_SYSTEM_ENFORCED, AudioSessionType::SYSTEM},
39 {STREAM_ACCESSIBILITY, AudioSessionType::SYSTEM},
40 {STREAM_ULTRASONIC, AudioSessionType::SYSTEM},
41 {STREAM_NOTIFICATION, AudioSessionType::NOTIFICATION},
42 {STREAM_DTMF, AudioSessionType::DTMF},
43 {STREAM_VOICE_ASSISTANT, AudioSessionType::VOICE_ASSISTANT},
44 };
45
AudioSessionService()46 AudioSessionService::AudioSessionService()
47 {
48 }
49
~AudioSessionService()50 AudioSessionService::~AudioSessionService()
51 {
52 }
53
Init()54 void AudioSessionService::Init()
55 {
56 AUDIO_INFO_LOG("AudioSessionService::Init");
57
58 sessionTimer_ = std::make_shared<AudioSessionTimer>();
59 sessionTimer_->SetAudioSessionTimerCallback(shared_from_this());
60 }
61
IsSameTypeForAudioSession(const AudioStreamType incomingType,const AudioStreamType existedType)62 bool AudioSessionService::IsSameTypeForAudioSession(const AudioStreamType incomingType,
63 const AudioStreamType existedType)
64 {
65 if (SESSION_TYPE_MAP.count(incomingType) == 0 || SESSION_TYPE_MAP.count(existedType) == 0) {
66 AUDIO_WARNING_LOG("The stream type (new:%{public}d or old:%{public}d) is invalid!", incomingType, existedType);
67 return false;
68 }
69 return SESSION_TYPE_MAP.at(incomingType) == SESSION_TYPE_MAP.at(existedType);
70 }
71
ActivateAudioSession(const int32_t callerPid,const AudioSessionStrategy & strategy)72 int32_t AudioSessionService::ActivateAudioSession(const int32_t callerPid, const AudioSessionStrategy &strategy)
73 {
74 AUDIO_INFO_LOG("ActivateAudioSession: callerPid %{public}d, concurrencyMode %{public}d",
75 callerPid, static_cast<int32_t>(strategy.concurrencyMode));
76 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
77 if (sessionMap_.count(callerPid) != 0 && sessionMap_[callerPid] != nullptr) {
78 // The audio session of the callerPid is already created. The strategy will be updated.
79 AUDIO_INFO_LOG("The audio seesion of pid %{public}d has already been created! Update strategy.", callerPid);
80 sessionMap_[callerPid]->SetSessionStrategy(strategy);
81 } else {
82 sessionMap_[callerPid] = std::make_shared<AudioSession>(callerPid, strategy, sessionTimer_);
83 sessionMap_[callerPid]->Activate();
84 }
85
86 if (sessionMap_[callerPid]->IsAudioSessionEmpty()) {
87 sessionTimer_->StartTimer(callerPid);
88 }
89
90 return SUCCESS;
91 }
92
DeactivateAudioSession(const int32_t callerPid)93 int32_t AudioSessionService::DeactivateAudioSession(const int32_t callerPid)
94 {
95 AUDIO_INFO_LOG("DeactivateAudioSession: callerPid %{public}d", callerPid);
96 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
97 return DeactivateAudioSessionInternal(callerPid);
98 }
99
DeactivateAudioSessionInternal(const int32_t callerPid,bool isSessionTimeout)100 int32_t AudioSessionService::DeactivateAudioSessionInternal(const int32_t callerPid, bool isSessionTimeout)
101 {
102 AUDIO_INFO_LOG("DeactivateAudioSessionInternal: callerPid %{public}d", callerPid);
103 if (sessionMap_.count(callerPid) == 0) {
104 // The audio session of the callerPid is not existed or has been released.
105 AUDIO_ERR_LOG("The audio seesion of pid %{public}d is not found!", callerPid);
106 return ERR_ILLEGAL_STATE;
107 }
108 sessionMap_[callerPid]->Deactivate();
109 sessionMap_.erase(callerPid);
110
111 if (!isSessionTimeout) {
112 sessionTimer_->StopTimer(callerPid);
113 }
114
115 return SUCCESS;
116 }
117
IsAudioSessionActivated(const int32_t callerPid)118 bool AudioSessionService::IsAudioSessionActivated(const int32_t callerPid)
119 {
120 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
121 if (sessionMap_.count(callerPid) == 0) {
122 // The audio session of the callerPid is not existed or has been released.
123 AUDIO_WARNING_LOG("The audio seesion of pid %{public}d is not found!", callerPid);
124 return false;
125 }
126 return true;
127 }
128
SetSessionTimeOutCallback(const std::shared_ptr<SessionTimeOutCallback> & timeOutCallback)129 int32_t AudioSessionService::SetSessionTimeOutCallback(
130 const std::shared_ptr<SessionTimeOutCallback> &timeOutCallback)
131 {
132 AUDIO_INFO_LOG("SetSessionTimeOutCallback is nullptr!");
133 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
134 if (timeOutCallback == nullptr) {
135 AUDIO_ERR_LOG("timeOutCallback is nullptr!");
136 return AUDIO_INVALID_PARAM;
137 }
138 timeOutCallback_ = timeOutCallback;
139 return SUCCESS;
140 }
141
GetAudioSessionByPid(const int32_t callerPid)142 std::shared_ptr<AudioSession> AudioSessionService::GetAudioSessionByPid(const int32_t callerPid)
143 {
144 AUDIO_INFO_LOG("GetAudioSessionByPid: callerPid %{public}d", callerPid);
145 std::lock_guard<std::mutex> lock(sessionServiceMutex_);
146 if (sessionMap_.count(callerPid) == 0) {
147 AUDIO_ERR_LOG("The audio seesion of pid %{public}d is not found!", callerPid);
148 return nullptr;
149 }
150 return sessionMap_[callerPid];
151 }
152
153 // Audio session timer callback
OnAudioSessionTimeOut(const int32_t callerPid)154 void AudioSessionService::OnAudioSessionTimeOut(const int32_t callerPid)
155 {
156 AUDIO_INFO_LOG("OnAudioSessionTimeOut: callerPid %{public}d", callerPid);
157 std::unique_lock<std::mutex> lock(sessionServiceMutex_);
158 DeactivateAudioSessionInternal(callerPid, true);
159 lock.unlock();
160
161 auto cb = timeOutCallback_.lock();
162 if (cb == nullptr) {
163 AUDIO_ERR_LOG("timeOutCallback_ is nullptr!");
164 return;
165 }
166 cb->OnSessionTimeout(callerPid);
167 }
168 } // namespace AudioStandard
169 } // namespace OHOS
170