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