• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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 "ipc_skeleton.h"
16 #include "napi_account_common.h"
17 
18 #include "account_log_wrapper.h"
19 #include "bundle_mgr_proxy.h"
20 #include "ipc_skeleton.h"
21 #include "iservice_registry.h"
22 #include "js_native_api.h"
23 #include "js_native_api_types.h"
24 #include "napi_account_error.h"
25 #include "napi/native_api.h"
26 #include "napi/native_common.h"
27 #include "napi/native_node_api.h"
28 #include "securec.h"
29 #include "system_ability_definition.h"
30 #include "tokenid_kit.h"
31 
32 namespace OHOS {
33 namespace AccountJsKit {
34 namespace {
35 constexpr int32_t BUSINESS_ERROR_ARG_SIZE = 2;
36 const char BUSINESS_ERROR_CODE_NAME[] = "code";
37 const char BUSINESS_ERROR_DATA_NAME[] = "data";
38 }
39 
40 using namespace AccountSA;
41 
~CommonAsyncContext()42 CommonAsyncContext::~CommonAsyncContext()
43 {
44     if (env == nullptr) {
45         return;
46     }
47     if (callbackRef != nullptr) {
48         napi_delete_reference(env, callbackRef);
49         callbackRef = nullptr;
50     }
51     if (work != nullptr) {
52         napi_delete_async_work(env, work);
53         work = nullptr;
54     }
55 }
56 
CreateExecEnv(napi_env env,uv_loop_s ** loop,uv_work_t ** work)57 bool CreateExecEnv(napi_env env, uv_loop_s **loop, uv_work_t **work)
58 {
59     *loop = nullptr;
60     napi_get_uv_event_loop(env, loop);
61     if (*loop == nullptr) {
62         ACCOUNT_LOGE("failed to get uv event loop");
63         return false;
64     }
65     *work = new (std::nothrow) uv_work_t;
66     if (*work == nullptr) {
67         ACCOUNT_LOGE("failed to create uv_work_t");
68         return false;
69     }
70     return true;
71 }
72 
ProcessCallbackOrPromise(napi_env env,const CommonAsyncContext * asyncContext,napi_value err,napi_value data)73 void ProcessCallbackOrPromise(napi_env env, const CommonAsyncContext *asyncContext, napi_value err, napi_value data)
74 {
75     napi_value args[BUSINESS_ERROR_ARG_SIZE] = {0};
76     if (asyncContext->errCode == ERR_OK) {
77         napi_get_null(env, &args[0]);
78         args[1] = data;
79     } else {
80         napi_get_null(env, &args[1]);
81         args[0] = err;
82     }
83     if (asyncContext->deferred) {
84         if (asyncContext->errCode == ERR_OK) {
85             napi_resolve_deferred(env, asyncContext->deferred, args[1]);
86         } else {
87             napi_reject_deferred(env, asyncContext->deferred, args[0]);
88         }
89     } else {
90         NapiCallVoidFunction(env, args, BUSINESS_ERROR_ARG_SIZE, asyncContext->callbackRef);
91     }
92 }
93 
ReturnCallbackOrPromise(napi_env env,const CommonAsyncContext * asyncContext,napi_value err,napi_value data)94 void ReturnCallbackOrPromise(napi_env env, const CommonAsyncContext *asyncContext, napi_value err, napi_value data)
95 {
96     napi_value args[BUSINESS_ERROR_ARG_SIZE] = {err, data};
97     if (asyncContext->errCode == ERR_OK) {
98         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &args[0]));
99     } else {
100         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &args[1]));
101     }
102     if (asyncContext->deferred != nullptr) {
103         if (asyncContext->errCode == ERR_OK) {
104             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncContext->deferred, args[1]));
105         } else {
106             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncContext->deferred, args[0]));
107         }
108         return;
109     }
110     if (asyncContext->callbackRef != nullptr) {
111         NapiCallVoidFunction(env, args, BUSINESS_ERROR_ARG_SIZE, asyncContext->callbackRef);
112     }
113 }
114 
GetIntProperty(napi_env env,napi_value obj,int32_t & property)115 bool GetIntProperty(napi_env env, napi_value obj, int32_t &property)
116 {
117     napi_valuetype valueType = napi_undefined;
118     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
119     if (valueType != napi_number) {
120         return false;
121     }
122 
123     NAPI_CALL_BASE(env, napi_get_value_int32(env, obj, &property), false);
124     return true;
125 }
126 
GetOptionIntProperty(napi_env env,napi_value obj,int32_t & property,bool & hasProperty)127 bool GetOptionIntProperty(napi_env env, napi_value obj, int32_t &property, bool &hasProperty)
128 {
129     napi_valuetype valueType = napi_undefined;
130     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
131     if ((valueType == napi_undefined) || (valueType == napi_null)) {
132         ACCOUNT_LOGI("This value is undefined or null");
133         return true;
134     }
135     if (valueType != napi_number) {
136         return false;
137     }
138     NAPI_CALL_BASE(env, napi_get_value_int32(env, obj, &property), false);
139     hasProperty = true;
140     return true;
141 }
142 
GetLongIntProperty(napi_env env,napi_value obj,int64_t & property)143 bool GetLongIntProperty(napi_env env, napi_value obj, int64_t &property)
144 {
145     napi_valuetype valueType = napi_undefined;
146     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
147     if (valueType != napi_number) {
148         return false;
149     }
150 
151     NAPI_CALL_BASE(env, napi_get_value_int64(env, obj, &property), false);
152     return true;
153 }
154 
GetBoolProperty(napi_env env,napi_value obj,bool & property)155 bool GetBoolProperty(napi_env env, napi_value obj, bool &property)
156 {
157     napi_valuetype valueType = napi_undefined;
158     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
159     if (valueType != napi_boolean) {
160         return false;
161     }
162     NAPI_CALL_BASE(env, napi_get_value_bool(env, obj, &property), false);
163     return true;
164 }
165 
GetStringProperty(napi_env env,napi_value obj,std::string & property)166 bool GetStringProperty(napi_env env, napi_value obj, std::string &property)
167 {
168     napi_valuetype valuetype = napi_undefined;
169     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valuetype), false);
170     if (valuetype != napi_string) {
171         return false;
172     }
173 
174     size_t propLen;
175     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, obj, nullptr, 0, &propLen), false);
176     property.reserve(propLen + 1);
177     property.resize(propLen);
178     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, obj, property.data(), propLen + 1, &propLen), false);
179     return true;
180 }
181 
GetStringArrayProperty(napi_env env,napi_value obj,std::vector<std::string> & property,bool allowEmpty)182 bool GetStringArrayProperty(napi_env env, napi_value obj, std::vector<std::string> &property, bool allowEmpty)
183 {
184     bool isArray = false;
185     NAPI_CALL_BASE(env, napi_is_array(env, obj, &isArray), false);
186     if (!isArray) {
187         return false;
188     }
189     uint32_t length = 0;
190     NAPI_CALL_BASE(env, napi_get_array_length(env, obj, &length), false);
191     if (!allowEmpty && (length == 0)) {
192         return false;
193     }
194 
195     for (size_t i = 0; i < length; i++) {
196         napi_value strJs = nullptr;
197         NAPI_CALL_BASE(env, napi_get_element(env, obj, i, &strJs), false);
198         std::string str;
199         if (!GetStringProperty(env, strJs, str)) {
200             return false;
201         }
202         property.emplace_back(str);
203     }
204     return true;
205 }
206 
GetStringArrayPropertyByKey(napi_env env,napi_value obj,const std::string & propertyName,std::vector<std::string> & property,bool allowEmpty)207 bool GetStringArrayPropertyByKey(napi_env env, napi_value obj, const std::string &propertyName,
208     std::vector<std::string> &property, bool allowEmpty)
209 {
210     napi_value value = nullptr;
211     NAPI_CALL_BASE(env, napi_get_named_property(env, obj, propertyName.c_str(), &value), false);
212     return GetStringArrayProperty(env, value, property, allowEmpty);
213 }
214 
GetCallbackProperty(napi_env env,napi_value obj,napi_ref & property,int argNum)215 bool GetCallbackProperty(napi_env env, napi_value obj, napi_ref &property, int argNum)
216 {
217     napi_valuetype valueType = napi_undefined;
218     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
219     if ((valueType == napi_undefined) || (valueType == napi_null)) {
220         ACCOUNT_LOGI("the callback is undefined or null");
221         return true;
222     } else if (valueType == napi_function) {
223         NAPI_CALL_BASE(env, napi_create_reference(env, obj, argNum, &property), false);
224         return true;
225     }
226     ACCOUNT_LOGE("the callback is not a napi_function");
227     return false;
228 }
229 
GetStringPropertyByKey(napi_env env,napi_value obj,const std::string & propertyName,std::string & property)230 bool GetStringPropertyByKey(napi_env env, napi_value obj, const std::string &propertyName, std::string &property)
231 {
232     napi_value value = nullptr;
233     NAPI_CALL_BASE(env, napi_get_named_property(env, obj, propertyName.c_str(), &value), false);
234     return GetStringProperty(env, value, property);
235 }
236 
GetOptionalStringPropertyByKey(napi_env env,napi_value obj,const std::string & propertyName,std::string & property)237 bool GetOptionalStringPropertyByKey(napi_env env, napi_value obj, const std::string &propertyName,
238     std::string &property)
239 {
240     bool hasProp = false;
241     napi_has_named_property(env, obj, propertyName.c_str(), &hasProp);
242     if (!hasProp) {
243         return true;
244     }
245     napi_value value = nullptr;
246     NAPI_CALL_BASE(env, napi_get_named_property(env, obj, propertyName.c_str(), &value), false);
247     napi_valuetype valuetype = napi_undefined;
248     NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false);
249     if ((valuetype == napi_undefined) || (valuetype == napi_null)) {
250         ACCOUNT_LOGI("this key's value is undefined or null");
251         return true;
252     }
253     return GetStringProperty(env, value, property);
254 }
255 
GetOptionalStringPropertyByKey(napi_env env,napi_value obj,const std::string & propertyName,std::string & property,bool & hasProperty)256 bool GetOptionalStringPropertyByKey(napi_env env, napi_value obj, const std::string &propertyName,
257     std::string &property, bool &hasProperty)
258 {
259     bool hasProp = false;
260     napi_has_named_property(env, obj, propertyName.c_str(), &hasProp);
261     if (!hasProp) {
262         return true;
263     }
264     napi_value value = nullptr;
265     NAPI_CALL_BASE(env, napi_get_named_property(env, obj, propertyName.c_str(), &value), false);
266     napi_valuetype valuetype = napi_undefined;
267     NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false);
268     if ((valuetype == napi_undefined) || (valuetype == napi_null)) {
269         ACCOUNT_LOGI("this key's value is undefined or null");
270         return true;
271     }
272     if (!GetStringProperty(env, value, property)) {
273         return false;
274     }
275     hasProperty = true;
276     return true;
277 }
278 
IsOptionalPropertyExist(napi_env env,napi_value obj,const std::string & propertyName)279 bool IsOptionalPropertyExist(napi_env env, napi_value obj, const std::string &propertyName)
280 {
281     bool hasProp = false;
282     napi_has_named_property(env, obj, propertyName.c_str(), &hasProp);
283     if (!hasProp) {
284         return false;
285     }
286     napi_value value = nullptr;
287     NAPI_CALL_BASE(env, napi_get_named_property(env, obj, propertyName.c_str(), &value), false);
288     napi_valuetype valuetype = napi_undefined;
289     NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false);
290     if ((valuetype == napi_undefined) || (valuetype == napi_null)) {
291         ACCOUNT_LOGI("This key's value is undefined or null");
292         return false;
293     }
294     return true;
295 }
296 
GetOptionalNumberPropertyByKey(napi_env env,napi_value obj,const std::string & propertyName,int32_t & numberProperty,bool & hasProperty)297 bool GetOptionalNumberPropertyByKey(napi_env env, napi_value obj, const std::string &propertyName,
298     int32_t &numberProperty, bool &hasProperty)
299 {
300     bool hasProp = false;
301     napi_has_named_property(env, obj, propertyName.c_str(), &hasProp);
302     if (!hasProp) {
303         ACCOUNT_LOGI("This property has no '%{public}s' key", propertyName.c_str());
304         return true;
305     }
306     napi_value value = nullptr;
307     NAPI_CALL_BASE(env, napi_get_named_property(env, obj, propertyName.c_str(), &value), false);
308     napi_valuetype valuetype = napi_undefined;
309     NAPI_CALL_BASE(env, napi_typeof(env, value, &valuetype), false);
310     if ((valuetype == napi_undefined) || (valuetype == napi_null)) {
311         ACCOUNT_LOGI("This key's value is undefined or null");
312         return true;
313     }
314     if (!GetIntProperty(env, value, numberProperty)) {
315         return false;
316     }
317     hasProperty = true;
318     return true;
319 }
320 
CompareOnAndOffRef(const napi_env env,napi_ref subscriberRef,napi_ref unsubscriberRef)321 bool CompareOnAndOffRef(const napi_env env, napi_ref subscriberRef, napi_ref unsubscriberRef)
322 {
323     napi_value subscriberCallback;
324     napi_get_reference_value(env, subscriberRef, &subscriberCallback);
325     napi_value unsubscriberCallback;
326     napi_get_reference_value(env, unsubscriberRef, &unsubscriberCallback);
327     bool result = false;
328     napi_strict_equals(env, subscriberCallback, unsubscriberCallback, &result);
329     return result;
330 }
331 
IsSystemApp(napi_env env)332 bool IsSystemApp(napi_env env)
333 {
334     uint64_t tokenId = IPCSkeleton::GetSelfTokenID();
335     bool isSystemApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
336     if (!isSystemApp) {
337         std::string errMsg = ConvertToJsErrMsg(ERR_JS_IS_NOT_SYSTEM_APP);
338         AccountNapiThrow(env, ERR_JS_IS_NOT_SYSTEM_APP, errMsg, true);
339         return false;
340     }
341     return true;
342 }
343 
CreateStringArray(napi_env env,const std::vector<std::string> & strVec)344 napi_value CreateStringArray(napi_env env, const std::vector<std::string> &strVec)
345 {
346     napi_value result = nullptr;
347     napi_create_array(env, &result);
348     for (size_t i = 0; i < strVec.size(); ++i) {
349         napi_value value = nullptr;
350         napi_create_string_utf8(env, strVec[i].c_str(), NAPI_AUTO_LENGTH, &value);
351         napi_set_element(env, result, i, value);
352     }
353     return result;
354 }
CreateUint8Array(napi_env env,const uint8_t * srcData,size_t length)355 napi_value CreateUint8Array(napi_env env, const uint8_t *srcData, size_t length)
356 {
357     napi_value result = nullptr;
358     void* dstData = nullptr;
359     napi_value napiArr = nullptr;
360     NAPI_CALL(env, napi_create_arraybuffer(env, length, &dstData, &napiArr));
361     if ((length > 0) && (memcpy_s(dstData, length, srcData, length) != EOK)) {
362         return result;
363     }
364     NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, length, napiArr, 0, &result));
365     return result;
366 }
367 
ParseUint8TypedArray(napi_env env,napi_value value,uint8_t ** data,size_t * length)368 napi_status ParseUint8TypedArray(napi_env env, napi_value value, uint8_t **data, size_t *length)
369 {
370     *data = nullptr;
371     *length = 0;
372     bool isTypedArray = false;
373     napi_is_typedarray(env, value, &isTypedArray);
374     if (!isTypedArray) {
375         ACCOUNT_LOGE("invalid uint8 array");
376         return napi_ok;
377     }
378     napi_typedarray_type arrayType = static_cast<napi_typedarray_type>(-1);  // -1 indicates invalid type
379     napi_value buffer = nullptr;
380     size_t offset = 0;
381     napi_get_typedarray_info(env, value, &arrayType, length, reinterpret_cast<void **>(data), &buffer, &offset);
382     if (arrayType != napi_uint8_array) {
383         ACCOUNT_LOGE("invalid uint8 array");
384         *data = nullptr;
385         *length = 0;
386     }
387     return napi_ok;
388 }
389 
ParseUint8TypedArrayToVector(napi_env env,napi_value value,std::vector<uint8_t> & vec)390 napi_status ParseUint8TypedArrayToVector(napi_env env, napi_value value, std::vector<uint8_t> &vec)
391 {
392     uint8_t *data = nullptr;
393     size_t length = 0;
394     napi_status status = ParseUint8TypedArray(env, value, &data, &length);
395     if (status != napi_ok) {
396         ACCOUNT_LOGE("failed to ParseUint8TypedArray");
397         return status;
398     }
399     vec.assign(data, data + length);
400     return napi_ok;
401 }
402 
ParseUint8TypedArrayToUint64(napi_env env,napi_value value,uint64_t & result)403 napi_status ParseUint8TypedArrayToUint64(napi_env env, napi_value value, uint64_t &result)
404 {
405     uint8_t *data = nullptr;
406     size_t length = 0;
407     napi_status status = ParseUint8TypedArray(env, value, &data, &length);
408     if (status != napi_ok) {
409         ACCOUNT_LOGE("failed to ParseUint8TypedArray");
410         return status;
411     }
412     if (data == nullptr) {
413         result = 0;
414         return napi_invalid_arg;
415     }
416     if (length != sizeof(uint64_t)) {
417         ACCOUNT_LOGE("failed to convert to uint64_t value");
418         return napi_invalid_arg;
419     }
420     result = *(reinterpret_cast<uint64_t *>(data));
421     return napi_ok;
422 }
423 
ParseBusinessError(napi_env env,napi_value value,BusinessError & error)424 bool ParseBusinessError(napi_env env, napi_value value, BusinessError &error)
425 {
426     napi_valuetype valueType = napi_undefined;
427     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
428     if (valueType == napi_null || (valueType == napi_undefined)) {
429         error.code = 0;
430         return true;
431     }
432     napi_value napiCode = nullptr;
433     NAPI_CALL_BASE(env, napi_get_named_property(env, value, BUSINESS_ERROR_CODE_NAME, &napiCode), false);
434     if (napiCode == nullptr) {
435         ACCOUNT_LOGE("code is undefined");
436         return false;
437     }
438     NAPI_CALL_BASE(env, napi_get_value_int32(env, napiCode, &error.code), false);
439     bool hasData = false;
440     napi_has_named_property(env, value, BUSINESS_ERROR_DATA_NAME, &hasData);
441     if (hasData) {
442         napi_value napiData = nullptr;
443         napi_get_named_property(env, value, BUSINESS_ERROR_DATA_NAME, &napiData);
444         return GetStringProperty(env, napiData, error.data);
445     }
446     return true;
447 }
448 
GetNamedJsFunction(napi_env env,napi_value object,const std::string & name,napi_ref & callback)449 bool GetNamedJsFunction(napi_env env, napi_value object, const std::string &name, napi_ref &callback)
450 {
451     napi_valuetype valueType = napi_undefined;
452     NAPI_CALL_BASE(env, napi_typeof(env, object, &valueType), false);
453     if (valueType != napi_object) {
454         ACCOUNT_LOGE("invalid object");
455         return false;
456     }
457     napi_value result = nullptr;
458     NAPI_CALL_BASE(env, napi_get_named_property(env, object, name.c_str(), &result), false);
459     return GetCallbackProperty(env, result, callback, 1);
460 }
461 
NapiCallVoidFunction(napi_env env,napi_value * argv,size_t argc,napi_ref funcRef)462 void NapiCallVoidFunction(napi_env env, napi_value *argv, size_t argc, napi_ref funcRef)
463 {
464     napi_value undefined = nullptr;
465     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
466     napi_value returnVal;
467     napi_value func = nullptr;
468     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, funcRef, &func));
469     napi_status status = napi_call_function(env, undefined, func, argc, argv, &returnVal);
470     ACCOUNT_LOGI("call js function finish, status: %{public}d", status);
471 }
472 
SetInt32ToJsProperty(napi_env env,int32_t number,const std::string & propertyName,napi_value & dataJs)473 void SetInt32ToJsProperty(napi_env env, int32_t number, const std::string &propertyName, napi_value &dataJs)
474 {
475     napi_value napiNum = nullptr;
476     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, number, &napiNum));
477     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, dataJs, propertyName.c_str(), napiNum));
478 }
479 
CreateAuthResult(napi_env env,const std::vector<uint8_t> & token,int32_t remainTimes,int32_t freezingTime)480 napi_value CreateAuthResult(
481     napi_env env, const std::vector<uint8_t> &token, int32_t remainTimes, int32_t freezingTime)
482 {
483     napi_value object = nullptr;
484     NAPI_CALL(env, napi_create_object(env, &object));
485     if (remainTimes >= 0) {
486         napi_value napiRemainTimes = 0;
487         NAPI_CALL(env, napi_create_uint32(env, remainTimes, &napiRemainTimes));
488         NAPI_CALL(env, napi_set_named_property(env, object, "remainTimes", napiRemainTimes));
489     }
490     if (freezingTime >= 0) {
491         napi_value napiFreezingTimes = 0;
492         NAPI_CALL(env, napi_create_uint32(env, freezingTime, &napiFreezingTimes));
493         NAPI_CALL(env, napi_set_named_property(env, object, "freezingTime", napiFreezingTimes));
494     }
495     if (token.size() > 0) {
496         napi_value napiToken = CreateUint8Array(env, token.data(), token.size());
497         NAPI_CALL(env, napi_set_named_property(env, object, "token", napiToken));
498     }
499     return object;
500 }
501 
ReleaseNapiRefAsync(napi_env env,napi_ref napiRef)502 void ReleaseNapiRefAsync(napi_env env, napi_ref napiRef)
503 {
504     ReleaseNapiRefArray(env, {napiRef});
505 }
506 
ReleaseNapiRefArray(napi_env env,const std::vector<napi_ref> & napiRefVec)507 void ReleaseNapiRefArray(napi_env env, const std::vector<napi_ref> &napiRefVec)
508 {
509     if (env == nullptr) {
510         ACCOUNT_LOGE("invalid env");
511         return;
512     }
513     std::unique_ptr<uv_work_t> work = std::make_unique<uv_work_t>();
514     std::unique_ptr<NapiRefArrayContext> context = std::make_unique<NapiRefArrayContext>();
515     uv_loop_s *loop = nullptr;
516     napi_get_uv_event_loop(env, &loop);
517     if ((loop == nullptr) || (work == nullptr) || (context == nullptr)) {
518         ACCOUNT_LOGE("fail to init execution environment");
519         return;
520     }
521     context->env = env;
522     context->napiRefVec = napiRefVec;
523     work->data = reinterpret_cast<void *>(context.get());
524     NAPI_CALL_RETURN_VOID(env, uv_queue_work_with_qos(loop, work.get(), [] (uv_work_t *work) {},
525         [] (uv_work_t *work, int status) {
526             if (work == nullptr) {
527                 ACCOUNT_LOGE("work is nullptr");
528                 return;
529             }
530             auto context = reinterpret_cast<NapiRefArrayContext *>(work->data);
531             if (context == nullptr) {
532                 ACCOUNT_LOGE("context is nullptr");
533                 delete work;
534                 return;
535             }
536             for (auto &napiRef : context->napiRefVec) {
537                 if (napiRef != nullptr) {
538                     napi_delete_reference(context->env, napiRef);
539                 }
540             }
541             delete context;
542             delete work;
543         }, uv_qos_default));
544     context.release();
545     work.release();
546 }
547 
~NapiCallbackRef()548 NapiCallbackRef::~NapiCallbackRef()
549 {
550     ReleaseNapiRefArray(env, {callbackRef});
551 }
552 
InitUvWorkCallbackEnv(uv_work_t * work,napi_handle_scope & scope)553 bool InitUvWorkCallbackEnv(uv_work_t *work, napi_handle_scope &scope)
554 {
555     if (work == nullptr) {
556         ACCOUNT_LOGE("work is nullptr");
557         return false;
558     }
559     if (work->data == nullptr) {
560         ACCOUNT_LOGE("data is nullptr");
561         return false;
562     }
563     CommonAsyncContext *data = reinterpret_cast<CommonAsyncContext *>(work->data);
564     napi_open_handle_scope(data->env, &scope);
565     if (scope == nullptr) {
566         ACCOUNT_LOGE("fail to open scope");
567         delete data;
568         work->data = nullptr;
569         return false;
570     }
571     return true;
572 }
573 
JsObjectToNativeString(napi_env env,napi_value jsData,std::string & nativeData)574 bool JsObjectToNativeString(napi_env env, napi_value jsData, std::string &nativeData)
575 {
576     napi_valuetype valueType = napi_undefined;
577     napi_typeof(env, jsData, &valueType);
578     if (valueType != napi_object) {
579         ACCOUNT_LOGI("The parameters is not object");
580         return false;
581     }
582     napi_value globalValue = nullptr;
583     napi_get_global(env, &globalValue);
584     napi_value jsonValue;
585     napi_get_named_property(env, globalValue, "JSON", &jsonValue);
586 
587     napi_value stringifyValue = nullptr;
588     napi_get_named_property(env, jsonValue, "stringify", &stringifyValue);
589     napi_value funcArgv[1] = { jsData };
590     napi_value transValue = nullptr;
591     napi_status status = napi_call_function(env, jsonValue, stringifyValue, 1, funcArgv, &transValue);
592     if (status != napi_ok) {
593         ACCOUNT_LOGE("Fail to call function, %{public}d", status);
594         return false;
595     }
596 
597     if (!GetStringProperty(env, transValue, nativeData)) {
598         ACCOUNT_LOGE("Get native data failed");
599         std::string errMsg = "The type of arg 2 must be string";
600         AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, false);
601         return false;
602     }
603     return true;
604 }
605 
NativeStringToJsObject(napi_env env,const std::string & nativeData)606 napi_value NativeStringToJsObject(napi_env env, const std::string &nativeData)
607 {
608     napi_value jsObjData = nullptr;
609     if (nativeData.empty()) {
610         napi_create_object(env, &jsObjData);
611         return jsObjData;
612     }
613     napi_value globalValue = nullptr;
614     napi_get_global(env, &globalValue);
615     napi_value jsonValue;
616     napi_get_named_property(env, globalValue, "JSON", &jsonValue);
617     napi_value parseValue = nullptr;
618     napi_get_named_property(env, jsonValue, "parse", &parseValue);
619     napi_value jsStringDate = nullptr;
620     NAPI_CALL(env, napi_create_string_utf8(env, nativeData.c_str(), NAPI_AUTO_LENGTH, &jsStringDate));
621     napi_value funcArgv[1] = { jsStringDate };
622     napi_status status = napi_call_function(env, jsonValue, parseValue, 1, funcArgv, &jsObjData);
623     if (status != napi_ok) {
624         ACCOUNT_LOGE("Fail to call function, status: %{public}d", status);
625     }
626     return jsObjData;
627 }
628 
GetSelfTargetVersion(uint32_t & targetVersion)629 bool GetSelfTargetVersion(uint32_t &targetVersion)
630 {
631     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
632     if (samgr == nullptr) {
633         ACCOUNT_LOGE("Samgr error");
634         return false;
635     }
636     auto bundleObj = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
637     if (bundleObj == nullptr) {
638         ACCOUNT_LOGE("BundleObj error");
639         return false;
640     }
641     auto bundleMgrProxy = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
642     if (bundleMgrProxy == nullptr) {
643         ACCOUNT_LOGE("BundleMgrProxy error");
644         return false;
645     }
646     AppExecFwk::BundleInfo bundleInfo;
647     ErrCode ret = bundleMgrProxy->GetBundleInfoForSelf(OHOS::AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo);
648     if (ret != ERR_OK) {
649         ACCOUNT_LOGE("GetBundleInfoForSelf error");
650         return false;
651     }
652     ACCOUNT_LOGI("Bundle targetVersion is %{public}d", bundleInfo.targetVersion);
653     targetVersion = bundleInfo.targetVersion;
654     return true;
655 }
656 } // namespace AccountJsKit
657 } // namespace OHOS