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