• 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 #include "work_scheduler_service.h"
22 
23 using namespace std;
24 
25 namespace OHOS {
26 namespace WorkScheduler {
OnConditionChanged(WorkCondition::Type type,shared_ptr<DetectorValue> conditionVal)27 vector<shared_ptr<WorkStatus>> WorkQueue::OnConditionChanged(WorkCondition::Type type,
28     shared_ptr<DetectorValue> conditionVal)
29 {
30     shared_ptr<Condition> value = make_shared<Condition>();
31     switch (type) {
32         case WorkCondition::Type::NETWORK:
33         // fall-through
34         case WorkCondition::Type::BATTERY_STATUS:
35         // fall-through
36         case WorkCondition::Type::STORAGE: {
37             value->enumVal = conditionVal->intVal;
38             break;
39         }
40         case WorkCondition::Type::CHARGER: {
41             value->enumVal = conditionVal->intVal;
42             value->boolVal = (conditionVal->intVal > WorkCondition::Charger::CHARGING_PLUGGED_ANY
43                 && conditionVal->intVal < WorkCondition::Charger::CHARGING_UNKNOWN);
44             break;
45         }
46         case WorkCondition::Type::BATTERY_LEVEL: {
47             value->intVal = conditionVal->intVal;
48             break;
49         }
50         case WorkCondition::Type::TIMER: {
51             break;
52         }
53         case WorkCondition::Type::GROUP: {
54             value->enumVal = conditionVal->intVal;
55             value->intVal = conditionVal->timeVal;
56             value->boolVal = conditionVal->boolVal;
57             value->strVal = conditionVal->strVal;
58             break;
59         }
60         case WorkCondition::Type::STANDBY: {
61             value->boolVal = conditionVal->boolVal;
62             break;
63         }
64         default: {}
65     }
66     vector<shared_ptr<WorkStatus>> result;
67     std::set<int32_t> uidList;
68     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
69     for (auto it : workList_) {
70         if (it->OnConditionChanged(type, value) == E_GROUP_CHANGE_NOT_MATCH_HAP) {
71             continue;
72         }
73         if (uidList.count(it->uid_) > 0 && it->GetMinInterval() != 0 &&
74             !DelayedSpSingleton<WorkSchedulerService>::GetInstance()->CheckEffiResApplyInfo(it->uid_)) {
75             WS_HILOGI("One uid can start only one work.");
76             continue;
77         }
78         if (it->IsReady()) {
79             result.emplace_back(it);
80             uidList.insert(it->uid_);
81         } else {
82             if (it->IsReadyStatus()) {
83                 it->MarkStatus(WorkStatus::Status::WAIT_CONDITION);
84             }
85         }
86         if (it->needRetrigger_) {
87             result.emplace_back(it);
88         }
89     }
90     return result;
91 }
92 
Push(shared_ptr<vector<shared_ptr<WorkStatus>>> workStatusVector)93 void WorkQueue::Push(shared_ptr<vector<shared_ptr<WorkStatus>>> workStatusVector)
94 {
95     for (auto it : *workStatusVector) {
96         Push(it);
97     }
98     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
99     workList_.sort(WorkComp());
100 }
101 
Push(shared_ptr<WorkStatus> workStatus)102 void WorkQueue::Push(shared_ptr<WorkStatus> workStatus)
103 {
104     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
105     if (this->Contains(make_shared<string>(workStatus->workId_))) {
106         for (auto it : workList_) {
107             if (it->workId_.compare(workStatus->workId_) == 0) {
108                 return;
109             }
110         }
111         return;
112     }
113     workList_.push_back(workStatus);
114 }
115 
Remove(shared_ptr<WorkStatus> workStatus)116 bool WorkQueue::Remove(shared_ptr<WorkStatus> workStatus)
117 {
118     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
119     auto iter = std::find(workList_.cbegin(), workList_.cend(), workStatus);
120     if (iter != workList_.end()) {
121         workList_.remove(*iter);
122     }
123     return true;
124 }
125 
GetSize()126 uint32_t WorkQueue::GetSize()
127 {
128     return workList_.size();
129 }
130 
Contains(std::shared_ptr<std::string> workId)131 bool WorkQueue::Contains(std::shared_ptr<std::string> workId)
132 {
133     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
134     auto iter = std::find_if(workList_.cbegin(), workList_.cend(), [&workId]
135         (const shared_ptr<WorkStatus> &workStatus) { return workId->compare(workStatus->workId_) == 0; });
136     if (iter != workList_.end()) {
137         return true;
138     }
139     return false;
140 }
141 
Find(string workId)142 shared_ptr<WorkStatus> WorkQueue::Find(string workId)
143 {
144     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
145     auto iter = std::find_if(workList_.cbegin(), workList_.cend(),
146         [&workId](const shared_ptr<WorkStatus> &workStatus) { return workStatus->workId_ == workId; });
147     if (iter != workList_.end()) {
148         return *iter;
149     }
150     return nullptr;
151 }
152 
GetWorkToRunByPriority()153 shared_ptr<WorkStatus> WorkQueue::GetWorkToRunByPriority()
154 {
155     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
156     workList_.sort(WorkComp());
157     auto work = workList_.begin();
158     shared_ptr<WorkStatus> workStatus = nullptr;
159     while (work != workList_.end()) {
160         if ((*work)->GetStatus() == WorkStatus::CONDITION_READY) {
161             workStatus = *work;
162             break;
163         }
164         work++;
165     }
166     return workStatus;
167 }
168 
CancelWork(shared_ptr<WorkStatus> workStatus)169 bool WorkQueue::CancelWork(shared_ptr<WorkStatus> workStatus)
170 {
171     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
172     workList_.remove(workStatus);
173     return true;
174 }
175 
GetWorkList()176 list<shared_ptr<WorkStatus>> WorkQueue::GetWorkList()
177 {
178     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
179     return workList_;
180 }
181 
RemoveUnReady()182 void WorkQueue::RemoveUnReady()
183 {
184     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
185     workList_.remove_if([](shared_ptr<WorkStatus> value) {
186         return (value->GetStatus() != WorkStatus::Status::CONDITION_READY);
187     });
188 }
189 
GetRunningCount()190 int32_t WorkQueue::GetRunningCount()
191 {
192     int32_t count = 0;
193     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
194     for (shared_ptr<WorkStatus> work : workList_) {
195         if (work->IsRunning()) {
196             count++;
197         }
198     }
199     return count;
200 }
201 
GetRunningWorks()202 std::list<std::shared_ptr<WorkInfo>> WorkQueue::GetRunningWorks()
203 {
204     std::list<std::shared_ptr<WorkInfo>> workInfo;
205     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
206     for (shared_ptr<WorkStatus> work : workList_) {
207         if (work->IsRunning()) {
208             auto info = std::make_shared<WorkInfo>();
209             info->SetElement(work->bundleName_, work->abilityName_);
210             info->RefreshUid(work->uid_);
211             workInfo.emplace_back(info);
212         }
213     }
214     return workInfo;
215 }
216 
GetWorkIdStr(string & result)217 void WorkQueue::GetWorkIdStr(string& result)
218 {
219     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
220     for (auto it : workList_) {
221         result.append(it->workId_ + ", ");
222     }
223 }
224 
Dump(string & result)225 void WorkQueue::Dump(string& result)
226 {
227     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
228     for (auto it : workList_) {
229         it->Dump(result);
230     }
231 }
232 
ClearAll()233 void WorkQueue::ClearAll()
234 {
235     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
236     workList_.clear();
237 }
238 
operator ()(const shared_ptr<WorkStatus> w1,const shared_ptr<WorkStatus> w2)239 bool WorkComp::operator () (const shared_ptr<WorkStatus> w1, const shared_ptr<WorkStatus> w2)
240 {
241     return w1->priority_ >= w2->priority_;
242 }
243 
SetMinIntervalByDump(int64_t interval)244 void WorkQueue::SetMinIntervalByDump(int64_t interval)
245 {
246     std::lock_guard<std::recursive_mutex> lock(workListMutex_);
247     for (auto it : workList_) {
248         it->SetMinIntervalByDump(interval);
249     }
250 }
251 } // namespace WorkScheduler
252 } // namespace OHOS