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