• 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 
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