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