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