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
RequestBaseTimeAndCycle(time_t baseTime,int32_t cycle)104 void WorkInfo::RequestBaseTimeAndCycle(time_t baseTime, int32_t cycle)
105 {
106 if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
107 conditionMap_.at(WorkCondition::Type::TIMER)->timeVal = baseTime;
108 conditionMap_.at(WorkCondition::Type::TIMER)->intVal = cycle;
109 }
110 }
111
RequestBaseTime(time_t baseTime)112 void WorkInfo::RequestBaseTime(time_t baseTime)
113 {
114 if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
115 conditionMap_.at(WorkCondition::Type::TIMER)->timeVal = baseTime;
116 }
117 }
118
RequestExtras(AAFwk::WantParams extras)119 void WorkInfo::RequestExtras(AAFwk::WantParams extras)
120 {
121 extras_ = std::make_shared<AAFwk::WantParams>(extras);
122 }
123
RefreshUid(int32_t uid)124 void WorkInfo::RefreshUid(int32_t uid)
125 {
126 uid_ = uid;
127 }
128
SetCallBySystemApp(bool callBySystemApp)129 void WorkInfo::SetCallBySystemApp(bool callBySystemApp)
130 {
131 callBySystemApp_ = callBySystemApp;
132 }
133
GetUid()134 int32_t WorkInfo::GetUid()
135 {
136 return uid_;
137 }
138
GetWorkId()139 int32_t WorkInfo::GetWorkId()
140 {
141 return workId_;
142 }
143
GetBundleName()144 std::string WorkInfo::GetBundleName()
145 {
146 return bundleName_;
147 }
148
GetAbilityName()149 std::string WorkInfo::GetAbilityName()
150 {
151 return abilityName_;
152 }
153
IsPersisted()154 bool WorkInfo::IsPersisted()
155 {
156 return persisted_;
157 }
158
GetNetworkType()159 WorkCondition::Network WorkInfo::GetNetworkType()
160 {
161 if (conditionMap_.count(WorkCondition::Type::NETWORK) > 0) {
162 int32_t enumVal = conditionMap_.at(WorkCondition::Type::NETWORK)->enumVal;
163 WorkCondition::Network network = WorkCondition::Network(enumVal);
164 return WorkCondition::Network(network);
165 }
166 return WorkCondition::Network::NETWORK_UNKNOWN;
167 }
168
GetChargerType()169 WorkCondition::Charger WorkInfo::GetChargerType()
170 {
171 if (conditionMap_.count(WorkCondition::Type::CHARGER) > 0) {
172 int32_t enumVal = conditionMap_.at(WorkCondition::Type::CHARGER)->enumVal;
173 WorkCondition::Charger charger = WorkCondition::Charger(enumVal);
174 return WorkCondition::Charger(charger);
175 }
176 return WorkCondition::Charger::CHARGING_UNKNOWN;
177 }
178
GetBatteryLevel()179 int32_t WorkInfo::GetBatteryLevel()
180 {
181 if (conditionMap_.count(WorkCondition::Type::BATTERY_LEVEL) > 0) {
182 return conditionMap_.at(WorkCondition::Type::BATTERY_LEVEL)->intVal;
183 }
184 return INVALID_VALUE;
185 }
186
GetBatteryStatus()187 WorkCondition::BatteryStatus WorkInfo::GetBatteryStatus()
188 {
189 if (conditionMap_.count(WorkCondition::Type::BATTERY_STATUS) > 0) {
190 int32_t enumVal = conditionMap_.at(WorkCondition::Type::BATTERY_STATUS)->enumVal;
191 WorkCondition::BatteryStatus battery = WorkCondition::BatteryStatus(enumVal);
192 return WorkCondition::BatteryStatus(battery);
193 }
194 return WorkCondition::BatteryStatus::BATTERY_UNKNOWN;
195 }
196
GetStorageLevel()197 WorkCondition::Storage WorkInfo::GetStorageLevel()
198 {
199 if (conditionMap_.count(WorkCondition::Type::STORAGE) > 0) {
200 int32_t enumVal = conditionMap_.at(WorkCondition::Type::STORAGE)->enumVal;
201 WorkCondition::Storage storage = WorkCondition::Storage(enumVal);
202 return WorkCondition::Storage(storage);
203 }
204 return WorkCondition::Storage::STORAGE_UNKNOWN;
205 }
206
IsRepeat()207 bool WorkInfo::IsRepeat()
208 {
209 if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
210 return conditionMap_.at(WorkCondition::Type::TIMER)->boolVal;
211 }
212 return false;
213 }
214
GetTimeInterval()215 uint32_t WorkInfo::GetTimeInterval()
216 {
217 if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
218 return conditionMap_.at(WorkCondition::Type::TIMER)->uintVal;
219 }
220 return INVALID_TIME_VALUE;
221 }
222
GetCycleCount()223 int32_t WorkInfo::GetCycleCount()
224 {
225 if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
226 if (IsRepeat()) {
227 return INVALID_VALUE;
228 }
229 return conditionMap_.at(WorkCondition::Type::TIMER)->intVal;
230 }
231 return INVALID_VALUE;
232 }
233
GetBaseTime()234 time_t WorkInfo::GetBaseTime()
235 {
236 if (conditionMap_.count(WorkCondition::Type::TIMER) > 0) {
237 return conditionMap_.at(WorkCondition::Type::TIMER)->timeVal;
238 }
239 time_t result;
240 time(&result);
241 return result;
242 }
243
GetConditionMap()244 std::shared_ptr<std::map<WorkCondition::Type, std::shared_ptr<Condition>>> WorkInfo::GetConditionMap()
245 {
246 return std::make_shared<std::map<WorkCondition::Type, std::shared_ptr<Condition>>>(conditionMap_);
247 }
248
GetExtras() const249 std::shared_ptr<AAFwk::WantParams> WorkInfo::GetExtras() const
250 {
251 return extras_;
252 }
253
IsCallBySystemApp()254 bool WorkInfo::IsCallBySystemApp()
255 {
256 return callBySystemApp_;
257 }
258
Marshalling(Parcel & parcel) const259 bool WorkInfo::Marshalling(Parcel &parcel) const
260 {
261 bool ret = false;
262 ret = parcel.WriteInt32(workId_);
263 ret = ret && parcel.WriteString(bundleName_);
264 ret = ret && parcel.WriteString(abilityName_);
265 ret = ret && parcel.WriteBool(persisted_);
266 ret = ret && parcel.WriteInt32(uid_);
267 ret = ret && parcel.WriteUint32(conditionMap_.size());
268 for (auto it : conditionMap_) {
269 switch (it.first) {
270 case WorkCondition::Type::NETWORK:
271 case WorkCondition::Type::BATTERY_STATUS:
272 case WorkCondition::Type::STORAGE: {
273 ret = ret && parcel.WriteInt32(it.first);
274 ret = ret && parcel.WriteInt32(it.second->enumVal);
275 break;
276 }
277 case WorkCondition::Type::CHARGER: {
278 ret = ret && parcel.WriteInt32(it.first);
279 ret = ret && parcel.WriteBool(it.second->boolVal);
280 ret = ret && parcel.WriteInt32(it.second->enumVal);
281 break;
282 }
283 case WorkCondition::Type::BATTERY_LEVEL: {
284 ret = ret && parcel.WriteInt32(it.first);
285 ret = ret && parcel.WriteInt32(it.second->intVal);
286 break;
287 }
288 case WorkCondition::Type::TIMER: {
289 ret = ret && parcel.WriteInt32(it.first);
290 ret = ret && parcel.WriteUint32(it.second->uintVal);
291 ret = ret && parcel.WriteBool(it.second->boolVal);
292 if (!it.second->boolVal) {
293 ret = ret && parcel.WriteInt32(it.second->intVal);
294 }
295 break;
296 }
297 default: {
298 ret = false;
299 }
300 }
301 }
302 parcel.WriteBool(extras_ ? true : false);
303 if (extras_) {
304 ret = ret && extras_->Marshalling(parcel);
305 }
306 return ret;
307 }
308
Unmarshalling(Parcel & parcel)309 sptr<WorkInfo> WorkInfo::Unmarshalling(Parcel &parcel)
310 {
311 sptr<WorkInfo> read = new (std::nothrow) WorkInfo();
312 if (read == nullptr) {
313 WS_HILOGE("read is nullptr.");
314 return nullptr;
315 }
316 read->workId_ = parcel.ReadInt32();
317 read->bundleName_ = parcel.ReadString();
318 read->abilityName_ = parcel.ReadString();
319 read->persisted_ = parcel.ReadBool();
320 read->uid_ = parcel.ReadInt32();
321 uint32_t mapsize = parcel.ReadUint32();
322 if (mapsize >= MAX_SIZE) {
323 WS_HILOGE("mapsize is too big.");
324 return nullptr;
325 }
326
327 UnmarshallCondition(parcel, read, mapsize);
328 bool hasExtras = parcel.ReadBool();
329 if (!hasExtras) {
330 return read;
331 }
332 AAFwk::WantParams *wantParams = AAFwk::WantParams::Unmarshalling(parcel);
333 if (wantParams != nullptr) {
334 read->extras_ = std::make_shared<AAFwk::WantParams>(*wantParams);
335 }
336 return read;
337 }
338
UnmarshallCondition(Parcel & parcel,sptr<WorkInfo> & read,uint32_t mapsize)339 void WorkInfo::UnmarshallCondition(Parcel &parcel, sptr<WorkInfo> &read, uint32_t mapsize)
340 {
341 read->conditionMap_ = std::map<WorkCondition::Type, std::shared_ptr<Condition>>();
342 for (uint32_t i = 0; i < mapsize; i++) {
343 int32_t key = parcel.ReadInt32();
344 auto condition = std::make_shared<Condition>();
345 switch (key) {
346 case WorkCondition::Type::NETWORK:
347 // fall-through
348 case WorkCondition::Type::BATTERY_STATUS:
349 // fall-through
350 case WorkCondition::Type::STORAGE: {
351 condition->enumVal = parcel.ReadInt32();
352 break;
353 }
354 case WorkCondition::Type::CHARGER: {
355 condition->boolVal = parcel.ReadBool();
356 condition->enumVal = parcel.ReadInt32();
357 break;
358 }
359 case WorkCondition::Type::BATTERY_LEVEL: {
360 condition->intVal = parcel.ReadInt32();
361 break;
362 }
363 case WorkCondition::Type::TIMER: {
364 condition->uintVal = parcel.ReadUint32();
365 condition->boolVal = parcel.ReadBool();
366 if (!condition->boolVal) {
367 condition->intVal = parcel.ReadInt32();
368 }
369 break;
370 }
371 default: {
372 }
373 }
374 read->conditionMap_.emplace(WorkCondition::Type(key), condition);
375 }
376 }
377
ParseToJsonStr()378 std::string WorkInfo::ParseToJsonStr()
379 {
380 Json::Value root;
381 if (uid_ != INVALID_VALUE) {
382 root["uid"] = uid_;
383 }
384 root["workId"] = workId_;
385 root["bundleName"] = bundleName_;
386 root["abilityName"] = abilityName_;
387 root["persisted"] = persisted_;
388 root["callBySystemApp"] = callBySystemApp_;
389 ParseConditionToJsonStr(root);
390 if (extras_) {
391 Json::Value extras;
392 Json::Value extrasType;
393 std::map<std::string, sptr<AAFwk::IInterface>> extrasMap = extras_->GetParams();
394 int typeId = INVALID_VALUE;
395 for (auto it : extrasMap) {
396 typeId = AAFwk::WantParams::GetDataType(it.second);
397 extrasType[it.first] = typeId;
398 if (typeId != INVALID_VALUE) {
399 std::string value = AAFwk::WantParams::GetStringByType(it.second, typeId);
400 extras[it.first] = value;
401 } else {
402 WS_HILOGE("parameters: type error.");
403 }
404 }
405 root["parameters"] = extras;
406 root["parametersType"] = extrasType;
407 }
408 Json::StreamWriterBuilder writerBuilder;
409 std::ostringstream os;
410 std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
411 jsonWriter->write(root, &os);
412 std::string result = os.str();
413 return result;
414 }
415
ParseConditionToJsonStr(Json::Value & root)416 void WorkInfo::ParseConditionToJsonStr(Json::Value &root)
417 {
418 Json::Value conditions;
419 for (auto it : conditionMap_) {
420 switch (it.first) {
421 case WorkCondition::Type::NETWORK: {
422 conditions["network"] = it.second->enumVal;
423 break;
424 }
425 case WorkCondition::Type::CHARGER: {
426 conditions["isCharging"] = it.second->boolVal;
427 conditions["chargerType"] = it.second->enumVal;
428 break;
429 }
430 case WorkCondition::Type::BATTERY_LEVEL: {
431 conditions["batteryLevel"] = it.second->intVal;
432 break;
433 }
434 case WorkCondition::Type::BATTERY_STATUS: {
435 conditions["batteryStatus"] = it.second->enumVal;
436 break;
437 }
438 case WorkCondition::Type::STORAGE: {
439 conditions["storage"] = it.second->enumVal;
440 break;
441 }
442 case WorkCondition::Type::TIMER: {
443 conditions["timer"] = it.second->uintVal;
444 conditions["repeat"] = it.second->boolVal;
445 conditions["baseTime"] = it.second->timeVal;
446 if (!it.second->boolVal) {
447 conditions["cycle"] = it.second->intVal;
448 }
449 break;
450 }
451 default: {}
452 }
453 }
454 root["conditions"] = conditions;
455 }
456
ParseFromJson(const Json::Value value)457 bool WorkInfo::ParseFromJson(const Json::Value value)
458 {
459 if (value.empty()) {
460 return false;
461 }
462 if (!value.isMember("workId") || !value.isMember("bundleName") || !value.isMember("abilityName")) {
463 return false;
464 }
465 this->workId_ = value["workId"].asInt();
466 this->bundleName_ = value["bundleName"].asString();
467 this->abilityName_ = value["abilityName"].asString();
468 this->persisted_ = value["persisted"].asBool();
469 this->callBySystemApp_ = value["callBySystemApp"].asBool();
470 ParseConditionFromJsonStr(value);
471 if (!value.isMember("parameters")) {
472 return true;
473 }
474 Json::Value extrasJson = value["parameters"];
475 Json::Value extrasType = value["parametersType"];
476 AAFwk::WantParams extras;
477 Json::Value::Members keyList = extrasJson.getMemberNames();
478 int typeId = INVALID_VALUE;
479 for (auto key : keyList) {
480 typeId = extrasType[key].asInt();
481 if (typeId != INVALID_VALUE) {
482 sptr<AAFwk::IInterface> exInterface = AAFwk::WantParams::GetInterfaceByType(typeId,
483 extrasJson[key].asString());
484 extras.SetParam(key, exInterface);
485 }
486 }
487 this->RequestExtras(extras);
488 return true;
489 }
490
ParseConditionFromJsonStr(const Json::Value value)491 void WorkInfo::ParseConditionFromJsonStr(const Json::Value value)
492 {
493 if (value.isMember("uid")) {
494 this->uid_ = value["uid"].asInt();
495 }
496 Json::Value conditions = value["conditions"];
497 if (conditions.isMember("network")) {
498 this->RequestNetworkType(WorkCondition::Network(conditions["network"].asInt()));
499 }
500 if (conditions.isMember("isCharging") && conditions.isMember("chargerType")) {
501 this->RequestChargerType(conditions["isCharging"].asBool(),
502 WorkCondition::Charger(conditions["chargerType"].asInt()));
503 }
504 if (conditions.isMember("batteryLevel")) {
505 this->RequestBatteryLevel(conditions["batteryLevel"].asInt());
506 }
507 if (conditions.isMember("batteryStatus")) {
508 this->RequestBatteryStatus(WorkCondition::BatteryStatus(conditions["batteryStatus"].asInt()));
509 }
510 if (conditions.isMember("storage")) {
511 this->RequestStorageLevel(WorkCondition::Storage(conditions["storage"].asInt()));
512 }
513 if (conditions.isMember("timer") && conditions.isMember("repeat")) {
514 if (conditions["repeat"].asBool()) {
515 this->RequestRepeatCycle(conditions["timer"].asInt());
516 } else {
517 if (conditions.isMember("cycle")) {
518 this->RequestRepeatCycle(conditions["timer"].asInt(), conditions["cycle"].asInt());
519 }
520 }
521 if (conditions.isMember("baseTime")) {
522 time_t baseTime = (time_t)(conditions["baseTime"].asInt64());
523 this->RequestBaseTime(baseTime);
524 }
525 }
526 }
527
Dump(std::string & result)528 void WorkInfo::Dump(std::string &result)
529 {
530 result.append(ParseToJsonStr());
531 }
532 } // namespace WorkScheduler
533 } // namespace OHOS
534