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