• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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().SetAppStateChangeObserver([this](int32_t uid, int32_t pid, bool isBackground) {
42         SLOGI("set background observe for uid=%{public}d, pid=%{public}d, isBackground=%{public}d",
43             uid, pid, isBackground);
44         HandleAppMuteState(uid, pid, isBackground);
45     });
46 }
47 
OnSessionCreate(const AVSessionDescriptor & descriptor)48 void BackgroundAudioController::OnSessionCreate(const AVSessionDescriptor& descriptor)
49 {
50     std::lock_guard lockGuard(lock_);
51     auto it = sessionUIDs_.find(descriptor.uid_);
52     if (it == sessionUIDs_.end()) {
53         std::set<int32_t> pidSet;
54         pidSet.insert(descriptor.pid_);
55         sessionUIDs_.insert(std::make_pair(descriptor.uid_, pidSet));
56     } else {
57         it->second.insert(descriptor.pid_);
58     }
59     SLOGI("OnSessionCreate remove observe for uid %{public}d pid %{public}d", descriptor.uid_, descriptor.pid_);
60     AppManagerAdapter::GetInstance().RemoveObservedApp(descriptor.uid_);
61 }
62 
OnSessionRelease(const AVSessionDescriptor & descriptor)63 void BackgroundAudioController::OnSessionRelease(const AVSessionDescriptor& descriptor)
64 {
65     bool isEmpty = false;
66     {
67         std::lock_guard lockGuard(lock_);
68         auto it = sessionUIDs_.find(descriptor.uid_);
69         if (it != sessionUIDs_.end()) {
70             it->second.erase(descriptor.pid_);
71             if (it->second.empty()) {
72                 it = sessionUIDs_.erase(it);
73                 isEmpty = true;
74             }
75         }
76     }
77 
78     if (descriptor.isThirdPartyApp_ && isEmpty) {
79         SLOGI("OnSessionRelease add observe for uid %{public}d isPidEmpty %{public}d", descriptor.uid_, isEmpty);
80         AppManagerAdapter::GetInstance().AddObservedApp(descriptor.uid_);
81         if (AppManagerAdapter::GetInstance().IsAppBackground(descriptor.uid_, descriptor.pid_)) {
82             auto mute = AudioAdapter::GetInstance().MuteAudioStream(descriptor.uid_, descriptor.pid_);
83             if (mute == AVSESSION_SUCCESS && ptr_ != nullptr) {
84                 SLOGI("mute uid=%{public}d done", descriptor.uid_);
85                 ptr_->NotifyAudioSessionCheckTrigger(descriptor.uid_);
86             }
87         }
88     }
89 }
90 
RendererChangeReport(AudioStandard::AudioRendererChangeInfo & info)91 void BackgroundAudioController::RendererChangeReport(AudioStandard::AudioRendererChangeInfo& info)
92 {
93     if (info.rendererState == AudioStandard::RENDERER_RUNNING ||
94         info.rendererState == AudioStandard::RENDERER_PAUSED ||
95         info.rendererState == AudioStandard::RENDERER_STOPPED) {
96             ptr_->NotifyBackgroundReportCheck(info.clientUID, info.clientPid, info.rendererInfo.streamUsage,
97                 info.rendererState);
98         }
99 }
100 
101 // LCOV_EXCL_START
HandleAudioStreamRendererStateChange(const AudioRendererChangeInfos & infos)102 void BackgroundAudioController::HandleAudioStreamRendererStateChange(const AudioRendererChangeInfos& infos)
103 {
104     for (const auto& info : infos) {
105         if (info->rendererState != AudioStandard::RENDERER_RUNNING) {
106             continue;
107         }
108         if (!AppManagerAdapter::GetInstance().IsAppBackground(info->clientUID, info->clientPid)) {
109             SLOGI("AudioStreamRendererStateChange add observe for uid %{public}d", info->clientUID);
110             AppManagerAdapter::GetInstance().AddObservedApp(info->clientUID);
111             if (!info->backMute) {
112                 SLOGI("uid=%{public}d renderer=%{public}d fore unmute, continue", info->clientUID, info->sessionId);
113             } else {
114                 AudioAdapter::GetInstance().UnMuteAudioStream(info->clientUID, info->rendererInfo.streamUsage);
115             }
116             continue;
117         }
118         if (HasAVSession(info->clientUID)) {
119             RendererChangeReport(*info);
120             continue;
121         }
122         if (PermissionChecker::GetInstance().CheckSystemPermissionByUid(info->clientUID)) {
123             SLOGD("uid=%{public}d is system app", info->clientUID);
124             continue;
125         }
126         if (info->backMute) {
127             SLOGI("renderer=%{public}d back is mute, continue", info->sessionId);
128             continue;
129         }
130         auto mute = AudioAdapter::GetInstance().MuteAudioStream(info->clientUID, info->rendererInfo.streamUsage);
131         if (mute == AVSESSION_SUCCESS && ptr_ != nullptr) {
132             SLOGI("mute uid=%{public}d done", info->clientUID);
133             ptr_->NotifyAudioSessionCheckTrigger(info->clientUID);
134         }
135     }
136 }
137 
HandleAppMuteState(int32_t uid,int32_t pid,bool isBackground)138 void BackgroundAudioController::HandleAppMuteState(int32_t uid, int32_t pid, bool isBackground)
139 {
140     if (!isBackground) {
141         SLOGI("try unmute uid=%{public}d", uid);
142         AudioAdapter::GetInstance().UnMuteAudioStream(uid);
143         return;
144     }
145     if (PermissionChecker::GetInstance().CheckSystemPermissionByUid(uid)) {
146         SLOGD("uid=%{public}d is system app", uid);
147         return;
148     }
149     if (HasAVSession(uid)) {
150         return;
151     }
152 
153     auto mute = AudioAdapter::GetInstance().MuteAudioStream(uid, pid);
154     if (mute == AVSESSION_SUCCESS && ptr_ != nullptr) {
155         SLOGI("mute uid=%{public}d done", uid);
156         ptr_->NotifyAudioSessionCheckTrigger(uid);
157     }
158 }
159 // LCOV_EXCL_STOP
160 
IsBackgroundMode(int32_t creatorUid,BackgroundMode backgroundMode) const161 bool BackgroundAudioController::IsBackgroundMode(int32_t creatorUid, BackgroundMode backgroundMode) const
162 {
163     // LCOV_EXCL_START
164     std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> continuousTaskList;
165     ErrCode code = BackgroundTaskMgr::BackgroundTaskMgrHelper::GetContinuousTaskApps(continuousTaskList);
166     if (code != OHOS::ERR_OK) {
167         SLOGE("uid=%{public}d no continuous task list, code=%{public}d", creatorUid, code);
168         return false;
169     }
170     // LCOV_EXCL_STOP
171 
172     for (const auto &task : continuousTaskList) {
173         SLOGD("uid=%{public}d taskCreatorUid=%{public}d", creatorUid, task->GetCreatorUid());
174         if (task->GetCreatorUid() != creatorUid) {
175             continue;
176         }
177 
178         std::vector<uint32_t> bgModeIds = task->GetTypeIds();
179         auto it = std::find_if(bgModeIds.begin(), bgModeIds.end(), [ = ](auto mode) {
180             uint32_t uMode = static_cast<uint32_t>(backgroundMode);
181             return (mode == uMode);
182         });
183         if (it != bgModeIds.end()) {
184             SLOGD("uid=%{public}d is audio playback", creatorUid);
185             return true;
186         }
187     }
188     SLOGD("uid=%{public}d isn't audio playback", creatorUid);
189     return false;
190 }
191 
HasAVSession(int32_t uid)192 bool BackgroundAudioController::HasAVSession(int32_t uid)
193 {
194     std::lock_guard lockGuard(lock_);
195     bool hasSession = false;
196     auto it = sessionUIDs_.find(uid);
197     if (it != sessionUIDs_.end()) {
198         SLOGD("uid=%{public}d has av_session, no need to handle mute or unmute strategy.", uid);
199         hasSession = true;
200     }
201     return hasSession;
202 }
203 }
204