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