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 "common.h"
16 #include "common_want.h"
17 
18 #include "errors.h"
19 #include "work_sched_hilog.h"
20 #include "work_sched_errors.h"
21 
22 namespace OHOS {
23 namespace WorkScheduler {
24 const int32_t NAME_MAXIMUM_LIMIT = 128;
25 const int32_t RESULT_PARAMS_NUM = 2;
26 const int32_t UNSET_INT_PARAM = -1;
27 const std::string UNSET_STRING_PARAM = "";
28 const int32_t TRUE_PARAM = 1;
29 const int32_t FALSE_PARAM = 0;
30 const int32_t BATTERY_LEVEL_MIN = 0;
31 const int32_t BATTERY_LEVEL_MAX = 100;
32 bool g_hasParamError = false;
33 
AsyncWorkData(napi_env napiEnv)34 AsyncWorkData::AsyncWorkData(napi_env napiEnv)
35 {
36     env = napiEnv;
37 }
38 
~AsyncWorkData()39 AsyncWorkData::~AsyncWorkData()
40 {
41     if (callback) {
42         WS_HILOGD("callback delete");
43         napi_delete_reference(env, callback);
44         callback = nullptr;
45     }
46     if (asyncWork) {
47         WS_HILOGD("asyncWork delete");
48         napi_delete_async_work(env, asyncWork);
49         asyncWork = nullptr;
50     }
51 }
52 
NapiGetNull(napi_env env)53 napi_value Common::NapiGetNull(napi_env env)
54 {
55     napi_value result = nullptr;
56     napi_get_null(env, &result);
57     return result;
58 }
59 
GetBaseWorkInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)60 bool Common::GetBaseWorkInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
61 {
62     // Get workid.
63     int32_t workId = GetIntProperty(env, objValue, "workId", E_WORKID_ERR);
64     if (workId == UNSET_INT_PARAM || workId < 0) {
65         WS_HILOGE("Work id is invalid, failed.");
66         HandleParamErr(env, E_WORKID_ERR);
67         return false;
68     }
69 
70     // Get bundleName and abilityName.
71     std::string bundleName = GetStringProperty(env, objValue, "bundleName", E_BUNDLE_OR_ABILITY_NAME_ERR);
72     std::string abilityName = GetStringProperty(env, objValue, "abilityName", E_BUNDLE_OR_ABILITY_NAME_ERR);
73     if (bundleName == UNSET_STRING_PARAM || abilityName == UNSET_STRING_PARAM) {
74         WS_HILOGE("BundleName or abilityName is invalid, failed.");
75         HandleParamErr(env, E_BUNDLE_OR_ABILITY_NAME_ERR);
76         return false;
77     }
78 
79     workInfo.SetWorkId(workId);
80     workInfo.SetElement(bundleName, abilityName);
81 
82     // Get persist param. if not set, it will be used false.
83     workInfo.RequestPersisted(GetBoolProperty(env, objValue, "isPersisted", E_IS_PERSISTED_ERR));
84     return true;
85 }
86 
GetNetWorkInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)87 bool Common::GetNetWorkInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
88 {
89     bool hasCondition = false;
90     int32_t networkType = GetIntProperty(env, objValue, "networkType", E_NETWORK_TYPE_ERR);
91     if (networkType == UNSET_INT_PARAM) {
92         WS_HILOGD("Unset networkType.");
93     } else if (networkType >= WorkCondition::Network::NETWORK_TYPE_ANY &&
94         networkType <= WorkCondition::Network::NETWORK_TYPE_ETHERNET) {
95         workInfo.RequestNetworkType(WorkCondition::Network(networkType));
96         hasCondition = true;
97     } else {
98         WS_HILOGE("NetworkType set is invalid, just ignore set.");
99         HandleParamErr(env, E_NETWORK_TYPE_ERR);
100     }
101     return hasCondition;
102 }
103 
GetChargeInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)104 bool Common::GetChargeInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
105 {
106     bool hasCondition = false;
107     int32_t isCharging = GetBoolToIntProperty(env, objValue, "isCharging", E_IS_CHARGING_ERR);
108     int32_t chargerType = GetIntProperty(env, objValue, "chargerType", E_CHARGER_TYPE_ERR);
109     if (isCharging == UNSET_INT_PARAM) {
110         WS_HILOGD("Unset isCharging, ignore ChargerType set also.");
111     } else if (isCharging == FALSE_PARAM) {
112         workInfo.RequestChargerType(false, WorkCondition::Charger::CHARGING_UNPLUGGED);
113         hasCondition = true;
114     }  else {
115         if (chargerType == UNSET_INT_PARAM) {
116             workInfo.RequestChargerType(true, WorkCondition::Charger::CHARGING_PLUGGED_ANY);
117         } else if (chargerType >=  WorkCondition::Charger::CHARGING_PLUGGED_ANY &&
118             chargerType <= WorkCondition::Charger::CHARGING_PLUGGED_WIRELESS) {
119             workInfo.RequestChargerType(true, WorkCondition::Charger(chargerType));
120         } else {
121             workInfo.RequestChargerType(true, WorkCondition::Charger::CHARGING_PLUGGED_ANY);
122             WS_HILOGE("ChargeType info is invalid, just ignore set.");
123             HandleParamErr(env, E_CHARGER_TYPE_ERR);
124         }
125         hasCondition = true;
126     }
127     return hasCondition;
128 }
129 
GetBatteryInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)130 bool Common::GetBatteryInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
131 {
132     bool hasCondition = false;
133     // Get battery level info.
134     int32_t batteryLevel = GetIntProperty(env, objValue, "batteryLevel", E_BATTERY_LEVEL_ERR);
135     if (batteryLevel == UNSET_INT_PARAM) {
136         WS_HILOGD("Unset batteryLevel.");
137     } else if (batteryLevel >= BATTERY_LEVEL_MIN && batteryLevel <= BATTERY_LEVEL_MAX) {
138         workInfo.RequestBatteryLevel(batteryLevel);
139         hasCondition = true;
140     } else {
141         WS_HILOGE("BatteryLevel set is invalid, just ignore set.");
142         HandleParamErr(env, E_BATTERY_LEVEL_ERR);
143     }
144 
145     // Get battery status info.
146     int32_t batteryStatus = GetIntProperty(env, objValue, "batteryStatus", E_BATTERY_STATUS_ERR);
147     if (batteryStatus == UNSET_INT_PARAM) {
148         WS_HILOGD("Unset batteryStatus.");
149     } else if (batteryStatus >= WorkCondition::BatteryStatus::BATTERY_STATUS_LOW &&
150         batteryStatus <= WorkCondition::BatteryStatus::BATTERY_STATUS_LOW_OR_OKAY) {
151         workInfo.RequestBatteryStatus(WorkCondition::BatteryStatus(batteryStatus));
152         hasCondition = true;
153     } else {
154         WS_HILOGE("BatteryStatus set is invalid, just ignore set.");
155         HandleParamErr(env, E_BATTERY_STATUS_ERR);
156     }
157     return hasCondition;
158 }
159 
GetStorageInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)160 bool Common::GetStorageInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
161 {
162     bool hasCondition = false;
163     int32_t storageRequest = GetIntProperty(env, objValue, "storageRequest", E_STORAGE_REQUEST_ERR);
164     if (storageRequest == UNSET_INT_PARAM) {
165         WS_HILOGD("Unset StorageRequest.");
166     } else if (storageRequest >= WorkCondition::Storage::STORAGE_LEVEL_LOW
167             && storageRequest <= WorkCondition::Storage::STORAGE_LEVEL_LOW_OR_OKAY) {
168         workInfo.RequestStorageLevel(WorkCondition::Storage(storageRequest));
169         hasCondition = true;
170     } else {
171         WS_HILOGE("StorageRequest set is invalid, just ignore set.");
172         HandleParamErr(env, E_STORAGE_REQUEST_ERR);
173     }
174     return hasCondition;
175 }
176 
GetRepeatInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)177 bool Common::GetRepeatInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
178 {
179     int32_t repeatCycleTime = GetIntProperty(env, objValue, "repeatCycleTime", E_REPEAT_CYCLE_TIME_TYPE_ERR);
180     if (repeatCycleTime == UNSET_INT_PARAM) {
181         WS_HILOGD("RepeatCycleTime not set, just ignore other repeat set.");
182         return false;
183     }
184 
185     bool isRepeat = GetBoolProperty(env, objValue, "isRepeat", E_IS_REPEAT_ERR);
186     int32_t repeatCount = GetIntProperty(env, objValue, "repeatCount", E_REPEAT_COUNT_ERR);
187     if (!isRepeat && repeatCount == UNSET_INT_PARAM) {
188         WS_HILOGD("Not set isRepeat or repeatCount, ignore.");
189         return false;
190     }
191     if (isRepeat) {
192         if (repeatCount > 0) {
193             WS_HILOGI("RepeatCount has been set , ignore isRepeat.");
194             workInfo.RequestRepeatCycle(repeatCycleTime, repeatCount);
195         } else {
196             workInfo.RequestRepeatCycle(repeatCycleTime);
197         }
198         return true;
199     } else {
200         if (repeatCount < 0) {
201             WS_HILOGE("RepeatCount is invalid, ignore.");
202             HandleParamErr(env, E_REPEAT_COUNT_ERR);
203             return false;
204         }
205         workInfo.RequestRepeatCycle(repeatCycleTime, repeatCount);
206         return true;
207     }
208 }
209 
GetExtrasInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)210 bool Common::GetExtrasInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
211 {
212     napi_value extras = nullptr;
213     napi_status getExtrasStatus = napi_get_named_property(env, objValue, "parameters", &extras);
214     if (getExtrasStatus != napi_ok) {
215         return true;
216     }
217     AAFwk::WantParams extraParams;
218     if (!UnwrapWantParams(env, extras, extraParams)) {
219         HandleParamErr(env, E_PARAMETERS_TYPE_ERR);
220         return false;
221     }
222     workInfo.RequestExtras(extraParams);
223     WS_HILOGD("Get parameters finished.");
224     return true;
225 }
226 
GetDeepIdleInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)227 bool Common::GetDeepIdleInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
228 {
229     int32_t isDeepIdle = GetBoolToIntProperty(env, objValue, "isDeepIdle", E_IS_DEEP_IDLE_ERR);
230     if (isDeepIdle == UNSET_INT_PARAM) {
231         return false;
232     }
233     workInfo.RequestDeepIdle(isDeepIdle == TRUE_PARAM);
234     return true;
235 }
236 
GetWorkInfo(napi_env env,napi_value objValue,WorkInfo & workInfo)237 bool Common::GetWorkInfo(napi_env env, napi_value objValue, WorkInfo &workInfo)
238 {
239     g_hasParamError = false;
240     // Get base info.
241     if (!GetBaseWorkInfo(env, objValue, workInfo)) {
242         return false;
243     }
244     // Get extra parameters.
245     if (!GetExtrasInfo(env, objValue, workInfo)) {
246         return false;
247     }
248 
249     // Get condition info.
250     bool hasConditions = false;
251     if (GetNetWorkInfo(env, objValue, workInfo)) {
252         hasConditions = true;
253     }
254     if (GetChargeInfo(env, objValue, workInfo)) {
255         hasConditions = true;
256     }
257     if (GetBatteryInfo(env, objValue, workInfo)) {
258         hasConditions = true;
259     }
260     if (GetStorageInfo(env, objValue, workInfo)) {
261         hasConditions = true;
262     }
263     if (GetRepeatInfo(env, objValue, workInfo)) {
264         hasConditions = true;
265     }
266     if (GetDeepIdleInfo(env, objValue, workInfo)) {
267         hasConditions = true;
268     }
269     // if param error occurs when get workInfo
270     if (g_hasParamError) {
271         return false;
272     }
273     if (!hasConditions) {
274         WS_HILOGE("Set none conditions, so fail to init WorkInfo.");
275         HandleParamErr(env, E_CONDITION_EMPTY);
276         return false;
277     }
278     return true;
279 }
280 
GetIntProperty(napi_env env,napi_value object,const std::string & propertyName,ErrCode errCode)281 int32_t Common::GetIntProperty(napi_env env, napi_value object,
282     const std::string &propertyName, ErrCode errCode)
283 {
284     int32_t intValue = UNSET_INT_PARAM;
285     napi_value value = nullptr;
286     napi_status getNameStatus = napi_get_named_property(env, object, propertyName.c_str(), &value);
287     if (getNameStatus != napi_ok) {
288         return intValue;
289     }
290     napi_valuetype valueType = napi_undefined;
291     napi_typeof(env, value, &valueType);
292     if (valueType == napi_undefined) {
293         WS_HILOGD("Unset %{public}s.", propertyName.c_str());
294         return intValue;
295     } else if (valueType != napi_number) {
296         WS_HILOGE("%{public}s type error, number expect.", propertyName.c_str());
297         HandleParamErr(env, errCode);
298         return intValue;
299     }
300     napi_get_value_int32(env, value, &intValue);
301     return intValue;
302 }
303 
GetBoolProperty(napi_env env,napi_value object,const std::string & propertyName,ErrCode errCode)304 bool Common::GetBoolProperty(napi_env env, napi_value object,
305     const std::string &propertyName, ErrCode errCode)
306 {
307     bool boolValue = false;
308     napi_value value = nullptr;
309     napi_status getNameStatus = napi_get_named_property(env, object, propertyName.c_str(), &value);
310     if (getNameStatus != napi_ok) {
311         return boolValue;
312     }
313     napi_valuetype valueType = napi_undefined;
314     napi_typeof(env, value, &valueType);
315     if (valueType == napi_undefined) {
316         WS_HILOGD("Unset %{public}s.", propertyName.c_str());
317         return boolValue;
318     } else if (valueType != napi_boolean) {
319         WS_HILOGE("%{public}s type error, boolean expect.", propertyName.c_str());
320         HandleParamErr(env, errCode);
321         return boolValue;
322     }
323     napi_get_value_bool(env, value, &boolValue);
324     return boolValue;
325 }
326 
GetBoolToIntProperty(napi_env env,napi_value object,const std::string & propertyName,ErrCode errCode)327 int32_t Common::GetBoolToIntProperty(napi_env env, napi_value object,
328     const std::string &propertyName, ErrCode errCode)
329 {
330     bool boolValue = false;
331     napi_value value = nullptr;
332     napi_status getNameStatus = napi_get_named_property(env, object, propertyName.c_str(), &value);
333     if (getNameStatus != napi_ok) {
334         return UNSET_INT_PARAM;
335     }
336     napi_valuetype valueType = napi_undefined;
337     napi_typeof(env, value, &valueType);
338     if (valueType == napi_undefined) {
339         WS_HILOGD("Unset %{public}s.", propertyName.c_str());
340         return UNSET_INT_PARAM;
341     } else if (valueType != napi_boolean) {
342         WS_HILOGE("%{public}s type error, boolean expect.", propertyName.c_str());
343         HandleParamErr(env, errCode);
344         return UNSET_INT_PARAM;
345     }
346     napi_status getIntStatus = napi_get_value_bool(env, value, &boolValue);
347     if (getIntStatus == napi_ok) {
348         return boolValue ? TRUE_PARAM : FALSE_PARAM;
349     }
350     return UNSET_INT_PARAM;
351 }
352 
GetStringProperty(napi_env env,napi_value object,const std::string & propertyName,ErrCode errCode)353 std::string Common::GetStringProperty(napi_env env, napi_value object,
354     const std::string &propertyName, ErrCode errCode)
355 {
356     napi_value value = nullptr;
357     napi_status getNameStatus = napi_get_named_property(env, object, propertyName.c_str(), &value);
358     if (getNameStatus != napi_ok) {
359         return UNSET_STRING_PARAM;
360     }
361     napi_valuetype valueType = napi_undefined;
362     napi_typeof(env, value, &valueType);
363     if (valueType == napi_undefined) {
364         WS_HILOGD("Unset %{public}s.", propertyName.c_str());
365         return UNSET_STRING_PARAM;
366     } else if (valueType != napi_string) {
367         WS_HILOGE("%{public}s type error, string expect.", propertyName.c_str());
368         HandleParamErr(env, errCode);
369         return UNSET_STRING_PARAM;
370     }
371     char chars[NAME_MAXIMUM_LIMIT] = {0};
372     size_t charLength = 0;
373     napi_status getStringStatus = napi_get_value_string_utf8(env, value, chars, NAME_MAXIMUM_LIMIT, &charLength);
374     if (getStringStatus == napi_ok && charLength > 0) {
375         return std::string(chars, charLength);
376     }
377     return UNSET_STRING_PARAM;
378 }
379 
MatchValueType(napi_env env,napi_value value,napi_valuetype targetType)380 bool Common::MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
381 {
382     napi_valuetype valueType = napi_undefined;
383     napi_typeof(env, value, &valueType);
384     return valueType == targetType;
385 }
386 
JSParaError(const napi_env & env,const napi_ref & callback)387 napi_value Common::JSParaError(const napi_env &env, const napi_ref &callback)
388 {
389     if (callback) {
390         return Common::NapiGetNull(env);
391     } else {
392         napi_value promise = nullptr;
393         napi_deferred deferred = nullptr;
394         napi_create_promise(env, &deferred, &promise);
395         napi_resolve_deferred(env, deferred, Common::NapiGetNull(env));
396         return promise;
397     }
398 }
399 
PaddingAsyncWorkData(const napi_env & env,const napi_ref & callback,AsyncWorkData & info,napi_value & promise)400 void Common::PaddingAsyncWorkData(
401     const napi_env &env, const napi_ref &callback, AsyncWorkData &info, napi_value &promise)
402 {
403     if (callback) {
404         info.callback = callback;
405         info.isCallback = true;
406     } else {
407         napi_deferred deferred = nullptr;
408         NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
409         info.deferred = deferred;
410         info.isCallback = false;
411     }
412 }
413 
GetNapiWorkInfo(napi_env env,std::shared_ptr<WorkInfo> & workInfo)414 napi_value Common::GetNapiWorkInfo(napi_env env, std::shared_ptr<WorkInfo> &workInfo)
415 {
416     if (workInfo == nullptr) {
417         return NapiGetNull(env);
418     }
419     napi_value napiWork = nullptr;
420     napi_create_object(env, &napiWork);
421 
422     // Set base info.
423     napi_value napiWorkId = nullptr;
424     napi_value napiBundleName = nullptr;
425     napi_value napiAbilityName = nullptr;
426     napi_create_int32(env, workInfo->GetWorkId(), &napiWorkId);
427     napi_create_string_utf8(env, workInfo->GetBundleName().c_str(), workInfo->GetBundleName().length(),
428         &napiBundleName);
429     napi_create_string_utf8(env, workInfo->GetAbilityName().c_str(), workInfo->GetAbilityName().length(),
430         &napiAbilityName);
431     napi_set_named_property(env, napiWork, "workId", napiWorkId);
432     napi_set_named_property(env, napiWork, "bundleName", napiBundleName);
433     napi_set_named_property(env, napiWork, "abilityName", napiAbilityName);
434 
435     // Set isPersisted.
436     napi_value napiIsPersisted = nullptr;
437     napi_get_boolean(env, workInfo->IsPersisted(), &napiIsPersisted);
438     napi_set_named_property(env, napiWork, "isPersisted", napiIsPersisted);
439 
440     GetConditionInfo(env, workInfo, napiWork);
441 
442     // Set timer info.
443     uint32_t timeInterval = workInfo->GetTimeInterval();
444     if (timeInterval > 0) {
445         napi_value napiTimer = nullptr;
446         napi_create_int32(env, static_cast<int32_t>(timeInterval), &napiTimer);
447         napi_set_named_property(env, napiWork, "repeatCycleTime", napiTimer);
448         if  (workInfo->IsRepeat()) {
449             napi_value napiIsRepeat = nullptr;
450             napi_get_boolean(env, true, &napiIsRepeat);
451             napi_set_named_property(env, napiWork, "isRepeat", napiIsRepeat);
452         } else {
453             napi_value napiCount = nullptr;
454             napi_create_int32(env, workInfo->GetCycleCount(), &napiCount);
455             napi_set_named_property(env, napiWork, "repeatCount", napiCount);
456         }
457     }
458 
459     if (workInfo->GetExtras()) {
460         napi_value parameters = WrapWantParams(env, *workInfo->GetExtras());
461         napi_set_named_property(env, napiWork, "parameters", parameters);
462     }
463     return napiWork;
464 }
465 
GetConditionInfo(napi_env env,std::shared_ptr<WorkInfo> & workInfo,napi_value & napiWork)466 void Common::GetConditionInfo(napi_env env, std::shared_ptr<WorkInfo> &workInfo, napi_value &napiWork)
467 {
468     if (workInfo == nullptr) {
469         return;
470     }
471 
472     // Set net info.
473     if (workInfo->GetNetworkType() != WorkCondition::Network::NETWORK_UNKNOWN) {
474         napi_value napiNetworkType = nullptr;
475         napi_create_int32(env, static_cast<int32_t>(workInfo->GetNetworkType()), &napiNetworkType);
476         napi_set_named_property(env, napiWork, "networkType", napiNetworkType);
477     }
478 
479     // Set charge info.
480     WorkCondition::Charger charger = workInfo-> GetChargerType();
481     if (charger != WorkCondition::Charger::CHARGING_UNKNOWN) {
482         napi_value napiIsCharging = nullptr;
483         if (charger == WorkCondition::Charger::CHARGING_UNPLUGGED) {
484             napi_get_boolean(env, false, &napiIsCharging);
485             napi_set_named_property(env, napiWork, "isCharging", napiIsCharging);
486         } else {
487             napi_get_boolean(env, true, &napiIsCharging);
488             napi_set_named_property(env, napiWork, "isCharging", napiIsCharging);
489             napi_value napiChargerType = nullptr;
490             napi_create_int32(env, static_cast<int32_t>(charger), &napiChargerType);
491             napi_set_named_property(env, napiWork, "chargerType", napiChargerType);
492         }
493     }
494 
495     // Set batteryLevel info.
496     if (workInfo->GetBatteryLevel() >= 0) {
497         napi_value napiBatteryLevel = nullptr;
498         napi_create_int32(env, workInfo->GetBatteryLevel(), &napiBatteryLevel);
499         napi_set_named_property(env, napiWork, "batteryLevel", napiBatteryLevel);
500     }
501 
502     // Set batteryStatus info.
503     if (workInfo->GetBatteryStatus() != WorkCondition::BatteryStatus::BATTERY_UNKNOWN) {
504         napi_value napiBatteryStatus = nullptr;
505         napi_create_int32(env, static_cast<int32_t>(workInfo->GetBatteryStatus()), &napiBatteryStatus);
506         napi_set_named_property(env, napiWork, "batteryStatus", napiBatteryStatus);
507     }
508 
509     // Set storage info.
510     if (workInfo->GetStorageLevel() != WorkCondition::Storage::STORAGE_UNKNOWN) {
511         napi_value napiStorageRequest = nullptr;
512         napi_create_int32(env, static_cast<int32_t>(workInfo->GetStorageLevel()), &napiStorageRequest);
513         napi_set_named_property(env, napiWork, "storageRequest", napiStorageRequest);
514     }
515 }
516 
GetCallbackErrorValue(napi_env env,int32_t errCode,const std::string errMsg)517 napi_value Common::GetCallbackErrorValue(napi_env env, int32_t errCode, const std::string errMsg)
518 {
519     if (errCode == ERR_OK) {
520         return NapiGetNull(env);
521     }
522     napi_value error = nullptr;
523     napi_value eCode = nullptr;
524     napi_value eMsg = nullptr;
525     NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
526     NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
527         errMsg.length(), &eMsg));
528     NAPI_CALL(env, napi_create_object(env, &error));
529     NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode));
530     NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg));
531     return error;
532 }
533 
SetCallback(const napi_env & env,const napi_ref & callbackIn,int32_t errCode,const napi_value & result)534 void Common::SetCallback(
535     const napi_env &env, const napi_ref &callbackIn, int32_t errCode, const napi_value &result)
536 {
537     napi_value undefined = nullptr;
538     napi_get_undefined(env, &undefined);
539 
540     napi_value callback = nullptr;
541     napi_value resultout = nullptr;
542     napi_get_reference_value(env, callbackIn, &callback);
543     napi_value results[RESULT_PARAMS_NUM] = {nullptr};
544     if (errCode == ERR_OK) {
545         results[0] = NapiGetNull(env);
546     } else {
547         std::string errMsg = FindErrMsg(env, errCode);
548         int32_t errCodeInfo = FindErrCode(env, errCode);
549         results[0] = GetCallbackErrorValue(env, errCodeInfo, errMsg);
550     }
551     results[1] = result;
552     NAPI_CALL_RETURN_VOID(env,
553         napi_call_function(env, undefined, callback, RESULT_PARAMS_NUM, &results[0], &resultout));
554 }
555 
SetPromise(const napi_env & env,const AsyncWorkData & info,const napi_value & result)556 napi_value Common::SetPromise(
557     const napi_env &env, const AsyncWorkData &info, const napi_value &result)
558 {
559     if (info.errorCode == ERR_OK) {
560         napi_resolve_deferred(env, info.deferred, result);
561     } else {
562         int32_t errCodeInfo = FindErrCode(env, info.errorCode);
563         std::string errMsg = FindErrMsg(env, info.errorCode);
564         napi_value error = nullptr;
565         napi_value eCode = nullptr;
566         napi_value eMsg = nullptr;
567         NAPI_CALL(env, napi_create_int32(env, errCodeInfo, &eCode));
568         NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
569             errMsg.length(), &eMsg));
570         NAPI_CALL(env, napi_create_object(env, &error));
571         NAPI_CALL(env, napi_set_named_property(env, error, "data", eCode));
572         NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode));
573         NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg));
574         napi_reject_deferred(env, info.deferred, error);
575     }
576     return result;
577 }
578 
ReturnCallbackPromise(const napi_env & env,const AsyncWorkData & info,const napi_value & result)579 void Common::ReturnCallbackPromise(const napi_env &env, const AsyncWorkData &info, const napi_value &result)
580 {
581     if (info.isCallback) {
582         SetCallback(env, info.callback, info.errorCode, result);
583     } else {
584         SetPromise(env, info, result);
585     }
586 }
587 
HandleErrCode(const napi_env & env,int32_t errCode)588 void Common::HandleErrCode(const napi_env &env, int32_t errCode)
589 {
590     WS_HILOGI("HandleErrCode errCode = %{public}d", errCode);
591     if (errCode == ERR_OK) {
592         return;
593     }
594     std::string errMsg = FindErrMsg(env, errCode);
595     int32_t errCodeInfo = FindErrCode(env, errCode);
596     if (errMsg != "") {
597         napi_throw_error(env, std::to_string(errCodeInfo).c_str(), errMsg.c_str());
598     }
599 }
600 
HandleParamErr(const napi_env & env,int32_t errCode)601 void Common::HandleParamErr(const napi_env &env, int32_t errCode)
602 {
603     WS_HILOGI("HandleParamErr errCode = %{public}d", errCode);
604     if (errCode == ERR_OK) {
605         return;
606     }
607     auto iter = paramErrCodeMsgMap.find(errCode);
608     if (iter != paramErrCodeMsgMap.end()) {
609         std::string errMessage = "BussinessError 401: Parameter error. ";
610         errMessage.append(iter->second);
611         napi_throw_error(env, std::to_string(E_PARAM_ERROR).c_str(), errMessage.c_str());
612         g_hasParamError = true;
613     }
614 }
615 
FindErrMsg(const napi_env & env,int32_t errCode)616 std::string Common::FindErrMsg(const napi_env &env, int32_t errCode)
617 {
618     if (errCode == ERR_OK) {
619         return "";
620     }
621     auto iter = saErrCodeMsgMap.find(errCode);
622     if (iter != saErrCodeMsgMap.end()) {
623         std::string errMessage = "BussinessError ";
624         int32_t errCodeInfo = FindErrCode(env, errCode);
625         errMessage.append(std::to_string(errCodeInfo)).append(": ").append(iter->second);
626         return errMessage;
627     }
628     iter = paramErrCodeMsgMap.find(errCode);
629     if (iter != paramErrCodeMsgMap.end()) {
630         std::string errMessage = "BussinessError 401: Parameter error. ";
631         errMessage.append(iter->second);
632         return errMessage;
633     }
634     return "Inner error.";
635 }
636 
FindErrCode(const napi_env & env,int32_t errCodeIn)637 int32_t Common::FindErrCode(const napi_env &env, int32_t errCodeIn)
638 {
639     auto iter = paramErrCodeMsgMap.find(errCodeIn);
640     if (iter != paramErrCodeMsgMap.end()) {
641         return E_PARAM_ERROR;
642     }
643     return errCodeIn > THRESHOLD ? errCodeIn / OFFSET : errCodeIn;
644 }
645 } // namespace WorkScheduler
646 } // namespace OHOS