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