• 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_info.h"
16 
17 #include "work_sched_hilog.h"
18 
19 namespace OHOS {
20 namespace WorkScheduler {
21 const int32_t INVALID_VALUE = -1;
22 const int32_t INVALID_TIME_VALUE = 0;
23 const uint32_t MAX_SIZE = 1024;
24 
WorkInfo()25 WorkInfo::WorkInfo()
26 {
27     workId_ = INVALID_VALUE;
28     uid_ = INVALID_VALUE;
29     persisted_ = false;
30     extras_ = nullptr;
31 }
32 
~WorkInfo()33 WorkInfo::~WorkInfo() {}
34 
SetWorkId(int32_t workId)35 void WorkInfo::SetWorkId(int32_t workId)
36 {
37     workId_ = workId;
38 }
39 
SetElement(std::string bundleName,std::string abilityName)40 void WorkInfo::SetElement(std::string bundleName, std::string abilityName)
41 {
42     bundleName_ = bundleName;
43     abilityName_ = abilityName;
44 }
45 
RequestPersisted(bool persisted)46 void WorkInfo::RequestPersisted(bool persisted)
47 {
48     persisted_ = persisted;
49 }
50 
RequestNetworkType(WorkCondition::Network condition)51 void WorkInfo::RequestNetworkType(WorkCondition::Network condition)
52 {
53     std::shared_ptr<Condition> networkCondition = std::make_shared<Condition>();
54     networkCondition->enumVal = static_cast<int32_t>(condition);
55     conditionMap_.emplace(WorkCondition::Type::NETWORK, networkCondition);
56 }
57 
RequestChargerType(bool isCharging,WorkCondition::Charger condition)58 void WorkInfo::RequestChargerType(bool isCharging, WorkCondition::Charger condition)
59 {
60     std::shared_ptr<Condition> chargerCondition = std::make_shared<Condition>();
61     chargerCondition->boolVal = isCharging;
62     chargerCondition->enumVal = static_cast<int32_t>(condition);
63     conditionMap_.emplace(WorkCondition::Type::CHARGER, chargerCondition);
64 }
65 
RequestBatteryLevel(int32_t battLevel)66 void WorkInfo::RequestBatteryLevel(int32_t battLevel)
67 {
68     std::shared_ptr<Condition> batteryLevelCondition = std::make_shared<Condition>();
69     batteryLevelCondition->intVal = battLevel;
70     conditionMap_.emplace(WorkCondition::Type::BATTERY_LEVEL, batteryLevelCondition);
71 }
72 
RequestBatteryStatus(WorkCondition::BatteryStatus condition)73 void WorkInfo::RequestBatteryStatus(WorkCondition::BatteryStatus condition)
74 {
75     std::shared_ptr<Condition> batteryCondition = std::make_shared<Condition>();
76     batteryCondition->enumVal = static_cast<int32_t>(condition);
77     conditionMap_.emplace(WorkCondition::Type::BATTERY_STATUS, batteryCondition);
78 }
79 
RequestStorageLevel(WorkCondition::Storage condition)80 void WorkInfo::RequestStorageLevel(WorkCondition::Storage condition)
81 {
82     std::shared_ptr<Condition> storageCondition = std::make_shared<Condition>();
83     storageCondition->enumVal = static_cast<int32_t>(condition);
84     conditionMap_.emplace(WorkCondition::Type::STORAGE, storageCondition);
85 }
86 
RequestRepeatCycle(uint32_t timeInterval,int32_t cycle)87 void WorkInfo::RequestRepeatCycle(uint32_t timeInterval, int32_t cycle)
88 {
89     std::shared_ptr<Condition> repeatCycle = std::make_shared<Condition>();
90     repeatCycle->uintVal = timeInterval;
91     repeatCycle->intVal = cycle;
92     repeatCycle->boolVal = false;
93     conditionMap_.emplace(WorkCondition::Type::TIMER, repeatCycle);
94 }
95 
RequestRepeatCycle(uint32_t timeInterval)96 void WorkInfo::RequestRepeatCycle(uint32_t timeInterval)
97 {
98     std::shared_ptr<Condition> repeatCycle = std::make_shared<Condition>();
99     repeatCycle->uintVal = timeInterval;
100     repeatCycle->boolVal = true;
101     conditionMap_.emplace(WorkCondition::Type::TIMER, repeatCycle);
102 }
103 
RequestExtras(AAFwk::WantParams extras)104 void WorkInfo::RequestExtras(AAFwk::WantParams extras)
105 {
106     extras_ = std::make_shared<AAFwk::WantParams>(extras);
107 }
108 
RefreshUid(int32_t uid)109 void WorkInfo::RefreshUid(int32_t uid)
110 {
111     uid_ = uid;
112 }
113 
GetUid()114 int32_t WorkInfo::GetUid()
115 {
116     return uid_;
117 }
118 
GetWorkId()119 int32_t WorkInfo::GetWorkId()
120 {
121     return workId_;
122 }
123 
GetBundleName()124 std::string WorkInfo::GetBundleName()
125 {
126     return bundleName_;
127 }
128 
GetAbilityName()129 std::string WorkInfo::GetAbilityName()
130 {
131     return abilityName_;
132 }
133 
IsPersisted()134 bool WorkInfo::IsPersisted()
135 {
136     return persisted_;
137 }
138 
GetNetworkType()139 WorkCondition::Network WorkInfo::GetNetworkType()
140 {
141     if (conditionMap_.count(WorkCondition::Type::NETWORK) > 0) {
142         int32_t enumVal = conditionMap_.at(WorkCondition::Type::NETWORK)->enumVal;
143         WorkCondition::Network network = WorkCondition::Network(enumVal);
144         return WorkCondition::Network(network);
145     }
146     return WorkCondition::Network::NETWORK_UNKNOWN;
147 }
148 
GetChargerType()149 WorkCondition::Charger WorkInfo::GetChargerType()
150 {
151     if (conditionMap_.count(WorkCondition::Type::CHARGER) > 0) {
152         int32_t enumVal = conditionMap_.at(WorkCondition::Type::CHARGER)->enumVal;
153         WorkCondition::Charger charger = WorkCondition::Charger(enumVal);
154         return WorkCondition::Charger(charger);
155     }
156     return WorkCondition::Charger::CHARGING_UNKNOWN;
157 }
158 
GetBatteryLevel()159 int32_t WorkInfo::GetBatteryLevel()
160 {
161     if (conditionMap_.count(WorkCondition::Type::BATTERY_LEVEL) > 0) {
162         return conditionMap_.at(WorkCondition::Type::BATTERY_LEVEL)->intVal;
163     }
164     return INVALID_VALUE;
165 }
166 
GetBatteryStatus()167 WorkCondition::BatteryStatus WorkInfo::GetBatteryStatus()
168 {
169     if (conditionMap_.count(WorkCondition::Type::BATTERY_STATUS) > 0) {
170         int32_t enumVal = conditionMap_.at(WorkCondition::Type::BATTERY_STATUS)->enumVal;
171         WorkCondition::BatteryStatus battery = WorkCondition::BatteryStatus(enumVal);
172         return WorkCondition::BatteryStatus(battery);
173     }
174     return WorkCondition::BatteryStatus::BATTERY_UNKNOWN;
175 }
176 
GetStorageLevel()177 WorkCondition::Storage WorkInfo::GetStorageLevel()
178 {
179     if (conditionMap_.count(WorkCondition::Type::STORAGE) > 0) {
180         int32_t enumVal = conditionMap_.at(WorkCondition::Type::STORAGE)->enumVal;
181         WorkCondition::Storage storage = WorkCondition::Storage(enumVal);
182         return WorkCondition::Storage(storage);
183     }
184     return WorkCondition::Storage::STORAGE_UNKNOWN;
185 }
186 
IsRepeat()187 bool WorkInfo::IsRepeat()
188 {
189     if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
190         return conditionMap_.at(WorkCondition::Type::TIMER)->boolVal;
191     }
192     return false;
193 }
194 
GetTimeInterval()195 uint32_t WorkInfo::GetTimeInterval()
196 {
197     if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
198         return conditionMap_.at(WorkCondition::Type::TIMER)->uintVal;
199     }
200     return INVALID_TIME_VALUE;
201 }
202 
GetCycleCount()203 int32_t WorkInfo::GetCycleCount()
204 {
205     if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
206         if (IsRepeat()) {
207             return INVALID_VALUE;
208         }
209         return conditionMap_.at(WorkCondition::Type::TIMER)->intVal;
210     }
211     return INVALID_VALUE;
212 }
213 
GetConditionMap()214 std::shared_ptr<std::map<WorkCondition::Type, std::shared_ptr<Condition>>> WorkInfo::GetConditionMap()
215 {
216     return std::make_shared<std::map<WorkCondition::Type, std::shared_ptr<Condition>>>(conditionMap_);
217 }
218 
GetExtras() const219 std::shared_ptr<AAFwk::WantParams> WorkInfo::GetExtras() const
220 {
221     return extras_;
222 }
223 
Marshalling(Parcel & parcel) const224 bool WorkInfo::Marshalling(Parcel &parcel) const
225 {
226     bool ret = false;
227     ret = parcel.WriteInt32(workId_);
228     ret = ret && parcel.WriteString(bundleName_);
229     ret = ret && parcel.WriteString(abilityName_);
230     ret = ret && parcel.WriteBool(persisted_);
231     ret = ret && parcel.WriteUint32(conditionMap_.size());
232     for (auto it : conditionMap_) {
233         switch (it.first) {
234             case WorkCondition::Type::NETWORK:
235             case WorkCondition::Type::BATTERY_STATUS:
236             case WorkCondition::Type::STORAGE: {
237                 ret = ret && parcel.WriteInt32(it.first);
238                 ret = ret && parcel.WriteInt32(it.second->enumVal);
239                 break;
240             }
241             case WorkCondition::Type::CHARGER: {
242                 ret = ret && parcel.WriteInt32(it.first);
243                 ret = ret && parcel.WriteBool(it.second->boolVal);
244                 ret = ret && parcel.WriteInt32(it.second->enumVal);
245                 break;
246             }
247             case WorkCondition::Type::BATTERY_LEVEL: {
248                 ret = ret && parcel.WriteInt32(it.first);
249                 ret = ret && parcel.WriteInt32(it.second->intVal);
250                 break;
251             }
252             case WorkCondition::Type::TIMER: {
253                 ret = ret && parcel.WriteInt32(it.first);
254                 ret = ret && parcel.WriteUint32(it.second->uintVal);
255                 ret = ret && parcel.WriteBool(it.second->boolVal);
256                 if (!it.second->boolVal) {
257                     ret = ret && parcel.WriteInt32(it.second->intVal);
258                 }
259                 break;
260             }
261             default: {
262                 ret = false;
263             }
264         }
265     }
266     if (extras_) {
267         ret = ret && extras_->Marshalling(parcel);
268     }
269     return ret;
270 }
271 
Unmarshalling(Parcel & parcel)272 sptr<WorkInfo> WorkInfo::Unmarshalling(Parcel &parcel)
273 {
274     sptr<WorkInfo> read = new (std::nothrow) WorkInfo();
275     if (read == nullptr) {
276         WS_HILOGE("read is nullptr.");
277         return nullptr;
278     }
279     read->workId_ = parcel.ReadInt32();
280     read->bundleName_ = parcel.ReadString();
281     read->abilityName_ = parcel.ReadString();
282     read->persisted_ = parcel.ReadBool();
283     uint32_t mapsize = parcel.ReadUint32();
284     if (mapsize >= MAX_SIZE) {
285         WS_HILOGE("mapsize is too big.");
286         return nullptr;
287     }
288 
289     UnmarshallCondition(parcel, read, mapsize);
290     AAFwk::WantParams *wantParams = AAFwk::WantParams::Unmarshalling(parcel);
291     if (wantParams != nullptr) {
292         read->extras_ = std::make_shared<AAFwk::WantParams>(*wantParams);
293     }
294     return read;
295 }
296 
UnmarshallCondition(Parcel & parcel,sptr<WorkInfo> & read,uint32_t mapsize)297 void WorkInfo::UnmarshallCondition(Parcel &parcel, sptr<WorkInfo> &read, uint32_t mapsize)
298 {
299     read->conditionMap_ = std::map<WorkCondition::Type, std::shared_ptr<Condition>>();
300     for (uint32_t i = 0; i < mapsize; i++) {
301         int32_t key = parcel.ReadInt32();
302         auto condition = std::make_shared<Condition>();
303         switch (key) {
304             case WorkCondition::Type::NETWORK:
305             // fall-through
306             case WorkCondition::Type::BATTERY_STATUS:
307             // fall-through
308             case WorkCondition::Type::STORAGE: {
309                 condition->enumVal = parcel.ReadInt32();
310                 break;
311             }
312             case WorkCondition::Type::CHARGER: {
313                 condition->boolVal = parcel.ReadBool();
314                 condition->enumVal = parcel.ReadInt32();
315                 break;
316             }
317             case WorkCondition::Type::BATTERY_LEVEL: {
318                 condition->intVal = parcel.ReadInt32();
319                 break;
320             }
321             case WorkCondition::Type::TIMER: {
322                 condition->uintVal = parcel.ReadUint32();
323                 condition->boolVal = parcel.ReadBool();
324                 if (!condition->boolVal) {
325                     condition->intVal = parcel.ReadInt32();
326                 }
327                 break;
328             }
329             default: {
330             }
331         }
332         read->conditionMap_.emplace(WorkCondition::Type(key), condition);
333     }
334 }
335 
ParseToJsonStr()336 std::string WorkInfo::ParseToJsonStr()
337 {
338     Json::Value root;
339     if (uid_ != INVALID_VALUE) {
340         root["uid"] = uid_;
341     }
342     root["workId"] = workId_;
343     root["bundleName"] = bundleName_;
344     root["abilityName"] = abilityName_;
345     root["persisted"] = persisted_;
346     ParseConditionToJsonStr(root);
347     if (extras_) {
348         Json::Value extras;
349         Json::Value extrasType;
350         std::map<std::string, sptr<AAFwk::IInterface>> extrasMap = extras_->GetParams();
351         int typeId = INVALID_VALUE;
352         for (auto it : extrasMap) {
353             typeId = AAFwk::WantParams::GetDataType(it.second);
354             extrasType[it.first] = typeId;
355             if (typeId != INVALID_VALUE) {
356                 std::string value = AAFwk::WantParams::GetStringByType(it.second, typeId);
357                 extras[it.first] = value;
358             } else {
359                 WS_HILOGE("parameters: type error.");
360             }
361         }
362         root["parameters"] = extras;
363         root["parametersType"] = extrasType;
364     }
365     Json::StreamWriterBuilder writerBuilder;
366     std::ostringstream os;
367     std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
368     jsonWriter->write(root, &os);
369     std::string result = os.str();
370     return result;
371 }
372 
ParseConditionToJsonStr(Json::Value & root)373 void WorkInfo::ParseConditionToJsonStr(Json::Value &root)
374 {
375     Json::Value conditions;
376     for (auto it : conditionMap_) {
377         switch (it.first) {
378             case WorkCondition::Type::NETWORK: {
379                 conditions["network"] = it.second->enumVal;
380                 break;
381             }
382             case WorkCondition::Type::CHARGER: {
383                 conditions["isCharging"] = it.second->boolVal;
384                 conditions["chargerType"] = it.second->enumVal;
385                 break;
386             }
387             case WorkCondition::Type::BATTERY_LEVEL: {
388                 conditions["batteryLevel"] = it.second->intVal;
389                 break;
390             }
391             case WorkCondition::Type::BATTERY_STATUS: {
392                 conditions["batteryStatus"] = it.second->enumVal;
393                 break;
394             }
395             case WorkCondition::Type::STORAGE: {
396                 conditions["storage"] = it.second->enumVal;
397                 break;
398             }
399             case WorkCondition::Type::TIMER: {
400                 conditions["timer"] = it.second->uintVal;
401                 conditions["repeat"] = it.second->boolVal;
402                 if (!it.second->boolVal) {
403                     conditions["cycle"] = it.second->intVal;
404                 }
405                 break;
406             }
407             default: {}
408         }
409     }
410     root["conditions"] = conditions;
411 }
412 
ParseFromJson(const Json::Value value)413 bool WorkInfo::ParseFromJson(const Json::Value value)
414 {
415     if (value.empty()) {
416         return false;
417     }
418     if (!value.isMember("workId") || !value.isMember("bundleName") || !value.isMember("abilityName")) {
419         return false;
420     }
421     this->workId_ = value["workId"].asInt();
422     this->bundleName_ = value["bundleName"].asString();
423     this->abilityName_ = value["abilityName"].asString();
424     this->persisted_ = value["persisted"].asBool();
425     ParseConditionFromJsonStr(value);
426     if (!value.isMember("parameters")) {
427         return true;
428     }
429     Json::Value extrasJson = value["parameters"];
430     Json::Value extrasType = value["parametersType"];
431     AAFwk::WantParams extras;
432     Json::Value::Members keyList = extrasJson.getMemberNames();
433     int typeId = INVALID_VALUE;
434     for (auto key : keyList) {
435         typeId = extrasType[key].asInt();
436         if (typeId != INVALID_VALUE) {
437             sptr<AAFwk::IInterface> exInterface = AAFwk::WantParams::GetInterfaceByType(typeId,
438                 extrasJson[key].asString());
439             extras.SetParam(key, exInterface);
440         }
441     }
442     this->RequestExtras(extras);
443     return true;
444 }
445 
ParseConditionFromJsonStr(const Json::Value value)446 void WorkInfo::ParseConditionFromJsonStr(const Json::Value value)
447 {
448     if (value.isMember("uid")) {
449         this->uid_ = value["uid"].asInt();
450     }
451     Json::Value conditions = value["conditions"];
452     if (conditions.isMember("network")) {
453         this->RequestNetworkType(WorkCondition::Network(conditions["network"].asInt()));
454     }
455     if (conditions.isMember("isCharging") && conditions.isMember("chargerType")) {
456         this->RequestChargerType(conditions["isCharging"].asBool(),
457             WorkCondition::Charger(conditions["chargerType"].asInt()));
458     }
459     if (conditions.isMember("batteryLevel")) {
460         this->RequestBatteryLevel(conditions["batteryLevel"].asInt());
461     }
462     if (conditions.isMember("batteryStatus")) {
463         this->RequestBatteryStatus(WorkCondition::BatteryStatus(conditions["batteryStatus"].asInt()));
464     }
465     if (conditions.isMember("storage")) {
466         this->RequestStorageLevel(WorkCondition::Storage(conditions["storage"].asInt()));
467     }
468     if (conditions.isMember("timer") && conditions.isMember("repeat")) {
469         if (conditions["repeat"].asBool()) {
470             this->RequestRepeatCycle(conditions["timer"].asInt());
471         } else {
472             if (conditions.isMember("cycle")) {
473                 this->RequestRepeatCycle(conditions["timer"].asInt(), conditions["cycle"].asInt());
474             }
475         }
476     }
477 }
478 
Dump(std::string & result)479 void WorkInfo::Dump(std::string &result)
480 {
481     result.append(ParseToJsonStr());
482 }
483 } // namespace WorkScheduler
484 } // namespace OHOS
485