• 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 "work_queue_manager.h"
16 #include "work_scheduler_service.h"
17 #include "work_sched_hilog.h"
18 
19 using namespace std;
20 
21 namespace OHOS {
22 namespace WorkScheduler {
23 const uint32_t TIME_CYCLE = 20 * 60 * 1000; // 20min
24 static int32_t g_timeRetrigger = INT32_MAX;
25 
WorkQueueManager(const wptr<WorkSchedulerService> & wss)26 WorkQueueManager::WorkQueueManager(const wptr<WorkSchedulerService>& wss) : wss_(wss)
27 {
28     timeCycle_ = TIME_CYCLE;
29 }
30 
Init()31 bool WorkQueueManager::Init()
32 {
33     return true;
34 }
35 
AddListener(WorkCondition::Type type,shared_ptr<IConditionListener> listener)36 bool WorkQueueManager::AddListener(WorkCondition::Type type, shared_ptr<IConditionListener> listener)
37 {
38     std::lock_guard<std::mutex> lock(mutex_);
39     if (listenerMap_.count(type) > 0) {
40         return false;
41     }
42     listenerMap_.emplace(type, listener);
43     return true;
44 }
45 
AddWork(shared_ptr<WorkStatus> workStatus)46 bool WorkQueueManager::AddWork(shared_ptr<WorkStatus> workStatus)
47 {
48     if (!workStatus || !workStatus->workInfo_ || !workStatus->workInfo_->GetConditionMap()) {
49         return false;
50     }
51     WS_HILOGD("workStatus ID: %{public}s", workStatus->workId_.c_str());
52     std::lock_guard<std::mutex> lock(mutex_);
53     auto map = workStatus->workInfo_->GetConditionMap();
54     for (auto it : *map) {
55         if (queueMap_.count(it.first) == 0) {
56             queueMap_.emplace(it.first, make_shared<WorkQueue>());
57             if (listenerMap_.count(it.first) != 0) {
58                 listenerMap_.at(it.first)->Start();
59             }
60         }
61         queueMap_.at(it.first)->Push(workStatus);
62     }
63     return true;
64 }
65 
RemoveWork(shared_ptr<WorkStatus> workStatus)66 bool WorkQueueManager::RemoveWork(shared_ptr<WorkStatus> workStatus)
67 {
68     std::lock_guard<std::mutex> lock(mutex_);
69     WS_HILOGD("workStatus ID: %{public}s", workStatus->workId_.c_str());
70     auto map = workStatus->workInfo_->GetConditionMap();
71     for (auto it : *map) {
72         if (queueMap_.count(it.first) > 0) {
73             queueMap_.at(it.first)->Remove(workStatus);
74         }
75         if (queueMap_.count(it.first) == 0) {
76             listenerMap_.at(it.first)->Stop();
77         }
78     }
79     return true;
80 }
81 
CancelWork(shared_ptr<WorkStatus> workStatus)82 bool WorkQueueManager::CancelWork(shared_ptr<WorkStatus> workStatus)
83 {
84     std::lock_guard<std::mutex> lock(mutex_);
85     WS_HILOGD("workStatus ID: %{public}s", workStatus->workId_.c_str());
86     for (auto it : queueMap_) {
87         it.second->CancelWork(workStatus);
88         if (queueMap_.count(it.first) == 0) {
89             listenerMap_.at(it.first)->Stop();
90         }
91     }
92     return true;
93 }
94 
GetReayQueue(WorkCondition::Type conditionType,shared_ptr<DetectorValue> conditionVal)95 vector<shared_ptr<WorkStatus>> WorkQueueManager::GetReayQueue(WorkCondition::Type conditionType,
96     shared_ptr<DetectorValue> conditionVal)
97 {
98     vector<shared_ptr<WorkStatus>> result;
99     std::lock_guard<std::mutex> lock(mutex_);
100     if (conditionType != WorkCondition::Type::GROUP && queueMap_.count(conditionType) > 0) {
101         shared_ptr<WorkQueue> workQueue = queueMap_.at(conditionType);
102         result = workQueue->OnConditionChanged(conditionType, conditionVal);
103     }
104     if (conditionType == WorkCondition::Type::GROUP) {
105         for (auto it : queueMap_) {
106             shared_ptr<WorkQueue> workQueue = it.second;
107             result = workQueue->OnConditionChanged(conditionType, conditionVal);
108         }
109     }
110     auto it = result.begin();
111     while (it != result.end()) {
112         if ((*it)->needRetrigger_) {
113             if (conditionType != WorkCondition::Type::TIMER
114                     && conditionType != WorkCondition::Type::GROUP) {
115                 WS_HILOGD("Need retrigger, start group listener.");
116                 SetTimeRetrigger((*it)->timeRetrigger_);
117                 listenerMap_.at(WorkCondition::Type::GROUP)->Start();
118             }
119             (*it)->needRetrigger_ = false;
120             (*it)->timeRetrigger_ = INT32_MAX;
121             it = result.erase(it);
122         } else {
123             ++it;
124         }
125     }
126     return result;
127 }
128 
OnConditionChanged(WorkCondition::Type conditionType,shared_ptr<DetectorValue> conditionVal)129 void WorkQueueManager::OnConditionChanged(WorkCondition::Type conditionType,
130     shared_ptr<DetectorValue> conditionVal)
131 {
132     vector<shared_ptr<WorkStatus>> readyWorkVector = GetReayQueue(conditionType, conditionVal);
133     if (readyWorkVector.size() == 0) {
134         return;
135     }
136     for (auto it : readyWorkVector) {
137         it->MarkStatus(WorkStatus::Status::CONDITION_READY);
138     }
139     auto ws = wss_.promote();
140     ws->OnConditionReady(make_shared<vector<shared_ptr<WorkStatus>>>(readyWorkVector));
141 }
142 
StopAndClearWorks(list<shared_ptr<WorkStatus>> workList)143 bool WorkQueueManager::StopAndClearWorks(list<shared_ptr<WorkStatus>> workList)
144 {
145     for (auto &it : workList) {
146         CancelWork(it);
147     }
148     return true;
149 }
150 
Dump(string & result)151 void WorkQueueManager::Dump(string& result)
152 {
153     std::lock_guard<std::mutex> lock(mutex_);
154     string conditionType[] = {"network", "charger", "battery_status", "battery_level",
155         "storage", "timer", "unknown"};
156     uint32_t size = sizeof(conditionType);
157     for (auto it : queueMap_) {
158         if (it.first < size) {
159             result.append(conditionType[it.first]);
160         } else {
161             result.append(conditionType[size - 1]);
162         }
163         result.append(" : ");
164         result.append("[");
165         string workIdStr;
166         it.second->GetWorkIdStr(workIdStr);
167         result.append(workIdStr);
168         result.append("]\n");
169     }
170 }
171 
SetTimeCycle(uint32_t time)172 void WorkQueueManager::SetTimeCycle(uint32_t time)
173 {
174     timeCycle_ = time;
175 }
176 
GetTimeCycle()177 uint32_t WorkQueueManager::GetTimeCycle()
178 {
179     return timeCycle_;
180 }
181 
SetTimeRetrigger(int32_t time)182 void WorkQueueManager::SetTimeRetrigger(int32_t time)
183 {
184     g_timeRetrigger = time;
185 }
186 
GetTimeRetrigger()187 int32_t WorkQueueManager::GetTimeRetrigger()
188 {
189     return g_timeRetrigger;
190 }
191 
SetMinIntervalByDump(int64_t interval)192 void WorkQueueManager::SetMinIntervalByDump(int64_t interval)
193 {
194     for (auto it : queueMap_) {
195         it.second->SetMinIntervalByDump(interval);
196     }
197 }
198 } // namespace WorkScheduler
199 } // namespace OHOS