• 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         args[0] = err;
65     }
66     if (asyncContext->deferred) {
67         if (asyncContext->errCode == ERR_OK) {
68             napi_resolve_deferred(env, asyncContext->deferred, args[1]);
69         } else {
70             napi_reject_deferred(env, asyncContext->deferred, args[0]);
71         }
72     } else {
73         NapiCallVoidFunction(env, args, BUSINESS_ERROR_ARG_SIZE, asyncContext->callbackRef);
74     }
75 }
76 
ReturnCallbackOrPromise(napi_env env,const CommonAsyncContext * asyncContext,napi_value err,napi_value data)77 void ReturnCallbackOrPromise(napi_env env, const CommonAsyncContext *asyncContext, napi_value err, napi_value data)
78 {
79     napi_value args[BUSINESS_ERROR_ARG_SIZE] = {err, data};
80     if (asyncContext->errCode == ERR_OK) {
81         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &args[0]));
82     } else {
83         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &args[1]));
84     }
85     if (asyncContext->deferred != nullptr) {
86         if (asyncContext->errCode == ERR_OK) {
87             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncContext->deferred, args[1]));
88         } else {
89             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncContext->deferred, args[0]));
90         }
91         return;
92     }
93     if (asyncContext->callbackRef != nullptr) {
94         NapiCallVoidFunction(env, args, BUSINESS_ERROR_ARG_SIZE, asyncContext->callbackRef);
95     }
96 }
97 
GetIntProperty(napi_env env,napi_value obj,int32_t & property)98 bool GetIntProperty(napi_env env, napi_value obj, int32_t &property)
99 {
100     napi_valuetype valueType = napi_undefined;
101     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
102     if (valueType != napi_number) {
103         return false;
104     }
105 
106     NAPI_CALL_BASE(env, napi_get_value_int32(env, obj, &property), false);
107     return true;
108 }
109 
GetOptionIntProperty(napi_env env,napi_value obj,int32_t & property,bool & hasProperty)110 bool GetOptionIntProperty(napi_env env, napi_value obj, int32_t &property, bool &hasProperty)
111 {
112     napi_valuetype valueType = napi_undefined;
113     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
114     if ((valueType == napi_undefined) || (valueType == napi_null)) {
115         ACCOUNT_LOGI("This value is undefined or null");
116         return true;
117     }
118     if (valueType != napi_number) {
119         return false;
120     }
121     NAPI_CALL_BASE(env, napi_get_value_int32(env, obj, &property), false);
122     hasProperty = true;
123     return true;
124 }
125 
GetLongIntProperty(napi_env env,napi_value obj,int64_t & property)126 bool GetLongIntProperty(napi_env env, napi_value obj, int64_t &property)
127 {
128     napi_valuetype valueType = napi_undefined;
129     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
130     if (valueType != napi_number) {
131         return false;
132     }
133 
134     NAPI_CALL_BASE(env, napi_get_value_int64(env, obj, &property), false);
135     return true;
136 }
137 
GetBoolProperty(napi_env env,napi_value obj,bool & property)138 bool GetBoolProperty(napi_env env, napi_value obj, bool &property)
139 {
140     napi_valuetype valueType = napi_undefined;
141     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
142     if (valueType != napi_boolean) {
143         return false;
144     }
145     NAPI_CALL_BASE(env, napi_get_value_bool(env, obj, &property), false);
146     return true;
147 }
148 
GetStringProperty(napi_env env,napi_value obj,std::string & property)149 bool GetStringProperty(napi_env env, napi_value obj, std::string &property)
150 {
151     napi_valuetype valuetype = napi_undefined;
152     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valuetype), false);
153     if (valuetype != napi_string) {
154         return false;
155     }
156 
157     size_t propLen;
158     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, obj, nullptr, 0, &propLen), false);
159     property.reserve(propLen + 1);
160     property.resize(propLen);
161     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, obj, property.data(), propLen + 1, &propLen), false);
162     return true;
163 }
164 
GetStringArrayProperty(napi_env env,napi_value obj,std::vector<std::string> & property,bool allowEmpty)165 bool GetStringArrayProperty(napi_env env, napi_value obj, std::vector<std::string> &property, bool allowEmpty)
166 {
167     bool isArray = false;
168     NAPI_CALL_BASE(env, napi_is_array(env, obj, &isArray), false);
169     if (!isArray) {
170         return false;
171     }
172     uint32_t length = 0;
173     NAPI_CALL_BASE(env, napi_get_array_length(env, obj, &length), false);
174     if (!allowEmpty && (length == 0)) {
175         return false;
176     }
177 
178     for (size_t i = 0; i < length; i++) {
179         napi_value strJs = nullptr;
180         NAPI_CALL_BASE(env, napi_get_element(env, obj, i, &strJs), false);
181         std::string str;
182         if (!GetStringProperty(env, strJs, str)) {
183             return false;
184         }
185         property.emplace_back(str);
186     }
187     return true;
188 }
189 
GetStringArrayPropertyByKey(napi_env env,napi_value obj,const std::string & propertyName,std::vector<std::string> & property,bool allowEmpty)190 bool GetStringArrayPropertyByKey(napi_env env, napi_value obj, const std::string &propertyName,
191     std::vector<std::string> &property, bool allowEmpty)
192 {
193     napi_value value = nullptr;
194     NAPI_CALL_BASE(env, napi_get_named_property(env, obj, propertyName.c_str(), &value), false);
195     return GetStringArrayProperty(env, value, property, allowEmpty);
196 }
197 
GetCallbackProperty(napi_env env,napi_value obj,napi_ref & property,int argNum)198 bool GetCallbackProperty(napi_env env, napi_value obj, napi_ref &property, int argNum)
199 {
200     napi_valuetype valueType = napi_undefined;
201     NAPI_CALL_BASE(env, napi_typeof(env, obj, &valueType), false);
202     if ((valueType == napi_undefined) || (valueType == napi_null)) {
203         ACCOUNT_LOGI("the callback is undefined or null");
204         return true;
205     } else if (valueType == napi_function) {
206         NAPI_CALL_BASE(env, napi_create_reference(env, obj, argNum, &property), false);
207         return true;
208     }
209     ACCOUNT_LOGE("the callback is not a napi_function");
210     return false;
211 }
212 
GetStringPropertyByKey(napi_env env,napi_value obj,const std::string & propertyName,std::string & property)213 bool GetStringPropertyByKey(napi_env env, napi_value obj, const std::string &propertyName, std::string &property)
214 {
215     napi_valuetype valueType = napi_undefined;
216     napi_typeof(env, obj, &valueType);
217     if (valueType != napi_object) {
218         ACCOUNT_LOGE("Obj is not an object");
219         return false;
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         ACCOUNT_LOGE("Memcpy_s failed");
352         return result;
353     }
354     NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, length, napiArr, 0, &result));
355     return result;
356 }
357 
ParseUint8TypedArray(napi_env env,napi_value value,uint8_t ** data,size_t * length)358 napi_status ParseUint8TypedArray(napi_env env, napi_value value, uint8_t **data, size_t *length)
359 {
360     *data = nullptr;
361     *length = 0;
362     bool isTypedArray = false;
363     napi_is_typedarray(env, value, &isTypedArray);
364     if (!isTypedArray) {
365         ACCOUNT_LOGE("invalid uint8 array");
366         return napi_ok;
367     }
368     napi_typedarray_type arrayType = static_cast<napi_typedarray_type>(-1);  // -1 indicates invalid type
369     napi_value buffer = nullptr;
370     size_t offset = 0;
371     napi_get_typedarray_info(env, value, &arrayType, length, reinterpret_cast<void **>(data), &buffer, &offset);
372     if (arrayType != napi_uint8_array) {
373         ACCOUNT_LOGE("invalid uint8 array");
374         *data = nullptr;
375         *length = 0;
376     }
377     return napi_ok;
378 }
379 
ParseUint8TypedArrayToVector(napi_env env,napi_value value,std::vector<uint8_t> & vec)380 napi_status ParseUint8TypedArrayToVector(napi_env env, napi_value value, std::vector<uint8_t> &vec)
381 {
382     uint8_t *data = nullptr;
383     size_t length = 0;
384     napi_status status = ParseUint8TypedArray(env, value, &data, &length);
385     if (status != napi_ok) {
386         ACCOUNT_LOGE("failed to ParseUint8TypedArray");
387         return status;
388     }
389     vec.assign(data, data + length);
390     return napi_ok;
391 }
392 
ParseUint8TypedArrayToUint64(napi_env env,napi_value value,uint64_t & result)393 napi_status ParseUint8TypedArrayToUint64(napi_env env, napi_value value, uint64_t &result)
394 {
395     uint8_t *data = nullptr;
396     size_t length = 0;
397     napi_status status = ParseUint8TypedArray(env, value, &data, &length);
398     if (status != napi_ok) {
399         ACCOUNT_LOGE("failed to ParseUint8TypedArray");
400         return status;
401     }
402     if (data == nullptr) {
403         result = 0;
404         return napi_invalid_arg;
405     }
406     if (length != sizeof(uint64_t)) {
407         ACCOUNT_LOGE("failed to convert to uint64_t value");
408         return napi_invalid_arg;
409     }
410     result = *(reinterpret_cast<uint64_t *>(data));
411     return napi_ok;
412 }
413 
ParseUint8ArrayToNativeUint8Array(napi_env env,napi_value value,uint8_t ** data,size_t * length)414 napi_status ParseUint8ArrayToNativeUint8Array(napi_env env, napi_value value, uint8_t **data, size_t *length)
415 {
416     *data = nullptr;
417     *length = 0;
418     bool isTypedArray = false;
419     napi_is_typedarray(env, value, &isTypedArray);
420     if (!isTypedArray) {
421         ACCOUNT_LOGE("Invalid uint8 array");
422         return napi_invalid_arg;
423     }
424     napi_typedarray_type arrayType = static_cast<napi_typedarray_type>(-1);  // -1 indicates invalid type
425     napi_value buffer = nullptr;
426     size_t offset = 0;
427     napi_get_typedarray_info(env, value, &arrayType, length, reinterpret_cast<void **>(data), &buffer, &offset);
428     if (arrayType != napi_uint8_array) {
429         ACCOUNT_LOGE("Invalid uint8 array");
430         *data = nullptr;
431         *length = 0;
432         return napi_invalid_arg;
433     }
434     return napi_ok;
435 }
436 
ParseBusinessError(napi_env env,napi_value value,BusinessError & error)437 bool ParseBusinessError(napi_env env, napi_value value, BusinessError &error)
438 {
439     napi_valuetype valueType = napi_undefined;
440     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
441     if (valueType == napi_null || (valueType == napi_undefined)) {
442         error.code = 0;
443         return true;
444     }
445     napi_value napiCode = nullptr;
446     NAPI_CALL_BASE(env, napi_get_named_property(env, value, BUSINESS_ERROR_CODE_NAME, &napiCode), false);
447     if (napiCode == nullptr) {
448         ACCOUNT_LOGE("code is undefined");
449         return false;
450     }
451     NAPI_CALL_BASE(env, napi_get_value_int32(env, napiCode, &error.code), false);
452     bool hasData = false;
453     napi_has_named_property(env, value, BUSINESS_ERROR_DATA_NAME, &hasData);
454     if (hasData) {
455         napi_value napiData = nullptr;
456         napi_get_named_property(env, value, BUSINESS_ERROR_DATA_NAME, &napiData);
457         return GetStringProperty(env, napiData, error.data);
458     }
459     return true;
460 }
461 
GetNamedJsFunction(napi_env env,napi_value object,const std::string & name,napi_ref & callback)462 bool GetNamedJsFunction(napi_env env, napi_value object, const std::string &name, napi_ref &callback)
463 {
464     napi_valuetype valueType = napi_undefined;
465     NAPI_CALL_BASE(env, napi_typeof(env, object, &valueType), false);
466     if (valueType != napi_object) {
467         ACCOUNT_LOGE("invalid object");
468         return false;
469     }
470     napi_value result = nullptr;
471     NAPI_CALL_BASE(env, napi_get_named_property(env, object, name.c_str(), &result), false);
472     return GetCallbackProperty(env, result, callback, 1);
473 }
474 
NapiCallVoidFunction(napi_env env,napi_value * argv,size_t argc,napi_ref funcRef)475 void NapiCallVoidFunction(napi_env env, napi_value *argv, size_t argc, napi_ref funcRef)
476 {
477     napi_value undefined = nullptr;
478     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
479     napi_value returnVal;
480     napi_value func = nullptr;
481     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, funcRef, &func));
482     napi_status status = napi_call_function(env, undefined, func, argc, argv, &returnVal);
483     ACCOUNT_LOGI("call js function finish, status: %{public}d", status);
484 }
485 
SetInt32ToJsProperty(napi_env env,int32_t number,const std::string & propertyName,napi_value & dataJs)486 void SetInt32ToJsProperty(napi_env env, int32_t number, const std::string &propertyName, napi_value &dataJs)
487 {
488     napi_value napiNum = nullptr;
489     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, number, &napiNum));
490     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, dataJs, propertyName.c_str(), napiNum));
491 }
492 
CreateAuthResult(napi_env env,const std::vector<uint8_t> & token,int32_t remainTimes,int32_t freezingTime)493 napi_value CreateAuthResult(
494     napi_env env, const std::vector<uint8_t> &token, int32_t remainTimes, int32_t freezingTime)
495 {
496     napi_value object = nullptr;
497     NAPI_CALL(env, napi_create_object(env, &object));
498     if (remainTimes >= 0) {
499         napi_value napiRemainTimes = 0;
500         NAPI_CALL(env, napi_create_uint32(env, remainTimes, &napiRemainTimes));
501         NAPI_CALL(env, napi_set_named_property(env, object, "remainTimes", napiRemainTimes));
502     }
503     if (freezingTime >= 0) {
504         napi_value napiFreezingTimes = 0;
505         NAPI_CALL(env, napi_create_uint32(env, freezingTime, &napiFreezingTimes));
506         NAPI_CALL(env, napi_set_named_property(env, object, "freezingTime", napiFreezingTimes));
507     }
508     if (token.size() > 0) {
509         napi_value napiToken = CreateUint8Array(env, token.data(), token.size());
510         NAPI_CALL(env, napi_set_named_property(env, object, "token", napiToken));
511     }
512     return object;
513 }
514 
ReleaseNapiRefAsync(napi_env env,napi_ref napiRef)515 void ReleaseNapiRefAsync(napi_env env, napi_ref napiRef)
516 {
517     ReleaseNapiRefArray(env, {napiRef});
518 }
519 
ReleaseNapiRefArray(napi_env env,const std::vector<napi_ref> & napiRefVec)520 void ReleaseNapiRefArray(napi_env env, const std::vector<napi_ref> &napiRefVec)
521 {
522     if (env == nullptr) {
523         ACCOUNT_LOGE("invalid env");
524         return;
525     }
526     std::shared_ptr<NapiRefArrayContext> context = std::make_shared<NapiRefArrayContext>();
527     context->env = env;
528     context->napiRefVec = napiRefVec;
529     NAPI_CALL_RETURN_VOID(env, napi_send_event(env,
530         [context = std::move(context)] () {
531             if (context == nullptr) {
532                 ACCOUNT_LOGE("context is nullptr");
533                 return;
534             }
535             for (auto &napiRef : context->napiRefVec) {
536                 if (napiRef != nullptr) {
537                     napi_delete_reference(context->env, napiRef);
538                 }
539             }
540         }, napi_eprio_vip));
541 }
542 
~NapiCallbackRef()543 NapiCallbackRef::~NapiCallbackRef()
544 {
545     if (callbackRef == nullptr) {
546         return;
547     }
548     ReleaseNapiRefArray(env, {callbackRef});
549     callbackRef = nullptr;
550 }
551 
JsObjectToNativeString(napi_env env,napi_value jsData,std::string & nativeData)552 bool JsObjectToNativeString(napi_env env, napi_value jsData, std::string &nativeData)
553 {
554     napi_valuetype valueType = napi_undefined;
555     napi_typeof(env, jsData, &valueType);
556     if (valueType != napi_object) {
557         ACCOUNT_LOGI("The parameters is not object");
558         return false;
559     }
560     napi_value globalValue = nullptr;
561     napi_get_global(env, &globalValue);
562     napi_value jsonValue;
563     napi_get_named_property(env, globalValue, "JSON", &jsonValue);
564 
565     napi_value stringifyValue = nullptr;
566     napi_get_named_property(env, jsonValue, "stringify", &stringifyValue);
567     napi_value funcArgv[1] = { jsData };
568     napi_value transValue = nullptr;
569     napi_status status = napi_call_function(env, jsonValue, stringifyValue, 1, funcArgv, &transValue);
570     if (status != napi_ok) {
571         ACCOUNT_LOGE("Fail to call function, %{public}d", status);
572         return false;
573     }
574 
575     if (!GetStringProperty(env, transValue, nativeData)) {
576         ACCOUNT_LOGE("Get native data failed");
577         std::string errMsg = "The type of arg 2 must be string";
578         AccountNapiThrow(env, ERR_JS_PARAMETER_ERROR, errMsg, false);
579         return false;
580     }
581     return true;
582 }
583 
NativeStringToJsObject(napi_env env,const std::string & nativeData)584 napi_value NativeStringToJsObject(napi_env env, const std::string &nativeData)
585 {
586     napi_value jsObjData = nullptr;
587     if (nativeData.empty()) {
588         napi_create_object(env, &jsObjData);
589         return jsObjData;
590     }
591     napi_value globalValue = nullptr;
592     napi_get_global(env, &globalValue);
593     napi_value jsonValue;
594     napi_get_named_property(env, globalValue, "JSON", &jsonValue);
595     napi_value parseValue = nullptr;
596     napi_get_named_property(env, jsonValue, "parse", &parseValue);
597     napi_value jsStringDate = nullptr;
598     NAPI_CALL(env, napi_create_string_utf8(env, nativeData.c_str(), NAPI_AUTO_LENGTH, &jsStringDate));
599     napi_value funcArgv[1] = { jsStringDate };
600     napi_status status = napi_call_function(env, jsonValue, parseValue, 1, funcArgv, &jsObjData);
601     if (status != napi_ok) {
602         ACCOUNT_LOGE("Fail to call function, status: %{public}d", status);
603     }
604     return jsObjData;
605 }
606 
GetSelfTargetVersion(uint32_t & targetVersion)607 bool GetSelfTargetVersion(uint32_t &targetVersion)
608 {
609     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
610     if (samgr == nullptr) {
611         ACCOUNT_LOGE("Samgr error");
612         return false;
613     }
614     auto bundleObj = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
615     if (bundleObj == nullptr) {
616         ACCOUNT_LOGE("BundleObj error");
617         return false;
618     }
619     auto bundleMgrProxy = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
620     if (bundleMgrProxy == nullptr) {
621         ACCOUNT_LOGE("BundleMgrProxy error");
622         return false;
623     }
624     AppExecFwk::BundleInfo bundleInfo;
625     ErrCode ret = bundleMgrProxy->GetBundleInfoForSelf(OHOS::AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo);
626     if (ret != ERR_OK) {
627         ACCOUNT_LOGE("GetBundleInfoForSelf error");
628         return false;
629     }
630     ACCOUNT_LOGI("Bundle targetVersion is %{public}d", bundleInfo.targetVersion);
631     targetVersion = bundleInfo.targetVersion;
632     return true;
633 }
634 } // namespace AccountJsKit
635 } // namespace OHOS