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