• 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_strategy.h"
17 #include <algorithm>
18 #include "standby_hitrace_chain.h"
19 #include "standby_service_log.h"
20 #include "system_ability_definition.h"
21 
22 #include "ability_manager_helper.h"
23 #ifdef ENABLE_BACKGROUND_TASK_MGR
24 #include "background_task_helper.h"
25 #endif
26 #include "app_mgr_helper.h"
27 #include "standby_service.h"
28 #ifdef STANDBY_POWER_MANAGER_ENABLE
29 #include "power_mgr_client.h"
30 #endif
31 #ifdef STANDBY_RSS_WORK_SCHEDULER_ENABLE
32 #include "workscheduler_srv_client.h"
33 #endif
34 #include "allow_type.h"
35 #include "standby_state.h"
36 #include "bundle_manager_helper.h"
37 #include "standby_service_impl.h"
38 #include "common_constant.h"
39 
40 namespace OHOS {
41 namespace DevStandbyMgr {
42 namespace {
43 const std::map<std::string, uint8_t> BGTASK_EXEMPTION_FLAG_MAP {
44     {CONTINUOUS_TASK, ExemptionTypeFlag::CONTINUOUS_TASK},
45     {TRANSIENT_TASK, ExemptionTypeFlag::TRANSIENT_TASK},
46     {WORK_SCHEDULER, ExemptionTypeFlag::WORK_SCHEDULER},
47 };
48 }
49 
HandleEvent(const StandbyMessage & message)50 void RunningLockStrategy::HandleEvent(const StandbyMessage& message)
51 {
52     STANDBYSERVICE_LOGD("RunningLockStrategy revceived message %{public}u, action: %{public}s",
53         message.eventId_, message.action_.c_str());
54     switch (message.eventId_) {
55         case StandbyMessageType::ALLOW_LIST_CHANGED:
56             UpdateExemptionList(message);
57             break;
58         case StandbyMessageType::RES_CTRL_CONDITION_CHANGED:
59             UpdateResourceConfig(message);
60             break;
61         case StandbyMessageType::PHASE_TRANSIT:
62             StartProxy(message);
63             break;
64         case StandbyMessageType::STATE_TRANSIT:
65             StopProxy(message);
66             break;
67         case StandbyMessageType::BG_TASK_STATUS_CHANGE:
68             UpdateBgTaskAppStatus(message);
69             break;
70         case StandbyMessageType::PROCESS_STATE_CHANGED:
71             HandleProcessStatusChanged(message);
72             break;
73         case StandbyMessageType::SYS_ABILITY_STATUS_CHANGED:
74             ResetProxyStatus(message);
75             break;
76         default:
77             break;
78     }
79 }
80 
OnCreated()81 ErrCode RunningLockStrategy::OnCreated()
82 {
83     #ifdef STANDBY_POWER_MANAGER_ENABLE
84     PowerMgr::PowerMgrClient::GetInstance().ResetRunningLocks();
85     #endif
86     return ERR_OK;
87 }
88 
OnDestroy()89 ErrCode RunningLockStrategy::OnDestroy()
90 {
91     if (isProxied_ && !isIdleMaintence_) {
92         ProxyAppAndProcess(false);
93     }
94     isProxied_ = false;
95     isIdleMaintence_ = false;
96     return ERR_OK;
97 }
98 
UpdateExemptionList(const StandbyMessage & message)99 ErrCode RunningLockStrategy::UpdateExemptionList(const StandbyMessage& message)
100 {
101     uint32_t allowType = static_cast<uint32_t>(message.want_->GetIntParam("allowType", 0));
102     if ((allowType & AllowType::RUNNING_LOCK) == 0) {
103         STANDBYSERVICE_LOGD("allowType is not running lock, currentType is %{public}d", allowType);
104         return ERR_STANDBY_STRATEGY_NOT_MATCH;
105     }
106     if (!isProxied_) {
107         STANDBYSERVICE_LOGD("current state is not sleep or maintenance, ignore exemption");
108         return ERR_STANDBY_CURRENT_STATE_NOT_MATCH;
109     }
110 
111     // according to message, add flag or remove flag
112     STANDBYSERVICE_LOGI("RunningLockStrategy start update allow list");
113     std::string processName = message.want_->GetStringParam("name");
114     bool added = message.want_->GetBoolParam("added", false);
115     int32_t uid = message.want_->GetIntParam("uid", -1);
116     STANDBYSERVICE_LOGD("%{public}s apply allow, added is %{public}d", processName.c_str(), added);
117     if (added) {
118         AddExemptionFlag(uid, processName, ExemptionTypeFlag::EXEMPTION);
119     } else {
120         RemoveExemptionFlag(uid, processName, ExemptionTypeFlag::EXEMPTION);
121     }
122     return ERR_OK;
123 }
124 
UpdateResourceConfig(const StandbyMessage & message)125 ErrCode RunningLockStrategy::UpdateResourceConfig(const StandbyMessage& message)
126 {
127     StopProxyInner();
128     StartProxyInner();
129     return ERR_OK;
130 }
131 
StartProxy(const StandbyMessage & message)132 ErrCode RunningLockStrategy::StartProxy(const StandbyMessage& message)
133 {
134     StandbyHitraceChain traceChain(__func__);
135     if (isProxied_) {
136         STANDBYSERVICE_LOGD("now is proxied, do not need StartProxy, repeat process");
137         return ERR_STANDBY_STRATEGY_STATE_REPEAT;
138     }
139     uint32_t curPhase = static_cast<uint32_t>(message.want_->GetIntParam(CURRENT_PHASE, 0));
140     uint32_t curState = static_cast<uint32_t>(message.want_->GetIntParam(CURRENT_STATE, 0));
141     if ((curState != StandbyState::SLEEP) || (curPhase != SleepStatePhase::APP_RES_DEEP)) {
142         return ERR_STANDBY_CURRENT_STATE_NOT_MATCH;
143     }
144     STANDBYSERVICE_LOGD("start proxy running lock, current state is %{public}d, current phase is %{public}d",
145         curPhase, curPhase);
146     // if enter sleep state and app_res_deep phase, start proxy running lock of applications.
147     if (auto ret = StartProxyInner(); ret != ERR_OK) {
148         return ret;
149     }
150     isProxied_ = true;
151     isIdleMaintence_ = false;
152     return ERR_OK;
153 }
154 
StartProxyInner()155 ErrCode RunningLockStrategy::StartProxyInner()
156 {
157     ClearProxyRecord();
158     if (InitProxiedAppInfo() != ERR_OK || InitNativeProcInfo() != ERR_OK) {
159         STANDBYSERVICE_LOGW("calculate proxied app or native process failed");
160         ClearProxyRecord();
161         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
162     }
163     ProxyAppAndProcess(true);
164     return ERR_OK;
165 }
166 
InitProxiedAppInfo()167 ErrCode RunningLockStrategy::InitProxiedAppInfo()
168 {
169     if (GetAllAppInfos() != ERR_OK || GetAllRunningAppInfo() != ERR_OK) {
170         STANDBYSERVICE_LOGW("failed to get all app info");
171         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
172     }
173     if (GetForegroundApplications() !=ERR_OK || GetBackgroundTaskApp() != ERR_OK ||
174         GetWorkSchedulerTask() != ERR_OK || GetExemptionConfig() != ERR_OK) {
175         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
176     }
177     uidBundleNmeMap_.clear();
178     return ERR_OK;
179 }
180 
GetAllAppInfos()181 ErrCode RunningLockStrategy::GetAllAppInfos()
182 {
183     // get all app and set UNRESTRICTED flag to system app.
184     std::vector<AppExecFwk::ApplicationInfo> applicationInfos {};
185     if (!BundleManagerHelper::GetInstance()->GetApplicationInfos(
186         AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
187         AppExecFwk::Constants::ALL_USERID, applicationInfos)) {
188         STANDBYSERVICE_LOGW("failed to get all applicationInfos");
189         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
190     }
191     STANDBYSERVICE_LOGI("succeed GetApplicationInfos, size is %{public}d",
192         static_cast<int32_t>(applicationInfos.size()));
193     for (const auto& info : applicationInfos) {
194         uidBundleNmeMap_.emplace(info.uid, info.name);
195         std::string key = std::to_string(info.uid) + "_" + info.name;
196         proxiedAppInfo_.emplace(key, ProxiedProcInfo {info.name, info.uid});
197         // system app have exemption
198         if (info.isSystemApp) {
199             proxiedAppInfo_[key].appExemptionFlag_ |= ExemptionTypeFlag::UNRESTRICTED;
200         }
201     }
202     return ERR_OK;
203 }
204 
GetAllRunningAppInfo()205 ErrCode RunningLockStrategy::GetAllRunningAppInfo()
206 {
207     std::vector<AppExecFwk::RunningProcessInfo> allAppProcessInfos {};
208     if (!AppMgrHelper::GetInstance()->GetAllRunningProcesses(allAppProcessInfos)) {
209         STANDBYSERVICE_LOGE("connect to app manager service failed");
210         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
211     }
212     // get all running proc of app, add them to proxiedAppInfo_.
213     STANDBYSERVICE_LOGI("current running processes size %{public}d", static_cast<int32_t>(allAppProcessInfos.size()));
214     std::set<int> runningUids {};
215     for (const auto& info : allAppProcessInfos) {
216         if (uidBundleNmeMap_.find(info.uid_) == uidBundleNmeMap_.end()) {
217             continue;
218         }
219         runningUids.emplace(info.uid_);
220         std::string key = std::to_string(info.uid_) + "_" + uidBundleNmeMap_[info.uid_];
221         auto iter = proxiedAppInfo_.find(key);
222         if (iter == proxiedAppInfo_.end()) {
223             std::tie(iter, std::ignore) = proxiedAppInfo_.emplace(key,
224                 ProxiedProcInfo {info.processName_, info.uid_});
225         }
226         iter->second.pids_.emplace(info.pid_);
227     }
228     // if app is not running, delete its info from proxiedAppInfo_.
229     for (auto appInfoIter = proxiedAppInfo_.begin(); appInfoIter != proxiedAppInfo_.end();) {
230         if (runningUids.find(appInfoIter->second.uid_) == runningUids.end()) {
231             appInfoIter = proxiedAppInfo_.erase(appInfoIter);
232         } else {
233             ++appInfoIter;
234         }
235     }
236     return ERR_OK;
237 }
238 
GetWorkSchedulerTask()239 ErrCode RunningLockStrategy::GetWorkSchedulerTask()
240 {
241     #ifdef STANDBY_RSS_WORK_SCHEDULER_ENABLE
242     std::list<std::shared_ptr<WorkScheduler::WorkInfo>> workInfos;
243     if (WorkScheduler::WorkSchedulerSrvClient::GetInstance().GetAllRunningWorks(workInfos) != ERR_OK) {
244         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
245     }
246 
247     STANDBYSERVICE_LOGD("GetWorkSchedulerTask succeed, size is %{public}d", static_cast<int32_t>(workInfos.size()));
248     for (const auto& task : workInfos) {
249         std::string key = std::to_string(task->GetUid()) + "_" + task->GetBundleName();
250         if (auto iter = proxiedAppInfo_.find(key); iter != proxiedAppInfo_.end()) {
251             iter->second.appExemptionFlag_ |= ExemptionTypeFlag::WORK_SCHEDULER;
252         }
253     }
254     #endif
255     return ERR_OK;
256 }
257 
GetForegroundApplications()258 ErrCode RunningLockStrategy::GetForegroundApplications()
259 {
260     std::vector<AppExecFwk::AppStateData> fgApps {};
261     if (!AppMgrHelper::GetInstance()->GetForegroundApplications(fgApps)) {
262         STANDBYSERVICE_LOGW("get foreground app failed");
263         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
264     }
265     // add foreground flag to app
266     for (const auto& appInfo : fgApps) {
267         std::string key = std::to_string(appInfo.uid) + "_" + appInfo.bundleName;
268         if (auto iter = proxiedAppInfo_.find(key); iter != proxiedAppInfo_.end()) {
269             iter->second.appExemptionFlag_ |= ExemptionTypeFlag::FOREGROUND_APP;
270         }
271     }
272     return ERR_OK;
273 }
274 
GetBackgroundTaskApp()275 ErrCode RunningLockStrategy::GetBackgroundTaskApp()
276 {
277     #ifdef ENABLE_BACKGROUND_TASK_MGR
278     std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> continuousTaskList;
279     if (!BackgroundTaskHelper::GetInstance()->GetContinuousTaskApps(continuousTaskList)) {
280         STANDBYSERVICE_LOGE("get continuous task app failed");
281         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
282     }
283     STANDBYSERVICE_LOGD("succeed GetContinuousTaskApps, size is %{public}d",
284         static_cast<int32_t>(continuousTaskList.size()));
285     std::vector<std::shared_ptr<TransientTaskAppInfo>> transientTaskList;
286     if (!BackgroundTaskHelper::GetInstance()->GetTransientTaskApps(transientTaskList)) {
287         STANDBYSERVICE_LOGE("get transient task app failed");
288         return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
289     }
290     // add continuous exemption flag for app with continuous task
291     STANDBYSERVICE_LOGD("succeed GetTransientTaskApps, size is %{public}d",
292         static_cast<int32_t>(transientTaskList.size()));
293     for (const auto& task : continuousTaskList) {
294         auto iter = uidBundleNmeMap_.find(task->GetCreatorUid());
295         if (iter == uidBundleNmeMap_.end()) {
296             continue;
297         }
298         std::string key = std::to_string(task->GetCreatorUid()) + "_" + iter->second;
299         if (auto infoIter = proxiedAppInfo_.find(key); infoIter == proxiedAppInfo_.end()) {
300             continue;
301         } else {
302             infoIter->second.appExemptionFlag_ |= ExemptionTypeFlag::CONTINUOUS_TASK;
303         }
304     }
305     // add transient exemption flag for app with transient task
306     for (const auto& task : transientTaskList) {
307         std::string key = std::to_string(task->GetUid()) + "_" + task->GetPackageName();
308         if (auto iter = proxiedAppInfo_.find(key); iter == proxiedAppInfo_.end()) {
309             continue;
310         } else {
311             iter->second.appExemptionFlag_ |= ExemptionTypeFlag::TRANSIENT_TASK;
312         }
313     }
314     #endif
315     return ERR_OK;
316 }
317 
GetExemptionConfig()318 ErrCode RunningLockStrategy::GetExemptionConfig()
319 {
320     // if app in exemption list, add its exemption flag
321     std::vector<AllowInfo> allowInfoList {};
322     StandbyServiceImpl::GetInstance()->GetAllowListInner(AllowType::RUNNING_LOCK, allowInfoList,
323         ReasonCodeEnum::REASON_APP_API);
324     std::set<std::string> allowNameList {};
325     for (const auto& info : allowInfoList) {
326         allowNameList.emplace(info.GetName());
327     }
328     for (auto& [key, value] : proxiedAppInfo_) {
329         if (allowNameList.find(value.name_) == allowNameList.end()) {
330             continue;
331         }
332         value.appExemptionFlag_ |= ExemptionTypeFlag::EXEMPTION;
333     }
334 
335     // if app in restrict list, add retricted flag
336     std::set<std::string> restrictBundleName {};
337     StandbyServiceImpl::GetInstance()->GetEligiableRestrictSet(AllowType::RUNNING_LOCK, "RUNNING_LOCK",
338         ReasonCodeEnum::REASON_APP_API, restrictBundleName);
339     STANDBYSERVICE_LOGI("running lock restrict app list, size is %{public}d",
340         static_cast<int32_t>(restrictBundleName.size()));
341     for (auto& [key, value] : proxiedAppInfo_) {
342         if (restrictBundleName.find(value.name_) == restrictBundleName.end()) {
343             continue;
344         }
345         value.appExemptionFlag_ |= ExemptionTypeFlag::RESTRICTED;
346     }
347     return ERR_OK;
348 }
349 
InitNativeProcInfo()350 ErrCode RunningLockStrategy::InitNativeProcInfo()
351 {
352     return ERR_OK;
353 }
354 
ProxyAppAndProcess(bool isProxied)355 ErrCode RunningLockStrategy::ProxyAppAndProcess(bool isProxied)
356 {
357     std::vector<std::pair<int32_t, int32_t>> proxiedAppList;
358     for (const auto& [key, value] : proxiedAppInfo_) {
359         if (ExemptionTypeFlag::IsExempted(value.appExemptionFlag_)) {
360             continue;
361         }
362         SetProxiedAppList(proxiedAppList, value);
363     }
364     STANDBYSERVICE_LOGD("proxied app size: %{public}d", static_cast<int32_t>(proxiedAppList.size()));
365     ProxyRunningLockList(isProxied, proxiedAppList);
366     return ERR_OK;
367 }
368 
StopProxy(const StandbyMessage & message)369 ErrCode RunningLockStrategy::StopProxy(const StandbyMessage& message)
370 {
371     StandbyHitraceChain traceChain(__func__);
372     if (!isProxied_) {
373         return ERR_STANDBY_CURRENT_STATE_NOT_MATCH;
374     }
375     uint32_t preState = static_cast<uint32_t>(message.want_->GetIntParam(PREVIOUS_STATE, 0));
376     uint32_t curState = static_cast<uint32_t>(message.want_->GetIntParam(CURRENT_STATE, 0));
377     if ((curState == StandbyState::MAINTENANCE) && (preState == StandbyState::SLEEP)) {
378         // enter maintenance, stop proxy
379         ProxyAppAndProcess(false);
380         isIdleMaintence_ = true;
381     } else if ((curState == StandbyState::SLEEP) && (preState == StandbyState::MAINTENANCE)) {
382         isIdleMaintence_ = false;
383         // exit maintenance, enter sleep, start proxy
384         ProxyAppAndProcess(true);
385     } else if (preState == StandbyState::SLEEP || preState == StandbyState::MAINTENANCE) {
386         StopProxyInner();
387         isProxied_ = false;
388         isIdleMaintence_ = false;
389     }
390     return ERR_OK;
391 }
392 
StopProxyInner()393 ErrCode RunningLockStrategy::StopProxyInner()
394 {
395     ProxyAppAndProcess(false);
396     ClearProxyRecord();
397     return ERR_OK;
398 }
399 
UpdateBgTaskAppStatus(const StandbyMessage & message)400 ErrCode RunningLockStrategy::UpdateBgTaskAppStatus(const StandbyMessage& message)
401 {
402     std::string type = message.want_->GetStringParam(BG_TASK_TYPE);
403     bool started = message.want_->GetBoolParam(BG_TASK_STATUS, false);
404     int32_t uid = message.want_->GetIntParam(BG_TASK_UID, 0);
405     std::string bundleName = message.want_->GetStringParam(BG_TASK_BUNDLE_NAME);
406 
407     STANDBYSERVICE_LOGD("received bgtask status changed, type: %{public}s, isstarted: %{public}d, uid: %{public}d",
408         type.c_str(), started, uid);
409     if (BGTASK_EXEMPTION_FLAG_MAP.find(type) == BGTASK_EXEMPTION_FLAG_MAP.end()) {
410         return ERR_STANDBY_KEY_INFO_NOT_MATCH;
411     }
412 
413     if (bundleName.empty()) {
414         bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(uid);
415     }
416     if (started) {
417         AddExemptionFlag(uid, bundleName, BGTASK_EXEMPTION_FLAG_MAP.at(type));
418     } else {
419         RemoveExemptionFlag(uid, bundleName, BGTASK_EXEMPTION_FLAG_MAP.at(type));
420     }
421     return ERR_OK;
422 }
423 
424 // when bgtask or work_scheduler service crash, reset proxy status
ResetProxyStatus(const StandbyMessage & message)425 void RunningLockStrategy::ResetProxyStatus(const StandbyMessage& message)
426 {
427     if (!isProxied_ || isIdleMaintence_) {
428         return;
429     }
430     bool isAdded = message.want_->GetBoolParam(SA_STATUS, false);
431     if (isAdded) {
432         return;
433     }
434     int32_t saId = message.want_->GetIntParam(SA_ID, 0);
435     if (saId != WORK_SCHEDULE_SERVICE_ID && saId != BACKGROUND_TASK_MANAGER_SERVICE_ID) {
436         return;
437     }
438     const uint8_t bgTaskFlag = (ExemptionTypeFlag::TRANSIENT_TASK | ExemptionTypeFlag::WORK_SCHEDULER);
439     for (const auto& [key, value] : proxiedAppInfo_) {
440         if ((value.appExemptionFlag_ & bgTaskFlag) == 0) {
441             continue;
442         }
443         RemoveExemptionFlag(value.uid_, value.name_, (value.appExemptionFlag_ & bgTaskFlag));
444     }
445     return;
446 }
447 
AddExemptionFlag(int32_t uid,const std::string & name,uint8_t flag)448 void RunningLockStrategy::AddExemptionFlag(int32_t uid, const std::string& name, uint8_t flag)
449 {
450     if (!isProxied_) {
451         return;
452     }
453     std::string mapKey = std::to_string(uid) + "_" + name;
454     // if last appExemptionFlag is not exempted, current appExemptionFlag is exempted, unproxy running lock
455     if (auto iter = proxiedAppInfo_.find(mapKey); iter != proxiedAppInfo_.end()) {
456         auto lastAppExemptionFlag = iter->second.appExemptionFlag_;
457         iter->second.appExemptionFlag_ |= flag;
458         if (!ExemptionTypeFlag::IsExempted(lastAppExemptionFlag) &&
459             ExemptionTypeFlag::IsExempted(iter->second.appExemptionFlag_)) {
460             std::vector<std::pair<int32_t, int32_t>> proxiedAppList;
461             SetProxiedAppList(proxiedAppList, iter->second);
462             ProxyRunningLockList(false, proxiedAppList);
463         }
464     }
465 }
466 
RemoveExemptionFlag(int32_t uid,const std::string & name,uint8_t flag)467 void RunningLockStrategy::RemoveExemptionFlag(int32_t uid, const std::string& name, uint8_t flag)
468 {
469     std::string mapKey = std::to_string(uid) + "_" + name;
470     auto iter = proxiedAppInfo_.find(mapKey);
471     if (iter == proxiedAppInfo_.end()) {
472         return;
473     }
474 
475     // if last appExemptionFlag is exempted, current appExemptionFlag is unexempted, proxy running lock
476     auto lastAppExemptionFlag = iter->second.appExemptionFlag_;
477     iter->second.appExemptionFlag_ &= (~flag);
478     if (ExemptionTypeFlag::IsExempted(iter->second.appExemptionFlag_) ||
479         !ExemptionTypeFlag::IsExempted(lastAppExemptionFlag)) {
480         return;
481     }
482 
483     std::vector<std::pair<int32_t, int32_t>> proxiedAppList;
484     SetProxiedAppList(proxiedAppList, iter->second);
485     ProxyRunningLockList(true, proxiedAppList);
486 }
487 
ClearProxyRecord()488 void RunningLockStrategy::ClearProxyRecord()
489 {
490     proxiedAppInfo_.clear();
491     uidBundleNmeMap_.clear();
492 }
493 
494 // when app is created, add app info to cache
GetAndCreateAppInfo(uint32_t uid,uint32_t pid,const std::string & bundleName)495 void RunningLockStrategy::GetAndCreateAppInfo(uint32_t uid, uint32_t pid, const std::string& bundleName)
496 {
497     const std::string mapKey = std::to_string(uid) + "_" + bundleName;
498     auto iter = proxiedAppInfo_.find(mapKey);
499     if (iter != proxiedAppInfo_.end()) {
500         iter->second.pids_.emplace(pid);
501         return;
502     }
503 
504     std::tie(iter, std::ignore) = proxiedAppInfo_.emplace(mapKey, ProxiedProcInfo {bundleName, uid});
505     iter->second.pids_.emplace(pid);
506 
507     bool isSystemApp {false};
508     if (BundleManagerHelper::GetInstance()->CheckIsSystemAppByUid(uid, isSystemApp) && isSystemApp) {
509         iter->second.appExemptionFlag_ |= ExemptionTypeFlag::UNRESTRICTED;
510     }
511     GetExemptionConfigForApp(iter->second, bundleName);
512 }
513 
GetExemptionConfigForApp(ProxiedProcInfo & appInfo,const std::string & bundleName)514 ErrCode RunningLockStrategy::GetExemptionConfigForApp(ProxiedProcInfo& appInfo, const std::string& bundleName)
515 {
516     // if app in exemption list, add exemption flag
517     std::vector<AllowInfo> allowInfoList {};
518     StandbyServiceImpl::GetInstance()->GetAllowListInner(AllowType::NETWORK, allowInfoList,
519         ReasonCodeEnum::REASON_APP_API);
520     std::set<std::string> allowNameList {};
521     for (const auto& info : allowInfoList) {
522         if (info.GetName() != bundleName) {
523             continue;
524         }
525         appInfo.appExemptionFlag_ |= ExemptionTypeFlag::EXEMPTION;
526     }
527 
528     // if app in restricted list, add retricted flag
529     std::set<std::string> restrictNameList {};
530     StandbyServiceImpl::GetInstance()->GetEligiableRestrictSet(AllowType::NETWORK, "NETWORK",
531         ReasonCodeEnum::REASON_APP_API, restrictNameList);
532     if (restrictNameList.find(bundleName) != restrictNameList.end()) {
533         appInfo.appExemptionFlag_ |= ExemptionTypeFlag::RESTRICTED;
534     }
535     return ERR_OK;
536 }
537 
SetProxiedAppList(std::vector<std::pair<int32_t,int32_t>> & proxiedAppList,const ProxiedProcInfo & info)538 void RunningLockStrategy::SetProxiedAppList(std::vector<std::pair<int32_t, int32_t>>& proxiedAppList,
539     const ProxiedProcInfo& info)
540 {
541     for (auto& pid : info.pids_) {
542         proxiedAppList.emplace_back(std::make_pair(pid, info.uid_));
543     }
544 }
545 
ProxyRunningLockList(bool isProxied,const std::vector<std::pair<int32_t,int32_t>> & proxiedAppList)546 void RunningLockStrategy::ProxyRunningLockList(bool isProxied,
547     const std::vector<std::pair<int32_t, int32_t>>& proxiedAppList)
548 {
549     if (proxiedAppList.empty()) {
550         return;
551     }
552     // in maintenance state, disallow proxy running lock
553     if (isIdleMaintence_) {
554         STANDBYSERVICE_LOGI("current is idle maintenance, can not proxy running lock");
555         return;
556     }
557     #ifdef STANDBY_POWER_MANAGER_ENABLE
558     if (!PowerMgr::PowerMgrClient::GetInstance().ProxyRunningLocks(isProxied, proxiedAppList)) {
559         STANDBYSERVICE_LOGW("failed to ProxyRunningLockList");
560     }
561     #endif
562 }
563 
HandleProcessStatusChanged(const StandbyMessage & message)564 void RunningLockStrategy::HandleProcessStatusChanged(const StandbyMessage& message)
565 {
566     if (!isProxied_) {
567         STANDBYSERVICE_LOGD("RunningLockStrategy is not in proxy, do not need process");
568         return;
569     }
570     int32_t uid = message.want_->GetIntParam("uid", -1);
571     int32_t pid = message.want_->GetIntParam("pid", -1);
572     std::string bundleName = message.want_->GetStringParam("name");
573     bool isCreated = message.want_->GetBoolParam("isCreated", false);
574 
575     auto key = std::to_string(uid) + "_" + bundleName;
576     if (isCreated) {
577         // if process is created
578         GetAndCreateAppInfo(uid, pid, bundleName);
579         if (!ExemptionTypeFlag::IsExempted(proxiedAppInfo_[key].appExemptionFlag_)) {
580             ProxyRunningLockList(true, {std::make_pair(pid, uid)});
581         }
582     } else {
583         auto iter = proxiedAppInfo_.find(key);
584         if (iter == proxiedAppInfo_.end()) {
585             return;
586         }
587         if (!ExemptionTypeFlag::IsExempted(proxiedAppInfo_[key].appExemptionFlag_)) {
588             ProxyRunningLockList(false, {std::make_pair(pid, uid)});
589         }
590         iter->second.pids_.erase(pid);
591         if (iter->second.pids_.empty()) {
592             proxiedAppInfo_.erase(iter);
593         }
594     }
595 }
596 
ShellDump(const std::vector<std::string> & argsInStr,std::string & result)597 void RunningLockStrategy::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
598 {
599     if (argsInStr[DUMP_FIRST_PARAM] == DUMP_DETAIL_INFO &&
600         argsInStr[DUMP_SECOND_PARAM] == DUMP_STRATGY_DETAIL) {
601         DumpShowDetailInfo(argsInStr, result);
602     }
603 }
604 
605 // dump detail info of running lock strategy
DumpShowDetailInfo(const std::vector<std::string> & argsInStr,std::string & result)606 void RunningLockStrategy::DumpShowDetailInfo(const std::vector<std::string>& argsInStr, std::string& result)
607 {
608     result.append("=================RunningLock======================\n");
609     result.append("Running Lock Strategy:\n").append("isProxied: " + std::to_string(isProxied_))
610         .append(" isIdleMaintence: " + std::to_string(isIdleMaintence_)).append("\n");
611     result.append("proxied app info: \n");
612     for (const auto& [key, value] : proxiedAppInfo_) {
613         result.append("key: ").append(key).append(" name: ").append(value.name_).append(" uid: ")
614             .append(std::to_string(value.uid_)).append(" pid_size: ")
615             .append(std::to_string(value.pids_.size())).append(" exemption flag: ")
616             .append(std::to_string(value.appExemptionFlag_)).append("\n");
617         if (value.pids_.empty()) {
618             continue;
619         }
620         result.append("pids list: ");
621         for (const auto pid : value.pids_) {
622             result.append(" ").append(std::to_string(pid));
623         }
624         result.append("\n");
625     }
626 }
627 }  // namespace DevStandbyMgr
628 }  // namespace OHOS