• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 <set>
16 #include "work_queue.h"
17 
18 #include "work_condition.h"
19 #include "work_sched_hilog.h"
20 #include "work_sched_errors.h"
21 
22 using namespace std;
23 
24 namespace OHOS {
25 namespace WorkScheduler {
OnConditionChanged(WorkCondition::Type type,shared_ptr<DetectorValue> conditionVal)26 vector<shared_ptr<WorkStatus>> WorkQueue::OnConditionChanged(WorkCondition::Type type,
27     shared_ptr<DetectorValue> conditionVal)
28 {
29     shared_ptr<Condition> value = make_shared<Condition>();
30     switch (type) {
31         case WorkCondition::Type::NETWORK:
32         // fall-through
33         case WorkCondition::Type::CHARGER:
34         // fall-through
35         case WorkCondition::Type::BATTERY_STATUS:
36         // fall-through
37         case WorkCondition::Type::STORAGE: {
38             value->enumVal = conditionVal->intVal;
39             break;
40         }
41         case WorkCondition::Type::BATTERY_LEVEL: {
42             value->intVal = conditionVal->intVal;
43             break;
44         }
45         case WorkCondition::Type::TIMER: {
46             break;
47         }
48         case WorkCondition::Type::GROUP: {
49             value->enumVal = conditionVal->intVal;
50             value->intVal = conditionVal->timeVal;
51             value->boolVal = conditionVal->boolVal;
52             value->strVal = conditionVal->strVal;
53             break;
54         }
55         default: {}
56     }
57     vector<shared_ptr<WorkStatus>> result;
58     std::set<int32_t> uidList;
59     for (auto it : workList_) {
60         if (it->OnConditionChanged(type, value) == E_GROUP_CHANGE_NOT_MATCH_HAP) {
61             continue;
62         }
63         if (uidList.count(it->uid_) > 0 && it->GetMinInterval() != 0) {
64             continue;
65         }
66         if (it->IsReady()) {
67             result.emplace_back(it);
68             uidList.insert(it->uid_);
69         } else {
70             if (it->IsReadyStatus()) {
71                 it->MarkStatus(WorkStatus::Status::WAIT_CONDITION);
72             }
73         }
74         if (it->needRetrigger_) {
75             result.emplace_back(it);
76         }
77     }
78     return result;
79 }
80 
Push(shared_ptr<vector<shared_ptr<WorkStatus>>> workStatusVector)81 void WorkQueue::Push(shared_ptr<vector<shared_ptr<WorkStatus>>> workStatusVector)
82 {
83     for (auto it : *workStatusVector) {
84         Push(it);
85     }
86     workList_.sort(WorkComp());
87 }
88 
Push(shared_ptr<WorkStatus> workStatus)89 void WorkQueue::Push(shared_ptr<WorkStatus> workStatus)
90 {
91     if (this->Contains(make_shared<string>(workStatus->workId_))) {
92         for (auto it : workList_) {
93             if (it->workId_.compare(workStatus->workId_) == 0) {
94                 return;
95             }
96         }
97         return;
98     }
99     workList_.push_back(workStatus);
100 }
101 
Remove(shared_ptr<WorkStatus> workStatus)102 bool WorkQueue::Remove(shared_ptr<WorkStatus> workStatus)
103 {
104     auto iter = std::find(workList_.cbegin(), workList_.cend(), workStatus);
105     if (iter != workList_.end()) {
106         workList_.remove(*iter);
107     }
108     return true;
109 }
110 
GetSize()111 uint32_t WorkQueue::GetSize()
112 {
113     return workList_.size();
114 }
115 
Contains(std::shared_ptr<std::string> workId)116 bool WorkQueue::Contains(std::shared_ptr<std::string> workId)
117 {
118     auto iter = std::find_if(workList_.cbegin(), workList_.cend(), [&workId]
119         (const shared_ptr<WorkStatus> &workStatus) { return workId->compare(workStatus->workId_) == 0; });
120     if (iter != workList_.end()) {
121         return true;
122     }
123     return false;
124 }
125 
Find(string workId)126 shared_ptr<WorkStatus> WorkQueue::Find(string workId)
127 {
128     auto iter = std::find_if(workList_.cbegin(), workList_.cend(),
129         [&workId](const shared_ptr<WorkStatus> &workStatus) { return workStatus->workId_ == workId; });
130     if (iter != workList_.end()) {
131         return *iter;
132     }
133     return nullptr;
134 }
135 
GetWorkToRunByPriority()136 shared_ptr<WorkStatus> WorkQueue::GetWorkToRunByPriority()
137 {
138     workList_.sort(WorkComp());
139     auto work = workList_.begin();
140     shared_ptr<WorkStatus> workStatus = nullptr;
141     while (work != workList_.end()) {
142         if ((*work)->GetStatus() == WorkStatus::CONDITION_READY) {
143             workStatus = *work;
144             break;
145         }
146         work++;
147     }
148     return workStatus;
149 }
150 
CancelWork(shared_ptr<WorkStatus> workStatus)151 bool WorkQueue::CancelWork(shared_ptr<WorkStatus> workStatus)
152 {
153     workList_.remove(workStatus);
154     return true;
155 }
156 
GetWorkList()157 list<shared_ptr<WorkStatus>> WorkQueue::GetWorkList()
158 {
159     return workList_;
160 }
161 
RemoveUnReady()162 void WorkQueue::RemoveUnReady()
163 {
164     workList_.remove_if([](shared_ptr<WorkStatus> value) {
165         return (value->GetStatus() != WorkStatus::Status::CONDITION_READY);
166     });
167 }
168 
GetRunningCount()169 int32_t WorkQueue::GetRunningCount()
170 {
171     int32_t count = 0;
172     for (shared_ptr<WorkStatus> work : workList_) {
173         if (work->IsRunning()) {
174             count++;
175         }
176     }
177     return count;
178 }
179 
GetWorkIdStr(string & result)180 void WorkQueue::GetWorkIdStr(string& result)
181 {
182     for (auto it : workList_) {
183         result.append(it->workId_ + ", ");
184     }
185 }
186 
Dump(string & result)187 void WorkQueue::Dump(string& result)
188 {
189     for (auto it : workList_) {
190         it->Dump(result);
191     }
192 }
193 
ClearAll()194 void WorkQueue::ClearAll()
195 {
196     workList_.clear();
197 }
198 
operator ()(const shared_ptr<WorkStatus> w1,const shared_ptr<WorkStatus> w2)199 bool WorkComp::operator () (const shared_ptr<WorkStatus> w1, const shared_ptr<WorkStatus> w2)
200 {
201     return w1->priority_ >= w2->priority_;
202 }
203 
SetMinIntervalByDump(int64_t interval)204 void WorkQueue::SetMinIntervalByDump(int64_t interval)
205 {
206     for (auto it : workList_) {
207         it->SetMinIntervalByDump(interval);
208     }
209 }
210 } // namespace WorkScheduler
211 } // namespace OHOS