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