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