1 /*
2 * Copyright (c) 2023 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 "running_lock_proxy.h"
17 #include "power_mgr_service.h"
18
19 #include <cmath>
20 #include "power_log.h"
21
22 namespace OHOS {
23 namespace PowerMgr {
24 namespace {
25 static const std::string OFFLOAD_RUNNING_NAME = "AudioOffloadBackgroundPlay";
26 static const std::string FAST_RUNNING_NAME = "AudioFastBackgroundPlay";
27 }
AddRunningLock(pid_t pid,pid_t uid,const sptr<IRemoteObject> & remoteObj)28 void RunningLockProxy::AddRunningLock(pid_t pid, pid_t uid, const sptr<IRemoteObject>& remoteObj)
29 {
30 std::string proxyKey = AssembleProxyKey(pid, uid);
31 auto proxyIter = proxyMap_.find(proxyKey);
32 WksMap wksMap;
33 if (proxyIter == proxyMap_.end()) {
34 TokenWorkSourceMap tokenWksMap;
35 tokenWksMap.emplace(remoteObj, std::make_pair(wksMap, 0));
36 proxyMap_.emplace(proxyKey, tokenWksMap);
37 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Add runninglock proxy, proxyKey=%{public}s", proxyKey.c_str());
38 } else {
39 auto& tokenWksMap = proxyIter->second;
40 auto tokenIter = tokenWksMap.find(remoteObj);
41 if (tokenIter == tokenWksMap.end()) {
42 tokenWksMap.emplace(remoteObj, std::make_pair(wksMap, 0));
43 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Insert runninglock, proxyKey=%{public}s", proxyKey.c_str());
44 } else {
45 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Already add runninglock, proxyKey=%{public}s", proxyKey.c_str());
46 }
47 }
48 }
49
RemoveRunningLock(pid_t pid,pid_t uid,const sptr<IRemoteObject> & remoteObj)50 void RunningLockProxy::RemoveRunningLock(pid_t pid, pid_t uid, const sptr<IRemoteObject>& remoteObj)
51 {
52 std::string proxyKey = AssembleProxyKey(pid, uid);
53 auto proxyIter = proxyMap_.find(proxyKey);
54 if (proxyIter == proxyMap_.end()) {
55 POWER_HILOGI(FEATURE_RUNNING_LOCK,
56 "Runninglock proxyKey is not existed, proxyKey=%{public}s", proxyKey.c_str());
57 return;
58 }
59 TokenWorkSourceMap& tokenWksMap = proxyIter->second;
60 auto tokenIter = tokenWksMap.find(remoteObj);
61 if (tokenIter == tokenWksMap.end()) {
62 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Runninglock is not existed, proxyKey=%{public}s", proxyKey.c_str());
63 return;
64 } else {
65 tokenWksMap.erase(tokenIter);
66 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Runninglocklist empty, earse proxyKey=%{public}s", proxyKey.c_str());
67 }
68 if (proxyIter->second.empty()) {
69 proxyMap_.erase(proxyIter);
70 POWER_HILOGD(FEATURE_RUNNING_LOCK, "Runninglocklist empty, earse proxyKey=%{public}s", proxyKey.c_str());
71 }
72 }
73
UpdateWorkSource(pid_t pid,pid_t uid,const sptr<IRemoteObject> & remoteObj,const std::map<int32_t,std::string> & workSources)74 bool RunningLockProxy::UpdateWorkSource(pid_t pid, pid_t uid, const sptr<IRemoteObject>& remoteObj,
75 const std::map<int32_t, std::string>& workSources)
76 {
77 std::string proxyKey = AssembleProxyKey(pid, uid);
78 auto proxyIter = proxyMap_.find(proxyKey);
79 if (proxyIter == proxyMap_.end()) {
80 POWER_HILOGW(FEATURE_RUNNING_LOCK, "UpdateWorkSource failed, proxyKey=%{public}s not existed",
81 proxyKey.c_str());
82 return false;
83 }
84 auto& tokenWksMap = proxyIter->second;
85 auto tokenWksMapIter = tokenWksMap.find(remoteObj);
86 if (tokenWksMapIter == tokenWksMap.end()) {
87 POWER_HILOGW(FEATURE_RUNNING_LOCK, "UpdateWorkSource failed, runninglock not existed");
88 return false;
89 }
90 auto& workSourceMap = tokenWksMapIter->second.first;
91 WksMap workSourcesState;
92 std::string bundleName;
93 int32_t proxyCount = 0;
94 for (const auto& wks : workSources) {
95 auto iter = workSourceMap.find(wks.first);
96 if (iter != workSourceMap.end()) {
97 workSourcesState.insert({ iter->first, { iter->second.first, iter->second.second } });
98 if (iter->second.second) {
99 proxyCount++;
100 } else {
101 bundleName.append(iter->second.first).append(" ");
102 }
103 } else {
104 workSourcesState.insert({ wks.first, { wks.second, false } });
105 bundleName.append(wks.second).append(" ");
106 }
107 }
108 if (!bundleName.empty()) {
109 bundleName.pop_back();
110 }
111 bool isProxyed = tokenWksMapIter->second.second != 0 &&
112 tokenWksMapIter->second.second == static_cast<int32_t>(workSourceMap.size());
113 int32_t wksCount = static_cast<int32_t>(workSourcesState.size());
114 if (isProxyed && wksCount > proxyCount) {
115 ProxyInner(remoteObj, bundleName, RunningLockEvent::RUNNINGLOCK_UNPROXY);
116 } else if (!isProxyed && wksCount > 0 && wksCount == proxyCount) {
117 ProxyInner(remoteObj, bundleName, RunningLockEvent::RUNNINGLOCK_PROXY);
118 } else {
119 ProxyInner(remoteObj, bundleName, RunningLockEvent::RUNNINGLOCK_UPDATE);
120 }
121 tokenWksMapIter->second.first = std::move(workSourcesState);
122 tokenWksMapIter->second.second = proxyCount;
123 return true;
124 }
125
ProxyInner(const sptr<IRemoteObject> & remoteObj,const std::string & bundleNames,RunningLockEvent event)126 void RunningLockProxy::ProxyInner(const sptr<IRemoteObject>& remoteObj,
127 const std::string& bundleNames, RunningLockEvent event)
128 {
129 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
130 if (pms == nullptr) {
131 POWER_HILOGW(FEATURE_RUNNING_LOCK, "Power service is nullptr");
132 return;
133 }
134 auto rlmgr = pms->GetRunningLockMgr();
135 if (rlmgr == nullptr) {
136 POWER_HILOGW(FEATURE_RUNNING_LOCK, "RunninglockMgr is nullptr");
137 return;
138 }
139 auto lockInner = rlmgr->GetRunningLockInner(remoteObj);
140 if (lockInner == nullptr) {
141 POWER_HILOGW(FEATURE_RUNNING_LOCK, "RunninglockMgr is nullptr");
142 return;
143 }
144 lockInner->SetBundleName(bundleNames);
145 switch (event) {
146 case RunningLockEvent::RUNNINGLOCK_UPDATE:
147 rlmgr->NotifyRunningLockChanged(lockInner->GetParam(), "DUBAI_TAG_RUNNINGLOCK_UPDATE", "UP");
148 break;
149 case RunningLockEvent::RUNNINGLOCK_PROXY:
150 rlmgr->NotifyRunningLockChanged(lockInner->GetParam(), "DUBAI_TAG_RUNNINGLOCK_UPDATE", "UP");
151 rlmgr->UnlockInnerByProxy(remoteObj, lockInner);
152 break;
153 case RunningLockEvent::RUNNINGLOCK_UNPROXY:
154 rlmgr->LockInnerByProxy(remoteObj, lockInner);
155 rlmgr->NotifyRunningLockChanged(lockInner->GetParam(), "DUBAI_TAG_RUNNINGLOCK_UPDATE", "UP");
156 break;
157 default:
158 break;
159 }
160 }
161
GetRunningLockName(const sptr<IRemoteObject> & remoteObj)162 std::string RunningLockProxy::GetRunningLockName(const sptr<IRemoteObject>& remoteObj)
163 {
164 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
165 if (pms == nullptr) {
166 POWER_HILOGW(FEATURE_RUNNING_LOCK, "Power service is nullptr");
167 return "";
168 }
169 auto rlmgr = pms->GetRunningLockMgr();
170 if (rlmgr == nullptr) {
171 POWER_HILOGW(FEATURE_RUNNING_LOCK, "RunninglockMgr is nullptr");
172 return "";
173 }
174 auto lockInner = rlmgr->GetRunningLockInner(remoteObj);
175 if (lockInner == nullptr) {
176 POWER_HILOGW(FEATURE_RUNNING_LOCK, "RunninglockMgr is nullptr");
177 return "";
178 }
179 return lockInner->GetName();
180 }
181
MergeBundleName(const WksMap & wksMap)182 std::string RunningLockProxy::MergeBundleName(const WksMap& wksMap)
183 {
184 std::string bundleName;
185 for (const auto& wks : wksMap) {
186 if (wks.second.second == false) {
187 bundleName.append(wks.second.first).append(" ");
188 }
189 }
190 if (!bundleName.empty()) {
191 bundleName.pop_back();
192 }
193 return bundleName;
194 }
195
IncreaseProxyCnt(pid_t pid,pid_t uid)196 bool RunningLockProxy::IncreaseProxyCnt(pid_t pid, pid_t uid)
197 {
198 std::string proxyKey = AssembleProxyKey(pid, uid);
199 // IncreaseProxyCnt proxykey
200 POWER_HILOGI(FEATURE_RUNNING_LOCK, "Inproxykey=%{public}s", proxyKey.c_str());
201 auto proxyIter = proxyMap_.find(proxyKey);
202 if (proxyIter != proxyMap_.end()) {
203 auto& tokenWksMap = proxyIter->second;
204 for (auto& tokenWksItem : tokenWksMap) {
205 for (auto& wks : tokenWksItem.second.first) {
206 wks.second.second = true;
207 }
208 tokenWksItem.second.second = static_cast<int32_t>(tokenWksItem.second.first.size());
209 ProxyInner(tokenWksItem.first, "", RunningLockEvent::RUNNINGLOCK_PROXY);
210 }
211 }
212 for (auto& proxyItem : proxyMap_) {
213 auto& tokenWksMap = proxyItem.second;
214 for (auto& tokenWksItem : tokenWksMap) {
215 if (GetRunningLockName(tokenWksItem.first).find(OFFLOAD_RUNNING_NAME) != std::string::npos) {
216 POWER_HILOGD(FEATURE_RUNNING_LOCK, "AudioOffloadBackgroudPlay runninglock skip");
217 continue;
218 }
219 #ifdef POWER_MANAGER_AUDIO_LOCK_UNPROXY
220 if (GetRunningLockName(tokenWksItem.first).find(FAST_RUNNING_NAME) != std::string::npos) {
221 POWER_HILOGD(FEATURE_RUNNING_LOCK, "AudioFastBackgroundPlay runninglock skip");
222 continue;
223 }
224 #endif
225 auto& wksMap = tokenWksItem.second.first;
226 if (wksMap.find(uid) != wksMap.end() && !wksMap[uid].second) {
227 wksMap[uid].second = true;
228 tokenWksItem.second.second++;
229 } else {
230 continue;
231 }
232 if (tokenWksItem.second.second == static_cast<int32_t>(wksMap.size())) {
233 ProxyInner(tokenWksItem.first, "", RunningLockEvent::RUNNINGLOCK_PROXY);
234 } else {
235 ProxyInner(tokenWksItem.first, MergeBundleName(wksMap), RunningLockEvent::RUNNINGLOCK_UPDATE);
236 }
237 }
238 }
239 return true;
240 }
241
DecreaseProxyCnt(pid_t pid,pid_t uid)242 bool RunningLockProxy::DecreaseProxyCnt(pid_t pid, pid_t uid)
243 {
244 std::string proxyKey = AssembleProxyKey(pid, uid);
245 POWER_HILOGI(FEATURE_RUNNING_LOCK, "Deproxykey=%{public}s", proxyKey.c_str());
246 auto proxyIter = proxyMap_.find(proxyKey);
247 if (proxyIter != proxyMap_.end()) {
248 auto& tokenWksMap = proxyIter->second;
249 for (auto& tokenWksItem : tokenWksMap) {
250 for (auto& wks : tokenWksItem.second.first) {
251 wks.second.second = false;
252 }
253 tokenWksItem.second.second = 0;
254 ProxyInner(tokenWksItem.first, MergeBundleName(tokenWksItem.second.first),
255 RunningLockEvent::RUNNINGLOCK_UNPROXY);
256 }
257 }
258 for (auto& proxyItem : proxyMap_) {
259 auto& tokenWksMap = proxyItem.second;
260 for (auto& tokenWksItem : tokenWksMap) {
261 if (GetRunningLockName(tokenWksItem.first).find(OFFLOAD_RUNNING_NAME) != std::string::npos) {
262 POWER_HILOGD(FEATURE_RUNNING_LOCK, "AudioOffloadBackgroudPlay runninglock skip");
263 continue;
264 }
265 auto& wksMap = tokenWksItem.second.first;
266 if (wksMap.find(uid) != wksMap.end() && wksMap[uid].second) {
267 wksMap[uid].second = false;
268 tokenWksItem.second.second = std::max(0, tokenWksItem.second.second - 1);
269 } else {
270 continue;
271 }
272 if (tokenWksItem.second.second == static_cast<int32_t>(wksMap.size()) - 1) {
273 ProxyInner(tokenWksItem.first, MergeBundleName(wksMap), RunningLockEvent::RUNNINGLOCK_UNPROXY);
274 } else {
275 ProxyInner(tokenWksItem.first, MergeBundleName(wksMap), RunningLockEvent::RUNNINGLOCK_UPDATE);
276 }
277 }
278 }
279 return true;
280 }
281
DumpProxyInfo()282 std::string RunningLockProxy::DumpProxyInfo()
283 {
284 std::string result {""};
285 int index = 0;
286 for (const auto& [key, value] : proxyMap_) {
287 index++;
288 result.append(" ProcessIndex=").append(std::to_string(index))
289 .append(" pid_uid=").append(key)
290 .append(" lock_cnt=").append(std::to_string(value.size())).append("\n");
291 int lockIndex = 0;
292 for (const auto& [token, tokenWksMap] : value) {
293 lockIndex++;
294 result.append("****lockIndex=").append(std::to_string(lockIndex))
295 .append("****workSourceSize=").append(std::to_string(tokenWksMap.first.size()))
296 .append("****proxyCount=").append(std::to_string(tokenWksMap.second))
297 .append("\n");
298 int appIndex = 0;
299 for (const auto& wks : tokenWksMap.first) {
300 appIndex++;
301 result.append("********workSourceIndex=").append(std::to_string(appIndex))
302 .append("********appuid=").append(std::to_string(wks.first))
303 .append("********bundleName=").append(wks.second.first)
304 .append("********proxyState=").append(std::to_string(wks.second.second))
305 .append("\n");
306 }
307 }
308 }
309 return result;
310 }
311
ResetRunningLocks()312 void RunningLockProxy::ResetRunningLocks()
313 {
314 POWER_HILOGI(FEATURE_RUNNING_LOCK, "reset proxycnt");
315 for (auto &proxyItem : proxyMap_) {
316 auto& tokenWksMap = proxyItem.second;
317 for (auto &tokenWksItem : tokenWksMap) {
318 for (auto &wks : tokenWksItem.second.first) {
319 wks.second.second = false;
320 }
321 ProxyInner(tokenWksItem.first, MergeBundleName(tokenWksItem.second.first),
322 RunningLockEvent::RUNNINGLOCK_UNPROXY);
323 tokenWksItem.second.second = 0;
324 }
325 }
326 }
327
UpdateProxyState(pid_t pid,pid_t uid,const sptr<IRemoteObject> & remoteObj,bool state)328 bool RunningLockProxy::UpdateProxyState(pid_t pid, pid_t uid, const sptr<IRemoteObject>& remoteObj,
329 bool state)
330 {
331 std::string proxyKey = AssembleProxyKey(pid, uid);
332 auto proxyIter = proxyMap_.find(proxyKey);
333 if (proxyIter == proxyMap_.end()) {
334 POWER_HILOGW(FEATURE_RUNNING_LOCK, "UpdateProxyState failed, proxyKey=%{public}s not existed",
335 proxyKey.c_str());
336 return false;
337 }
338 auto& tokenWksMap = proxyIter->second;
339 auto tokenWksMapIter = tokenWksMap.find(remoteObj);
340 if (tokenWksMapIter == tokenWksMap.end()) {
341 POWER_HILOGW(FEATURE_RUNNING_LOCK, "UpdateProxyState failed, runninglock not existed");
342 return false;
343 }
344 auto& workSourceMap = tokenWksMapIter->second.first;
345 for (auto &wks : workSourceMap) {
346 wks.second.second = false;
347 }
348 tokenWksMapIter->second.second = 0;
349 return true;
350 }
351
IsExistAudioStream(pid_t uid)352 bool RunningLockProxy::IsExistAudioStream(pid_t uid)
353 {
354 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
355 if (pms == nullptr) {
356 POWER_HILOGW(FEATURE_RUNNING_LOCK, "Power service is nullptr");
357 return false;
358 }
359 auto rlmgr = pms->GetRunningLockMgr();
360 if (rlmgr == nullptr) {
361 POWER_HILOGW(FEATURE_RUNNING_LOCK, "RunninglockMgr is nullptr");
362 return false;
363 }
364 for (auto &proxyItem : proxyMap_) {
365 TokenWorkSourceMap& tokenWksMap = proxyItem.second;
366 for (auto &tokenWksItem : tokenWksMap) {
367 auto lockInner = rlmgr->GetRunningLockInner(tokenWksItem.first);
368 if (lockInner == nullptr) {
369 POWER_HILOGW(FEATURE_RUNNING_LOCK, "RunninglockInner is nullptr");
370 continue;
371 }
372 if (lockInner->GetType() != RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO) {
373 continue;
374 }
375 WksMap& wksMap = tokenWksItem.second.first;
376 auto wksMapIter = wksMap.find(uid);
377 if (wksMapIter != wksMap.end() && !wksMapIter->second.second) {
378 return true;
379 }
380 }
381 }
382 return false;
383 }
384
Clear()385 void RunningLockProxy::Clear()
386 {
387 proxyMap_.clear();
388 }
389
AssembleProxyKey(pid_t pid,pid_t uid)390 std::string RunningLockProxy::AssembleProxyKey(pid_t pid, pid_t uid)
391 {
392 return std::to_string(pid) + "_" + std::to_string(uid);
393 }
394 } // namespace PowerMgr
395 } // namespace OHOS
396
397