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