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