1 /*
2 * Copyright (c) 2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioBackgroundManager"
17 #endif
18
19 #include "audio_background_manager.h"
20 #include "audio_policy_log.h"
21 #include "audio_log.h"
22 #include "audio_policy_utils.h"
23 #include "audio_inner_call.h"
24 #include "i_policy_provider.h"
25
26 #include "audio_server_proxy.h"
27 #include "continuous_task_callback_info.h"
28 #include "background_task_listener.h"
29 #include "background_task_subscriber.h"
30 #include "background_task_mgr_helper.h"
31
32 namespace OHOS {
33 namespace AudioStandard {
34
35 constexpr int32_t BOOTUP_MUSIC_UID = 1003;
36 static const int64_t WATI_PLAYBACK_TIME = 200000; // 200ms
37 mutex g_isAllowedPlaybackListenerMutex;
38 mutex g_backgroundMuteListenerMutex;
39
SetQueryAllowedPlaybackCallback(const sptr<IRemoteObject> & object)40 int32_t AudioBackgroundManager::SetQueryAllowedPlaybackCallback(const sptr<IRemoteObject> &object)
41 {
42 lock_guard<mutex> lock(g_isAllowedPlaybackListenerMutex);
43 isAllowedPlaybackListener_ = iface_cast<IStandardAudioPolicyManagerListener>(object);
44 return SUCCESS;
45 }
46
SetBackgroundMuteCallback(const sptr<IRemoteObject> & object)47 int32_t AudioBackgroundManager::SetBackgroundMuteCallback(const sptr<IRemoteObject> &object)
48 {
49 lock_guard<mutex> lock(g_backgroundMuteListenerMutex);
50 backgroundMuteListener_ = iface_cast<IStandardAudioPolicyManagerListener>(object);
51 return SUCCESS;
52 }
53
SubscribeBackgroundTask()54 void AudioBackgroundManager::SubscribeBackgroundTask()
55 {
56 AUDIO_INFO_LOG("in");
57 if (backgroundTaskListener_ == nullptr) {
58 backgroundTaskListener_ = std::make_shared<BackgroundTaskListener>();
59 }
60 auto ret = BackgroundTaskMgr::BackgroundTaskMgrHelper::SubscribeBackgroundTask(*backgroundTaskListener_);
61 if (ret != 0) {
62 AUDIO_INFO_LOG(" failed, err:%{public}d", ret);
63 }
64 }
65
IsAllowedPlayback(const int32_t & uid,const int32_t & pid)66 bool AudioBackgroundManager::IsAllowedPlayback(const int32_t &uid, const int32_t &pid)
67 {
68 std::lock_guard<std::mutex> lock(appStatesMapMutex_);
69 if (!FindKeyInMap(pid)) {
70 AppState appState;
71 appState.isSystem = CheckoutSystemAppUtil::CheckoutSystemApp(uid);
72 InsertIntoAppStatesMap(pid, appState);
73 }
74
75 AppState &appState = appStatesMap_[pid];
76 AUDIO_INFO_LOG("appStatesMap_ start pid: %{public}d with hasSession: %{public}d, isBack: %{public}d, "
77 "hasBackgroundTask: %{public}d, isFreeze: %{public}d", pid, appState.hasSession, appState.isBack,
78 appState.hasBackTask, appState.isFreeze);
79 if (appState.isBack) {
80 bool mute = appState.hasBackTask ? false : (appState.isBinder ? true : false);
81 if (!appState.hasSession) {
82 // for media
83 HandleSessionStateChange(uid, pid);
84 // for others
85 streamCollector_.HandleStartStreamMuteState(uid, pid, mute, true);
86 } else {
87 streamCollector_.HandleStartStreamMuteState(uid, pid, mute, false);
88 }
89 } else {
90 streamCollector_.HandleStartStreamMuteState(uid, pid, false, false);
91 }
92 return true;
93 }
94
NotifyAppStateChange(const int32_t uid,const int32_t pid,AppIsBackState state)95 void AudioBackgroundManager::NotifyAppStateChange(const int32_t uid, const int32_t pid, AppIsBackState state)
96 {
97 bool isBack = (state != STATE_FOREGROUND);
98 {
99 std::lock_guard<std::mutex> lock(appStatesMapMutex_);
100 if (state == STATE_END) {
101 return DeleteFromMap(pid);
102 }
103 if (!FindKeyInMap(pid)) {
104 AppState appState;
105 appState.isBack = isBack;
106 appState.isSystem = CheckoutSystemAppUtil::CheckoutSystemApp(uid);
107 InsertIntoAppStatesMap(pid, appState);
108 }
109 return;
110 }
111
112 bool notifyMute = false;
113 {
114 std::lock_guard<std::mutex> lock(appStatesMapMutex_);
115 AppState &appState = appStatesMap_[pid];
116 CHECK_AND_RETURN(appState.isBack != isBack);
117 appState.isBack = isBack;
118 appState.isFreeze = isBack ? appState.isFreeze : false;
119 appState.isBinder = isBack ? appState.isBinder : false;
120 AUDIO_INFO_LOG("appStatesMap_ change pid: %{public}d with hasSession: %{public}d, isBack: %{public}d, "
121 "hasBackgroundTask: %{public}d, isFreeze: %{public}d", pid, appState.hasSession, appState.isBack,
122 appState.hasBackTask, appState.isFreeze);
123 if (!isBack) {
124 return streamCollector_.HandleForegroundUnmute(uid, pid);
125 }
126 bool needMute = !appState.hasSession && appState.isBack && !CheckoutSystemAppUtil::CheckoutSystemApp(uid);
127 streamCollector_.HandleAppStateChange(uid, pid, needMute, notifyMute, appState.hasBackTask);
128 streamCollector_.HandleKaraokeAppToBack(uid, pid);
129 }
130 if (notifyMute && !VolumeUtils::IsPCVolumeEnable()) {
131 lock_guard<mutex> lock(g_backgroundMuteListenerMutex);
132 CHECK_AND_RETURN_LOG(backgroundMuteListener_ != nullptr, "backgroundMuteListener_ is nulptr");
133 AUDIO_INFO_LOG("OnBackground with uid: %{public}d", uid);
134 backgroundMuteListener_->OnBackgroundMute(uid);
135 }
136 }
137
NotifyBackgroundTaskStateChange(const int32_t uid,const int32_t pid,bool hasBackgroundTask)138 void AudioBackgroundManager::NotifyBackgroundTaskStateChange(const int32_t uid, const int32_t pid, bool hasBackgroundTask)
139 {
140 std::lock_guard<std::mutex> lock(appStatesMapMutex_);
141 if (!FindKeyInMap(pid)) {
142 AppState appState;
143 appState.hasBackTask = hasBackgroundTask;
144 appState.isSystem = CheckoutSystemAppUtil::CheckoutSystemApp(uid);
145 InsertIntoAppStatesMap(pid, appState);
146 } else {
147 AppState &appState = appStatesMap_[pid];
148 CHECK_AND_RETURN(appState.hasBackTask != hasBackgroundTask);
149 appState.hasBackTask = hasBackgroundTask;
150 AUDIO_INFO_LOG("appStatesMap_ change pid: %{public}d with hasSession: %{public}d, isBack: %{public}d, "
151 "hasBackgroundTask: %{public}d, isFreeze: %{public}d", pid, appState.hasSession, appState.isBack,
152 appState.hasBackTask, appState.isFreeze);
153 if (appState.hasBackTask && !appState.isFreeze) {
154 streamCollector_.HandleBackTaskStateChange(uid, appState.hasSession);
155 }
156 }
157 }
158
NotifySessionStateChange(const int32_t uid,const int32_t pid,const bool hasSession)159 int32_t AudioBackgroundManager::NotifySessionStateChange(const int32_t uid, const int32_t pid, const bool hasSession)
160 {
161 std::lock_guard<std::mutex> lock(appStatesMapMutex_);
162 if (!FindKeyInMap(pid)) {
163 AppState appState;
164 appState.hasSession = hasSession;
165 appState.isSystem = CheckoutSystemAppUtil::CheckoutSystemApp(uid);
166 InsertIntoAppStatesMap(pid, appState);
167 } else {
168 AppState &appState = appStatesMap_[pid];
169 CHECK_AND_RETURN_RET(appState.hasSession != hasSession, SUCCESS);
170 appState.hasSession = hasSession;
171 AUDIO_INFO_LOG("appStatesMap_ change pid: %{public}d with hasSession: %{public}d, isBack: %{public}d, "
172 "hasBackgroundTask: %{public}d, isFreeze: %{public}d", pid, appState.hasSession, appState.isBack,
173 appState.hasBackTask, appState.isFreeze);
174 HandleSessionStateChange(uid, pid);
175 }
176 return SUCCESS;
177 }
178
HandleSessionStateChange(const int32_t uid,const int32_t pid)179 void AudioBackgroundManager::HandleSessionStateChange(const int32_t uid, const int32_t pid)
180 {
181 auto it = appStatesMap_.find(pid);
182 AppState &appState = (it != appStatesMap_.end()) ? it->second : appStatesMap_[pid];
183 if (it == appStatesMap_.end()) {
184 appState.isSystem = CheckoutSystemAppUtil::CheckoutSystemApp(uid);
185 }
186 bool needMute = !appState.hasSession && appState.isBack && !appState.isSystem;
187 bool notifyMute = false;
188 streamCollector_.HandleAppStateChange(uid, pid, needMute, notifyMute, appState.hasBackTask);
189 if (notifyMute && !VolumeUtils::IsPCVolumeEnable()) {
190 lock_guard<mutex> lock(g_backgroundMuteListenerMutex);
191 CHECK_AND_RETURN_LOG(backgroundMuteListener_ != nullptr, "backgroundMuteListener_ is nulptr");
192 AUDIO_INFO_LOG("OnBackground with uid: %{public}d", uid);
193 backgroundMuteListener_->OnBackgroundMute(uid);
194 }
195 }
196
NotifyFreezeStateChange(const std::set<int32_t> & pidList,const bool isFreeze)197 int32_t AudioBackgroundManager::NotifyFreezeStateChange(const std::set<int32_t> &pidList, const bool isFreeze)
198 {
199 std::lock_guard<std::mutex> lock(appStatesMapMutex_);
200 for (auto pid : pidList) {
201 if (!FindKeyInMap(pid)) {
202 AppState appState;
203 appState.isFreeze = isFreeze;
204 InsertIntoAppStatesMap(pid, appState);
205 } else {
206 AppState &appState = appStatesMap_[pid];
207 CHECK_AND_RETURN_RET(appState.isFreeze != isFreeze, SUCCESS);
208 appState.isFreeze = isFreeze;
209 appState.isBinder = !isFreeze;
210 AUDIO_INFO_LOG("appStatesMap_ change pid: %{public}d with hasSession: %{public}d, isBack: %{public}d, "
211 "hasBackgroundTask: %{public}d, isFreeze: %{public}d", pid, appState.hasSession, appState.isBack,
212 appState.hasBackTask, appState.isFreeze);
213 HandleFreezeStateChange(pid, isFreeze);
214 }
215 }
216 return SUCCESS;
217 }
218
ResetAllProxy()219 int32_t AudioBackgroundManager::ResetAllProxy()
220 {
221 AUDIO_INFO_LOG("RSS reset all proxy to unfreeze");
222 std::lock_guard<std::mutex> lock(appStatesMapMutex_);
223 for (auto& it : appStatesMap_) {
224 it.second.isFreeze = false;
225 it.second.isBinder = false;
226 }
227 return SUCCESS;
228 }
229
HandleFreezeStateChange(const int32_t pid,bool isFreeze)230 void AudioBackgroundManager::HandleFreezeStateChange(const int32_t pid, bool isFreeze)
231 {
232 AppState& appState = appStatesMap_[pid];
233 if (isFreeze) {
234 if (!appState.hasBackTask) {
235 streamCollector_.HandleFreezeStateChange(pid, true, appState.hasSession);
236 }
237 } else {
238 if (appState.hasBackTask) {
239 streamCollector_.HandleFreezeStateChange(pid, false, appState.hasSession);
240 }
241 }
242 }
243
InsertIntoAppStatesMap(int32_t pid,AppState appState)244 void AudioBackgroundManager::InsertIntoAppStatesMap(int32_t pid, AppState appState)
245 {
246 appStatesMap_.insert(std::make_pair(pid, appState));
247 AUDIO_INFO_LOG("appStatesMap_ add pid: %{public}d with hasSession: %{public}d, isBack: %{public}d, "
248 "hasBackgroundTask: %{public}d, isFreeze: %{public}d", pid, appState.hasSession, appState.isBack,
249 appState.hasBackTask, appState.isFreeze);
250 }
251
DeleteFromMap(int32_t pid)252 void AudioBackgroundManager::DeleteFromMap(int32_t pid)
253 {
254 if (FindKeyInMap(pid)) {
255 appStatesMap_.erase(pid);
256 AUDIO_INFO_LOG("Delete pid: %{public}d success.", pid);
257 } else {
258 AUDIO_DEBUG_LOG("Delete pid: %{public}d failed. It does nt exist", pid);
259 }
260 }
261
FindKeyInMap(int32_t pid)262 bool AudioBackgroundManager::FindKeyInMap(int32_t pid)
263 {
264 return appStatesMap_.find(pid) != appStatesMap_.end();
265 }
266 }
267 }
268