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