• 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 #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