From 92b33a2f1f91a0c2c4745746ef4b41e50c006536 Mon Sep 17 00:00:00 2001 From: hxf Date: Thu, 12 Dec 2024 15:41:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BB=B6=E8=BF=9F=E4=BB=BB=E5=8A=A1=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=97=B2=E6=97=B6=E6=8B=89=E8=B5=B7SA=20Signed-off-by?= =?UTF-8?q?:=20hxf=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frameworks/include/iwork_sched_service.h | 8 + .../iwork_sched_service_ipc_interface_code.h | 1 + frameworks/include/work_info.h | 9 + frameworks/include/workscheduler_srv_client.h | 8 + frameworks/src/work_info.cpp | 57 ++- frameworks/src/workscheduler_srv_client.cpp | 11 + .../test/unittest/src/workinfo_test.cpp | 43 +++ services/native/include/work_policy_manager.h | 9 + services/native/include/work_queue.h | 7 + .../native/include/work_scheduler_service.h | 15 +- services/native/include/work_status.h | 12 + services/native/src/work_policy_manager.cpp | 42 ++- services/native/src/work_queue.cpp | 19 +- .../native/src/work_scheduler_service.cpp | 154 ++++---- services/native/src/work_status.cpp | 64 +++- services/test/src/work_status_test.cpp | 345 ++++++++++++++++++ .../test/src/workschedulerservice_test.cpp | 62 ++-- .../zidl/include/work_sched_service_proxy.h | 7 + .../zidl/include/work_sched_service_stub.h | 20 +- .../zidl/src/work_sched_service_proxy.cpp | 31 ++ services/zidl/src/work_sched_service_stub.cpp | 70 +++- 21 files changed, 834 insertions(+), 160 deletions(-) diff --git a/frameworks/include/iwork_sched_service.h b/frameworks/include/iwork_sched_service.h index ae6274d..e74b517 100644 --- a/frameworks/include/iwork_sched_service.h +++ b/frameworks/include/iwork_sched_service.h @@ -115,6 +115,14 @@ public: */ virtual int32_t SetWorkSchedulerConfig(const std::string &configData, int32_t sourceType) = 0; + /** + * @brief Stop SA. + * + * @param saId SA id. + * @return ErrCode ERR_OK on success, others on failure + */ + virtual int32_t StopWorkForSA(int32_t saId) = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.workscheduler.iworkschedservice"); }; } // namespace WorkScheduler diff --git a/frameworks/include/iwork_sched_service_ipc_interface_code.h b/frameworks/include/iwork_sched_service_ipc_interface_code.h index 7d99d52..06ce4b7 100644 --- a/frameworks/include/iwork_sched_service_ipc_interface_code.h +++ b/frameworks/include/iwork_sched_service_ipc_interface_code.h @@ -31,6 +31,7 @@ namespace WorkScheduler { PAUSE_RUNNING_WORKS, RESUME_PAUSED_WORKS, SET_WORK_SCHEDULER_CONFIG, + STOP_WORK_FOR_SA, }; } // namespace WorkScheduler } // namespace OHOS diff --git a/frameworks/include/work_info.h b/frameworks/include/work_info.h index 4354301..0ad91d1 100644 --- a/frameworks/include/work_info.h +++ b/frameworks/include/work_info.h @@ -278,6 +278,13 @@ public: * @return True if success,else false. */ bool ParseFromJson(const Json::Value &value); + /** + * @brief Parse element from json. + * + * @param value The value. + * @return True if success,else false. + */ + bool ParseElementFromJson(const Json::Value &value); /** * @brief Set preinstalled flag. */ @@ -324,6 +331,8 @@ public: * @return ResidentSa or not. */ bool IsResidentSa() const; + bool IsSA(); + std::string GetBriefInfo(); private: int32_t workId_; diff --git a/frameworks/include/workscheduler_srv_client.h b/frameworks/include/workscheduler_srv_client.h index 62f3b8b..a165eba 100644 --- a/frameworks/include/workscheduler_srv_client.h +++ b/frameworks/include/workscheduler_srv_client.h @@ -112,6 +112,14 @@ public: * @return ErrCode ERR_OK on success, others on failure */ ErrCode SetWorkSchedulerConfig(const std::string &configData, int32_t sourceType); + + /** + * @brief Stop SA. + * + * @param saId SA id. + * @return ErrCode ERR_OK on success, others on failure + */ + ErrCode StopWorkForSA(int32_t saId); private: class WorkSchedulerDeathRecipient : public IRemoteObject::DeathRecipient { public: diff --git a/frameworks/src/work_info.cpp b/frameworks/src/work_info.cpp index 9a32538..7cc72dc 100644 --- a/frameworks/src/work_info.cpp +++ b/frameworks/src/work_info.cpp @@ -462,14 +462,19 @@ std::string WorkInfo::ParseToJsonStr() root["uid"] = uid_; } root["workId"] = workId_; - root["bundleName"] = bundleName_; - root["abilityName"] = abilityName_; + if (IsSA()) { + root["saId"] = saId_; + root["resident"] = IsResidentSa() ? "true" : "false"; + } else { + root["bundleName"] = bundleName_; + root["abilityName"] = abilityName_; + root["callBySystemApp"] = callBySystemApp_; + root["appIndex"] = appIndex_; + root["extension"] = extension_; + } root["persisted"] = persisted_; root["preinstalled"] = preinstalled_; root["uriKey"] = uriKey_; - root["callBySystemApp"] = callBySystemApp_; - root["appIndex"] = appIndex_; - root["extension"] = extension_; ParseConditionToJsonStr(root); if (extras_) { Json::Value extras; @@ -548,20 +553,18 @@ bool WorkInfo::ParseFromJson(const Json::Value &value) WS_HILOGE("workinfo json is empty"); return false; } + if (!value.isMember("workId") || !value["workId"].isInt()) { + WS_HILOGE("workinfo json is invalid, workId is missing or not int"); + return false; + } + this->workId_ = value["workId"].asInt(); if ((value.isMember("saId") && value["saId"].isInt()) && IsHasBoolProp(value, "residentSa")) { this->saId_ = value["saId"].asInt(); this->residentSa_ = value["residentSa"].asBool(); - return true; } - if (!value.isMember("workId") || !value["workId"].isInt() || - !value.isMember("bundleName") || !value["bundleName"].isString() || - !value.isMember("abilityName") || !value["abilityName"].isString()) { - WS_HILOGE("workinfo json is invalid"); + if (!ParseElementFromJson(value)) { return false; } - this->workId_ = value["workId"].asInt(); - this->bundleName_ = value["bundleName"].asString(); - this->abilityName_ = value["abilityName"].asString(); if (IsHasBoolProp(value, "persisted")) { this->persisted_ = value["persisted"].asBool(); } @@ -588,6 +591,20 @@ bool WorkInfo::ParseFromJson(const Json::Value &value) return true; } +bool WorkInfo::ParseElementFromJson(const Json::Value &value) +{ + if (!IsSA()) { + if (!value.isMember("bundleName") || !value["bundleName"].isString() || + !value.isMember("abilityName") || !value["abilityName"].isString()) { + WS_HILOGE("workinfo json is invalid, bundleName or abilityName is missing or not string"); + return false; + } + this->bundleName_ = value["bundleName"].asString(); + this->abilityName_ = value["abilityName"].asString(); + } + return true; +} + void WorkInfo::ParseParametersFromJsonStr(const Json::Value &value) { Json::Value extrasJson = value["parameters"]; @@ -682,5 +699,19 @@ bool WorkInfo::IsResidentSa() const { return residentSa_; } + +bool WorkInfo::IsSA() +{ + return saId_ != INVALID_VALUE; +} + +std::string WorkInfo::GetBriefInfo() +{ + if (IsSA()) { + return std::to_string(GetSaId()) + "_" + std::to_string(GetWorkId()); + } else { + return GetBundleName() + "_" + std::to_string(GetWorkId()); + } +} } // namespace WorkScheduler } // namespace OHOS diff --git a/frameworks/src/workscheduler_srv_client.cpp b/frameworks/src/workscheduler_srv_client.cpp index b9e051c..68dee27 100644 --- a/frameworks/src/workscheduler_srv_client.cpp +++ b/frameworks/src/workscheduler_srv_client.cpp @@ -212,5 +212,16 @@ ErrCode WorkSchedulerSrvClient::SetWorkSchedulerConfig(const std::string &config } return iWorkSchedService_->SetWorkSchedulerConfig(configData, sourceType); } + +ErrCode WorkSchedulerSrvClient::StopWorkForSA(int32_t saId) +{ + WS_HILOGD("Stop SA"); + std::lock_guard lock(mutex_); + ErrCode code = Connect(); + if (code != ERR_OK) { + return code; + } + return iWorkSchedService_->StopWorkForSA(saId); +} } // namespace WorkScheduler } // namespace OHOS \ No newline at end of file diff --git a/frameworks/test/unittest/src/workinfo_test.cpp b/frameworks/test/unittest/src/workinfo_test.cpp index 74039c6..742488d 100644 --- a/frameworks/test/unittest/src/workinfo_test.cpp +++ b/frameworks/test/unittest/src/workinfo_test.cpp @@ -321,6 +321,10 @@ HWTEST_F (WorkInfoTest, WorkInfoTestJson001, Function | MediumTest | Level0) workInfo.RequestRepeatCycle(timeInterval); res = workInfo.ParseToJsonStr(); + workInfo.saId_ = 1000; + workInfo.residentSa_ = true; + res = workInfo.ParseToJsonStr(); + workInfo.RefreshUid(1); workInfo.RequestRepeatCycle(timeInterval, 3); AAFwk::WantParams extras; @@ -502,6 +506,45 @@ HWTEST_F (WorkInfoTest, WorkInfoTestJson005, Function | MediumTest | Level0) EXPECT_FALSE(res); } +/** + * @tc.name WorkInfoTestJson006 + * @tc.desc Set workInfo json func + * @tc.type FUNC + * @tc.require: issueI5Y6YK + */ +HWTEST_F (WorkInfoTest, WorkInfoTestJson006, Function | MediumTest | Level0) +{ + using namespace OHOS::WorkScheduler; + WorkInfo workInfo = WorkInfo(); + Json::Value root; + root.clear(); + root["workId"] = 1; + root["bundleName"] = "bundleName"; + root["abilityName"] = "abilityName"; + root["saId"] = "1"; + root["residentSa"] = true; + bool res = workInfo.ParseFromJson(root); + EXPECT_TRUE(res); + + root.clear(); + root["workId"] = 1; + root["bundleName"] = "bundleName"; + root["abilityName"] = "abilityName"; + root["saId"] = 1; + root["residentSa"] = "true"; + res = workInfo.ParseFromJson(root); + EXPECT_TRUE(res); + + root.clear(); + root["workId"] = 1; + root["bundleName"] = "bundleName"; + root["abilityName"] = "abilityName"; + root["saId"] = 1; + root["residentSa"] = true; + res = workInfo.ParseFromJson(root); + EXPECT_TRUE(res); +} + /** * @tc.name WorkInfoTest019 * @tc.desc Set workInfo Marshalling and Unmarshalling diff --git a/services/native/include/work_policy_manager.h b/services/native/include/work_policy_manager.h index d1278c8..d136f4d 100644 --- a/services/native/include/work_policy_manager.h +++ b/services/native/include/work_policy_manager.h @@ -105,6 +105,14 @@ public: * @return The uid queue map. */ std::shared_ptr FindWorkStatus(WorkInfo& workInfo, int32_t uid); + /** + * @brief Find SA. + * + * @param saId The id of sa. + * @param uid The uid. + * @return The SA of uid. + */ + std::shared_ptr FindSA(int32_t saId, int32_t uid); /** * @brief The OnConditionReady callback. * @@ -282,6 +290,7 @@ private: void RemoveFromReadyQueue(std::shared_ptr workStatus); void AddToReadyQueue(std::shared_ptr>> workStatusVector); void RealStartWork(std::shared_ptr workStatus); + void RealStartSA(std::shared_ptr workStatus); void AddToRunningQueue(std::shared_ptr workStatus); void RemoveConditionUnReady(); std::shared_ptr GetWorkToRun(); diff --git a/services/native/include/work_queue.h b/services/native/include/work_queue.h index 817c8d4..6fd1ecd 100644 --- a/services/native/include/work_queue.h +++ b/services/native/include/work_queue.h @@ -83,6 +83,13 @@ public: * @return The id of work. */ std::shared_ptr Find(std::string workId); + /** + * @brief Find SA. + * + * @param saId The id of sa. + * @return The SA of saId. + */ + std::shared_ptr FindSA(int32_t saId); /** * @brief Get size. * diff --git a/services/native/include/work_scheduler_service.h b/services/native/include/work_scheduler_service.h index 1737c63..7914d90 100644 --- a/services/native/include/work_scheduler_service.h +++ b/services/native/include/work_scheduler_service.h @@ -270,9 +270,10 @@ public: */ int32_t StopDeepIdleWorks(); /** - * @brief load sa. + * @brief load SA. + * @return success or fail. */ - void LoadSa(); + bool LoadSa(std::shared_ptr workStatus); /** * @brief Handle DeepIdle callback Msg. */ @@ -295,6 +296,13 @@ public: int32_t SetWorkSchedulerConfig(const std::string &configData, int32_t sourceType) override; void InitDeviceStandyWhitelist(); bool IsPreinstalledBundle(const std::string& checkBundleName); + /** + * @brief Stop SA. + * + * @param saId SA id. + * @return ErrCode ERR_OK on success, others on failure + */ + int32_t StopWorkForSA(int32_t saId) override; private: void RegisterStandbyStateObserver(); void WorkQueueManagerInit(const std::shared_ptr& runner); @@ -329,13 +337,12 @@ private: bool CheckProcessName(); bool GetAppIndexAndBundleNameByUid(int32_t uid, int32_t &appIndex, std::string &bundleName); bool CheckExtensionInfos(WorkInfo &workInfo, int32_t uid); - void DumpLoadSaWorks(const std::string &saIdStr, const std::string &residentSaStr, std::string &result); + void DumpLoadSaWorks(const std::string &saIdStr, const std::string &uidStr, std::string &result); std::string DumpExemptionBundles(); private: std::set whitelist_; ffrt::mutex whitelistMutex_; - std::map saMap_; #ifdef RESOURCESCHEDULE_BGTASKMGR_ENABLE std::shared_ptr subscriber_; #endif diff --git a/services/native/include/work_status.h b/services/native/include/work_status.h index 2c282cd..c8ac498 100644 --- a/services/native/include/work_status.h +++ b/services/native/include/work_status.h @@ -70,6 +70,12 @@ public: * @return True if success,else false. */ bool IsReady(); + /** + * @brief Judge state whether is ready. + * + * @return True if success,else false. + */ + bool IsSAReady(); /** * @brief Judge state whether is ready status. * @@ -133,6 +139,12 @@ public: * @param result The result. */ void Dump(std::string& result); + /** + * @brief Dump Condition. + * + * @param result The result. + */ + void DumpCondition(std::string& result); /** * @brief Update timer if need. */ diff --git a/services/native/src/work_policy_manager.cpp b/services/native/src/work_policy_manager.cpp index 975ae3a..4d5acc5 100644 --- a/services/native/src/work_policy_manager.cpp +++ b/services/native/src/work_policy_manager.cpp @@ -187,6 +187,16 @@ shared_ptr WorkPolicyManager::FindWorkStatus(WorkInfo& workInfo, int return nullptr; } +shared_ptr WorkPolicyManager::FindSA(int32_t saId, int32_t uid) +{ + WS_HILOGD("Find SA, saId:%{public}d, uid:%{public}d", saId, uid); + std::lock_guard lock(uidMapMutex_); + if (uidQueueMap_.count(uid) > 0) { + return uidQueueMap_.at(uid)->FindSA(saId); + } + return nullptr; +} + void WorkPolicyManager::RemoveFromUidQueue(std::shared_ptr workStatus, int32_t uid) { std::lock_guard lock(uidMapMutex_); @@ -385,7 +395,11 @@ void WorkPolicyManager::CheckWorkToRun() int32_t allowRunningCount = GetMaxRunningCount(policyName); if (runningCount < allowRunningCount || IsSpecialScene(topWork)) { WS_HILOGD("running count < max running count"); - RealStartWork(topWork); + if (topWork->workInfo_->IsSA()) { + RealStartSA(topWork); + } else { + RealStartWork(topWork); + } SendRetrigger(DELAY_TIME_SHORT); } else { WS_HILOGD("trigger delay: %{public}d", DELAY_TIME_LONG); @@ -415,6 +429,32 @@ std::shared_ptr WorkPolicyManager::GetWorkToRun() return topWork; } +void WorkPolicyManager::RealStartSA(std::shared_ptr topWork) +{ + WS_HILOGI("RealStartSA %{public}d workId:%{public}s", topWork->workInfo_->GetSaId(), topWork->workId_.c_str()); + if (wss_.expired()) { + WS_HILOGE("wss_ expired"); + return; + } + wss_.lock()->UpdateWorkBeforeRealStart(topWork); + RemoveFromReadyQueue(topWork); + bool ret = wss_.lock()->LoadSa(topWork); + if (ret) { + WS_HILOGI("startSA %{public}d workId:%{public}s success", + topWork->workInfo_->GetSaId(), topWork->workId_.c_str()); + topWork->UpdateUidLastTimeMap(); + if (!topWork->IsRepeating()) { + topWork->MarkStatus(WorkStatus::Status::REMOVED); + RemoveFromUidQueue(topWork, topWork->uid_); + } else { + topWork->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + } + return; + } + WS_HILOGE("startSA %{public}d workId:%{public}s failed", + topWork->workInfo_->GetSaId(), topWork->workId_.c_str()); +} + void WorkPolicyManager::RealStartWork(std::shared_ptr topWork) { WS_HILOGD("RealStartWork topWork ID: %{public}s", topWork->workId_.c_str()); diff --git a/services/native/src/work_queue.cpp b/services/native/src/work_queue.cpp index 63012ea..4877f6b 100644 --- a/services/native/src/work_queue.cpp +++ b/services/native/src/work_queue.cpp @@ -42,7 +42,8 @@ vector> WorkQueue::OnConditionChanged(WorkCondition::Type it->uid_, it->bundleName_.c_str()); continue; } - if (it->IsReady()) { + bool isReady = it->workInfo_->IsSA() ? it->IsSAReady() : it->IsReady(); + if (isReady) { result.emplace_back(it); uidList.insert(it->uid_); } else { @@ -160,6 +161,19 @@ shared_ptr WorkQueue::Find(string workId) return nullptr; } +shared_ptr WorkQueue::FindSA(int32_t saId) +{ + std::lock_guard lock(workListMutex_); + auto iter = std::find_if(workList_.cbegin(), workList_.cend(), + [&saId](const shared_ptr &workStatus) { + return workStatus->workInfo_->IsSA() && workStatus->workInfo_->GetSaId() == saId; + }); + if (iter != workList_.end()) { + return *iter; + } + return nullptr; +} + bool WorkQueue::Find(const int32_t userId, const std::string &bundleName) { std::lock_guard lock(workListMutex_); @@ -240,7 +254,8 @@ std::list> WorkQueue::GetDeepIdleWorks() std::list> works; std::lock_guard lock(workListMutex_); for (shared_ptr work : workList_) { - if (work->IsRunning() && work->workInfo_->GetDeepIdle() == WorkCondition::DeepIdle::DEEP_IDLE_IN) { + if (work->IsRunning() && work->workInfo_->GetDeepIdle() == WorkCondition::DeepIdle::DEEP_IDLE_IN && + !work->workInfo_->IsSA()) { works.emplace_back(work); } } diff --git a/services/native/src/work_scheduler_service.cpp b/services/native/src/work_scheduler_service.cpp index 5d7d4ac..349f3ab 100644 --- a/services/native/src/work_scheduler_service.cpp +++ b/services/native/src/work_scheduler_service.cpp @@ -170,49 +170,33 @@ void WorkSchedulerService::InitPersistedWork() WS_HILOGD("init persisted work"); list> persistedWorks = ReadPersistedWorks(); for (auto it : persistedWorks) { - WS_HILOGI("get persisted work, id: %{public}d", it->GetWorkId()); + WS_HILOGI("get persisted work, id: %{public}d, isSa:%{public}d", it->GetWorkId(), it->IsSA()); AddWorkInner(*it); } + RefreshPersistedWorks(); } void WorkSchedulerService::InitPreinstalledWork() { WS_HILOGD("init preinstalled work"); - bool needRefresh = false; list> preinstalledWorks = ReadPreinstalledWorks(); for (auto work : preinstalledWorks) { - WS_HILOGD("preinstalled workinfo id %{public}d, uid %{public}d", work->GetWorkId(), work->GetUid()); - if (!work->IsPersisted()) { - time_t baseTime; - (void)time(&baseTime); - work->RequestBaseTime(baseTime); - AddWorkInner(*work); - continue; - } - auto iter = std::find_if(persistedMap_.begin(), persistedMap_.end(), [&](const auto &pair) { - return (pair.second->GetUid() == work->GetUid()) && (pair.second->GetWorkId() == work->GetWorkId()); - }); - if (iter != persistedMap_.end()) { - WS_HILOGD("find workid %{public}d in persisted map, ignore", work->GetWorkId()); - continue; - } - needRefresh = true; + WS_HILOGI("preinstalled workinfo id %{public}s, isSa:%{public}d", work->GetBriefInfo().c_str(), work->IsSA()); time_t baseTime; (void)time(&baseTime); work->RequestBaseTime(baseTime); AddWorkInner(*work); - string workId = "u" + to_string(work->GetUid()) + "_" + to_string(work->GetWorkId()); - persistedMap_.emplace(workId, work); - } - if (needRefresh) { - RefreshPersistedWorks(); + if (work->IsPersisted()) { + string workId = "u" + to_string(work->GetUid()) + "_" + to_string(work->GetWorkId()); + persistedMap_.emplace(workId, work); + } } } void WorkSchedulerService::InitWorkInner() { - InitPersistedWork(); InitPreinstalledWork(); + InitPersistedWork(); } list> WorkSchedulerService::ReadPersistedWorks() @@ -225,12 +209,24 @@ list> WorkSchedulerService::ReadPersistedWorks() for (const auto &it : root.getMemberNames()) { Json::Value workJson = root[it]; shared_ptr workInfo = make_shared(); - if (workInfo->ParseFromJson(workJson)) { - workInfos.emplace_back(workInfo); - WS_HILOGI("find one persisted work %{public}d", workInfo->GetWorkId()); - string workId = "u" + to_string(workInfo->GetUid()) + "_" + to_string(workInfo->GetWorkId()); - persistedMap_.emplace(workId, workInfo); + if (!workInfo->ParseFromJson(workJson)) { + WS_HILOGE("ReadPersistedWorks failed, parseFromJson error"); + continue; + } + workInfos.emplace_back(workInfo); + WS_HILOGI("find one persisted work %{public}s", workInfo->GetBriefInfo().c_str()); + auto iter = std::find_if(persistedMap_.begin(), persistedMap_.end(), [&](const auto &pair) { + return (pair.second->GetUid() == workInfo->GetUid()) && (pair.second->GetWorkId() == workInfo->GetWorkId()); + }); + if (iter != persistedMap_.end()) { + WS_HILOGI("find work %{public}s in persisted map, ignore, isSA:%{public}d", + workInfo->GetBriefInfo().c_str(), + workInfo->IsSA()); + // update basetime + continue; } + string workId = "u" + to_string(workInfo->GetUid()) + "_" + to_string(workInfo->GetWorkId()); + persistedMap_.emplace(workId, workInfo); } return workInfos; } @@ -257,22 +253,20 @@ void WorkSchedulerService::LoadWorksFromFile(const char *path, list workinfo = make_shared(); - if (workinfo->ParseFromJson(workJson)) { - if (workinfo->GetSaId() > -1) { - saMap_.emplace(workinfo->GetSaId(), workinfo->IsResidentSa()); - continue; - } + if (!workinfo->ParseFromJson(workJson)) { + WS_HILOGE("LoadWorksFromFile failed, parseFromJson error"); + continue; + } + if (!workinfo->IsSA()) { int32_t uid; if (!GetUidByBundleName(workinfo->GetBundleName(), uid)) { continue; } workinfo->RefreshUid(uid); - workinfo->SetPreinstalled(true); - workInfos.emplace_back(workinfo); preinstalledBundles_.insert(workinfo->GetBundleName()); - } else { - WS_HILOGE("ParseFromJson error"); } + workinfo->SetPreinstalled(true); + workInfos.emplace_back(workinfo); } } @@ -961,7 +955,7 @@ void WorkSchedulerService::DumpUsage(std::string &result) .append(" -min_interval (number): set min interval time, set 0 means close test mode.\n") .append(" -cpu (number): set the usage cpu.\n") .append(" -count (number): set the max running task count.\n") - .append(" -s (number) (bool): set the sa id running task.\n"); + .append(" -s (number) (number): load or report sa.\n"); } void WorkSchedulerService::DumpAllInfo(std::string &result) @@ -1374,62 +1368,63 @@ bool WorkSchedulerService::IsExemptionBundle(const std::string& checkBundleName) return iter != exemptionBundles_.end(); } -void WorkSchedulerService::LoadSa() +bool WorkSchedulerService::LoadSa(std::shared_ptr workStatus) { if (!ready_) { WS_HILOGE("service is not ready."); - return; - } - if (saMap_.empty()) { - WS_HILOGI("saMap is empty."); - return; + return false; } sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgr == nullptr) { - WS_HILOGE("get sa manager failed."); - return; + WS_HILOGE("get SA manager failed."); + return false; } - for (auto &it : saMap_) { - sptr object = samgr->CheckSystemAbility(it.first); - if (it.second && object == nullptr) { - WS_HILOGE("resident sa: %{public}d does not exist.", it.first); - continue; - } else if (!it.second && object == nullptr) { - object = samgr->LoadSystemAbility(it.first, TIME_OUT); - if (object == nullptr) { - WS_HILOGE("load sa: %{public}d failed.", it.first); - continue; - } - WS_HILOGD("load sa: %{public}d successed.", it.first); + int32_t saId = workStatus->workInfo_->GetSaId(); + bool isResidentSa = workStatus->workInfo_->IsResidentSa(); + sptr object = samgr->CheckSystemAbility(saId); + if (isResidentSa && object == nullptr) { + WS_HILOGE("resident SA: %{public}d residentSA:%{public}d does not exist.", saId, isResidentSa); + return false; + } else if (!isResidentSa && object == nullptr) { + object = samgr->LoadSystemAbility(saId, TIME_OUT); + if (object == nullptr) { + WS_HILOGE("load SA: %{public}d residentSA:%{public}d failed.", saId, isResidentSa); + return false; } - std::string action = ""; - std::unordered_map payload; - payload["action"] = action; - payload["saId"] = std::to_string(it.first); - uint32_t type = ResourceSchedule::ResType::RES_TYPE_DEVICE_IDLE; - ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload); - } + WS_HILOGI("load SA: %{public}d residentSA:%{public}d successed.", saId, isResidentSa); + } + std::string action = ""; + std::unordered_map payload; + payload["action"] = action; + payload["saId"] = std::to_string(saId); + uint32_t type = ResourceSchedule::ResType::RES_TYPE_DEVICE_IDLE; + ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload); + WS_HILOGI("Report SA: %{public}d residentSA:%{public}d successed.", saId, isResidentSa); + return true; } -void WorkSchedulerService::DumpLoadSaWorks(const std::string &saIdStr, const std::string &residentSaStr, - std::string &result) +void WorkSchedulerService::DumpLoadSaWorks(const std::string &saIdStr, const std::string &uidStr, std::string &result) { - if (saIdStr.empty() || residentSaStr.empty()) { + if (saIdStr.empty() || uidStr.empty()) { result.append("param error."); return; } int32_t saId = std::stoi(saIdStr); - if (saId < 0 || (residentSaStr != "true" && residentSaStr != "false")) { + int32_t uid = std::stoi(uidStr); + if (saId < 0 || uid < 0) { result.append("the parameter is invalid."); return; } - bool residentSa = (residentSaStr == "true") ? true : false; - if (saMap_.count(saId) > 0) { - saMap_.at(saId) = residentSa; - } else { - saMap_.emplace(saId, residentSa); + auto sa = workPolicyManager_->FindSA(saId, uid); + if (sa == nullptr) { + result.append("the sa does not exist."); + return; } - LoadSa(); + if (LoadSa(sa)) { + result.append("load sa success."); + return; + } + result.append("load sa failed."); } void WorkSchedulerService::HandleDeepIdleMsg() @@ -1440,7 +1435,6 @@ void WorkSchedulerService::HandleDeepIdleMsg() } workQueueManager_->OnConditionChanged(WorkCondition::Type::DEEP_IDLE, std::make_shared(0, 0, true, std::string())); - LoadSa(); } bool WorkSchedulerService::IsPreinstalledBundle(const std::string& checkBundleName) @@ -1451,5 +1445,11 @@ bool WorkSchedulerService::IsPreinstalledBundle(const std::string& checkBundleNa } return preinstalledBundles_.find(checkBundleName) != preinstalledBundles_.end(); } + +int32_t WorkSchedulerService::StopWorkForSA(int32_t saId) +{ + WS_HILOGI("StopWork for SA:%{public}d success", saId); + return ERR_OK; +} } // namespace WorkScheduler } // namespace OHOS diff --git a/services/native/src/work_status.cpp b/services/native/src/work_status.cpp index 67f5893..270e477 100644 --- a/services/native/src/work_status.cpp +++ b/services/native/src/work_status.cpp @@ -104,7 +104,7 @@ WorkStatus::~WorkStatus() {} int32_t WorkStatus::OnConditionChanged(WorkCondition::Type &type, shared_ptr value) { - WS_HILOGD("Work status condition changed."); + conditionStatus_.clear(); if (workInfo_->GetConditionMap()->count(type) > 0 && type != WorkCondition::Type::TIMER && type != WorkCondition::Type::GROUP) { @@ -115,6 +115,12 @@ int32_t WorkStatus::OnConditionChanged(WorkCondition::Type &type, shared_ptrIsSA()) { + if (IsSAReady()) { + MarkStatus(Status::CONDITION_READY); + } + return ERR_OK; + } groupChanged_ = false; if (type == WorkCondition::Type::GROUP && value && value->boolVal) { WS_HILOGD("Group changed, bundleName: %{public}s.", value->strVal.c_str()); @@ -255,6 +261,16 @@ bool WorkStatus::IsReady() return true; } +bool WorkStatus::IsSAReady() +{ + conditionStatus_.clear(); + if (!IsConditionReady()) { + return false; + } + WS_HILOGI("All condition ready, saId:%{public}d, workId:%{public}s", workInfo_->GetSaId(), workId_.c_str()); + return true; +} + bool WorkStatus::IsConditionReady() { auto workConditionMap = workInfo_->GetConditionMap(); @@ -355,12 +371,7 @@ bool WorkStatus::IsStandbyExemption() { auto dataManager = DelayedSingleton::GetInstance(); if (dataManager->GetDeviceSleep()) { - if (dataManager->IsInDeviceStandyWhitelist(bundleName_)) { - conditionStatus_ += "|" + COND_TYPE_STRING_MAP[WorkCondition::Type::STANDBY] + "&exemption"; - return true; - } - conditionStatus_ += "|" + COND_TYPE_STRING_MAP[WorkCondition::Type::STANDBY] + "&unExemption"; - return false; + return dataManager->IsInDeviceStandyWhitelist(bundleName_); } return true; } @@ -533,11 +544,26 @@ void WorkStatus::Dump(string& result) { result.append("{\n"); result.append(string("\"workId\":") + workId_ + ",\n"); - result.append(string("\"bundleName\":") + bundleName_ + ",\n"); + result.append(string("\"isSA\":") + (workInfo_->IsSA() ? "true" : "false") + ",\n"); + if (workInfo_->IsSA()) { + result.append(string("\"SAId\":") + to_string(workInfo_->GetSaId()) + ",\n"); + result.append(string("\"resident\":") + (workInfo_->IsResidentSa() ? "true" : "false") + ",\n"); + } else { + result.append(string("\"bundleName\":") + bundleName_ + ",\n"); + } result.append(string("\"status\":") + to_string(currentStatus_) + ",\n"); result.append(string("\"paused\":") + (paused_ ? "true" : "false") + ",\n"); result.append(string("\"priority\":") + to_string(priority_) + ",\n"); result.append(string("\"conditionMap\":{\n")); + DumpCondition(result); + result.append("},\n\"workInfo\":\n"); + workInfo_->Dump(result); + result.append("}\n"); + result.append("\n"); +} + +void WorkStatus::DumpCondition(string& result) +{ std::lock_guard lock(conditionMapMutex_); if (conditionMap_.count(WorkCondition::Type::NETWORK) > 0) { result.append(string("\"networkType\":") + @@ -574,20 +600,28 @@ void WorkStatus::Dump(string& result) result.append(string("\"isDeepIdle\":") + to_string(conditionMap_.at(WorkCondition::Type::DEEP_IDLE)->boolVal) + ",\n"); } - result.append("},\n\"workInfo\":\n"); - workInfo_->Dump(result); - result.append("}\n"); - result.append("\n"); } void WorkStatus::ToString(WorkCondition::Type type) { + auto dataManager = DelayedSingleton::GetInstance(); + if (dataManager->GetDeviceSleep()) { + if (dataManager->IsInDeviceStandyWhitelist(bundleName_)) { + conditionStatus_ += DELIMITER + COND_TYPE_STRING_MAP[WorkCondition::Type::STANDBY] + "&exemption"; + } + conditionStatus_ += DELIMITER + COND_TYPE_STRING_MAP[WorkCondition::Type::STANDBY] + "&unExemption"; + } if (conditionStatus_.empty()) { + WS_HILOGE("eventType:%{public}s, conditionStatus is empty", COND_TYPE_STRING_MAP[type].c_str()); return; } - IsStandbyExemption(); - WS_HILOGI("eventType:%{public}s,workStatus:%{public}s_%{public}s%{public}s", COND_TYPE_STRING_MAP[type].c_str(), - bundleName_.c_str(), workId_.c_str(), conditionStatus_.c_str()); + if (workInfo_->IsSA()) { + WS_HILOGI("eventType:%{public}s,SAStatus:%{public}s%{public}s", COND_TYPE_STRING_MAP[type].c_str(), + workId_.c_str(), conditionStatus_.c_str()); + } else { + WS_HILOGI("eventType:%{public}s,workStatus:%{public}s_%{public}s%{public}s", COND_TYPE_STRING_MAP[type].c_str(), + bundleName_.c_str(), workId_.c_str(), conditionStatus_.c_str()); + } } } // namespace WorkScheduler } // namespace OHOS \ No newline at end of file diff --git a/services/test/src/work_status_test.cpp b/services/test/src/work_status_test.cpp index ea80f78..680ec3d 100644 --- a/services/test/src/work_status_test.cpp +++ b/services/test/src/work_status_test.cpp @@ -458,6 +458,22 @@ HWTEST_F(WorkStatusTest, dump_001, TestSize.Level1) EXPECT_FALSE(ret); } +/** + * @tc.name: dump_002 + * @tc.desc: Test WorkStatus Dump. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, dump_002, TestSize.Level1) +{ + workStatus_->workInfo_->saId_ = 1000; + workStatus_->workInfo_->residentSa_ = true; + + std::string result; + workStatus_->Dump(result); + EXPECT_TRUE(workStatus_->workInfo_->IsSA()); +} + /** * @tc.name: getMinInterval_001 * @tc.desc: Test WorkStatus GetMinInterval. @@ -709,5 +725,334 @@ HWTEST_F(WorkStatusTest, GetStatus_001, TestSize.Level1) workStatus_->MarkStatus(WorkStatus::Status::RUNNING); EXPECT_EQ(workStatus_->GetStatus(), WorkStatus::Status::RUNNING); } + +/** + * @tc.name: IsSAReady_001 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_001, TestSize.Level1) +{ + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::RUNNING); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_TRUE(result); +} + +/** + * @tc.name: IsSAReady_002 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_002, TestSize.Level1) +{ + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workInfo_->RequestNetworkType(WorkCondition::Network::NETWORK_UNKNOWN); + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_003 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_003, TestSize.Level1) +{ + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestNetworkType(WorkCondition::Network::NETWORK_TYPE_BLUETOOTH); + std::shared_ptr networkCondition = std::make_shared(); + networkCondition->enumVal = WorkCondition::Network::NETWORK_TYPE_ETHERNET; + workStatus_->conditionMap_.emplace(WorkCondition::Type::NETWORK, networkCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_004 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_004, TestSize.Level1) +{ + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestBatteryStatus(WorkCondition::BatteryStatus::BATTERY_STATUS_LOW); + std::shared_ptr batteryCondition = std::make_shared(); + batteryCondition->enumVal = WorkCondition::BatteryStatus::BATTERY_STATUS_OKAY; + workStatus_->conditionMap_.emplace(WorkCondition::Type::BATTERY_STATUS, batteryCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_005 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_005, TestSize.Level1) +{ + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workInfo_->RequestBatteryLevel(80); + std::shared_ptr batteryLevelCondition = std::make_shared(); + batteryLevelCondition->intVal = 70; + workStatus_->conditionMap_.emplace(WorkCondition::Type::BATTERY_LEVEL, batteryLevelCondition); + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_006 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_006, TestSize.Level1) +{ + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestBatteryLevel(60); + workInfo_->SetPreinstalled(true); + std::shared_ptr batteryLevelCondition = std::make_shared(); + batteryLevelCondition->intVal = 70; + workStatus_->conditionMap_.emplace(WorkCondition::Type::BATTERY_LEVEL, batteryLevelCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_TRUE(result); +} + +/** + * @tc.name: IsSAReady_007 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_007, TestSize.Level1) +{ + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestStorageLevel(WorkCondition::Storage::STORAGE_LEVEL_OKAY); + std::shared_ptr storageCondition = std::make_shared(); + storageCondition->enumVal = WorkCondition::Storage::STORAGE_LEVEL_LOW; + workStatus_->conditionMap_.emplace(WorkCondition::Type::STORAGE, storageCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_008 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_008, TestSize.Level1) +{ + workStatus_->s_uid_last_time_map.clear(); + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + uint32_t timeInterval = 1200; + workInfo_->RequestRepeatCycle(timeInterval); + workInfo_->SetPreinstalled(true); + workStatus_->workInfo_ = workInfo_; + + std::shared_ptr timerCondition = std::make_shared(); + timerCondition->boolVal = true; + timerCondition->uintVal = 7200001; + workStatus_->conditionMap_.emplace(WorkCondition::Type::TIMER, timerCondition); + bool result = workStatus_->IsSAReady(); + EXPECT_TRUE(result); +} + +/** + * @tc.name: IsSAReady_009 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_009, TestSize.Level1) +{ + workStatus_->s_uid_last_time_map.clear(); + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestStorageLevel(WorkCondition::Storage::STORAGE_LEVEL_OKAY); + std::shared_ptr storageCondition = std::make_shared(); + storageCondition->enumVal = WorkCondition::Storage::STORAGE_LEVEL_OKAY; + workStatus_->conditionMap_.emplace(WorkCondition::Type::STORAGE, storageCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_0010 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_0010, TestSize.Level1) +{ + workStatus_->s_uid_last_time_map.clear(); + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestStorageLevel(WorkCondition::Storage::STORAGE_LEVEL_OKAY); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_0011 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_0011, TestSize.Level1) +{ + workStatus_->s_uid_last_time_map.clear(); + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestChargerType(true, WorkCondition::Charger::CHARGING_PLUGGED_AC); + std::shared_ptr chargingCondition = std::make_shared(); + chargingCondition->enumVal = WorkCondition::Charger::CHARGING_PLUGGED_USB; + chargingCondition->boolVal = false; + workStatus_->conditionMap_.emplace(WorkCondition::Type::CHARGER, chargingCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_0012 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_0012, TestSize.Level1) +{ + workStatus_->s_uid_last_time_map.clear(); + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestChargerType(true, WorkCondition::Charger::CHARGING_PLUGGED_AC); + std::shared_ptr chargingCondition = std::make_shared(); + chargingCondition->enumVal = WorkCondition::Charger::CHARGING_PLUGGED_USB; + chargingCondition->boolVal = true; + workStatus_->conditionMap_.emplace(WorkCondition::Type::CHARGER, chargingCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_0013 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_0013, TestSize.Level1) +{ + workStatus_->s_uid_last_time_map.clear(); + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestChargerType(false, WorkCondition::Charger::CHARGING_PLUGGED_AC); + std::shared_ptr chargingCondition = std::make_shared(); + chargingCondition->enumVal = WorkCondition::Charger::CHARGING_PLUGGED_USB; + chargingCondition->boolVal = false; + workStatus_->conditionMap_.emplace(WorkCondition::Type::CHARGER, chargingCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: IsSAReady_0014 + * @tc.desc: Test WorkStatus IsSAReady. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, IsSAReady_0014, TestSize.Level1) +{ + workStatus_->s_uid_last_time_map.clear(); + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->workId_ = -1; + workStatus_->MarkStatus(WorkStatus::Status::WAIT_CONDITION); + workInfo_->RequestChargerType(true, WorkCondition::Charger::CHARGING_PLUGGED_AC); + std::shared_ptr chargingCondition = std::make_shared(); + chargingCondition->enumVal = WorkCondition::Charger::CHARGING_PLUGGED_AC; + chargingCondition->boolVal = true; + workStatus_->conditionMap_.emplace(WorkCondition::Type::CHARGER, chargingCondition); + workStatus_->workInfo_ = workInfo_; + bool result = workStatus_->IsSAReady(); + EXPECT_FALSE(result); +} + +/** + * @tc.name: ToString_001 + * @tc.desc: Test WorkStatus ToString. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, ToString_001, TestSize.Level1) +{ + workStatus_->conditionStatus_.clear(); + workStatus_->ToString(WorkCondition::Type::TIMER); + EXPECT_TRUE(workStatus_->conditionStatus_.empty()); +} + +/** + * @tc.name: ToString_002 + * @tc.desc: Test WorkStatus ToString. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, ToString_002, TestSize.Level1) +{ + workStatus_->conditionStatus_.clear(); + workStatus_->conditionStatus_ = "TIMER&ready"; + workStatus_->workInfo_->saId_ = 1000; + workStatus_->workInfo_->residentSa_ = true; + workStatus_->ToString(WorkCondition::Type::TIMER); + EXPECT_FALSE(workStatus_->conditionStatus_.empty()); +} + +/** + * @tc.name: ToString_003 + * @tc.desc: Test WorkStatus ToString. + * @tc.type: FUNC + * @tc.require: I95QHG + */ +HWTEST_F(WorkStatusTest, ToString_003, TestSize.Level1) +{ + workStatus_->conditionStatus_.clear(); + workStatus_->conditionStatus_ = "TIMER&ready"; + workStatus_->ToString(WorkCondition::Type::TIMER); + EXPECT_FALSE(workStatus_->conditionStatus_.empty()); +} } } \ No newline at end of file diff --git a/services/test/src/workschedulerservice_test.cpp b/services/test/src/workschedulerservice_test.cpp index 17977e3..208890e 100644 --- a/services/test/src/workschedulerservice_test.cpp +++ b/services/test/src/workschedulerservice_test.cpp @@ -117,6 +117,7 @@ class MyWorkSchedulerService : public WorkSchedServiceStub { int32_t PauseRunningWorks(int32_t uid) {return 0; } int32_t ResumePausedWorks(int32_t uid) {return 0; } int32_t SetWorkSchedulerConfig(const std::string &configData, int32_t sourceType) { return 0; } + int32_t StopWorkForSA(int32_t saId) { return 0; } }; /** * @tc.name: onStart_001 @@ -504,37 +505,42 @@ HWTEST_F(WorkSchedulerServiceTest, Dump_006, TestSize.Level1) std::vector argsInStr; std::string result; argsInStr.push_back("-s"); - argsInStr.push_back("1"); workSchedulerService_->DumpProcessForEngMode(argsInStr, result); WS_HILOGI("%{public}s", result.c_str()); - EXPECT_EQ(result.empty(), false); + EXPECT_FALSE(result.empty()); argsInStr.clear(); result.clear(); argsInStr.push_back("-s"); - argsInStr.push_back("1"); - argsInStr.push_back("1"); + argsInStr.push_back("-1"); + argsInStr.push_back("-1"); workSchedulerService_->DumpProcessForEngMode(argsInStr, result); WS_HILOGI("%{public}s", result.c_str()); - EXPECT_EQ(result.empty(), false); + EXPECT_FALSE(result.empty()); argsInStr.clear(); result.clear(); argsInStr.push_back("-s"); argsInStr.push_back("1"); - argsInStr.push_back("true"); + argsInStr.push_back("200000"); workSchedulerService_->DumpProcessForEngMode(argsInStr, result); WS_HILOGI("%{public}s", result.c_str()); - EXPECT_EQ(result.empty(), true); + EXPECT_FALSE(result.empty()); argsInStr.clear(); result.clear(); + WorkInfo workinfo = WorkInfo(); + workinfo.uid_ = 202000; + workinfo.workId_ = 1; + workinfo.saId_ = 1000; + workinfo.residentSa_ = true; + workSchedulerService_->AddWorkInner(workinfo); argsInStr.push_back("-s"); - argsInStr.push_back("1"); - argsInStr.push_back("false"); + argsInStr.push_back("1000"); + argsInStr.push_back("202000"); workSchedulerService_->DumpProcessForEngMode(argsInStr, result); WS_HILOGI("%{public}s", result.c_str()); - EXPECT_EQ(result.empty(), true); + EXPECT_FALSE(result.empty()); WS_HILOGI("====== WorkSchedulerServiceTest.Dump_006 end ====== "); } @@ -845,27 +851,35 @@ HWTEST_F(WorkSchedulerServiceTest, GetAppIndexAndBundleNameByUid_001, TestSize.L */ HWTEST_F(WorkSchedulerServiceTest, LoadSa_001, TestSize.Level1) { + std::shared_ptr workInfo_ = std::make_shared(); + workInfo_->SetWorkId(-1); + std::string bundleName = "com.example.workStatus"; + std::string abilityName = "workStatusAbility"; + workInfo_->SetElement(bundleName, abilityName); + workInfo_->RequestPersisted(false); + time_t baseTime; + (void)time(&baseTime); + workInfo_->RequestBaseTime(baseTime); + std::shared_ptr workStatus_ = std::make_shared(*(workInfo_.get()), -1); + workSchedulerService_->ready_ = false; - workSchedulerService_->LoadSa(); + workSchedulerService_->LoadSa(workStatus_); workSchedulerService_->ready_ = true; - workSchedulerService_->saMap_.clear(); - workSchedulerService_->LoadSa(); + workSchedulerService_->LoadSa(workStatus_); - int32_t saId1 = 401; - workSchedulerService_->saMap_.emplace(saId1, true); - workSchedulerService_->LoadSa(); + workInfo_->saId_ = 401; + workSchedulerService_->LoadSa(workStatus_); - workSchedulerService_->saMap_.emplace(saId1, false); - workSchedulerService_->LoadSa(); + workInfo_->residentSa_ = true; + workSchedulerService_->LoadSa(workStatus_); - int32_t saId2 = 5300; - workSchedulerService_->saMap_.emplace(saId2, true); - workSchedulerService_->LoadSa(); + workInfo_->saId_ = 5300; + workSchedulerService_->LoadSa(workStatus_); - workSchedulerService_->saMap_.emplace(saId2, false); - workSchedulerService_->LoadSa(); - EXPECT_FALSE(workSchedulerService_->saMap_.empty()); + workInfo_->residentSa_ = false; + bool ret = workSchedulerService_->LoadSa(workStatus_); + EXPECT_FALSE(ret); } /** diff --git a/services/zidl/include/work_sched_service_proxy.h b/services/zidl/include/work_sched_service_proxy.h index e6104d1..53807a0 100644 --- a/services/zidl/include/work_sched_service_proxy.h +++ b/services/zidl/include/work_sched_service_proxy.h @@ -115,6 +115,13 @@ public: * @return ErrCode ERR_OK on success, others on failure */ int32_t SetWorkSchedulerConfig(const std::string &configData, int32_t sourceType) override; + /** + * @brief Stop SA. + * + * @param saId SA id. + * @return ErrCode ERR_OK on success, others on failure + */ + int32_t StopWorkForSA(int32_t saId) override; private: static inline BrokerDelegator delegator_; }; diff --git a/services/zidl/include/work_sched_service_stub.h b/services/zidl/include/work_sched_service_stub.h index de10509..3e62091 100644 --- a/services/zidl/include/work_sched_service_stub.h +++ b/services/zidl/include/work_sched_service_stub.h @@ -46,30 +46,34 @@ public: * @brief Start work stub. * * @param data The data. + * @param reply The reply. * @return error code, ERR_OK if success. */ - int32_t StartWorkStub(MessageParcel& data); + int32_t StartWorkStub(MessageParcel& data, MessageParcel& reply); /** * @brief Stop work stub. * * @param data The data. + * @param reply The reply. * @return error code, ERR_OK if success. */ - int32_t StopWorkStub(MessageParcel& data); + int32_t StopWorkStub(MessageParcel& data, MessageParcel& reply); /** * @brief Stop and cancel work stub. * * @param data The data. + * @param reply The reply. * @return error code, ERR_OK if success. */ - int32_t StopAndCancelWorkStub(MessageParcel& data); + int32_t StopAndCancelWorkStub(MessageParcel& data, MessageParcel& reply); /** * @brief Stop and clear works stub. * * @param data The data. + * @param reply The reply. * @return error code, ERR_OK if success. */ - int32_t StopAndClearWorksStub(MessageParcel& data); + int32_t StopAndClearWorksStub(MessageParcel& data, MessageParcel& reply); /** * @brief The last work time out stub. * @@ -120,6 +124,14 @@ public: * @return ErrCode ERR_OK on success, others on failure */ int32_t ResumePausedWorksStub(MessageParcel &data, MessageParcel& reply); + /** + * @brief Stop SA. + * + * @param data The data. + * @param reply The reply. + * @return ErrCode ERR_OK on success, others on failure + */ + int32_t StopWorkForSAStub(MessageParcel &data, MessageParcel& reply); private: int32_t HandleObtainAllWorksRequest(MessageParcel &data, MessageParcel &reply); int32_t HandleGetWorkStatusRequest(MessageParcel &data, MessageParcel &reply); diff --git a/services/zidl/src/work_sched_service_proxy.cpp b/services/zidl/src/work_sched_service_proxy.cpp index bfac64c..29fb35f 100644 --- a/services/zidl/src/work_sched_service_proxy.cpp +++ b/services/zidl/src/work_sched_service_proxy.cpp @@ -372,5 +372,36 @@ int32_t WorkSchedServiceProxy::SetWorkSchedulerConfig(const std::string &configD } return ret; } + +int32_t WorkSchedServiceProxy::StopWorkForSA(int32_t saId) +{ + WS_HILOGD("Stop SA, saId:%{public}d", saId); + sptr remote = Remote(); + RETURN_IF_WITH_RET(remote == nullptr, E_CLIENT_CONNECT_SERVICE_FAILED); + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(WorkSchedServiceProxy::GetDescriptor())) { + WS_HILOGE("StopWorkForSA failed, write descriptor failed!"); + return E_PARCEL_OPERATION_FAILED; + } + if (!data.WriteInt32(saId)) { + WS_HILOGE("StopWorkForSA failed, write saId failed!"); + return E_PARCEL_OPERATION_FAILED; + } + int32_t ret = remote->SendRequest( + static_cast(IWorkSchedServiceInterfaceCode::STOP_WORK_FOR_SA), data, reply, option); + if (ret != ERR_OK) { + WS_HILOGE("StopWorkForSA failed, err code: %{public}d", ret); + return E_PARCEL_OPERATION_FAILED; + } + + if (!reply.ReadInt32(ret)) { + WS_HILOGE("StopWorkForSA failed, read errCode error"); + return E_PARCEL_OPERATION_FAILED; + } + return ret; +} } // namespace WorkScheduler } // namespace OHOS diff --git a/services/zidl/src/work_sched_service_stub.cpp b/services/zidl/src/work_sched_service_stub.cpp index 4f474a1..7adef77 100644 --- a/services/zidl/src/work_sched_service_stub.cpp +++ b/services/zidl/src/work_sched_service_stub.cpp @@ -105,24 +105,16 @@ int32_t WorkSchedServiceStub::HandleRequest(uint32_t code, MessageParcel &data, { switch (code) { case static_cast(IWorkSchedServiceInterfaceCode::START_WORK): { - int32_t ret = StartWorkStub(data); - reply.WriteInt32(ret); - return ret; + return StartWorkStub(data, reply); } case static_cast(IWorkSchedServiceInterfaceCode::STOP_WORK): { - int32_t ret = StopWorkStub(data); - reply.WriteInt32(ret); - return ret; + return StopWorkStub(data, reply); } case static_cast(IWorkSchedServiceInterfaceCode::STOP_AND_CANCEL_WORK): { - int32_t ret = StopAndCancelWorkStub(data); - reply.WriteInt32(ret); - return ret; + return StopAndCancelWorkStub(data, reply); } case static_cast(IWorkSchedServiceInterfaceCode::STOP_AND_CLEAR_WORKS): { - int32_t ret = StopAndClearWorksStub(data); - reply.WriteInt32(ret); - return ret; + return StopAndClearWorksStub(data, reply); } case static_cast(IWorkSchedServiceInterfaceCode::IS_LAST_WORK_TIMEOUT): { return HandleIsLastWorkTimeOutRequest(data, reply); @@ -145,6 +137,9 @@ int32_t WorkSchedServiceStub::HandleRequest(uint32_t code, MessageParcel &data, case static_cast(IWorkSchedServiceInterfaceCode::SET_WORK_SCHEDULER_CONFIG): { return HandleSetWorkSchedulerConfig(data, reply); } + case static_cast(IWorkSchedServiceInterfaceCode::STOP_WORK_FOR_SA): { + return StopWorkForSAStub(data, reply); + } default: { WS_HILOGD("OnRemoteRequest switch default, code: %{public}u", code); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -169,39 +164,59 @@ int32_t WorkSchedServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data return result; } -int32_t WorkSchedServiceStub::StartWorkStub(MessageParcel& data) +int32_t WorkSchedServiceStub::StartWorkStub(MessageParcel& data, MessageParcel& reply) { sptr workInfo = data.ReadStrongParcelable(); if (workInfo == nullptr) { WS_HILOGD("workInfo is nullptr"); return E_PARCEL_OPERATION_FAILED; } - return StartWork(*workInfo); + int32_t ret = StartWork(*workInfo); + if (!reply.WriteInt32(ret)) { + WS_HILOGE("StartWorkStub failed, write result error"); + return E_PARCEL_OPERATION_FAILED; + } + return ret; } -int32_t WorkSchedServiceStub::StopWorkStub(MessageParcel& data) +int32_t WorkSchedServiceStub::StopWorkStub(MessageParcel& data, MessageParcel& reply) { sptr workInfo = data.ReadStrongParcelable(); if (workInfo == nullptr) { WS_HILOGD("workInfo is nullptr"); return E_PARCEL_OPERATION_FAILED; } - return StopWork(*workInfo); + int32_t ret = StopWork(*workInfo); + if (!reply.WriteInt32(ret)) { + WS_HILOGE("StopWorkStub failed, write result error"); + return E_PARCEL_OPERATION_FAILED; + } + return ret; } -int32_t WorkSchedServiceStub::StopAndCancelWorkStub(MessageParcel& data) +int32_t WorkSchedServiceStub::StopAndCancelWorkStub(MessageParcel& data, MessageParcel& reply) { sptr workInfo = data.ReadStrongParcelable(); if (workInfo == nullptr) { WS_HILOGD("workInfo is nullptr"); return E_PARCEL_OPERATION_FAILED; } - return StopAndCancelWork(*workInfo); + int32_t ret = StopAndCancelWork(*workInfo); + if (!reply.WriteInt32(ret)) { + WS_HILOGE("StopAndCancelWorkStub failed, write result error"); + return E_PARCEL_OPERATION_FAILED; + } + return ret; } -int32_t WorkSchedServiceStub::StopAndClearWorksStub(MessageParcel& data) +int32_t WorkSchedServiceStub::StopAndClearWorksStub(MessageParcel& data, MessageParcel& reply) { - return StopAndClearWorks(); + int32_t ret = StopAndClearWorks(); + if (!reply.WriteInt32(ret)) { + WS_HILOGE("StopAndClearWorksStub failed, write result error"); + return E_PARCEL_OPERATION_FAILED; + } + return ret; } int32_t WorkSchedServiceStub::IsLastWorkTimeoutStub(MessageParcel& data, bool &result) @@ -257,6 +272,21 @@ int32_t WorkSchedServiceStub::ResumePausedWorksStub(MessageParcel& data, Message return ret; } +int32_t WorkSchedServiceStub::StopWorkForSAStub(MessageParcel& data, MessageParcel& reply) +{ + int32_t saId = -1; + if (!data.ReadInt32(saId)) { + WS_HILOGE("StopWorkForSAStub failed, read saId error"); + return E_PARCEL_OPERATION_FAILED; + } + int32_t ret = StopWorkForSA(saId); + if (!reply.WriteInt32(ret)) { + WS_HILOGE("StopWorkForSAStub failed, write result error"); + return E_PARCEL_OPERATION_FAILED; + } + return ret; +} + int32_t WorkSchedServiceStub::SetTimer(uint32_t code) { #ifdef HICOLLIE_ENABLE -- Gitee