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 #include "base_network_strategy.h"
16 #include <algorithm>
17 #include "common_event_data.h"
18 #include "common_event_manager.h"
19 #include "common_event_support.h"
20 #include "system_ability_definition.h"
21 #include "power_mgr_client.h"
22 #include "workscheduler_srv_client.h"
23
24 #include "standby_service_log.h"
25 #include "background_task_helper.h"
26 #include "app_mgr_helper.h"
27 #include "standby_service.h"
28 #include "allow_type.h"
29 #include "standby_state.h"
30 #include "bundle_manager_helper.h"
31 #include "net_policy_client.h"
32 #include "background_mode.h"
33 #include "standby_config_manager.h"
34 #include "time_provider.h"
35 #include "standby_service_impl.h"
36 #include "common_constant.h"
37
38 namespace OHOS {
39 namespace DevStandbyMgr {
40 namespace {
41 const std::map<std::string, uint8_t> BGTASK_EXEMPTION_FLAG_MAP {
42 {CONTINUOUS_TASK, ExemptionTypeFlag::CONTINUOUS_TASK},
43 {TRANSIENT_TASK, ExemptionTypeFlag::TRANSIENT_TASK},
44 {WORK_SCHEDULER, ExemptionTypeFlag::WORK_SCHEDULER},
45 };
46 }
47
48 using namespace OHOS::BackgroundTaskMgr;
49
HandleEvent(const StandbyMessage & message)50 void BaseNetworkStrategy::HandleEvent(const StandbyMessage& message)
51 {
52 STANDBYSERVICE_LOGD("BaseNetworkStrategy 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::BG_TASK_STATUS_CHANGE:
59 UpdateBgTaskAppStatus(message);
60 break;
61 case StandbyMessageType::PROCESS_STATE_CHANGED:
62 HandleProcessStatusChanged(message);
63 break;
64 case StandbyMessageType::SYS_ABILITY_STATUS_CHANGED:
65 ResetFirewallStatus(message);
66 break;
67 default:
68 break;
69 }
70 }
71
OnCreated()72 ErrCode BaseNetworkStrategy::OnCreated()
73 {
74 // when initialized, stop net limit mode in case of unexpected process restart
75 ResetFirewallAllowList();
76 isFirewallEnabled_ = false;
77 isIdleMaintence_ = false;
78 return ERR_OK;
79 }
80
OnDestroy()81 ErrCode BaseNetworkStrategy::OnDestroy()
82 {
83 ResetFirewallAllowList();
84 return ERR_OK;
85 }
86
UpdateExemptionList(const StandbyMessage & message)87 ErrCode BaseNetworkStrategy::UpdateExemptionList(const StandbyMessage& message)
88 {
89 uint32_t allowType = static_cast<uint32_t>(message.want_->GetIntParam("allowType", 0));
90 if ((allowType & AllowType::NETWORK) == 0) {
91 STANDBYSERVICE_LOGD("allowType is not network, currentType is %{public}d", allowType);
92 return ERR_STANDBY_STRATEGY_NOT_MATCH;
93 }
94 if (!isFirewallEnabled_) {
95 STANDBYSERVICE_LOGD("current state is not sleep or maintenance, ignore exemption");
96 return ERR_STANDBY_CURRENT_STATE_NOT_MATCH;
97 }
98 // start update exemption flag
99 std::string processName = message.want_->GetStringParam("name");
100 bool added = message.want_->GetBoolParam("added", false);
101 int32_t uid = message.want_->GetIntParam("uid", -1);
102 STANDBYSERVICE_LOGI("updatee exemption list, %{public}s apply exemption, added is %{public}d",
103 processName.c_str(), added);
104 if (added) {
105 AddExemptionFlag(uid, processName, ExemptionTypeFlag::EXEMPTION);
106 } else {
107 RemoveExemptionFlag(uid, ExemptionTypeFlag::EXEMPTION);
108 }
109 return ERR_OK;
110 }
111
OnDayNightSwitched(const StandbyMessage & message)112 ErrCode BaseNetworkStrategy::OnDayNightSwitched(const StandbyMessage& message)
113 {
114 SetNetAllowApps(false);
115 netLimitedAppInfo_.clear();
116 if (InitNetLimitedAppInfo() != ERR_OK) {
117 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
118 }
119 SetFirewallStatus(true);
120 return ERR_OK;
121 }
122
EnableNetworkFirewall(const StandbyMessage & message)123 ErrCode BaseNetworkStrategy::EnableNetworkFirewall(const StandbyMessage& message)
124 {
125 if (isFirewallEnabled_) {
126 STANDBYSERVICE_LOGD("now is doze, do not need start net limit mode, repeat process");
127 return ERR_STANDBY_STRATEGY_STATE_REPEAT;
128 }
129 STANDBYSERVICE_LOGD("start net limit mode");
130 // if enter sleep state and app_res_deep phase, start net limit mode.
131 if (auto ret = EnableNetworkFirewallInner(); ret != ERR_OK) {
132 return ret;
133 }
134 isFirewallEnabled_ = true;
135 isIdleMaintence_ = false;
136 return ERR_OK;
137 }
138
EnableNetworkFirewallInner()139 ErrCode BaseNetworkStrategy::EnableNetworkFirewallInner()
140 {
141 netLimitedAppInfo_.clear();
142 if (InitNetLimitedAppInfo() != ERR_OK) {
143 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
144 }
145 SetFirewallStatus(true);
146 return ERR_OK;
147 }
148
149 // get app info, add exemption according to the status of app.
InitNetLimitedAppInfo()150 ErrCode BaseNetworkStrategy::InitNetLimitedAppInfo()
151 {
152 if (GetAllRunningAppInfo() != ERR_OK) {
153 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
154 }
155
156 std::vector<AppExecFwk::ApplicationInfo> applicationInfos {};
157 if (!BundleManagerHelper::GetInstance()->GetApplicationInfos(
158 AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
159 AppExecFwk::Constants::ALL_USERID, applicationInfos)) {
160 STANDBYSERVICE_LOGW("failed to get all applicationInfos");
161 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
162 }
163 STANDBYSERVICE_LOGD("succeed GetApplicationInfos, size is %{public}d",
164 static_cast<int32_t>(applicationInfos.size()));
165 for (const auto& info : applicationInfos) {
166 if (netLimitedAppInfo_.find(info.uid) == netLimitedAppInfo_.end()) {
167 continue;
168 }
169 if (info.isSystemApp) {
170 netLimitedAppInfo_[info.uid].appExemptionFlag_ |= ExemptionTypeFlag::UNRESTRICTED;
171 }
172 }
173
174 if (GetForegroundApplications() !=ERR_OK || GetBackgroundTaskApp() != ERR_OK ||
175 GetWorkSchedulerTask() != ERR_OK || GetExemptionConfig() != ERR_OK) {
176 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
177 }
178 return ERR_OK;
179 }
180
GetAllRunningAppInfo()181 ErrCode BaseNetworkStrategy::GetAllRunningAppInfo()
182 {
183 std::vector<AppExecFwk::RunningProcessInfo> allAppProcessInfos {};
184 if (!AppMgrHelper::GetInstance()->GetAllRunningProcesses(allAppProcessInfos)) {
185 STANDBYSERVICE_LOGE("connect to app manager service failed");
186 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
187 }
188 STANDBYSERVICE_LOGI("current running processes size %{public}d", static_cast<int32_t>(allAppProcessInfos.size()));
189 for (const auto &info : allAppProcessInfos) {
190 netLimitedAppInfo_.emplace(info.uid_, NetLimtedAppInfo {info.processName_});
191 }
192 return ERR_OK;
193 }
194
GetForegroundApplications()195 ErrCode BaseNetworkStrategy::GetForegroundApplications()
196 {
197 std::vector<AppExecFwk::AppStateData> fgApps {};
198 if (!AppMgrHelper::GetInstance()->GetForegroundApplications(fgApps)) {
199 STANDBYSERVICE_LOGW("get foreground app failed");
200 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
201 }
202 for (const auto& appInfo : fgApps) {
203 AddExemptionFlagByUid(appInfo.uid, ExemptionTypeFlag::FOREGROUND_APP);
204 }
205 return ERR_OK;
206 }
207
GetBackgroundTaskApp()208 ErrCode BaseNetworkStrategy::GetBackgroundTaskApp()
209 {
210 std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> continuousTaskList;
211 if (!BackgroundTaskHelper::GetInstance()->GetContinuousTaskApps(continuousTaskList)) {
212 STANDBYSERVICE_LOGW("get continuous task app failed");
213 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
214 }
215 STANDBYSERVICE_LOGD("succeed GetContinuousTaskApps, size is %{public}d",
216 static_cast<int32_t>(continuousTaskList.size()));
217 std::vector<std::shared_ptr<TransientTaskAppInfo>> transientTaskList;
218 if (!BackgroundTaskHelper::GetInstance()->GetTransientTaskApps(transientTaskList)) {
219 STANDBYSERVICE_LOGW("get transient task app failed");
220 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
221 }
222 STANDBYSERVICE_LOGD("succeed GetTransientTaskApps, size is %{public}d",
223 static_cast<int32_t>(transientTaskList.size()));
224 condition_ = TimeProvider::GetCondition();
225 for (const auto& task : continuousTaskList) {
226 if (auto infoIter = netLimitedAppInfo_.find(task->GetCreatorUid()); infoIter == netLimitedAppInfo_.end()) {
227 continue;
228 } else if (condition_ == ConditionType::DAY_STANDBY ||
229 (nightExemptionTaskType_ & (1<< task->GetTypeId())) != 0) {
230 infoIter->second.appExemptionFlag_ |= ExemptionTypeFlag::CONTINUOUS_TASK;
231 }
232 }
233 for (const auto& task : transientTaskList) {
234 AddExemptionFlagByUid(task->GetUid(), ExemptionTypeFlag::TRANSIENT_TASK);
235 }
236 return ERR_OK;
237 }
238
GetWorkSchedulerTask()239 ErrCode BaseNetworkStrategy::GetWorkSchedulerTask()
240 {
241 std::list<std::shared_ptr<WorkScheduler::WorkInfo>> workInfos;
242 if (WorkScheduler::WorkSchedulerSrvClient::GetInstance().GetAllRunningWorks(workInfos) != ERR_OK) {
243 return ERR_STRATEGY_DEPENDS_SA_NOT_AVAILABLE;
244 }
245 STANDBYSERVICE_LOGD("GetWorkSchedulerTask succeed, size is %{public}d", static_cast<int32_t>(workInfos.size()));
246 for (const auto& task : workInfos) {
247 AddExemptionFlagByUid(task->GetUid(), ExemptionTypeFlag::WORK_SCHEDULER);
248 }
249 return ERR_OK;
250 }
251
AddExemptionFlagByUid(int32_t uid,uint8_t flag)252 void BaseNetworkStrategy::AddExemptionFlagByUid(int32_t uid, uint8_t flag)
253 {
254 if (auto iter = netLimitedAppInfo_.find(uid); iter != netLimitedAppInfo_.end()) {
255 iter->second.appExemptionFlag_ |= flag;
256 }
257 }
258
GetExemptionConfig()259 ErrCode BaseNetworkStrategy::GetExemptionConfig()
260 {
261 // if app in exemption list, add exemption flag
262 std::vector<AllowInfo> allowInfoList {};
263 StandbyServiceImpl::GetInstance()->GetAllowListInner(AllowType::NETWORK, allowInfoList,
264 ReasonCodeEnum::REASON_APP_API);
265 std::set<std::string> allowNameList {};
266 for (const auto& info : allowInfoList) {
267 allowNameList.emplace(info.GetName());
268 }
269 for (auto& [key, value] : netLimitedAppInfo_) {
270 if (allowNameList.find(value.name_) == allowNameList.end()) {
271 continue;
272 }
273 value.appExemptionFlag_ |= ExemptionTypeFlag::EXEMPTION;
274 }
275 // if app in restricted list, add retricted flag
276 std::set<std::string> restrictNameList {};
277 StandbyServiceImpl::GetInstance()->GetEligiableRestrictSet(AllowType::NETWORK, "NETWORK",
278 ReasonCodeEnum::REASON_APP_API, restrictNameList);
279 for (auto& [key, value] : netLimitedAppInfo_) {
280 if (restrictNameList.find(value.name_) == restrictNameList.end()) {
281 continue;
282 }
283 value.appExemptionFlag_ |= ExemptionTypeFlag::RESTRICTED;
284 }
285 return ERR_OK;
286 }
287
GetExemptionConfigForApp(NetLimtedAppInfo & appInfo,const std::string & bundleName)288 ErrCode BaseNetworkStrategy::GetExemptionConfigForApp(NetLimtedAppInfo& appInfo, const std::string& bundleName)
289 {
290 // if app in exemption list, add exemption flag
291 std::vector<AllowInfo> allowInfoList {};
292 StandbyServiceImpl::GetInstance()->GetAllowListInner(AllowType::NETWORK, allowInfoList,
293 ReasonCodeEnum::REASON_APP_API);
294 std::set<std::string> allowNameList {};
295 for (const auto& info : allowInfoList) {
296 if (info.GetName() != bundleName) {
297 continue;
298 }
299 appInfo.appExemptionFlag_ |= ExemptionTypeFlag::EXEMPTION;
300 }
301
302 // if app in restricted list, add retricted flag
303 std::set<std::string> restrictNameList {};
304 StandbyServiceImpl::GetInstance()->GetEligiableRestrictSet(AllowType::NETWORK, "NETWORK",
305 ReasonCodeEnum::REASON_APP_API, restrictNameList);
306 if (restrictNameList.find(bundleName) != restrictNameList.end()) {
307 appInfo.appExemptionFlag_ |= ExemptionTypeFlag::RESTRICTED;
308 }
309 return ERR_OK;
310 }
311
SetNetAllowApps(bool isAllow)312 void BaseNetworkStrategy::SetNetAllowApps(bool isAllow)
313 {
314 std::vector<uint32_t> uids;
315 for (const auto& [key, value] : netLimitedAppInfo_) {
316 if (!ExemptionTypeFlag::IsExempted(value.appExemptionFlag_)) {
317 continue;
318 }
319 uids.emplace_back(key);
320 STANDBYSERVICE_LOGD("uid: %{public}d, name: %{public}s, isAllow: %{public}d",
321 key, value.name_.c_str(), isAllow);
322 }
323 STANDBYSERVICE_LOGD("all application size: %{public}d, network allow: %{public}d",
324 static_cast<int32_t>(netLimitedAppInfo_.size()), static_cast<int32_t>(uids.size()));
325 SetFirewallAllowedList(uids, isAllow);
326 }
327
DisableNetworkFirewall(const StandbyMessage & message)328 ErrCode BaseNetworkStrategy::DisableNetworkFirewall(const StandbyMessage& message)
329 {
330 if (!isFirewallEnabled_) {
331 return ERR_STANDBY_CURRENT_STATE_NOT_MATCH;
332 }
333 uint32_t preState = static_cast<uint32_t>(message.want_->GetIntParam(PREVIOUS_STATE, 0));
334 uint32_t curState = static_cast<uint32_t>(message.want_->GetIntParam(CURRENT_STATE, 0));
335 if ((curState == StandbyState::MAINTENANCE) && (preState == StandbyState::SLEEP)) {
336 // restart net limit mode
337 SetFirewallStatus(false);
338 isIdleMaintence_ = true;
339 } else if ((curState == StandbyState::SLEEP) && (preState == StandbyState::MAINTENANCE)) {
340 isIdleMaintence_ = false;
341 // stop net limit mode
342 SetFirewallStatus(true);
343 } else if (preState == StandbyState::SLEEP || preState == StandbyState::MAINTENANCE) {
344 DisableNetworkFirewallInner();
345 isIdleMaintence_ = false;
346 isFirewallEnabled_ = false;
347 }
348 return ERR_OK;
349 }
350
DisableNetworkFirewallInner()351 ErrCode BaseNetworkStrategy::DisableNetworkFirewallInner()
352 {
353 STANDBYSERVICE_LOGD("stop net limit mode");
354 SetFirewallStatus(false);
355 netLimitedAppInfo_.clear();
356 return ERR_OK;
357 }
358
UpdateBgTaskAppStatus(const StandbyMessage & message)359 ErrCode BaseNetworkStrategy::UpdateBgTaskAppStatus(const StandbyMessage& message)
360 {
361 if (!isFirewallEnabled_) {
362 STANDBYSERVICE_LOGD("current state is not sleep or maintenance, ignore exemption");
363 return ERR_STANDBY_CURRENT_STATE_NOT_MATCH;
364 }
365
366 std::string type = message.want_->GetStringParam(BG_TASK_TYPE);
367 bool started = message.want_->GetBoolParam(BG_TASK_STATUS, false);
368 int32_t uid = message.want_->GetIntParam(BG_TASK_UID, 0);
369 std::string bundleName = message.want_->GetStringParam(BG_TASK_BUNDLE_NAME);
370 if (BGTASK_EXEMPTION_FLAG_MAP.find(type) == BGTASK_EXEMPTION_FLAG_MAP.end()) {
371 return ERR_STANDBY_KEY_INFO_NOT_MATCH;
372 }
373 if (bundleName.empty()) {
374 bundleName = BundleManagerHelper::GetInstance()->GetClientBundleName(uid);
375 }
376 if (started) {
377 AddExemptionFlag(static_cast<uint32_t>(uid), bundleName, BGTASK_EXEMPTION_FLAG_MAP.at(type));
378 } else {
379 RemoveExemptionFlag(static_cast<uint32_t>(uid), BGTASK_EXEMPTION_FLAG_MAP.at(type));
380 }
381 return ERR_OK;
382 }
383
HandleProcessStatusChanged(const StandbyMessage & message)384 void BaseNetworkStrategy::HandleProcessStatusChanged(const StandbyMessage& message)
385 {
386 if (!isFirewallEnabled_) {
387 STANDBYSERVICE_LOGD("current state is not sleep or maintenance, ignore state of process");
388 return;
389 }
390 int32_t uid = message.want_->GetIntParam("uid", -1);
391 std::string bundleName = message.want_->GetStringParam("name");
392 bool isCreated = message.want_->GetBoolParam("isCreated", false);
393 if (isCreated) {
394 GetAndCreateAppInfo(uid, bundleName);
395 auto iter = netLimitedAppInfo_.find(uid);
396 if (ExemptionTypeFlag::IsExempted(iter->second.appExemptionFlag_)) {
397 SetFirewallAllowedList( {uid}, isCreated);
398 }
399 } else {
400 bool isRunning {false};
401 if (AppMgrHelper::GetInstance()->GetAppRunningStateByBundleName(bundleName, isRunning) && !isRunning) {
402 netLimitedAppInfo_.erase(uid);
403 SetFirewallAllowedList( {uid}, isCreated);
404 }
405 }
406 }
407
AddExemptionFlag(uint32_t uid,const std::string & bundleName,uint8_t flag)408 void BaseNetworkStrategy::AddExemptionFlag(uint32_t uid, const std::string& bundleName, uint8_t flag)
409 {
410 if (!isFirewallEnabled_) {
411 return;
412 }
413 STANDBYSERVICE_LOGD("AddExemptionFlag uid is %{public}u, flag is %{public}d", uid, flag);
414 GetAndCreateAppInfo(uid, bundleName);
415 auto iter = netLimitedAppInfo_.find(uid);
416 if (iter == netLimitedAppInfo_.end()) {
417 netLimitedAppInfo_[uid] = NetLimtedAppInfo {bundleName};
418 }
419 auto lastAppExemptionFlag = iter->second.appExemptionFlag_;
420 iter->second.appExemptionFlag_ |= flag;
421 if (!ExemptionTypeFlag::IsExempted(lastAppExemptionFlag) &&
422 ExemptionTypeFlag::IsExempted(iter->second.appExemptionFlag_)) {
423 SetFirewallAllowedList({iter->first}, true);
424 }
425 iter->second.appExemptionFlag_ |= flag;
426 }
427
RemoveExemptionFlag(uint32_t uid,uint8_t flag)428 void BaseNetworkStrategy::RemoveExemptionFlag(uint32_t uid, uint8_t flag)
429 {
430 if (!isFirewallEnabled_) {
431 return;
432 }
433 auto iter = netLimitedAppInfo_.find(uid);
434 if (iter == netLimitedAppInfo_.end()) {
435 return;
436 }
437
438 STANDBYSERVICE_LOGD("RemoveExemptionFlag uid is flag is %{public}d, flag is %{public}d", uid, flag);
439 auto lastAppExemptionFlag = iter->second.appExemptionFlag_;
440 iter->second.appExemptionFlag_ &= (~flag);
441 if (ExemptionTypeFlag::IsExempted(lastAppExemptionFlag) &&
442 !ExemptionTypeFlag::IsExempted(iter->second.appExemptionFlag_)) {
443 SetFirewallAllowedList({iter->first}, false);
444 }
445 }
446
447 // when app is created, add app info to cache
GetAndCreateAppInfo(uint32_t uid,const std::string & bundleName)448 void BaseNetworkStrategy::GetAndCreateAppInfo(uint32_t uid, const std::string& bundleName)
449 {
450 auto iter = netLimitedAppInfo_.find(uid);
451 if (iter != netLimitedAppInfo_.end()) {
452 return;
453 }
454 std::tie(iter, std::ignore) = netLimitedAppInfo_.emplace(uid, NetLimtedAppInfo {bundleName});
455
456 bool isSystemApp {false};
457 if (BundleManagerHelper::GetInstance()->CheckIsSystemAppByUid(uid, isSystemApp) && isSystemApp) {
458 iter->second.appExemptionFlag_ |= ExemptionTypeFlag::UNRESTRICTED;
459 }
460 GetExemptionConfigForApp(iter->second, bundleName);
461 }
462
463 // when bgtask or work_scheduler service crash, reset relative flag
ResetFirewallStatus(const StandbyMessage & message)464 void BaseNetworkStrategy::ResetFirewallStatus(const StandbyMessage& message)
465 {
466 if (!isFirewallEnabled_ || isIdleMaintence_) {
467 return;
468 }
469 bool isAdded = message.want_->GetBoolParam(SA_STATUS, false);
470 if (isAdded) {
471 return;
472 }
473 int32_t saId = message.want_->GetIntParam(SA_ID, 0);
474 if (saId != WORK_SCHEDULE_SERVICE_ID && saId != BACKGROUND_TASK_MANAGER_SERVICE_ID) {
475 return;
476 }
477 const uint8_t bgTaskFlag = (ExemptionTypeFlag::TRANSIENT_TASK | ExemptionTypeFlag::WORK_SCHEDULER);
478 for (const auto& [key, value] : netLimitedAppInfo_) {
479 if ((value.appExemptionFlag_ & bgTaskFlag) == 0) {
480 continue;
481 }
482 RemoveExemptionFlag(key, (value.appExemptionFlag_ & bgTaskFlag));
483 }
484 return;
485 }
486
ShellDump(const std::vector<std::string> & argsInStr,std::string & result)487 void BaseNetworkStrategy::ShellDump(const std::vector<std::string>& argsInStr, std::string& result)
488 {
489 result.append("Network Strategy:\n").append("isFirewallEnabled: " + std::to_string(isFirewallEnabled_))
490 .append(" isIdleMaintence: " + std::to_string(isIdleMaintence_)).append("\n");
491 result.append("limited app info: \n");
492 for (const auto& [key, value] : netLimitedAppInfo_) {
493 result.append("uid: ").append(std::to_string(key)).append(" name: ").append(value.name_).append(" uid: ")
494 .append(std::to_string(key)).append(" exemption flag: ")
495 .append(std::to_string(value.appExemptionFlag_)).append("\n");
496 }
497 }
498 } // namespace DevStandbyMgr
499 } // namespace OHOS
500