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