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