• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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 "work_scheduler_service.h"
16 
17 #include <cstdio>
18 #include <cstdlib>
19 #include <fstream>
20 #include <iostream>
21 #include <climits>          // for PATH_MAX
22 
23 #include <dirent.h>
24 #include <fcntl.h>
25 #include <file_ex.h>
26 #include <if_system_ability_manager.h>
27 #include <ipc_skeleton.h>
28 #include <iservice_registry.h>
29 #include <string_ex.h>
30 #include <system_ability_definition.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 
34 #include "parameters.h"
35 #include "accesstoken_kit.h"
36 #include "bundle_mgr_proxy.h"
37 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
38 #include "bundle_active_client.h"
39 #endif
40 #ifdef DEVICE_STANDBY_ENABLE
41 #include "standby_service_client.h"
42 #include "allow_type.h"
43 #endif
44 #include "conditions/battery_level_listener.h"
45 #include "conditions/battery_status_listener.h"
46 #include "conditions/charger_listener.h"
47 #include "conditions/condition_checker.h"
48 #include "conditions/network_listener.h"
49 #include "conditions/screen_listener.h"
50 #include "conditions/storage_listener.h"
51 #include "conditions/timer_listener.h"
52 #include "conditions/group_listener.h"
53 #include "config_policy_utils.h"           // for GetOneCfgFile
54 #include "event_publisher.h"
55 #include "json/json.h"
56 #include "policy/app_data_clear_listener.h"
57 #include "policy/memory_policy.h"
58 #include "policy/thermal_policy.h"
59 #include "policy/cpu_policy.h"
60 #ifdef POWERMGR_POWER_MANAGER_ENABLE
61 #include "policy/power_mode_policy.h"
62 #endif
63 #ifdef RESOURCESCHEDULE_BGTASKMGR_ENABLE
64 #include "scheduler_bg_task_subscriber.h"
65 #include "background_task_mgr_helper.h"
66 #include "resource_type.h"
67 #endif
68 #include "work_datashare_helper.h"
69 #include "work_scheduler_connection.h"
70 #include "work_bundle_group_change_callback.h"
71 #include "work_sched_errors.h"
72 #include "work_sched_hilog.h"
73 #include "work_sched_utils.h"
74 #include "hitrace_meter.h"
75 #include "res_type.h"
76 #include "res_sched_client.h"
77 #include "work_sched_data_manager.h"
78 #include "work_sched_config.h"
79 
80 #ifdef HICOLLIE_ENABLE
81 #include "xcollie/xcollie.h"
82 #include "xcollie/xcollie_define.h"
83 #define XCOLLIE_TIMEOUT_SECONDS 10
84 #endif
85 
86 using namespace std;
87 using namespace OHOS::AppExecFwk;
88 
89 namespace OHOS {
90 namespace WorkScheduler {
91 namespace {
92 const std::string WORKSCHEDULER_SERVICE_NAME = "WorkSchedulerService";
93 const std::string PRINSTALLED_WORKS_KEY = "work_scheduler_preinstalled_works";
94 const std::string EXEMPTION_BUNDLES_KEY = "work_scheduler_eng_exemption_bundles";
95 const std::string MIN_REPEAT_TIME_KEY = "work_scheduler_min_repeat_time";
96 auto instance = DelayedSingleton<WorkSchedulerService>::GetInstance();
97 auto wss = instance.get();
98 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(wss);
99 const int32_t UID_TRANSFORM_DIVISOR = 200000;
100 const int32_t INIT_DELAY = 2 * 1000;
101 const int32_t CHECK_CONDITION_DELAY = 5 * 1000;
102 const int32_t MAX_BUFFER = 2048;
103 const int32_t DUMP_OPTION = 0;
104 const int32_t DUMP_PARAM_INDEX = 1;
105 const int32_t DUMP_VALUE_INDEX = 2;
106 const int32_t TIME_OUT = 4;
107 const uint32_t SYS_APP_MIN_REPEAT_TIME = 5 * 60 * 1000;
108 const char* PERSISTED_FILE_PATH = "/data/service/el1/public/WorkScheduler/persisted_work";
109 const char* PERSISTED_PATH = "/data/service/el1/public/WorkScheduler";
110 const char* PREINSTALLED_FILE_PATH = "etc/backgroundtask/config.json";
111 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
112 static int g_hasGroupObserver = -1;
113 #endif
114 const static std::string STRATEGY_NAME = "WORK_SCHEDULER";
115 const std::set<std::string> WORK_SCHED_NATIVE_OPERATE_CALLER = {
116     "resource_schedule_service",
117     "hidumper_service",
118 };
119 }
120 
121 #ifdef WORK_SCHEDULER_TEST
122 #define WEAK_FUNC __attribute__((weak))
123 #else
124 #define WEAK_FUNC
125 #endif
126 
WorkSchedulerService()127 WorkSchedulerService::WorkSchedulerService() : SystemAbility(WORK_SCHEDULE_SERVICE_ID, true) {}
~WorkSchedulerService()128 WorkSchedulerService::~WorkSchedulerService() {}
129 
OnStart()130 void WorkSchedulerService::OnStart()
131 {
132     if (ready_) {
133         WS_HILOGI("OnStart is ready, nothing to do.");
134         return;
135     }
136 
137     // Init handler.
138     if (!eventRunner_) {
139         eventRunner_ = AppExecFwk::EventRunner::Create(WORKSCHEDULER_SERVICE_NAME, AppExecFwk::ThreadMode::FFRT);
140     }
141     if (eventRunner_ == nullptr) {
142         WS_HILOGE("Init failed due to create EventRunner");
143         return;
144     }
145     handler_ = std::make_shared<WorkEventHandler>(eventRunner_, instance);
146     if (!handler_) {
147         WS_HILOGE("Init failed due to create handler_");
148         return;
149     }
150 
151     // Try to init.
152     Init(eventRunner_);
153 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
154     AddSystemAbilityListener(DEVICE_USAGE_STATISTICS_SYS_ABILITY_ID);
155 #endif
156 #ifdef DEVICE_STANDBY_ENABLE
157     AddSystemAbilityListener(DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID);
158 #endif
159     WS_HILOGD("On start success.");
160 }
161 
IsBaseAbilityReady()162 WEAK_FUNC bool WorkSchedulerService::IsBaseAbilityReady()
163 {
164     sptr<ISystemAbilityManager> systemAbilityManager
165         = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
166     if (systemAbilityManager == nullptr
167         || systemAbilityManager->CheckSystemAbility(APP_MGR_SERVICE_ID) == nullptr
168         || systemAbilityManager->CheckSystemAbility(COMMON_EVENT_SERVICE_ID) == nullptr
169         || systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID) == nullptr
170         || systemAbilityManager->CheckSystemAbility(BACKGROUND_TASK_MANAGER_SERVICE_ID) == nullptr
171         || systemAbilityManager->CheckSystemAbility(TIME_SERVICE_ID) == nullptr) {
172         return false;
173     }
174     return true;
175 }
176 
InitPersistedWork()177 void WorkSchedulerService::InitPersistedWork()
178 {
179     WS_HILOGD("init persisted work");
180     std::lock_guard<ffrt::mutex> lock(mutex_);
181     list<shared_ptr<WorkInfo>> persistedWorks = ReadPersistedWorks();
182     for (auto it : persistedWorks) {
183         WS_HILOGI("get persisted work, id: %{public}d, isSa:%{public}d", it->GetWorkId(), it->IsSA());
184         AddWorkInner(*it);
185     }
186     RefreshPersistedWorks();
187 }
188 
InitPreinstalledWork()189 void WorkSchedulerService::InitPreinstalledWork()
190 {
191     WS_HILOGD("init preinstalled work");
192     list<shared_ptr<WorkInfo>> preinstalledWorks = ReadPreinstalledWorks();
193     std::lock_guard<ffrt::mutex> lock(mutex_);
194     for (auto work : preinstalledWorks) {
195         WS_HILOGI("preinstalled workinfo id %{public}s, isSa:%{public}d", work->GetBriefInfo().c_str(), work->IsSA());
196         time_t baseTime;
197         (void)time(&baseTime);
198         work->RequestBaseTime(baseTime);
199         AddWorkInner(*work);
200         if (work->IsPersisted()) {
201             string workId = "u" + to_string(work->GetUid()) + "_" + to_string(work->GetWorkId());
202             persistedMap_.emplace(workId, work);
203         }
204     }
205     if (minCheckTime_ && minCheckTime_ < workQueueManager_->GetTimeCycle()) {
206         workQueueManager_->SetTimeCycle(minCheckTime_);
207     }
208 }
209 
InitWorkInner()210 void WorkSchedulerService::InitWorkInner()
211 {
212     InitPreinstalledWork();
213     InitPersistedWork();
214 }
215 
ReadPersistedWorks()216 list<shared_ptr<WorkInfo>> WorkSchedulerService::ReadPersistedWorks()
217 {
218     list<shared_ptr<WorkInfo>> workInfos;
219     Json::Value root;
220     if (!GetJsonFromFile(PERSISTED_FILE_PATH, root)) {
221         return workInfos;
222     }
223     for (const auto &it : root.getMemberNames()) {
224         Json::Value workJson = root[it];
225         shared_ptr<WorkInfo> workInfo = make_shared<WorkInfo>();
226         if (!workInfo->ParseFromJson(workJson)) {
227             WS_HILOGE("ReadPersistedWorks failed, parseFromJson error");
228             continue;
229         }
230         workInfos.emplace_back(workInfo);
231         WS_HILOGI("find one persisted work %{public}s", workInfo->GetBriefInfo().c_str());
232         auto iter = std::find_if(persistedMap_.begin(), persistedMap_.end(), [&](const auto &pair) {
233             return (pair.second->GetUid() == workInfo->GetUid()) && (pair.second->GetWorkId() == workInfo->GetWorkId());
234         });
235         if (iter != persistedMap_.end()) {
236             WS_HILOGI("find work %{public}s in persisted map, ignore, isSA:%{public}d",
237                 workInfo->GetBriefInfo().c_str(),
238                 workInfo->IsSA());
239             // update basetime
240             continue;
241         }
242         string workId = "u" + to_string(workInfo->GetUid()) + "_" + to_string(workInfo->GetWorkId());
243         persistedMap_.emplace(workId, workInfo);
244     }
245     return workInfos;
246 }
247 
LoadWorksFromFile(const char * path,list<shared_ptr<WorkInfo>> & workInfos)248 void WorkSchedulerService::LoadWorksFromFile(const char *path, list<shared_ptr<WorkInfo>> &workInfos)
249 {
250     if (!path) {
251         return;
252     }
253     Json::Value root;
254     if (!GetJsonFromFile(path, root) || root.empty()) {
255         WS_HILOGE("file is empty %{private}s", path);
256         return;
257     }
258     if (!root.isMember(PRINSTALLED_WORKS_KEY)) {
259         WS_HILOGE("no work_scheduler_preinstalled_works key");
260         return;
261     }
262     Json::Value preinstalledWorksRoot = root[PRINSTALLED_WORKS_KEY];
263     if (preinstalledWorksRoot.empty() || !preinstalledWorksRoot.isObject()) {
264         WS_HILOGE("work_scheduler_preinstalled_works content is empty");
265         return;
266     }
267     for (const auto &it : preinstalledWorksRoot.getMemberNames()) {
268         Json::Value workJson = preinstalledWorksRoot[it];
269         shared_ptr<WorkInfo> workinfo = make_shared<WorkInfo>();
270         if (!workinfo->ParseFromJson(workJson)) {
271             WS_HILOGE("LoadWorksFromFile failed, parseFromJson error");
272             continue;
273         }
274         if (!workinfo->IsSA()) {
275             int32_t uid;
276             if (!GetUidByBundleName(workinfo->GetBundleName(), uid)) {
277                 continue;
278             }
279             workinfo->RefreshUid(uid);
280             preinstalledBundles_.insert(workinfo->GetBundleName());
281         }
282         workinfo->SetPreinstalled(true);
283         workInfos.emplace_back(workinfo);
284     }
285 }
286 
LoadExemptionBundlesFromFile(const char * path)287 void WorkSchedulerService::LoadExemptionBundlesFromFile(const char *path)
288 {
289     if (!path) {
290         return;
291     }
292     Json::Value root;
293     if (!GetJsonFromFile(path, root) || root.empty()) {
294         WS_HILOGE("file is empty %{private}s", path);
295         return;
296     }
297     if (!root.isMember(EXEMPTION_BUNDLES_KEY)) {
298         WS_HILOGE("no work_scheduler_eng_exemption_bundles key");
299         return;
300     }
301     Json::Value exemptionBundlesRoot = root[EXEMPTION_BUNDLES_KEY];
302     if (exemptionBundlesRoot.empty() || !exemptionBundlesRoot.isArray()) {
303         WS_HILOGE("work_scheduler_eng_exemption_bundles content is empty");
304         return;
305     }
306 
307     for (const auto &exemptionBundleName : exemptionBundlesRoot) {
308         if (exemptionBundleName.empty() || !exemptionBundleName.isString()) {
309             WS_HILOGE("Item type error");
310         } else {
311             WS_HILOGI("bundle name:%{public}s", exemptionBundleName.asString().c_str());
312             exemptionBundles_.insert(exemptionBundleName.asString());
313         }
314     }
315 }
316 
LoadMinRepeatTimeFromFile(const char * path)317 void WorkSchedulerService::LoadMinRepeatTimeFromFile(const char *path)
318 {
319     if (!path) {
320         return;
321     }
322     Json::Value root;
323     if (!GetJsonFromFile(path, root) || root.empty()) {
324         WS_HILOGE("file is empty %{private}s", path);
325         return;
326     }
327     if (!root.isMember(MIN_REPEAT_TIME_KEY)) {
328         WS_HILOGE("no work_scheduler_min_repeat_time key");
329         return;
330     }
331     Json::Value minRepeatTimeRoot = root[MIN_REPEAT_TIME_KEY];
332     if (minRepeatTimeRoot.empty() || !minRepeatTimeRoot.isObject()) {
333         WS_HILOGE("work_scheduler_min_repeat_time content is empty");
334         return;
335     }
336     if (minRepeatTimeRoot.isMember("default") && minRepeatTimeRoot["default"].isInt()) {
337         minTimeCycle_ = static_cast<uint32_t>(minRepeatTimeRoot["default"].asInt());
338     }
339     if (!minRepeatTimeRoot.isMember("special")) {
340         WS_HILOGE("no special key");
341         return;
342     }
343     Json::Value specialRoot = minRepeatTimeRoot["special"];
344     if (specialRoot.empty() || !specialRoot.isArray()) {
345         WS_HILOGE("special content is empty");
346         return;
347     }
348     minCheckTime_ = workQueueManager_->GetTimeCycle();
349     for (const auto &it : specialRoot) {
350         if (!it.isMember("bundleName") || !it["bundleName"].isString() ||
351             !it.isMember("time") || !it["time"].isInt()) {
352             WS_HILOGE("special content is error");
353             continue;
354         }
355         uint32_t time = static_cast<uint32_t>(it["time"].asInt());
356         if (time < SYS_APP_MIN_REPEAT_TIME) {
357             WS_HILOGE("bundleName: %{public}s set time: %{public}d not available, must more than %{public}d",
358                 it["bundleName"].asString().c_str(), time, SYS_APP_MIN_REPEAT_TIME);
359             continue;
360         }
361         if (minCheckTime_ > time) {
362             minCheckTime_ = time;
363         }
364         specialMap_.emplace(it["bundleName"].asString(), time);
365     }
366 }
367 
ReadPreinstalledWorks()368 list<shared_ptr<WorkInfo>> WorkSchedulerService::ReadPreinstalledWorks()
369 {
370     list<shared_ptr<WorkInfo>> workInfos;
371     CfgFiles *files = GetCfgFiles(PREINSTALLED_FILE_PATH);
372     if (!files) {
373         WS_HILOGE("GetCfgFiles failed");
374         return workInfos;
375     }
376     // china->base
377     for (int i = MAX_CFG_POLICY_DIRS_CNT - 1; i >= 0; i--) {
378         LoadWorksFromFile(files->paths[i], workInfos);
379         LoadExemptionBundlesFromFile(files->paths[i]);
380         LoadMinRepeatTimeFromFile(files->paths[i]);
381     }
382     FreeCfgFiles(files);
383     return workInfos;
384 }
385 
GetJsonFromFile(const char * filePath,Json::Value & root)386 bool WorkSchedulerService::GetJsonFromFile(const char *filePath, Json::Value &root)
387 {
388     ifstream fin;
389     std::string realPath;
390     if (!WorkSchedUtils::ConvertFullPath(filePath, realPath)) {
391         WS_HILOGE("Get real path failed %{private}s", filePath);
392         return false;
393     }
394     WS_HILOGD("Read from %{private}s", realPath.c_str());
395     fin.open(realPath, ios::in);
396     WS_HILOGI("file open success");
397     if (!fin.is_open()) {
398         WS_HILOGE("cannot open file %{private}s", realPath.c_str());
399         return false;
400     }
401     char buffer[MAX_BUFFER];
402     ostringstream os;
403     while (fin.getline(buffer, MAX_BUFFER)) {
404         os << buffer;
405     }
406     string data = os.str();
407     WS_HILOGI("data read success");
408     JSONCPP_STRING errs;
409     Json::CharReaderBuilder readerBuilder;
410     const unique_ptr<Json::CharReader> jsonReader(readerBuilder.newCharReader());
411     bool res = jsonReader->parse(data.c_str(), data.c_str() + data.length(), &root, &errs);
412     fin.close();
413     if (!res || !errs.empty()) {
414         WS_HILOGE("parse %{private}s json error", realPath.c_str());
415         return false;
416     }
417     WS_HILOGI("json parse success");
418     return true;
419 }
420 
OnStop()421 void WorkSchedulerService::OnStop()
422 {
423     WS_HILOGI("stop service.");
424     std::lock_guard<ffrt::mutex> observerLock(observerMutex_);
425 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
426     DeviceUsageStats::BundleActiveClient::GetInstance().UnRegisterAppGroupCallBack(groupObserver_);
427     groupObserver_ = nullptr;
428     g_hasGroupObserver = -1;
429 #endif
430 #ifdef DEVICE_STANDBY_ENABLE
431     DevStandbyMgr::StandbyServiceClient::GetInstance().UnsubscribeStandbyCallback(standbyStateObserver_);
432     standbyStateObserver_ = nullptr;
433 #endif
434 #ifdef RESOURCESCHEDULE_BGTASKMGR_ENABLE
435     ErrCode ret = BackgroundTaskMgr::BackgroundTaskMgrHelper::UnsubscribeBackgroundTask(*subscriber_);
436     if (ret != ERR_OK) {
437         WS_HILOGE("unscribe bgtask failed.");
438     }
439 #endif
440     eventRunner_.reset();
441     handler_.reset();
442     ready_ = false;
443 }
444 
Init(const std::shared_ptr<AppExecFwk::EventRunner> & runner)445 bool WorkSchedulerService::Init(const std::shared_ptr<AppExecFwk::EventRunner>& runner)
446 {
447     if (!IsBaseAbilityReady()) {
448         WS_HILOGE("request system service is not ready yet!");
449         GetHandler()->SendEvent(InnerEvent::Get(WorkEventHandler::SERVICE_INIT_MSG, 0), INIT_DELAY);
450         return false;
451     }
452     WorkQueueManagerInit(runner);
453     if (!WorkPolicyManagerInit(runner)) {
454         WS_HILOGE("init failed due to work policy manager init.");
455         return false;
456     }
457     InitWorkInner();
458     if (!Publish(wss)) {
459         WS_HILOGE("OnStart register to system ability manager failed!");
460         return false;
461     }
462     checkBundle_ = true;
463     ready_ = true;
464     WS_HILOGI("start init background task subscriber!");
465     if (!InitBgTaskSubscriber()) {
466         WS_HILOGE("subscribe background task failed!");
467         return false;
468     }
469     WS_HILOGI("init success.");
470     return true;
471 }
472 
InitBgTaskSubscriber()473 bool WorkSchedulerService::InitBgTaskSubscriber()
474 {
475 #ifdef RESOURCESCHEDULE_BGTASKMGR_ENABLE
476     subscriber_ = make_shared<SchedulerBgTaskSubscriber>();
477     ErrCode ret = BackgroundTaskMgr::BackgroundTaskMgrHelper::SubscribeBackgroundTask(*subscriber_);
478     if (ret != ERR_OK) {
479         WS_HILOGE("SubscribeBackgroundTask failed.");
480         return false;
481     }
482     this->QueryResAppliedUid();
483     WS_HILOGD("subscribe background TASK success!");
484 #endif
485     return true;
486 }
487 
QueryResAppliedUid()488 ErrCode WorkSchedulerService::QueryResAppliedUid()
489 {
490 #ifdef RESOURCESCHEDULE_BGTASKMGR_ENABLE
491     std::vector<std::shared_ptr<BackgroundTaskMgr::ResourceCallbackInfo>> appList;
492     std::vector<std::shared_ptr<BackgroundTaskMgr::ResourceCallbackInfo>> procList;
493     ErrCode result = BackgroundTaskMgr::BackgroundTaskMgrHelper::GetEfficiencyResourcesInfos(appList, procList);
494     if (result != ERR_OK) {
495         WS_HILOGE("failed to GetEfficiencyResourcesInfos, errcode: %{public}d", result);
496         return result;
497     }
498     std::lock_guard<ffrt::mutex> lock(whitelistMutex_);
499     for (const auto& info : appList) {
500         if ((info->GetResourceNumber() & BackgroundTaskMgr::ResourceType::WORK_SCHEDULER) != 0) {
501             whitelist_.emplace(info->GetUid());
502         }
503     }
504     for (const auto& info : procList) {
505         if ((info->GetResourceNumber() & BackgroundTaskMgr::ResourceType::WORK_SCHEDULER) != 0) {
506             whitelist_.emplace(info->GetUid());
507         }
508     }
509     WS_HILOGI("get efficiency resources infos succeed.");
510 #endif
511     return ERR_OK;
512 }
513 
WorkQueueManagerInit(const std::shared_ptr<AppExecFwk::EventRunner> & runner)514 void WorkSchedulerService::WorkQueueManagerInit(const std::shared_ptr<AppExecFwk::EventRunner>& runner)
515 {
516     WS_HILOGD("come in");
517     if (workQueueManager_ == nullptr) {
518         workQueueManager_ = make_shared<WorkQueueManager>(instance);
519     }
520 
521     auto networkListener = make_shared<NetworkListener>(workQueueManager_);
522 #ifdef POWERMGR_BATTERY_MANAGER_ENABLE
523     auto chargerListener = make_shared<ChargerListener>(workQueueManager_);
524     auto batteryStatusListener = make_shared<BatteryStatusListener>(workQueueManager_);
525     auto batteryLevelListener = make_shared<BatteryLevelListener>(workQueueManager_, shared_from_this());
526     batteryLevelListener->Start();
527 #endif // POWERMGR_BATTERY_MANAGER_ENABLE
528     auto storageListener = make_shared<StorageListener>(workQueueManager_);
529     auto timerListener = make_shared<TimerListener>(workQueueManager_, runner);
530     auto groupListener = make_shared<GroupListener>(workQueueManager_, runner);
531     auto screenListener = make_shared<ScreenListener>(workQueueManager_, shared_from_this());
532 
533     workQueueManager_->AddListener(WorkCondition::Type::NETWORK, networkListener);
534 #ifdef POWERMGR_BATTERY_MANAGER_ENABLE
535     workQueueManager_->AddListener(WorkCondition::Type::CHARGER, chargerListener);
536     workQueueManager_->AddListener(WorkCondition::Type::BATTERY_STATUS, batteryStatusListener);
537     workQueueManager_->AddListener(WorkCondition::Type::BATTERY_LEVEL, batteryLevelListener);
538 #endif // POWERMGR_BATTERY_MANAGER_ENABLE
539     workQueueManager_->AddListener(WorkCondition::Type::STORAGE, storageListener);
540     workQueueManager_->AddListener(WorkCondition::Type::TIMER, timerListener);
541     workQueueManager_->AddListener(WorkCondition::Type::GROUP, groupListener);
542     workQueueManager_->AddListener(WorkCondition::Type::DEEP_IDLE, screenListener);
543 
544 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
545     GroupObserverInit();
546 #endif
547     RegisterStandbyStateObserver();
548 }
549 
WorkPolicyManagerInit(const std::shared_ptr<AppExecFwk::EventRunner> & runner)550 bool WorkSchedulerService::WorkPolicyManagerInit(const std::shared_ptr<AppExecFwk::EventRunner>& runner)
551 {
552     WS_HILOGD("come in");
553     if (workPolicyManager_ == nullptr) {
554         workPolicyManager_ = make_shared<WorkPolicyManager>(instance);
555     }
556     if (!workPolicyManager_->Init(runner)) {
557         WS_HILOGE("work policy manager init failed!");
558         return false;
559     }
560 
561 #ifdef POWERMGR_THERMAL_MANAGER_ENABLE
562     auto thermalFilter = make_shared<ThermalPolicy>(workPolicyManager_);
563     workPolicyManager_->AddPolicyFilter(thermalFilter);
564 #endif // POWERMGR_THERMAL_MANAGER_ENABLE
565     auto memoryFilter = make_shared<MemoryPolicy>(workPolicyManager_);
566     workPolicyManager_->AddPolicyFilter(memoryFilter);
567 
568     auto cpuFilter = make_shared<CpuPolicy>(workPolicyManager_);
569     workPolicyManager_->AddPolicyFilter(cpuFilter);
570 
571 #ifdef POWERMGR_POWER_MANAGER_ENABLE
572     auto powerModeFilter = make_shared<PowerModePolicy>(workPolicyManager_);
573     workPolicyManager_->AddPolicyFilter(powerModeFilter);
574 #endif
575 
576     auto appDataClearListener = make_shared<AppDataClearListener>(workPolicyManager_);
577     workPolicyManager_->AddAppDataClearListener(appDataClearListener);
578 
579     WS_HILOGI("work policy manager init success.");
580     return true;
581 }
582 
GetUidByBundleName(const string & bundleName,int32_t & uid)583 WEAK_FUNC bool WorkSchedulerService::GetUidByBundleName(const string &bundleName, int32_t &uid)
584 {
585     sptr<ISystemAbilityManager> systemAbilityManager =
586         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
587     if (!systemAbilityManager) {
588         WS_HILOGE("fail to get system ability mgr.");
589         return false;
590     }
591     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
592     if (!remoteObject) {
593         WS_HILOGE("fail to get bundle manager proxy.");
594         return false;
595     }
596     sptr<IBundleMgr> bundleMgr =  iface_cast<IBundleMgr>(remoteObject);
597     BundleInfo bundleInfo;
598     int32_t currentAccountId = WorkSchedUtils::GetCurrentAccountId();
599     if (bundleMgr->GetBundleInfo(bundleName, BundleFlag::GET_BUNDLE_WITH_ABILITIES,
600         bundleInfo, currentAccountId)) {
601         WS_HILOGD("currentAccountId : %{public}d, bundleName : %{public}s, uid = %{public}d",
602             currentAccountId, bundleName.c_str(), bundleInfo.uid);
603         uid = bundleInfo.uid;
604         return true;
605     }
606     WS_HILOGE("Get bundle info %{public}s failed.", bundleName.c_str());
607     return false;
608 }
609 
GetAppIndexAndBundleNameByUid(int32_t uid,int32_t & appIndex,std::string & bundleName)610 bool WorkSchedulerService::GetAppIndexAndBundleNameByUid(int32_t uid, int32_t &appIndex, std::string &bundleName)
611 {
612     sptr<ISystemAbilityManager> systemAbilityManager =
613         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
614     if (!systemAbilityManager) {
615         WS_HILOGE("fail to get system ability mgr.");
616         return false;
617     }
618     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
619     if (!remoteObject) {
620         WS_HILOGE("fail to get bundle manager proxy.");
621         return false;
622     }
623     sptr<IBundleMgr> bundleMgr =  iface_cast<IBundleMgr>(remoteObject);
624     ErrCode ret = bundleMgr->GetNameAndIndexForUid(uid, bundleName, appIndex);
625     if (ret == ERR_OK) {
626         WS_HILOGD("appIndex = %{public}d", appIndex);
627         return true;
628     }
629     WS_HILOGE("fail to get app index.");
630     return false;
631 }
632 
CheckExtensionInfos(WorkInfo & workInfo,int32_t uid)633 bool WorkSchedulerService::CheckExtensionInfos(WorkInfo &workInfo, int32_t uid)
634 {
635     sptr<ISystemAbilityManager> systemAbilityManager =
636         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
637     if (!systemAbilityManager) {
638         WS_HILOGE("fail to get system ability mgr.");
639         return false;
640     }
641     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
642     if (!remoteObject) {
643         WS_HILOGE("fail to get bundle manager proxy.");
644         return false;
645     }
646     sptr<IBundleMgr> bundleMgr =  iface_cast<IBundleMgr>(remoteObject);
647     BundleInfo bundleInfo;
648     if (bundleMgr->GetBundleInfo(workInfo.GetBundleName(),
649         BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO,
650         bundleInfo, uid / UID_TRANSFORM_DIVISOR)) {
651         auto findIter = std::find_if(bundleInfo.extensionInfos.begin(), bundleInfo.extensionInfos.end(),
652             [&](const auto &info) {
653                 WS_HILOGD("%{public}s %{public}s %{public}d", info.bundleName.c_str(), info.name.c_str(), info.type);
654                 return info.bundleName == workInfo.GetBundleName() &&
655                     info.name == workInfo.GetAbilityName() &&
656                     info.type == ExtensionAbilityType::WORK_SCHEDULER;
657             });
658         if (findIter == bundleInfo.extensionInfos.end()) {
659             workInfo.RefreshExtension(false);
660             WS_HILOGE("extension info is error");
661             return false;
662         }
663     }
664     return true;
665 }
666 
CheckWorkInfo(WorkInfo & workInfo,int32_t & uid)667 bool WorkSchedulerService::CheckWorkInfo(WorkInfo &workInfo, int32_t &uid)
668 {
669     int32_t appIndex;
670     string bundleName;
671     if (GetAppIndexAndBundleNameByUid(uid, appIndex, bundleName)) {
672         workInfo.RefreshAppIndex(appIndex);
673         if (workInfo.GetBundleName() == bundleName) {
674             CheckExtensionInfos(workInfo, uid);
675             return true;
676         }
677     }
678     WS_HILOGE("bundleName %{public}s is invalid", workInfo.GetBundleName().c_str());
679     return false;
680 }
681 
CheckCondition(WorkInfo & workInfo)682 bool WorkSchedulerService::CheckCondition(WorkInfo& workInfo)
683 {
684     if (workInfo.GetConditionMap()->size() < 1) {
685         return false;
686     }
687     if (workInfo.GetConditionMap()->count(WorkCondition::Type::TIMER) > 0) {
688         uint32_t time = workInfo.GetConditionMap()->at(WorkCondition::Type::TIMER)->uintVal;
689         string bundleName = workInfo.GetBundleName();
690         std::lock_guard<ffrt::mutex> lock(specialMutex_);
691         if (specialMap_.count(bundleName) > 0) {
692             if (time < specialMap_.at(bundleName)) {
693                 WS_HILOGE("fail, set time:%{public}u must more than %{public}u", time, specialMap_.at(bundleName));
694                 return false;
695             }
696             return true;
697         }
698         if (time < minTimeCycle_) {
699             WS_HILOGE("fail, set time:%{public}u must more than %{public}u", time, minTimeCycle_);
700             return false;
701         }
702     }
703     return true;
704 }
705 
StartWork(const WorkInfo & workInfo)706 int32_t WorkSchedulerService::StartWork(const WorkInfo& workInfo)
707 {
708     HitraceScoped traceScoped(HITRACE_TAG_OHOS, "WorkSchedulerService::StartWork");
709     int32_t timerId = SetTimer();
710     int32_t ret = StartWorkInner(workInfo);
711     CancelTimer(timerId);
712     return ret;
713 }
714 
StartWorkInner(const WorkInfo & workInfo)715 int32_t WorkSchedulerService::StartWorkInner(const WorkInfo& workInfo)
716 {
717     WorkInfo workInfo_ = workInfo;
718     if (!ready_) {
719         WS_HILOGE("service is not ready.");
720         return E_SERVICE_NOT_READY;
721     }
722     int32_t uid = IPCSkeleton::GetCallingUid();
723     if (checkBundle_ && !CheckWorkInfo(workInfo_, uid)) {
724         WS_HILOGE("check workInfo failed, bundleName inconsistency.");
725         return E_CHECK_WORKINFO_FAILED;
726     }
727     if (!CheckCondition(workInfo_)) {
728         return E_REPEAT_CYCLE_TIME_ERR;
729     }
730     time_t baseTime;
731     (void)time(&baseTime);
732     workInfo_.RequestBaseTime(baseTime);
733     WS_HILOGD("workInfo %{public}s/%{public}s ID: %{public}d, uid: %{public}d",
734         workInfo_.GetBundleName().c_str(), workInfo_.GetAbilityName().c_str(), workInfo_.GetWorkId(), uid);
735     shared_ptr<WorkStatus> workStatus = make_shared<WorkStatus>(workInfo_, uid);
736     int32_t ret = workPolicyManager_->AddWork(workStatus, uid);
737     if (ret == ERR_OK) {
738         workQueueManager_->AddWork(workStatus);
739         if (workInfo_.IsPersisted()) {
740             std::lock_guard<ffrt::mutex> lock(mutex_);
741             workStatus->workInfo_->RefreshUid(uid);
742             persistedMap_.emplace(workStatus->workId_, workStatus->workInfo_);
743             RefreshPersistedWorks();
744         }
745         GetHandler()->RemoveEvent(WorkEventHandler::CHECK_CONDITION_MSG);
746         GetHandler()->SendEvent(InnerEvent::Get(WorkEventHandler::CHECK_CONDITION_MSG, 0),
747             CHECK_CONDITION_DELAY);
748     }
749     return ret;
750 }
751 
AddWorkInner(WorkInfo & workInfo)752 void WorkSchedulerService::AddWorkInner(WorkInfo& workInfo)
753 {
754     WS_HILOGD("come in");
755     if (workInfo.GetUid() > 0) {
756         shared_ptr<WorkStatus> workStatus = make_shared<WorkStatus>(workInfo, workInfo.GetUid());
757         if (workPolicyManager_->AddWork(workStatus, workInfo.GetUid()) == ERR_OK) {
758             workQueueManager_->AddWork(workStatus);
759         }
760     } else {
761         WS_HILOGE("uid is invalid : %{public}d", workInfo.GetUid());
762     }
763 }
764 
StopWork(const WorkInfo & workInfo)765 int32_t WorkSchedulerService::StopWork(const WorkInfo& workInfo)
766 {
767     HitraceScoped traceScoped(HITRACE_TAG_OHOS, "WorkSchedulerService::StopWork");
768     WorkInfo workInfo_ = workInfo;
769     if (!ready_) {
770         WS_HILOGE("service is not ready.");
771         return E_SERVICE_NOT_READY;
772     }
773     int32_t uid = IPCSkeleton::GetCallingUid();
774     if (checkBundle_ && !CheckWorkInfo(workInfo_, uid)) {
775         WS_HILOGE("check workInfo failed, bundleName inconsistency.");
776         return E_CHECK_WORKINFO_FAILED;
777     }
778     shared_ptr<WorkStatus> workStatus = workPolicyManager_->FindWorkStatus(workInfo_, uid);
779     if (workStatus == nullptr) {
780         WS_HILOGE("workStatus is nullptr");
781         return E_WORK_NOT_EXIST_FAILED;
782     }
783     StopWorkInner(workStatus, uid, false, false);
784     return ERR_OK;
785 }
786 
StopAndCancelWork(const WorkInfo & workInfo)787 int32_t WorkSchedulerService::StopAndCancelWork(const WorkInfo& workInfo)
788 {
789     if (!ready_) {
790         WS_HILOGE("service is not ready.");
791         return E_SERVICE_NOT_READY;
792     }
793     WorkInfo workInfo_ = workInfo;
794     int32_t uid = IPCSkeleton::GetCallingUid();
795     if (checkBundle_ && !CheckWorkInfo(workInfo_, uid)) {
796         WS_HILOGE("check workInfo failed, bundleName inconsistency.");
797         return E_CHECK_WORKINFO_FAILED;
798     }
799     shared_ptr<WorkStatus> workStatus = workPolicyManager_->FindWorkStatus(workInfo_, uid);
800     if (workStatus == nullptr) {
801         WS_HILOGE("workStatus is nullptr");
802         return E_WORK_NOT_EXIST_FAILED;
803     }
804     StopWorkInner(workStatus, uid, true, false);
805     if (workStatus->persisted_) {
806         std::lock_guard<ffrt::mutex> lock(mutex_);
807         persistedMap_.erase(workStatus->workId_);
808         RefreshPersistedWorks();
809     }
810     return ERR_OK;
811 }
812 
StopWorkInner(std::shared_ptr<WorkStatus> workStatus,int32_t uid,const bool needCancel,bool isTimeOut)813 bool WorkSchedulerService::StopWorkInner(std::shared_ptr<WorkStatus> workStatus, int32_t uid,
814     const bool needCancel, bool isTimeOut)
815 {
816     if (workPolicyManager_->StopWork(workStatus, uid, needCancel, isTimeOut)) {
817         workQueueManager_->CancelWork(workStatus);
818     }
819     if (!isTimeOut) {
820         workPolicyManager_->RemoveWatchDog(workStatus);
821     }
822     return true;
823 }
824 
WatchdogTimeOut(std::shared_ptr<WorkStatus> workStatus)825 void WorkSchedulerService::WatchdogTimeOut(std::shared_ptr<WorkStatus> workStatus)
826 {
827     StopWorkInner(workStatus, workStatus->uid_, false, true);
828 }
829 
StopAndClearWorks()830 int32_t WorkSchedulerService::StopAndClearWorks()
831 {
832     HitraceScoped traceScoped(HITRACE_TAG_OHOS, "WorkSchedulerService::StopAndClearWorks");
833     if (!ready_) {
834         WS_HILOGE("service is not ready.");
835         return E_SERVICE_NOT_READY;
836     }
837     StopAndClearWorksByUid(IPCSkeleton::GetCallingUid());
838     return ERR_OK;
839 }
840 
StopAndClearWorksByUid(int32_t uid)841 bool WorkSchedulerService::StopAndClearWorksByUid(int32_t uid)
842 {
843     WS_HILOGD("Stop and clear works by Uid:%{public}d", uid);
844     list<std::shared_ptr<WorkStatus>> allWorks = workPolicyManager_->GetAllWorkStatus(uid);
845     list<std::string> workIdList;
846     std::transform(allWorks.cbegin(), allWorks.cend(), std::back_inserter(workIdList),
847         [](std::shared_ptr<WorkStatus> work) { return work->workId_; });
848     bool ret = workQueueManager_->StopAndClearWorks(allWorks)
849         && workPolicyManager_->StopAndClearWorks(uid);
850     if (ret) {
851         std::lock_guard<ffrt::mutex> lock(mutex_);
852         for (auto workId : workIdList) {
853             if (persistedMap_.count(workId) != 0) {
854                 persistedMap_.erase(workId);
855             }
856         }
857         RefreshPersistedWorks();
858     }
859     return ret;
860 }
861 
IsLastWorkTimeout(int32_t workId,bool & result)862 int32_t WorkSchedulerService::IsLastWorkTimeout(int32_t workId, bool &result)
863 {
864     HitraceScoped traceScoped(HITRACE_TAG_OHOS, "WorkSchedulerService::IsLastWorkTimeout");
865     if (!ready_) {
866         WS_HILOGE("service is not ready.");
867         return E_SERVICE_NOT_READY;
868     }
869     int32_t uid = IPCSkeleton::GetCallingUid();
870     return workPolicyManager_->IsLastWorkTimeout(workId, uid, result);
871 }
872 
OnConditionReady(shared_ptr<vector<shared_ptr<WorkStatus>>> workStatusVector)873 void WorkSchedulerService::OnConditionReady(shared_ptr<vector<shared_ptr<WorkStatus>>> workStatusVector)
874 {
875     workPolicyManager_->OnConditionReady(workStatusVector);
876 }
877 
ObtainAllWorks(std::vector<WorkInfo> & workInfos)878 int32_t WorkSchedulerService::ObtainAllWorks(std::vector<WorkInfo>& workInfos)
879 {
880     HitraceScoped traceScoped(HITRACE_TAG_OHOS, "WorkSchedulerService::ObtainAllWorks");
881     int32_t uid = IPCSkeleton::GetCallingUid();
882     if (!ready_) {
883         WS_HILOGE("service is not ready.");
884         return E_SERVICE_NOT_READY;
885     }
886     workInfos = workPolicyManager_->ObtainAllWorks(uid);
887     return ERR_OK;
888 }
889 
GetWorkStatus(int32_t workId,WorkInfo & workInfo)890 int32_t WorkSchedulerService::GetWorkStatus(int32_t workId, WorkInfo& workInfo)
891 {
892     HitraceScoped traceScoped(HITRACE_TAG_OHOS, "WorkSchedulerService::GetWorkStatus");
893     int32_t uid = IPCSkeleton::GetCallingUid();
894     if (!ready_) {
895         WS_HILOGE("service is not ready.");
896         return E_SERVICE_NOT_READY;
897     }
898     std::shared_ptr<WorkInfo> workInfoPtr = workPolicyManager_->GetWorkStatus(uid, workId);
899     if (workInfoPtr != nullptr) {
900         workInfo = *workInfoPtr;
901         return ERR_OK;
902     }
903     return E_WORK_NOT_EXIST_FAILED;
904 }
905 
GetAllRunningWorks(std::vector<WorkInfo> & workInfos)906 int32_t WorkSchedulerService::GetAllRunningWorks(std::vector<WorkInfo>& workInfos)
907 {
908     if (!ready_) {
909         WS_HILOGE("service is not ready.");
910         return E_SERVICE_NOT_READY;
911     }
912     if (!CheckProcessName()) {
913         return E_INVALID_PROCESS_NAME;
914     }
915     workInfos = workPolicyManager_->GetAllRunningWorks();
916     return ERR_OK;
917 }
918 
UpdateWorkBeforeRealStart(std::shared_ptr<WorkStatus> work)919 void WorkSchedulerService::UpdateWorkBeforeRealStart(std::shared_ptr<WorkStatus> work)
920 {
921     if (work == nullptr) {
922         return;
923     }
924     work->UpdateTimerIfNeed();
925     if (work->NeedRemove()) {
926         workQueueManager_->RemoveWork(work);
927         if (work->persisted_ && !work->IsRepeating()) {
928             std::lock_guard<ffrt::mutex> lock(mutex_);
929             persistedMap_.erase(work->workId_);
930             RefreshPersistedWorks();
931         }
932     }
933 }
934 
AllowDump()935 bool WorkSchedulerService::AllowDump()
936 {
937     Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetFirstTokenID();
938     int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.DUMP");
939     if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
940         WS_HILOGE("CheckPermission failed");
941         return false;
942     }
943     return true;
944 }
945 
DumpProcessForEngMode(std::vector<std::string> & argsInStr,std::string & result)946 void WorkSchedulerService::DumpProcessForEngMode(std::vector<std::string> &argsInStr, std::string &result)
947 {
948     switch (argsInStr.size()) {
949         case 0:
950             // hidumper -s said '-h'
951             DumpUsage(result);
952             break;
953         case DUMP_OPTION + 1:
954             // hidumper -s said '-h' or hidumper -s said '-a'
955             if (argsInStr[DUMP_OPTION] == "-h") {
956                 DumpUsage(result);
957             } else if (argsInStr[DUMP_OPTION] == "-a") {
958                 DumpAllInfo(result);
959             } else {
960                 result.append("Error params.");
961             }
962             break;
963         case DUMP_PARAM_INDEX + 1:
964             if (argsInStr[DUMP_OPTION] == "-k") {
965                 string key = argsInStr[DUMP_PARAM_INDEX];
966                 string value;
967                 WorkDatashareHelper::GetInstance().GetStringValue(key, value);
968                 result.append("key: " + key + ", value: " + value);
969                 break;
970             }
971             DumpParamSet(argsInStr[DUMP_OPTION], argsInStr[DUMP_PARAM_INDEX], result);
972             break;
973         case DUMP_VALUE_INDEX + 1:
974             if (argsInStr[DUMP_OPTION] == "-d") {
975                 EventPublisher eventPublisher;
976                 eventPublisher.Dump(result, argsInStr[DUMP_PARAM_INDEX], argsInStr[DUMP_VALUE_INDEX]);
977             } else if (argsInStr[DUMP_OPTION] == "-t") {
978                 DumpProcessWorks(argsInStr[DUMP_PARAM_INDEX], argsInStr[DUMP_VALUE_INDEX], result);
979             } else if (argsInStr[DUMP_OPTION] == "-x") {
980                 DumpRunningWorks(argsInStr[DUMP_PARAM_INDEX], argsInStr[DUMP_VALUE_INDEX], result);
981             } else if (argsInStr[DUMP_OPTION] == "-s") {
982                 DumpLoadSaWorks(argsInStr[DUMP_PARAM_INDEX], argsInStr[DUMP_VALUE_INDEX], result);
983             } else {
984                 result.append("Error params.");
985             }
986             break;
987         default:
988             result.append("Error params.");
989     }
990 }
991 
Dump(int32_t fd,const std::vector<std::u16string> & args)992 int32_t WorkSchedulerService::Dump(int32_t fd, const std::vector<std::u16string>& args)
993 {
994     if (!AllowDump()) {
995         return ERR_OK;
996     }
997     std::string result;
998     if (!ready_) {
999         WS_HILOGE("service is not ready.");
1000         result.append("service is not ready.");
1001         if (!SaveStringToFd(fd, result)) {
1002             WS_HILOGE("save to fd failed.");
1003         }
1004         return ERR_OK;
1005     }
1006 
1007     std::vector<std::string> argsInStr;
1008     std::transform(args.begin(), args.end(), std::back_inserter(argsInStr),
1009         [](const std::u16string &arg) {
1010         return Str16ToStr8(arg);
1011     });
1012     bool secureMode = OHOS::system::GetBoolParameter("const.security.developermode.state", false);
1013     bool debugable = OHOS::system::GetIntParameter("const.debuggable", 0) == 1;
1014     if (secureMode && !debugable) {
1015         WS_HILOGD("User mode.");
1016         DumpProcessForUserMode(argsInStr, result);
1017     } else if (debugable) {
1018         WS_HILOGD("Eng mode.");
1019         DumpProcessForEngMode(argsInStr, result);
1020     }
1021     if (!SaveStringToFd(fd, result)) {
1022         WS_HILOGE("save to fd failed.");
1023     }
1024     return ERR_OK;
1025 }
1026 
DumpProcessForUserMode(std::vector<std::string> & argsInStr,std::string & result)1027 void WorkSchedulerService::DumpProcessForUserMode(std::vector<std::string> &argsInStr, std::string &result)
1028 {
1029     if (argsInStr.size() == (DUMP_VALUE_INDEX + 1) && argsInStr[DUMP_OPTION] == "-t") {
1030         DumpProcessWorks(argsInStr[DUMP_PARAM_INDEX], argsInStr[DUMP_VALUE_INDEX], result);
1031     } else if (argsInStr.size() == (DUMP_VALUE_INDEX + 1) && argsInStr[DUMP_OPTION] == "-s") {
1032         DumpLoadSaWorks(argsInStr[DUMP_PARAM_INDEX], argsInStr[DUMP_VALUE_INDEX], result);
1033     }
1034 }
1035 
DumpUsage(std::string & result)1036 void WorkSchedulerService::DumpUsage(std::string &result)
1037 {
1038     result.append("usage: workscheduler dump [<options>]\n")
1039         .append("    -h: show the help.\n")
1040         .append("    -a: show all info.\n")
1041         .append("    -d event info: show the event info.\n")
1042         .append("    -d (eventType) (TypeValue): publish the event.\n")
1043         .append("    -t (bundleName) (abilityName): trigger the work.\n")
1044         .append("    -x (uid) (option): pause or resume the work.\n")
1045         .append("    -memory (number): set the available memory.\n")
1046         .append("    -watchdog_time (number): set watch dog time, default 120000.\n")
1047         .append("    -repeat_time_min (number): set min repeat cycle time, default 1200000.\n")
1048         .append("    -min_interval (number): set min interval time, set 0 means close test mode.\n")
1049         .append("    -cpu (number): set the usage cpu.\n")
1050         .append("    -count (number): set the max running task count.\n")
1051         .append("    -s (number) (number): load or report sa.\n");
1052 }
1053 
DumpAllInfo(std::string & result)1054 void WorkSchedulerService::DumpAllInfo(std::string &result)
1055 {
1056     result.append("================Work Queue Infos================\n");
1057     if (workQueueManager_ != nullptr) {
1058         workQueueManager_->Dump(result);
1059     }
1060     result.append("================Work Policy Infos================\n");
1061     if (workPolicyManager_ != nullptr) {
1062         workPolicyManager_->Dump(result);
1063     }
1064     result.append("================Other Infos================\n");
1065     result.append("Need check bundle:" + std::to_string(checkBundle_) + "\n")
1066         .append("Dump set memory:" + std::to_string(workPolicyManager_->GetDumpSetMemory()) + "\n")
1067         .append("Repeat cycle time min:" + std::to_string(workQueueManager_->GetTimeCycle()) + "\n")
1068         .append("Watchdog time:" + std::to_string(workPolicyManager_->GetWatchdogTime()) + "\n")
1069         .append("Exemption bundle whitelist:" + DumpExemptionBundles() + "\n")
1070         .append("Efficiency Resource whitelist:" + DumpEffiResApplyUid() + "\n");
1071 }
1072 
IsDebugApp(const std::string & bundleName)1073 bool WorkSchedulerService::IsDebugApp(const std::string &bundleName)
1074 {
1075     sptr<ISystemAbilityManager> systemAbilityManager =
1076         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1077     if (!systemAbilityManager) {
1078         WS_HILOGE("fail to get system ability mgr.");
1079         return false;
1080     }
1081     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
1082     if (!remoteObject) {
1083         WS_HILOGE("fail to get bundle manager proxy.");
1084         return false;
1085     }
1086     sptr<IBundleMgr> bundleMgr =  iface_cast<IBundleMgr>(remoteObject);
1087     BundleInfo bundleInfo;
1088     int32_t currentAccountId = WorkSchedUtils::GetCurrentAccountId();
1089     if (bundleMgr->GetBundleInfo(bundleName, BundleFlag::GET_BUNDLE_WITH_ABILITIES,
1090         bundleInfo, currentAccountId)) {
1091         WS_HILOGD("bundleUid : %{public}d , debug : %{public}d.", bundleInfo.uid, bundleInfo.applicationInfo.debug);
1092         return bundleInfo.applicationInfo.debug;
1093     }
1094     WS_HILOGE("Get bundle info failed.");
1095     return false;
1096 }
1097 
DumpProcessWorks(const std::string & bundleName,const std::string & abilityName,std::string & result)1098 void WorkSchedulerService::DumpProcessWorks(const std::string &bundleName, const std::string &abilityName,
1099     std::string &result)
1100 {
1101     if (bundleName.empty() || abilityName.empty()) {
1102         result.append("param error");
1103         return;
1104     }
1105     workPolicyManager_->DumpCheckIdeWorkToRun(bundleName, abilityName);
1106 }
1107 
DumpRunningWorks(const std::string & uidStr,const std::string & option,std::string & result)1108 void WorkSchedulerService::DumpRunningWorks(const std::string &uidStr, const std::string &option, std::string &result)
1109 {
1110     if (!std::all_of(uidStr.begin(), uidStr.end(), ::isdigit) || option.empty()) {
1111         result.append("param error");
1112         return;
1113     }
1114 
1115     int32_t uid = std::atoi(uidStr.c_str());
1116     if (uid == 0) {
1117         result.append("uidStr param error, uidStr:" + uidStr);
1118         return;
1119     }
1120     int32_t ret = ERR_OK;
1121     if (option == "p") {
1122         ret = workPolicyManager_->PauseRunningWorks(uid);
1123     } else if (option == "r") {
1124         ret = workPolicyManager_->ResumePausedWorks(uid);
1125     } else {
1126         result.append("param error");
1127     }
1128 
1129     if (ret != ERR_OK) {
1130         auto iter = paramErrCodeMsgMap.find(ret);
1131         if (iter != paramErrCodeMsgMap.end()) {
1132             result.append("BussinessError:" + iter->second);
1133         }
1134     }
1135 }
1136 
DumpEffiResApplyUid()1137 std::string WorkSchedulerService::DumpEffiResApplyUid()
1138 {
1139     std::lock_guard<ffrt::mutex> lock(whitelistMutex_);
1140     if (whitelist_.empty()) {
1141         return "[]";
1142     }
1143     std::string res {""};
1144     for (auto &it : whitelist_) {
1145         res.append(std::to_string(it) + " ");
1146     }
1147     WS_HILOGD("GetWhiteList  : %{public}s", res.c_str());
1148     return res;
1149 }
1150 
DumpExemptionBundles()1151 std::string WorkSchedulerService::DumpExemptionBundles()
1152 {
1153     if (exemptionBundles_.empty()) {
1154         return "[]";
1155     }
1156 
1157     std::string bundles {""};
1158     for (auto &bundle : exemptionBundles_) {
1159         bundles.append(bundle + " ");
1160     }
1161     return bundles;
1162 }
1163 
DumpParamSet(std::string & key,std::string & value,std::string & result)1164 void WorkSchedulerService::DumpParamSet(std::string &key, std::string &value, std::string &result)
1165 {
1166     if (!std::all_of(value.begin(), value.end(), ::isdigit)) {
1167         result.append("Error params.");
1168         return;
1169     }
1170     if (key == "-memory") {
1171         workPolicyManager_->SetMemoryByDump(std::stoi(value));
1172         result.append("Set memory success.");
1173     } else if (key == "-watchdog_time") {
1174         workPolicyManager_->SetWatchdogTimeByDump(std::stoi(value));
1175         result.append("Set watchdog time success.");
1176     } else if (key == "-repeat_time_min") {
1177         workQueueManager_->SetTimeCycle(std::stoi(value));
1178         result.append("Set repeat time min value success.");
1179     } else if (key == "-min_interval") {
1180         workQueueManager_->SetMinIntervalByDump(std::stoi(value));
1181         result.append("Set min interval value success.");
1182     } else if (key == "-cpu") {
1183         workPolicyManager_->SetCpuUsageByDump(std::stoi(value));
1184         result.append("Set cpu success.");
1185     } else if (key == "-nap") {
1186 #ifdef DEVICE_STANDBY_ENABLE
1187         standbyStateObserver_->OnDeviceIdleMode(std::stoi(value), 0);
1188 #endif
1189     } else if (key == "-count") {
1190         workPolicyManager_->SetMaxRunningCountByDump(std::stoi(value));
1191         result.append("Set max running task count success.");
1192     } else {
1193         result.append("Error params.");
1194     }
1195 }
1196 
RefreshPersistedWorks()1197 void WorkSchedulerService::RefreshPersistedWorks()
1198 {
1199     Json::Value root;
1200     for (auto &it : persistedMap_) {
1201         auto workInfo = it.second;
1202         string data = workInfo->ParseToJsonStr();
1203         JSONCPP_STRING errs;
1204         Json::Value workJson;
1205         Json::CharReaderBuilder readerBuilder;
1206         const unique_ptr<Json::CharReader> jsonReader(readerBuilder.newCharReader());
1207         bool res = jsonReader->parse(data.c_str(), data.c_str() + data.length(), &workJson, &errs);
1208         if (res && errs.empty()) {
1209             root[it.first] = workJson;
1210         }
1211     }
1212     Json::StreamWriterBuilder writerBuilder;
1213     ostringstream os;
1214     unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
1215     jsonWriter->write(root, &os);
1216     string result = os.str();
1217     CreateNodeDir(PERSISTED_PATH);
1218     CreateNodeFile(PERSISTED_FILE_PATH);
1219     ofstream fout;
1220     std::string realPath;
1221     if (!WorkSchedUtils::ConvertFullPath(PERSISTED_FILE_PATH, realPath)) {
1222         WS_HILOGE("Get real path failed");
1223         return;
1224     }
1225     WS_HILOGD("Refresh path %{private}s", realPath.c_str());
1226     fout.open(realPath, ios::out);
1227     fout<<result.c_str()<<endl;
1228     fout.close();
1229     WS_HILOGD("Refresh persisted works success");
1230 }
1231 
CreateNodeDir(std::string dir)1232 int32_t WorkSchedulerService::CreateNodeDir(std::string dir)
1233 {
1234     WS_HILOGD("Enter");
1235     if (access(dir.c_str(), 0) != ERR_OK) {
1236         int32_t flag = mkdir(dir.c_str(), S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
1237         if (flag == ERR_OK) {
1238             WS_HILOGD("Create directory successfully.");
1239         } else {
1240             WS_HILOGE("Fail to create directory, flag: %{public}d", flag);
1241             return flag;
1242         }
1243     } else {
1244         WS_HILOGD("This directory already exists.");
1245     }
1246     return ERR_OK;
1247 }
1248 
CreateNodeFile(std::string filePath)1249 int32_t WorkSchedulerService::CreateNodeFile(std::string filePath)
1250 {
1251     if (access(filePath.c_str(), 0) != 0) {
1252         int32_t fd = open(filePath.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
1253         if (fd < ERR_OK) {
1254             WS_HILOGE("Open file fail.");
1255             return fd;
1256         } else {
1257             WS_HILOGI("Open file success.");
1258             close(fd);
1259         }
1260     } else {
1261         WS_HILOGD("The file already exists.");
1262     }
1263     return ERR_OK;
1264 }
1265 
UpdateEffiResApplyInfo(int32_t uid,bool isAdd)1266 void WorkSchedulerService::UpdateEffiResApplyInfo(int32_t uid, bool isAdd)
1267 {
1268     std::lock_guard<ffrt::mutex> lock(whitelistMutex_);
1269     if (isAdd) {
1270         whitelist_.emplace(uid);
1271     } else {
1272         whitelist_.erase(uid);
1273     }
1274 }
1275 
CheckEffiResApplyInfo(int32_t uid)1276 bool WorkSchedulerService::CheckEffiResApplyInfo(int32_t uid)
1277 {
1278     std::lock_guard<ffrt::mutex> lock(whitelistMutex_);
1279     return whitelist_.find(uid) != whitelist_.end();
1280 }
1281 
InitDeviceStandyWhitelist()1282 void WorkSchedulerService::InitDeviceStandyWhitelist()
1283 {
1284 #ifdef DEVICE_STANDBY_ENABLE
1285     std::vector<DevStandbyMgr::AllowInfo> allowInfoArray;
1286     auto res = DevStandbyMgr::StandbyServiceClient::GetInstance().GetAllowList(DevStandbyMgr::AllowType::WORK_SCHEDULER,
1287         allowInfoArray, DevStandbyMgr::ReasonCodeEnum::REASON_APP_API);
1288     if (res != ERR_OK) {
1289         WS_HILOGE("GetAllowList fail");
1290         return;
1291     }
1292     WS_HILOGI("allowInfoArray size is %{public}d", static_cast<int32_t>(allowInfoArray.size()));
1293     std::list<std::string> tempList = {};
1294     for (const auto& item : allowInfoArray) {
1295         WS_HILOGI("Allow bundleName %{public}s", item.GetName().c_str());
1296         tempList.push_back(item.GetName());
1297     }
1298     DelayedSingleton<DataManager>::GetInstance()->AddDeviceStandyWhitelist(tempList);
1299 #endif
1300 }
1301 
InitDeviceStandyRestrictlist()1302 void WorkSchedulerService::InitDeviceStandyRestrictlist()
1303 {
1304 #ifdef DEVICE_STANDBY_ENABLE
1305     std::vector<DevStandbyMgr::AllowInfo> allowInfoArray;
1306     auto res = DevStandbyMgr::StandbyServiceClient::GetInstance().GetRestrictList(
1307         DevStandbyMgr::AllowType::WORK_SCHEDULER, allowInfoArray, DevStandbyMgr::ReasonCodeEnum::REASON_APP_API);
1308     if (res != ERR_OK) {
1309         WS_HILOGE("GetRestrictlist fail");
1310         return;
1311     }
1312     WS_HILOGI("restrictInfoArray size is %{public}d", static_cast<int32_t>(allowInfoArray.size()));
1313     std::list<std::string> tempList = {};
1314     for (const auto& item : allowInfoArray) {
1315         WS_HILOGI("Restrict bundleName %{public}s", item.GetName().c_str());
1316         tempList.push_back(item.GetName());
1317     }
1318     DelayedSingleton<DataManager>::GetInstance()->AddDeviceStandyRestrictlist(tempList);
1319 #endif
1320 }
1321 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)1322 void WorkSchedulerService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
1323 {
1324     if (systemAbilityId == DEVICE_USAGE_STATISTICS_SYS_ABILITY_ID) {
1325 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
1326         GroupObserverInit();
1327 #endif
1328     }
1329     if (systemAbilityId == DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID) {
1330         InitDeviceStandyWhitelist();
1331         InitDeviceStandyRestrictlist();
1332         RegisterStandbyStateObserver();
1333     }
1334 }
1335 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)1336 void WorkSchedulerService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
1337 {
1338     if (systemAbilityId == DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID) {
1339         DelayedSingleton<DataManager>::GetInstance()->ClearDeviceStandyWhitelist();
1340         DelayedSingleton<DataManager>::GetInstance()->ClearDeviceStandyRestrictlist();
1341         if (!workQueueManager_) {
1342             return;
1343         }
1344         workQueueManager_->OnConditionChanged(WorkCondition::Type::STANDBY,
1345             std::make_shared<DetectorValue>(0, 0, false, std::string()));
1346 #ifdef  DEVICE_STANDBY_ENABLE
1347         std::lock_guard<ffrt::mutex> observerLock(observerMutex_);
1348         standbyStateObserver_ = nullptr;
1349 #endif
1350     } else if (systemAbilityId == DEVICE_USAGE_STATISTICS_SYS_ABILITY_ID) {
1351 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
1352         std::lock_guard<ffrt::mutex> observerLock(observerMutex_);
1353         groupObserver_ = nullptr;
1354         DelayedSingleton<DataManager>::GetInstance()->ClearAllGroup();
1355 #endif
1356     }
1357 }
1358 
1359 #ifdef DEVICE_USAGE_STATISTICS_ENABLE
GroupObserverInit()1360 __attribute__((no_sanitize("cfi"))) void WorkSchedulerService::GroupObserverInit()
1361 {
1362     if (!workQueueManager_) {
1363         return;
1364     }
1365     std::lock_guard<ffrt::mutex> observerLock(observerMutex_);
1366     if (!groupObserver_) {
1367         groupObserver_ = new (std::nothrow) WorkBundleGroupChangeCallback(workQueueManager_);
1368     }
1369     if (groupObserver_ && g_hasGroupObserver != ERR_OK) {
1370         g_hasGroupObserver =
1371             DeviceUsageStats::BundleActiveClient::GetInstance().RegisterAppGroupCallBack(groupObserver_);
1372     }
1373 }
1374 #endif
1375 
RegisterStandbyStateObserver()1376 void WorkSchedulerService::RegisterStandbyStateObserver()
1377 {
1378     if (!workQueueManager_) {
1379         return;
1380     }
1381 #ifdef  DEVICE_STANDBY_ENABLE
1382     std::lock_guard<ffrt::mutex> observerLock(observerMutex_);
1383     if (standbyStateObserver_) {
1384         WS_HILOGD("standbyStateObserver_ is already exist, do not need repeat process.");
1385         return;
1386     }
1387     standbyStateObserver_ = new (std::nothrow) WorkStandbyStateChangeCallback(workQueueManager_);
1388     if (!standbyStateObserver_) {
1389         return;
1390     }
1391     standbyStateObserver_->SetSubscriberName(STRATEGY_NAME);
1392     ErrCode ret = DevStandbyMgr::StandbyServiceClient::GetInstance().SubscribeStandbyCallback(standbyStateObserver_);
1393     if (ret != ERR_OK) {
1394         WS_HILOGE("Subscriber standbyStateObserver_ failed.");
1395         standbyStateObserver_ = nullptr;
1396     }
1397 #endif
1398 }
1399 
CheckProcessName()1400 bool WorkSchedulerService::CheckProcessName()
1401 {
1402     Security::AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
1403     Security::AccessToken::NativeTokenInfo callingTokenInfo;
1404     Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, callingTokenInfo);
1405     WS_HILOGD("process name: %{public}s called CheckProcessName.", callingTokenInfo.processName.c_str());
1406     if (WORK_SCHED_NATIVE_OPERATE_CALLER.find(callingTokenInfo.processName) == WORK_SCHED_NATIVE_OPERATE_CALLER.end()) {
1407         WS_HILOGE("check process name illegal access to this interface; process name: %{public}s.",
1408             callingTokenInfo.processName.c_str());
1409         return false;
1410     }
1411     return true;
1412 }
1413 
PauseRunningWorks(int32_t uid)1414 int32_t WorkSchedulerService::PauseRunningWorks(int32_t uid)
1415 {
1416     WS_HILOGD("pause Running Work Scheduler Work, uid:%{public}d", uid);
1417     if (!CheckProcessName()) {
1418         return E_INVALID_PROCESS_NAME;
1419     }
1420 
1421     int32_t ret = workPolicyManager_->PauseRunningWorks(uid);
1422     return ret;
1423 }
1424 
ResumePausedWorks(int32_t uid)1425 int32_t WorkSchedulerService::ResumePausedWorks(int32_t uid)
1426 {
1427     WS_HILOGD("resume Paused Work Scheduler Work, uid:%{public}d", uid);
1428     if (!CheckProcessName()) {
1429         return E_INVALID_PROCESS_NAME;
1430     }
1431 
1432     int32_t ret = workPolicyManager_->ResumePausedWorks(uid);
1433     return ret;
1434 }
1435 
TriggerWorkIfConditionReady()1436 void WorkSchedulerService::TriggerWorkIfConditionReady()
1437 {
1438     ConditionChecker checker(workQueueManager_);
1439     checker.CheckAllStatus();
1440 }
1441 
StopDeepIdleWorks()1442 int32_t WorkSchedulerService::StopDeepIdleWorks()
1443 {
1444     if (!ready_) {
1445         WS_HILOGE("service is not ready.");
1446         return E_SERVICE_NOT_READY;
1447     }
1448     std::list<std::shared_ptr<WorkStatus>> works =  workPolicyManager_->GetDeepIdleWorks();
1449     if (works.size() == 0) {
1450         WS_HILOGD("stop work by condition, no matched works");
1451         return ERR_OK;
1452     }
1453 
1454     for (shared_ptr<WorkStatus> workStatus : works) {
1455         WS_HILOGI("stop work by condition, bundleName:%{public}s, workId:%{public}s",
1456             workStatus->bundleName_.c_str(), workStatus->workId_.c_str());
1457         StopWorkInner(workStatus, workStatus->uid_, false, false);
1458         workPolicyManager_->RemoveWatchDog(workStatus);
1459     }
1460     return ERR_OK;
1461 }
1462 
SetWorkSchedulerConfig(const std::string & configData,int32_t sourceType)1463 int32_t WorkSchedulerService::SetWorkSchedulerConfig(const std::string &configData, int32_t sourceType)
1464 {
1465     if (!ready_) {
1466         WS_HILOGE("service is not ready");
1467         return E_SERVICE_NOT_READY;
1468     }
1469     if (!CheckProcessName()) {
1470         return E_INVALID_PROCESS_NAME;
1471     }
1472     WS_HILOGD("Set work scheduler configData: %{public}s, sourceType: %{public}d", configData.c_str(), sourceType);
1473     DelayedSingleton<WorkSchedulerConfig>::GetInstance()->InitActiveGroupWhitelist(configData);
1474     return ERR_OK;
1475 }
1476 
IsExemptionBundle(const std::string & checkBundleName)1477 bool WorkSchedulerService::IsExemptionBundle(const std::string& checkBundleName)
1478 {
1479     if (checkBundleName.empty()) {
1480         WS_HILOGE("check exemption bundle error, bundleName is empty");
1481         return false;
1482     }
1483     auto iter = std::find_if(exemptionBundles_.begin(), exemptionBundles_.end(),
1484     [&](const std::string &bundleName) {
1485         return checkBundleName == bundleName;
1486     });
1487     return iter != exemptionBundles_.end();
1488 }
1489 
LoadSa(std::shared_ptr<WorkStatus> workStatus,const std::string & action)1490 bool WorkSchedulerService::LoadSa(std::shared_ptr<WorkStatus> workStatus, const std::string& action)
1491 {
1492     if (!ready_) {
1493         WS_HILOGE("service is not ready.");
1494         return false;
1495     }
1496     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1497     if (samgr == nullptr) {
1498         WS_HILOGE("get SA manager failed.");
1499         return false;
1500     }
1501     int32_t saId = workStatus->workInfo_->GetSaId();
1502     bool isResidentSa = workStatus->workInfo_->IsResidentSa();
1503     sptr<IRemoteObject> object = samgr->CheckSystemAbility(saId);
1504     if (isResidentSa && object == nullptr) {
1505         WS_HILOGE("resident SA: %{public}d residentSA:%{public}d does not exist.", saId, isResidentSa);
1506         return false;
1507     } else if (!isResidentSa && object == nullptr) {
1508         object = samgr->LoadSystemAbility(saId, TIME_OUT);
1509         if (object == nullptr) {
1510             WS_HILOGE("load SA: %{public}d residentSA:%{public}d failed.", saId, isResidentSa);
1511             return false;
1512         }
1513         WS_HILOGI("load SA: %{public}d residentSA:%{public}d successed.", saId, isResidentSa);
1514     }
1515     std::unordered_map<std::string, std::string> payload;
1516     payload["action"] = action;
1517     payload["saId"] = std::to_string(saId);
1518     uint32_t type = ResourceSchedule::ResType::RES_TYPE_DEVICE_IDLE;
1519     ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
1520     WS_HILOGI("Report SA: %{public}d residentSA:%{public}d successed.", saId, isResidentSa);
1521     return true;
1522 }
1523 
DumpLoadSaWorks(const std::string & saIdStr,const std::string & uidStr,std::string & result)1524 void WorkSchedulerService::DumpLoadSaWorks(const std::string &saIdStr, const std::string &uidStr, std::string &result)
1525 {
1526     if (!std::all_of(saIdStr.begin(), saIdStr.end(), ::isdigit) ||
1527         !std::all_of(uidStr.begin(), uidStr.end(), ::isdigit)) {
1528         result.append("param error.");
1529         return;
1530     }
1531     int32_t saId = std::atoi(saIdStr.c_str());
1532     int32_t uid = std::atoi(uidStr.c_str());
1533     if (saId <= 0 || uid <= 0) {
1534         result.append("the parameter is invalid.");
1535         return;
1536     }
1537     auto sa = workPolicyManager_->FindSA(saId, uid);
1538     if (sa == nullptr) {
1539         result.append("the sa does not exist.");
1540         return;
1541     }
1542     if (LoadSa(sa, "hidumper")) {
1543         result.append("load sa success.");
1544         return;
1545     }
1546     result.append("load sa failed.");
1547 }
1548 
HandleDeepIdleMsg()1549 void WorkSchedulerService::HandleDeepIdleMsg()
1550 {
1551     if (!ready_) {
1552         WS_HILOGE("service is not ready.");
1553         return;
1554     }
1555     workQueueManager_->OnConditionChanged(WorkCondition::Type::DEEP_IDLE,
1556         std::make_shared<DetectorValue>(0, 0, true, std::string()));
1557 }
1558 
IsPreinstalledBundle(const std::string & checkBundleName)1559 bool WorkSchedulerService::IsPreinstalledBundle(const std::string& checkBundleName)
1560 {
1561     if (checkBundleName.empty()) {
1562         WS_HILOGE("check preinstalled bundle error, bundleName is empty");
1563         return false;
1564     }
1565     return preinstalledBundles_.find(checkBundleName) != preinstalledBundles_.end();
1566 }
1567 
StopWorkForSA(int32_t saId)1568 int32_t WorkSchedulerService::StopWorkForSA(int32_t saId)
1569 {
1570     WS_HILOGI("StopWork for SA:%{public}d success", saId);
1571     return ERR_OK;
1572 }
1573 
SetTimer()1574 int32_t WorkSchedulerService::SetTimer()
1575 {
1576 #ifdef HICOLLIE_ENABLE
1577     int32_t idTimer = HiviewDFX::INVALID_ID;
1578     std::string collieName = "WorkSchedulerService:START_WORK";
1579     unsigned int flag = HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY;
1580     auto TimerCallback = [](void *) {
1581         WS_HILOGE("OnRemoteRequest timeout func: START_WORK");
1582     };
1583     idTimer = HiviewDFX::XCollie::GetInstance().SetTimer(
1584         collieName, XCOLLIE_TIMEOUT_SECONDS, TimerCallback, nullptr, flag);
1585     WS_HILOGI("SetTimer id: %{public}d, name: %{public}s.", idTimer, collieName.c_str());
1586     return idTimer;
1587 #else
1588     WS_HILOGD("No HICOLLIE_ENABLE");
1589     return -1;
1590 #endif
1591 }
1592 
CancelTimer(int32_t id)1593 void WorkSchedulerService::CancelTimer(int32_t id)
1594 {
1595 #ifdef HICOLLIE_ENABLE
1596     if (id == HiviewDFX::INVALID_ID) {
1597         return;
1598     }
1599     WS_HILOGI("CancelTimer id: %{public}d.", id);
1600     HiviewDFX::XCollie::GetInstance().CancelTimer(id);
1601 #else
1602     return;
1603 #endif
1604 }
1605 } // namespace WorkScheduler
1606 } // namespace OHOS
1607