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