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