1 /*
2 * Copyright (c) 2022 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
16 #include "background_audio_controller.h"
17 #include "avsession_log.h"
18 #include "avsession_service.h"
19 #include "avsession_item.h"
20 #include "permission_checker.h"
21
22 namespace OHOS::AVSession {
23 using AudioStandard::RendererState;
24
BackgroundAudioController()25 BackgroundAudioController::BackgroundAudioController() : ptr_(nullptr)
26 {
27 SLOGI("construct");
28 }
29
~BackgroundAudioController()30 BackgroundAudioController::~BackgroundAudioController()
31 {
32 SLOGI("destroy");
33 }
34
Init(AVSessionService * ptr)35 void BackgroundAudioController::Init(AVSessionService *ptr)
36 {
37 ptr_ = ptr;
38 AudioAdapter::GetInstance().AddStreamRendererStateListener([this](const auto& infos) {
39 HandleAudioStreamRendererStateChange(infos);
40 });
41 AppManagerAdapter::GetInstance().SetAppBackgroundStateObserver([this](int32_t uid, int32_t pid) {
42 SLOGI("set background observe for uid=%{public}d pid=%{public}d", uid, pid);
43 HandleAppBackgroundState(uid, pid);
44 });
45 }
46
OnSessionCreate(const AVSessionDescriptor & descriptor)47 void BackgroundAudioController::OnSessionCreate(const AVSessionDescriptor& descriptor)
48 {
49 std::lock_guard lockGuard(lock_);
50 sessionUIDs_.insert(descriptor.uid_);
51 AppManagerAdapter::GetInstance().RemoveObservedApp(descriptor.uid_);
52 SLOGI("OnSessionCreate remove observe for uid %{public}d", descriptor.uid_);
53 }
54
OnSessionRelease(const AVSessionDescriptor & descriptor)55 void BackgroundAudioController::OnSessionRelease(const AVSessionDescriptor& descriptor)
56 {
57 {
58 std::lock_guard lockGuard(lock_);
59 sessionUIDs_.erase(descriptor.uid_);
60 }
61
62 if (descriptor.isThirdPartyApp_) {
63 if (!AppManagerAdapter::GetInstance().IsAppBackground(descriptor.uid_, descriptor.pid_)) {
64 AppManagerAdapter::GetInstance().AddObservedApp(descriptor.uid_);
65 SLOGI("OnSessionRelease add observe for uid %{public}d", descriptor.uid_);
66 return;
67 }
68
69 int32_t uid = descriptor.uid_;
70 bool isRunning = AudioAdapter::GetInstance().GetRendererRunning(uid);
71 if (!isRunning) {
72 SLOGI("renderer state is not AudioStandard::RENDERER_RUNNING");
73 return;
74 }
75 if (!IsBackgroundMode(descriptor.uid_, BackgroundMode::AUDIO_PLAYBACK)) {
76 SLOGI("uid=%{public}d hasn't AUDIO_PLAYBACK task", descriptor.uid_);
77 return;
78 }
79 SLOGI("pause uid=%{public}d", descriptor.uid_);
80 ptr_->NotifyAudioSessionCheckTrigger(descriptor.uid_);
81 AudioAdapter::GetInstance().PauseAudioStream(descriptor.uid_);
82 }
83 }
84
85 // LCOV_EXCL_START
HandleAudioStreamRendererStateChange(const AudioRendererChangeInfos & infos)86 void BackgroundAudioController::HandleAudioStreamRendererStateChange(const AudioRendererChangeInfos& infos)
87 {
88 for (const auto& info : infos) {
89 if (info->rendererState != AudioStandard::RENDERER_RUNNING) {
90 continue;
91 }
92
93 if (PermissionChecker::GetInstance().CheckSystemPermissionByUid(info->clientUID)) {
94 SLOGD("uid=%{public}d is system app", info->clientUID);
95 continue;
96 }
97
98 if (!AppManagerAdapter::GetInstance().IsAppBackground(info->clientUID, info->clientPid)) {
99 AppManagerAdapter::GetInstance().AddObservedApp(info->clientUID);
100 SLOGI("AudioStreamRendererStateChange add observe for uid %{public}d", info->clientUID);
101 continue;
102 }
103
104 if (!IsBackgroundMode(info->clientUID, BackgroundMode::AUDIO_PLAYBACK)) {
105 SLOGI("uid=%{public}d hasn't AUDIO_PLAYBACK task", info->clientUID);
106 continue;
107 }
108
109 if (HasAVSession(info->clientUID)) {
110 continue;
111 }
112
113 SLOGI("pause uid=%{public}d", info->clientUID);
114 ptr_->NotifyAudioSessionCheckTrigger(info->clientUID);
115 AudioAdapter::GetInstance().PauseAudioStream(info->clientUID);
116 }
117 }
118
HandleAppBackgroundState(int32_t uid,int32_t pid)119 void BackgroundAudioController::HandleAppBackgroundState(int32_t uid, int32_t pid)
120 {
121 if (PermissionChecker::GetInstance().CheckSystemPermissionByUid(uid)) {
122 SLOGD("uid=%{public}d is system app", uid);
123 return;
124 }
125
126 std::vector<std::unique_ptr<AudioStandard::AudioRendererChangeInfo>> infos;
127 auto ret = AudioStandard::AudioStreamManager::GetInstance()->GetCurrentRendererChangeInfos(infos);
128 if (ret != 0) {
129 SLOGE("get renderer state failed");
130 return;
131 }
132
133 bool isRunning = false;
134 for (const auto& info : infos) {
135 if (info->rendererState == AudioStandard::RENDERER_RUNNING and
136 (info->clientUID == uid and info->clientPid == pid)) {
137 SLOGI("find uid=%{public}d pid=%{public}d renderer state is %{public}d, is running",
138 uid, pid, info->rendererState);
139 isRunning = true;
140 break;
141 }
142 }
143 if (!isRunning) {
144 SLOGI("find uid=%{public}d pid=%{public}d isn't running, return", uid, pid);
145 return;
146 }
147
148 if (!IsBackgroundMode(uid, BackgroundMode::AUDIO_PLAYBACK)) {
149 SLOGI("uid=%{public}d hasn't AUDIO_PLAYBACK task", uid);
150 return;
151 }
152
153 if (HasAVSession(uid)) {
154 return;
155 }
156
157 SLOGI("pause uid=%{public}d", uid);
158 ptr_->NotifyAudioSessionCheckTrigger(uid);
159 AudioAdapter::GetInstance().PauseAudioStream(uid);
160 }
161 // LCOV_EXCL_STOP
162
IsBackgroundMode(int32_t creatorUid,BackgroundMode backgroundMode) const163 bool BackgroundAudioController::IsBackgroundMode(int32_t creatorUid, BackgroundMode backgroundMode) const
164 {
165 // LCOV_EXCL_START
166 std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> continuousTaskList;
167 ErrCode code = BackgroundTaskMgr::BackgroundTaskMgrHelper::GetContinuousTaskApps(continuousTaskList);
168 if (code != OHOS::ERR_OK) {
169 SLOGE("uid=%{public}d no continuous task list, code=%{public}d", creatorUid, code);
170 return false;
171 }
172 // LCOV_EXCL_STOP
173
174 for (const auto &task : continuousTaskList) {
175 SLOGD("uid=%{public}d taskCreatorUid=%{public}d", creatorUid, task->GetCreatorUid());
176 if (task->GetCreatorUid() != creatorUid) {
177 continue;
178 }
179
180 std::vector<uint32_t> bgModeIds = task->GetTypeIds();
181 auto it = std::find_if(bgModeIds.begin(), bgModeIds.end(), [ = ](auto mode) {
182 uint32_t uMode = static_cast<uint32_t>(backgroundMode);
183 return (mode == uMode);
184 });
185 if (it != bgModeIds.end()) {
186 SLOGD("uid=%{public}d is audio playback", creatorUid);
187 return true;
188 }
189 }
190 SLOGD("uid=%{public}d isn't audio playback", creatorUid);
191 return false;
192 }
193
HasAVSession(int32_t uid)194 bool BackgroundAudioController::HasAVSession(int32_t uid)
195 {
196 std::lock_guard lockGuard(lock_);
197 bool hasSession = false;
198 auto it = sessionUIDs_.find(uid);
199 if (it != sessionUIDs_.end()) {
200 SLOGD("uid=%{public}d has session", uid);
201 hasSession = true;
202 }
203 return hasSession;
204 }
205 }
206