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