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