• 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 
16 #include "work_status.h"
17 
18 #include "battery_srv_client.h"
19 #include "work_sched_common.h"
20 #include "work_sched_utils.h"
21 
22 using namespace std;
23 using namespace OHOS::PowerMgr;
24 
25 namespace OHOS {
26 namespace WorkScheduler {
27 static const int ONE_SECOND = 1000;
28 
getCurrentTime()29 time_t getCurrentTime()
30 {
31     time_t result;
32     time(&result);
33     return result;
34 }
35 
WorkStatus(WorkInfo & workInfo,int32_t uid)36 WorkStatus::WorkStatus(WorkInfo &workInfo, int32_t uid)
37 {
38     this->workInfo_ = make_shared<WorkInfo>(workInfo);
39     this->workId_ = MakeWorkId(workInfo.GetWorkId(), uid);
40     this->bundleName_ = workInfo.GetBundleName();
41     this->abilityName_ = workInfo.GetAbilityName();
42     this->baseTime_ = getCurrentTime();
43     this->uid_ = uid;
44     this->userId_ = WorkSchedUtils::GetUserIdByUid(uid);
45     if (workInfo.GetConditionMap()->count(WorkCondition::Type::TIMER) > 0) {
46         auto workTimerCondition = workInfo.GetConditionMap()->at(WorkCondition::Type::TIMER);
47         shared_ptr<Condition> timeCondition = make_shared<Condition>();
48         timeCondition->uintVal = workTimerCondition->uintVal;
49         if (!workTimerCondition->boolVal) {
50             timeCondition->intVal = workTimerCondition->intVal;
51         }
52         conditionMap_.emplace(WorkCondition::Type::TIMER, timeCondition);
53     }
54     this->persisted_ = workInfo.IsPersisted();
55     this->priority_ = DEFAULT_PRIORITY;
56     this->currentStatus_ = WAIT_CONDITION;
57 }
58 
~WorkStatus()59 WorkStatus::~WorkStatus() {}
60 
OnConditionChanged(WorkCondition::Type & type,shared_ptr<Condition> value)61 void WorkStatus::OnConditionChanged(WorkCondition::Type &type, shared_ptr<Condition> value)
62 {
63     if (workInfo_->GetConditionMap()->count(type) > 0
64         && type != WorkCondition::Type::TIMER) {
65         if (conditionMap_.count(type) > 0) {
66             conditionMap_.at(type) = value;
67         } else {
68             conditionMap_.emplace(type, value);
69         }
70     }
71     if (IsReady()) {
72         MarkStatus(Status::CONDITION_READY);
73     }
74 }
75 
MakeWorkId(int32_t workId,int32_t uid)76 string WorkStatus::MakeWorkId(int32_t workId, int32_t uid)
77 {
78     return string("u") + to_string(uid) + "_" + to_string(workId);
79 }
80 
MarkTimeout()81 void WorkStatus::MarkTimeout()
82 {
83     lastTimeout_ = true;
84 }
85 
MarkStatus(Status status)86 void WorkStatus::MarkStatus(Status status)
87 {
88     currentStatus_ = status;
89 }
90 
MarkRound()91 void WorkStatus::MarkRound() {}
92 
UpdateTimerIfNeed()93 void WorkStatus::UpdateTimerIfNeed()
94 {
95     if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
96         baseTime_ = getCurrentTime();
97         if (conditionMap_.at(WorkCondition::Type::TIMER)->boolVal) {
98             return;
99         }
100         int cycleLeft = conditionMap_.at(WorkCondition::Type::TIMER)->intVal;
101         conditionMap_.at(WorkCondition::Type::TIMER)->intVal = cycleLeft - 1;
102     }
103 }
104 
NeedRemove()105 bool WorkStatus::NeedRemove()
106 {
107     if (conditionMap_.count(WorkCondition::Type::TIMER) <= 0) {
108         return true;
109     }
110     if (conditionMap_.at(WorkCondition::Type::TIMER)->boolVal) {
111         return false;
112     }
113     if (conditionMap_.at(WorkCondition::Type::TIMER)->intVal <= 0) {
114         return true;
115     }
116     return false;
117 }
118 
IsSameUser()119 bool WorkStatus::IsSameUser()
120 {
121     if (!WorkSchedUtils::IsIdActive(userId_)) {
122         return false;
123     }
124     return true;
125 }
126 
IsReady()127 bool WorkStatus::IsReady()
128 {
129     if (!IsSameUser()) {
130         WS_HILOGD("Not same user. WorkId:%{public}s", workId_.c_str());
131         return false;
132     }
133     if (IsRunning()) {
134         WS_HILOGD("Work is running");
135         return false;
136     }
137     auto workConditionMap = workInfo_->GetConditionMap();
138     for (auto it : *workConditionMap) {
139         if (conditionMap_.count(it.first) <= 0) {
140             return false;
141         }
142         switch (it.first) {
143             case WorkCondition::Type::NETWORK: {
144                 if (conditionMap_.at(it.first)->enumVal == WorkCondition::Network::NETWORK_UNKNOWN) {
145                     return false;
146                 }
147                 if (workConditionMap->at(it.first)->enumVal != WorkCondition::Network::NETWORK_TYPE_ANY &&
148                     workConditionMap->at(it.first)->enumVal != conditionMap_.at(it.first)->enumVal) {
149                     return false;
150                 }
151                 break;
152             }
153             case WorkCondition::Type::BATTERY_STATUS: {
154                 int batteryReq = workConditionMap->at(it.first)->enumVal;
155                 if (batteryReq != WorkCondition::BatteryStatus::BATTERY_STATUS_LOW_OR_OKAY &&
156                     batteryReq != conditionMap_.at(it.first)->enumVal) {
157                     return false;
158                 }
159                 break;
160             }
161             case WorkCondition::Type::STORAGE: {
162                 if (workConditionMap->at(it.first)->enumVal != WorkCondition::Storage::STORAGE_LEVEL_LOW_OR_OKAY &&
163                     workConditionMap->at(it.first)->enumVal != conditionMap_.at(it.first)->enumVal) {
164                     return false;
165                 }
166                 break;
167             }
168             case WorkCondition::Type::CHARGER: {
169                 auto conditionSet = workConditionMap->at(it.first);
170                 auto conditionCurrent = conditionMap_.at(it.first);
171                 if (conditionSet->boolVal) {
172                     if (conditionCurrent->enumVal != conditionSet->enumVal &&
173                         conditionSet->enumVal !=
174                         static_cast<int32_t>(WorkCondition::Charger::CHARGING_PLUGGED_ANY)) {
175                         return false;
176                     }
177                 } else {
178                     if (conditionCurrent->enumVal !=
179                         static_cast<int32_t>(WorkCondition::Charger::CHARGING_UNPLUGGED)) {
180                         return false;
181                     }
182                 }
183                 break;
184             }
185             case WorkCondition::Type::BATTERY_LEVEL: {
186                 if (workConditionMap->at(it.first)->intVal > conditionMap_.at(it.first)->intVal) {
187                     return false;
188                 }
189                 break;
190             }
191             case WorkCondition::Type::TIMER: {
192                 uint32_t intervalTime = workConditionMap->at(WorkCondition::Type::TIMER)->uintVal;
193                 double del = difftime(getCurrentTime(), baseTime_) * ONE_SECOND;
194                 WS_HILOGD("del time:%{public}f, intervalTime:%{public}d", del, intervalTime);
195                 if (del < intervalTime) {
196                     return false;
197                 }
198                 break;
199             }
200             default:
201                 break;
202         }
203     }
204     return true;
205 }
206 
IsRunning()207 bool WorkStatus::IsRunning()
208 {
209     return currentStatus_ == RUNNING;
210 }
211 
IsReadyStatus()212 bool WorkStatus::IsReadyStatus()
213 {
214     return currentStatus_ == CONDITION_READY;
215 }
216 
IsRemoved()217 bool WorkStatus::IsRemoved()
218 {
219     return currentStatus_ == REMOVED;
220 }
221 
IsLastWorkTimeout()222 bool WorkStatus::IsLastWorkTimeout()
223 {
224     return lastTimeout_;
225 }
226 
IsRepeating()227 bool WorkStatus::IsRepeating()
228 {
229     if (conditionMap_.count(WorkCondition::Type::TIMER) <= 0) {
230         return false;
231     }
232     if (conditionMap_.at(WorkCondition::Type::TIMER)->boolVal) {
233         return true;
234     } else {
235         return conditionMap_.at(WorkCondition::Type::TIMER)->intVal > 0;
236     }
237 }
238 
GetStatus()239 WorkStatus::Status WorkStatus::GetStatus()
240 {
241     return currentStatus_;
242 }
243 
Dump(string & result)244 void WorkStatus::Dump(string& result)
245 {
246     result.append("{\n");
247     result.append(string("\"workId\":") + workId_ + ",\n");
248     result.append(string("\"bundleName\":") + bundleName_ + ",\n");
249     result.append(string("\"status\":") + to_string(currentStatus_) + ",\n");
250     result.append(string("\"conditionMap\":{\n"));
251     if (conditionMap_.count(WorkCondition::Type::NETWORK) > 0) {
252         result.append(string("\"networkType\":") +
253             to_string(conditionMap_.at(WorkCondition::Type::NETWORK)->enumVal) + ",\n");
254     }
255     if (conditionMap_.count(WorkCondition::Type::CHARGER) > 0) {
256         result.append(string("\"isCharging\":") +
257             (conditionMap_.at(WorkCondition::Type::CHARGER)->boolVal ? "true" : "false") + ",\n");
258         result.append(string("\"chargerType\":") +
259             to_string(conditionMap_.at(WorkCondition::Type::CHARGER)->enumVal) + ",\n");
260     }
261     if (conditionMap_.count(WorkCondition::Type::BATTERY_LEVEL) > 0) {
262         result.append(string("\"batteryLevel\":") +
263             to_string(conditionMap_.at(WorkCondition::Type::BATTERY_LEVEL)->intVal) + ",\n");
264     }
265     if (conditionMap_.count(WorkCondition::Type::BATTERY_STATUS) > 0) {
266         result.append(string("\"batteryStatus\":") +
267             to_string(conditionMap_.at(WorkCondition::Type::BATTERY_STATUS)->enumVal) + ",\n");
268     }
269     if (conditionMap_.count(WorkCondition::Type::STORAGE) > 0) {
270         result.append(string("\"storageLevel\":") +
271             to_string(conditionMap_.at(WorkCondition::Type::STORAGE)->enumVal) + ",\n");
272     }
273     if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
274         result.append(string("\"baseTime\":") + to_string(baseTime_) + ",\n");
275         if (conditionMap_.at(WorkCondition::Type::TIMER)->boolVal) {
276             result.append(string("\"isRepeat\": true,\n"));
277         } else {
278             result.append(string("\"cycleLeft\":") +
279                 to_string(conditionMap_.at(WorkCondition::Type::TIMER)->intVal) + ",\n");
280         }
281     }
282     result.append("},\n\"workInfo\":\n");
283     workInfo_->Dump(result);
284     result.append("}\n");
285     result.append("\n");
286     WS_HILOGD("%s", result.c_str());
287 }
288 } // namespace WorkScheduler
289 } // namespace OHOS