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