/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "work_queue.h" #include "work_condition.h" #include "work_sched_hilog.h" #include "work_sched_errors.h" using namespace std; namespace OHOS { namespace WorkScheduler { vector> WorkQueue::OnConditionChanged(WorkCondition::Type type, shared_ptr conditionVal) { shared_ptr value = make_shared(); switch (type) { case WorkCondition::Type::NETWORK: // fall-through case WorkCondition::Type::CHARGER: // fall-through case WorkCondition::Type::BATTERY_STATUS: // fall-through case WorkCondition::Type::STORAGE: { value->enumVal = conditionVal->intVal; break; } case WorkCondition::Type::BATTERY_LEVEL: { value->intVal = conditionVal->intVal; break; } case WorkCondition::Type::TIMER: { break; } case WorkCondition::Type::GROUP: { value->enumVal = conditionVal->intVal; value->intVal = conditionVal->timeVal; value->boolVal = conditionVal->boolVal; value->strVal = conditionVal->strVal; break; } default: {} } vector> result; std::set uidList; for (auto it : workList_) { if (it->OnConditionChanged(type, value) == E_GROUP_CHANGE_NOT_MATCH_HAP) { continue; } if (uidList.count(it->uid_) > 0 && it->GetMinInterval() != 0) { continue; } if (it->IsReady()) { result.emplace_back(it); uidList.insert(it->uid_); } else { if (it->IsReadyStatus()) { it->MarkStatus(WorkStatus::Status::WAIT_CONDITION); } } if (it->needRetrigger_) { result.emplace_back(it); } } return result; } void WorkQueue::Push(shared_ptr>> workStatusVector) { for (auto it : *workStatusVector) { Push(it); } workList_.sort(WorkComp()); } void WorkQueue::Push(shared_ptr workStatus) { if (this->Contains(make_shared(workStatus->workId_))) { for (auto it : workList_) { if (it->workId_.compare(workStatus->workId_) == 0) { return; } } return; } workList_.push_back(workStatus); } bool WorkQueue::Remove(shared_ptr workStatus) { auto iter = std::find(workList_.cbegin(), workList_.cend(), workStatus); if (iter != workList_.end()) { workList_.remove(*iter); } return true; } uint32_t WorkQueue::GetSize() { return workList_.size(); } bool WorkQueue::Contains(std::shared_ptr workId) { auto iter = std::find_if(workList_.cbegin(), workList_.cend(), [&workId] (const shared_ptr &workStatus) { return workId->compare(workStatus->workId_) == 0; }); if (iter != workList_.end()) { return true; } return false; } shared_ptr WorkQueue::Find(string workId) { auto iter = std::find_if(workList_.cbegin(), workList_.cend(), [&workId](const shared_ptr &workStatus) { return workStatus->workId_ == workId; }); if (iter != workList_.end()) { return *iter; } return nullptr; } shared_ptr WorkQueue::GetWorkToRunByPriority() { workList_.sort(WorkComp()); auto work = workList_.begin(); shared_ptr workStatus = nullptr; while (work != workList_.end()) { if ((*work)->GetStatus() == WorkStatus::CONDITION_READY) { workStatus = *work; break; } work++; } return workStatus; } bool WorkQueue::CancelWork(shared_ptr workStatus) { workList_.remove(workStatus); return true; } list> WorkQueue::GetWorkList() { return workList_; } void WorkQueue::RemoveUnReady() { workList_.remove_if([](shared_ptr value) { return (value->GetStatus() != WorkStatus::Status::CONDITION_READY); }); } int32_t WorkQueue::GetRunningCount() { int32_t count = 0; for (shared_ptr work : workList_) { if (work->IsRunning()) { count++; } } return count; } void WorkQueue::GetWorkIdStr(string& result) { for (auto it : workList_) { result.append(it->workId_ + ", "); } } void WorkQueue::Dump(string& result) { for (auto it : workList_) { it->Dump(result); } } void WorkQueue::ClearAll() { workList_.clear(); } bool WorkComp::operator () (const shared_ptr w1, const shared_ptr w2) { return w1->priority_ >= w2->priority_; } void WorkQueue::SetMinIntervalByDump(int64_t interval) { for (auto it : workList_) { it->SetMinIntervalByDump(interval); } } } // namespace WorkScheduler } // namespace OHOS