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