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 "common.h"
17
18 #include "cancel_suspend_delay.h"
19 #include "transient_task_log.h"
20
21 namespace OHOS {
22 namespace BackgroundTaskMgr {
23 const uint32_t STR_MAX_SIZE = 64;
24 const uint32_t EXPIRE_CALLBACK_PARAM_NUM = 1;
25 const uint32_t ASYNC_CALLBACK_PARAM_NUM = 2;
26
AsyncWorkData(napi_env napiEnv)27 AsyncWorkData::AsyncWorkData(napi_env napiEnv)
28 {
29 env = napiEnv;
30 }
31
~AsyncWorkData()32 AsyncWorkData::~AsyncWorkData()
33 {
34 if (callback) {
35 BGTASK_LOGD("AsyncWorkData::~AsyncWorkData delete callback");
36 napi_delete_reference(env, callback);
37 callback = nullptr;
38 }
39 if (asyncWork) {
40 BGTASK_LOGD("AsyncWorkData::~AsyncWorkData delete asyncWork");
41 napi_delete_async_work(env, asyncWork);
42 asyncWork = nullptr;
43 }
44 }
45
NapiGetboolean(const napi_env & env,const bool isValue)46 napi_value Common::NapiGetboolean(const napi_env &env, const bool isValue)
47 {
48 napi_value result = nullptr;
49 NAPI_CALL(env, napi_get_boolean(env, isValue, &result));
50 return result;
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
GetCallbackErrorValue(napi_env env,const int32_t errCode,const std::string errMsg)60 napi_value Common::GetCallbackErrorValue(napi_env env, const int32_t errCode, const std::string errMsg)
61 {
62 if (errCode == ERR_OK) {
63 return NapiGetNull(env);
64 }
65 napi_value error = nullptr;
66 napi_value eCode = nullptr;
67 napi_value eMsg = nullptr;
68 NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
69 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
70 errMsg.length(), &eMsg));
71 NAPI_CALL(env, napi_create_object(env, &error));
72 NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode));
73 NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg));
74 return error;
75 }
76
GetExpireCallbackValue(napi_env env,int32_t errCode,const napi_value & value)77 napi_value Common::GetExpireCallbackValue(napi_env env, int32_t errCode, const napi_value &value)
78 {
79 napi_value result = nullptr;
80 napi_value eCode = nullptr;
81 NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
82 NAPI_CALL(env, napi_create_object(env, &result));
83 NAPI_CALL(env, napi_set_named_property(env, result, "code", eCode));
84 NAPI_CALL(env, napi_set_named_property(env, result, "data", value));
85 return result;
86 }
87
SetCallback(const napi_env & env,const napi_ref & callbackIn,const napi_value & result)88 void Common::SetCallback(const napi_env &env, const napi_ref &callbackIn, const napi_value &result)
89 {
90 napi_value undefined = nullptr;
91 napi_get_undefined(env, &undefined);
92
93 napi_value callback = nullptr;
94 napi_value resultout = nullptr;
95 napi_value res = nullptr;
96 res = GetExpireCallbackValue(env, 0, result);
97 napi_get_reference_value(env, callbackIn, &callback);
98 NAPI_CALL_RETURN_VOID(env,
99 napi_call_function(env, undefined, callback, EXPIRE_CALLBACK_PARAM_NUM, &res, &resultout));
100 }
101
SetCallback(const napi_env & env,const napi_ref & callbackIn,const int32_t & errCode,const napi_value & result)102 void Common::SetCallback(
103 const napi_env &env, const napi_ref &callbackIn, const int32_t &errCode, const napi_value &result)
104 {
105 napi_value undefined = nullptr;
106 napi_get_undefined(env, &undefined);
107
108 napi_value callback = nullptr;
109 napi_value resultout = nullptr;
110 napi_get_reference_value(env, callbackIn, &callback);
111 napi_value results[ASYNC_CALLBACK_PARAM_NUM] = {nullptr};
112 if (errCode == ERR_OK) {
113 results[0] = NapiGetNull(env);
114 } else {
115 int32_t errCodeInfo = FindErrCode(env, errCode);
116 std::string errMsg = FindErrMsg(env, errCode);
117 results[0] = GetCallbackErrorValue(env, errCodeInfo, errMsg);
118 }
119 results[1] = result;
120 NAPI_CALL_RETURN_VOID(env,
121 napi_call_function(env, undefined, callback, ASYNC_CALLBACK_PARAM_NUM, &results[0], &resultout));
122 }
123
SetPromise(const napi_env & env,const AsyncWorkData & info,const napi_value & result)124 napi_value Common::SetPromise(
125 const napi_env &env, const AsyncWorkData &info, const napi_value &result)
126 {
127 if (info.errCode == ERR_OK) {
128 napi_resolve_deferred(env, info.deferred, result);
129 } else {
130 int32_t errCodeInfo = FindErrCode(env, info.errCode);
131 std::string errMsg = FindErrMsg(env, info.errCode);
132 napi_value error = nullptr;
133 napi_value eCode = nullptr;
134 napi_value eMsg = nullptr;
135 NAPI_CALL(env, napi_create_int32(env, errCodeInfo, &eCode));
136 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
137 errMsg.length(), &eMsg));
138 NAPI_CALL(env, napi_create_object(env, &error));
139 NAPI_CALL(env, napi_set_named_property(env, error, "data", eCode));
140 NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode));
141 NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg));
142 napi_reject_deferred(env, info.deferred, error);
143 }
144 return result;
145 }
146
ReturnCallbackPromise(const napi_env & env,const AsyncWorkData & info,const napi_value & result)147 void Common::ReturnCallbackPromise(const napi_env &env, const AsyncWorkData &info, const napi_value &result)
148 {
149 if (info.isCallback) {
150 SetCallback(env, info.callback, info.errCode, result);
151 } else {
152 SetPromise(env, info, result);
153 }
154 }
155
JSParaError(const napi_env & env,const napi_ref & callback)156 napi_value Common::JSParaError(const napi_env &env, const napi_ref &callback)
157 {
158 if (callback) {
159 SetCallback(env, callback, ERR_BGTASK_INVALID_PARAM, nullptr);
160 return Common::NapiGetNull(env);
161 } else {
162 napi_value promise = nullptr;
163 napi_deferred deferred = nullptr;
164 napi_create_promise(env, &deferred, &promise);
165
166 napi_value res = nullptr;
167 napi_value eCode = nullptr;
168 napi_value eMsg = nullptr;
169 std::string errMsg = FindErrMsg(env, ERR_BGTASK_INVALID_PARAM);
170 NAPI_CALL(env, napi_create_int32(env, ERR_BGTASK_INVALID_PARAM, &eCode));
171 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(),
172 errMsg.length(), &eMsg));
173 NAPI_CALL(env, napi_create_object(env, &res));
174 NAPI_CALL(env, napi_set_named_property(env, res, "data", eCode));
175 NAPI_CALL(env, napi_set_named_property(env, res, "code", eCode));
176 NAPI_CALL(env, napi_set_named_property(env, res, "message", eMsg));
177 napi_reject_deferred(env, deferred, res);
178 return promise;
179 }
180 }
181
GetU16StringValue(const napi_env & env,const napi_value & value,std::u16string & result)182 napi_value Common::GetU16StringValue(const napi_env &env, const napi_value &value, std::u16string &result)
183 {
184 napi_valuetype valuetype = napi_undefined;
185
186 NAPI_CALL(env, napi_typeof(env, value, &valuetype));
187 if (valuetype == napi_string) {
188 char str[STR_MAX_SIZE] = {0};
189 size_t strLen = 0;
190 NAPI_CALL(env, napi_get_value_string_utf8(env, value, str, STR_MAX_SIZE - 1, &strLen));
191
192 result = Str8ToStr16((std::string)str);
193 BGTASK_LOGD("GetU16StringValue result: %{public}s", Str16ToStr8(result).c_str());
194 } else {
195 return nullptr;
196 }
197
198 return Common::NapiGetNull(env);
199 }
200
GetInt32NumberValue(const napi_env & env,const napi_value & value,int32_t & result)201 napi_value Common::GetInt32NumberValue(const napi_env &env, const napi_value &value, int32_t &result)
202 {
203 napi_valuetype valuetype = napi_undefined;
204 BGTASK_NAPI_CALL(env, napi_typeof(env, value, &valuetype));
205 if (valuetype != napi_number) {
206 return nullptr;
207 }
208 BGTASK_NAPI_CALL(env, napi_get_value_int32(env, value, &result));
209 BGTASK_LOGD("GetInt32NumberValue result: %{public}d", result);
210 return Common::NapiGetNull(env);
211 }
212
PaddingAsyncWorkData(const napi_env & env,const napi_ref & callback,AsyncWorkData & info,napi_value & promise)213 void Common::PaddingAsyncWorkData(
214 const napi_env &env, const napi_ref &callback, AsyncWorkData &info, napi_value &promise)
215 {
216 if (callback) {
217 info.callback = callback;
218 info.isCallback = true;
219 } else {
220 napi_deferred deferred = nullptr;
221 NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
222 info.deferred = deferred;
223 info.isCallback = false;
224 }
225 }
226
SetDelaySuspendInfo(const napi_env & env,std::shared_ptr<DelaySuspendInfo> & delaySuspendInfo,napi_value & result)227 napi_value Common::SetDelaySuspendInfo(
228 const napi_env &env, std::shared_ptr<DelaySuspendInfo>& delaySuspendInfo, napi_value &result)
229 {
230 if (delaySuspendInfo == nullptr) {
231 BGTASK_LOGI("delaySuspendInfo is nullptr");
232 return NapiGetboolean(env, false);
233 }
234 napi_value value = nullptr;
235
236 // readonly requestId?: number
237 napi_create_int32(env, delaySuspendInfo->GetRequestId(), &value);
238 napi_set_named_property(env, result, "requestId", value);
239
240 // readonly actualDelayTime?: number
241 napi_create_int32(env, delaySuspendInfo->GetActualDelayTime(), &value);
242 napi_set_named_property(env, result, "actualDelayTime", value);
243
244 return NapiGetboolean(env, true);
245 }
246
GetStringValue(const napi_env & env,const napi_value & value,std::string & result)247 napi_value Common::GetStringValue(const napi_env &env, const napi_value &value, std::string &result)
248 {
249 napi_valuetype valuetype = napi_undefined;
250 BGTASK_NAPI_CALL(env, napi_typeof(env, value, &valuetype));
251 if (valuetype != napi_string) {
252 return nullptr;
253 }
254
255 char str[STR_MAX_SIZE] = {0};
256 size_t strLen = 0;
257 napi_status status = napi_get_value_string_utf8(env, value, str, STR_MAX_SIZE - 1, &strLen);
258 if (status != napi_ok) {
259 return nullptr;
260 }
261 result = std::string(str);
262 BGTASK_LOGD("GetStringValue result: %{public}s", result.c_str());
263 return Common::NapiGetNull(env);
264 }
265
HandleErrCode(const napi_env & env,int32_t errCode,bool isThrow)266 void Common::HandleErrCode(const napi_env &env, int32_t errCode, bool isThrow)
267 {
268 BGTASK_LOGD("HandleErrCode errCode = %{public}d, isThrow = %{public}d", errCode, isThrow);
269 if (!isThrow || errCode == ERR_OK) {
270 return;
271 }
272 std::string errMsg = FindErrMsg(env, errCode);
273 int32_t errCodeInfo = FindErrCode(env, errCode);
274 if (errMsg != "") {
275 napi_throw_error(env, std::to_string(errCodeInfo).c_str(), errMsg.c_str());
276 }
277 }
278
HandleParamErr(const napi_env & env,int32_t errCode,bool isThrow)279 bool Common::HandleParamErr(const napi_env &env, int32_t errCode, bool isThrow)
280 {
281 BGTASK_LOGD("HandleParamErr errCode = %{public}d, isThrow = %{public}d", errCode, isThrow);
282 if (!isThrow || errCode == ERR_OK) {
283 return false;
284 }
285 auto iter = paramErrCodeMsgMap.find(errCode);
286 if (iter != paramErrCodeMsgMap.end()) {
287 std::string errMessage = "BussinessError 401: Parameter error. ";
288 errMessage.append(iter->second);
289 napi_throw_error(env, std::to_string(ERR_BGTASK_INVALID_PARAM).c_str(), errMessage.c_str());
290 return true;
291 }
292 return false;
293 }
294
FindErrMsg(const napi_env & env,const int32_t errCode)295 std::string Common::FindErrMsg(const napi_env &env, const int32_t errCode)
296 {
297 if (errCode == ERR_OK) {
298 return "";
299 }
300 auto iter = saErrCodeMsgMap.find(errCode);
301 if (iter != saErrCodeMsgMap.end()) {
302 std::string errMessage = "BussinessError ";
303 int32_t errCodeInfo = FindErrCode(env, errCode);
304 errMessage.append(std::to_string(errCodeInfo)).append(": ").append(iter->second);
305 return errMessage;
306 }
307 iter = paramErrCodeMsgMap.find(errCode);
308 if (iter != paramErrCodeMsgMap.end()) {
309 std::string errMessage = "BussinessError 401: Parameter error. ";
310 errMessage.append(iter->second);
311 return errMessage;
312 }
313 return "Inner error.";
314 }
315
FindErrCode(const napi_env & env,const int32_t errCodeIn)316 int32_t Common::FindErrCode(const napi_env &env, const int32_t errCodeIn)
317 {
318 auto iter = paramErrCodeMsgMap.find(errCodeIn);
319 if (iter != paramErrCodeMsgMap.end()) {
320 return ERR_BGTASK_INVALID_PARAM;
321 }
322 return errCodeIn > THRESHOLD ? errCodeIn / OFFSET : errCodeIn;
323 }
324
GetBooleanValue(const napi_env & env,const napi_value & value,bool & result)325 napi_value Common::GetBooleanValue(const napi_env &env, const napi_value &value, bool &result)
326 {
327 napi_valuetype valuetype = napi_undefined;
328 BGTASK_NAPI_CALL(env, napi_typeof(env, value, &valuetype));
329 if (valuetype != napi_boolean) {
330 return nullptr;
331 }
332 BGTASK_NAPI_CALL(env, napi_get_value_bool(env, value, &result));
333 BGTASK_LOGD("GetBooleanValue result: %{public}d", result);
334
335 return Common::NapiGetNull(env);
336 }
337 } // namespace BackgroundTaskMgr
338 } // namespace OHOS
339