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 
16 #include "napi_edm_common.h"
17 
18 #include "edm_constants.h"
19 #include "edm_errors.h"
20 #include "edm_log.h"
21 #include "js_native_api.h"
22 #include "js_native_api_types.h"
23 #include "napi/native_api.h"
24 #include "napi/native_common.h"
25 #include "napi/native_node_api.h"
26 #include "napi_edm_error.h"
27 #include "securec.h"
28 
29 namespace OHOS {
30 namespace EDM {
NativeCallbackComplete(napi_env env,napi_status status,AsyncCallbackInfo * asyncCallbackInfo,napi_value result)31 static void NativeCallbackComplete(napi_env env, napi_status status, AsyncCallbackInfo *asyncCallbackInfo,
32     napi_value result)
33 {
34     EDMLOGD("NativeCallbackComplete asyncCallbackInfo->ret is %{public}d", asyncCallbackInfo->ret);
35     if (asyncCallbackInfo->deferred != nullptr) {
36         EDMLOGD("NativeCallbackComplete asyncCallbackInfo->deferred != nullptr");
37         if (asyncCallbackInfo->ret == ERR_OK) {
38             napi_resolve_deferred(env, asyncCallbackInfo->deferred, result);
39         } else {
40             if (asyncCallbackInfo->innerCodeMsg.empty()) {
41                 napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateError(env, asyncCallbackInfo->ret));
42             } else {
43                 napi_reject_deferred(env, asyncCallbackInfo->deferred,
44                     CreateErrorWithInnerCode(env, asyncCallbackInfo->ret, asyncCallbackInfo->innerCodeMsg));
45             }
46         }
47     } else {
48         napi_value callbackValue[ARGS_SIZE_TWO] = {0};
49         if (asyncCallbackInfo->ret == ERR_OK) {
50             napi_get_null(env, &callbackValue[ARR_INDEX_ZERO]);
51             callbackValue[ARR_INDEX_ONE] = result;
52         } else {
53             if (asyncCallbackInfo->innerCodeMsg.empty()) {
54                 callbackValue[ARR_INDEX_ZERO] = CreateError(env, asyncCallbackInfo->ret);
55             } else {
56                 callbackValue[ARR_INDEX_ZERO] =
57                     CreateErrorWithInnerCode(env, asyncCallbackInfo->ret, asyncCallbackInfo->innerCodeMsg);
58             }
59             napi_get_null(env, &callbackValue[ARR_INDEX_ONE]);
60         }
61         napi_value callback = nullptr;
62         napi_value ret = nullptr;
63         napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
64         napi_call_function(env, nullptr, callback, std::size(callbackValue), callbackValue, &ret);
65         napi_delete_reference(env, asyncCallbackInfo->callback);
66     }
67     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
68 }
69 
MatchValueType(napi_env env,napi_value value,napi_valuetype targetType)70 bool MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
71 {
72     napi_valuetype valueType = napi_undefined;
73     napi_typeof(env, value, &valueType);
74     return valueType == targetType;
75 }
76 
ParseElementName(napi_env env,AppExecFwk::ElementName & elementName,napi_value args)77 bool ParseElementName(napi_env env, AppExecFwk::ElementName &elementName, napi_value args)
78 {
79     napi_valuetype valueType;
80     NAPI_CALL_BASE(env, napi_typeof(env, args, &valueType), false);
81     if (valueType != napi_object) {
82         EDMLOGE("Parameter element valueType error");
83         return false;
84     }
85     std::string bundleName;
86     std::string abilityName;
87     if (!JsObjectToString(env, args, "bundleName", true, bundleName) ||
88         !JsObjectToString(env, args, "abilityName", true, abilityName)) {
89         EDMLOGE("Parameter element bundleName error");
90         return false;
91     }
92     EDMLOGD("ParseElementName bundleName %{public}s ", bundleName.c_str());
93     EDMLOGD("ParseElementName abilityname %{public}s", abilityName.c_str());
94 
95     elementName.SetBundleName(bundleName);
96     elementName.SetAbilityName(abilityName);
97     return true;
98 }
99 
ParseLong(napi_env env,int64_t & param,napi_value args)100 bool ParseLong(napi_env env, int64_t &param, napi_value args)
101 {
102     napi_valuetype valueType = napi_undefined;
103     if (napi_typeof(env, args, &valueType) != napi_ok || valueType != napi_number ||
104         napi_get_value_int64(env, args, &param) != napi_ok) {
105         EDMLOGE("Wrong argument type. int64 expected.");
106         return false;
107     }
108     return true;
109 }
110 
ParseInt(napi_env env,int32_t & param,napi_value args)111 bool ParseInt(napi_env env, int32_t &param, napi_value args)
112 {
113     napi_valuetype valueType = napi_undefined;
114     if (napi_typeof(env, args, &valueType) != napi_ok || valueType != napi_number ||
115         napi_get_value_int32(env, args, &param) != napi_ok) {
116         EDMLOGE("Wrong argument type. int32 expected.");
117         return false;
118     }
119     return true;
120 }
121 
ParseCallback(napi_env env,napi_ref & param,napi_value args)122 bool ParseCallback(napi_env env, napi_ref &param, napi_value args)
123 {
124     napi_valuetype valueType = napi_undefined;
125     if (napi_typeof(env, args, &valueType) != napi_ok || valueType != napi_function ||
126         napi_create_reference(env, args, NAPI_RETURN_ONE, &param) != napi_ok) {
127         EDMLOGE("Wrong argument type. napi_function expected.");
128         return false;
129     }
130     return true;
131 }
132 
ParseUint(napi_env env,uint32_t & param,napi_value args)133 bool ParseUint(napi_env env, uint32_t &param, napi_value args)
134 {
135     napi_valuetype valueType = napi_undefined;
136     if (napi_typeof(env, args, &valueType) != napi_ok || valueType != napi_number ||
137         napi_get_value_uint32(env, args, &param) != napi_ok) {
138         EDMLOGE("Wrong argument type. uint32 expected.");
139         return false;
140     }
141     return true;
142 }
143 
ParseBool(napi_env env,bool & param,napi_value args)144 bool ParseBool(napi_env env, bool &param, napi_value args)
145 {
146     napi_valuetype valueType = napi_undefined;
147     if (napi_typeof(env, args, &valueType) != napi_ok || valueType != napi_boolean ||
148         napi_get_value_bool(env, args, &param) != napi_ok) {
149         EDMLOGE("Wrong argument type. bool expected.");
150         return false;
151     }
152     return true;
153 }
154 
ParseString(napi_env env,std::string & param,napi_value args)155 bool ParseString(napi_env env, std::string &param, napi_value args)
156 {
157     napi_valuetype valuetype;
158     if (napi_typeof(env, args, &valuetype) != napi_ok || valuetype != napi_string ||
159         !GetStringFromNAPI(env, args, param)) {
160         EDMLOGE("can not get string value");
161         return false;
162     }
163     EDMLOGD("ParseString param = %{public}s.", param.c_str());
164     return true;
165 }
166 
GetStringFromNAPI(napi_env env,napi_value value,std::string & resultStr)167 bool GetStringFromNAPI(napi_env env, napi_value value, std::string &resultStr)
168 {
169     std::string result;
170     size_t size = 0;
171 
172     if (napi_get_value_string_utf8(env, value, nullptr, NAPI_RETURN_ZERO, &size) != napi_ok) {
173         EDMLOGE("can not get string size");
174         return false;
175     }
176     result.reserve(size + NAPI_RETURN_ONE);
177     result.resize(size);
178     if (napi_get_value_string_utf8(env, value, result.data(), (size + NAPI_RETURN_ONE), &size) != napi_ok) {
179         EDMLOGE("can not get string value");
180         return false;
181     }
182     resultStr = result;
183     return true;
184 }
185 
ParseCharArray(napi_env env,napi_value args,size_t maxLength,std::vector<char> & ret)186 bool ParseCharArray(napi_env env, napi_value args, size_t maxLength, std::vector<char> &ret)
187 {
188     napi_valuetype valuetype;
189     if (napi_typeof(env, args, &valuetype) != napi_ok || valuetype != napi_string) {
190         EDMLOGE("can not get string value");
191         return false;
192     }
193     size_t size = 0;
194     if (napi_get_value_string_utf8(env, args, nullptr, NAPI_RETURN_ZERO, &size) != napi_ok) {
195         EDMLOGE("can not get string size");
196         return false;
197     }
198     if (size >= maxLength) {
199         EDMLOGE("string size too long");
200         return false;
201     }
202     std::vector<char> buf(size + NAPI_RETURN_ONE);
203     if (napi_get_value_string_utf8(env, args, buf.data(), (size + NAPI_RETURN_ONE), &size) != napi_ok) {
204         EDMLOGE("can not get string value");
205         return false;
206     }
207     ret = buf;
208     memset_s(buf.data(), buf.size(), '\0', buf.size());
209     return true;
210 }
211 
ParseStringArray(napi_env env,std::vector<std::string> & stringArray,napi_value args)212 napi_value ParseStringArray(napi_env env, std::vector<std::string> &stringArray, napi_value args)
213 {
214     EDMLOGD("begin to parse string array");
215     bool isArray = false;
216     NAPI_CALL(env, napi_is_array(env, args, &isArray));
217     if (!isArray) {
218         EDMLOGE("napi object is not array.");
219         return nullptr;
220     }
221     uint32_t arrayLength = 0;
222     NAPI_CALL(env, napi_get_array_length(env, args, &arrayLength));
223     EDMLOGD("length=%{public}ud", arrayLength);
224     for (uint32_t j = 0; j < arrayLength; j++) {
225         napi_value value = nullptr;
226         NAPI_CALL(env, napi_get_element(env, args, j, &value));
227         napi_valuetype valueType = napi_undefined;
228         NAPI_CALL(env, napi_typeof(env, value, &valueType));
229         if (valueType != napi_string) {
230             stringArray.clear();
231             return nullptr;
232         }
233         std::string str;
234         GetStringFromNAPI(env, value, str);
235         stringArray.push_back(str);
236     }
237     // create result code
238     napi_value result;
239     napi_status status = napi_create_int32(env, NAPI_RETURN_ONE, &result);
240     if (status != napi_ok) {
241         return nullptr;
242     }
243     return result;
244 }
245 
ParseElementArray(napi_env env,std::vector<AppExecFwk::ElementName> & elementArray,napi_value args)246 napi_value ParseElementArray(napi_env env, std::vector<AppExecFwk::ElementName> &elementArray, napi_value args)
247 {
248     EDMLOGD("begin to parse element array");
249     bool isArray = false;
250     NAPI_CALL(env, napi_is_array(env, args, &isArray));
251     if (!isArray) {
252         EDMLOGE("napi object is not array.");
253         return nullptr;
254     }
255     uint32_t arrayLength = 0;
256     NAPI_CALL(env, napi_get_array_length(env, args, &arrayLength));
257     EDMLOGD("length=%{public}ud", arrayLength);
258     for (uint32_t j = 0; j < arrayLength; j++) {
259         napi_value value = nullptr;
260         NAPI_CALL(env, napi_get_element(env, args, j, &value));
261         napi_valuetype valueType = napi_undefined;
262         NAPI_CALL(env, napi_typeof(env, value, &valueType));
263         if (valueType != napi_object) {
264             elementArray.clear();
265             return nullptr;
266         }
267         AppExecFwk::ElementName element;
268         ParseElementName(env, element, value);
269         elementArray.push_back(element);
270     }
271     // create result code
272     napi_value result;
273     napi_status status = napi_create_int32(env, NAPI_RETURN_ONE, &result);
274     if (status != napi_ok) {
275         return nullptr;
276     }
277     return result;
278 }
279 
JsObjectToInt(napi_env env,napi_value object,const char * filedStr,bool isNecessaryProp,int32_t & result)280 bool JsObjectToInt(napi_env env, napi_value object, const char *filedStr, bool isNecessaryProp, int32_t &result)
281 {
282     bool hasProperty = false;
283     if (napi_has_named_property(env, object, filedStr, &hasProperty) != napi_ok) {
284         EDMLOGE("get js property failed.");
285         return false;
286     }
287     if (isNecessaryProp && !hasProperty) {
288         return false;
289     }
290     if (hasProperty) {
291         napi_value prop = nullptr;
292         return napi_get_named_property(env, object, filedStr, &prop) == napi_ok && ParseInt(env, result, prop);
293     }
294     return true;
295 }
296 
JsObjectToUint(napi_env env,napi_value object,const char * filedStr,bool isNecessaryProp,uint32_t & result)297 bool JsObjectToUint(napi_env env, napi_value object, const char *filedStr, bool isNecessaryProp, uint32_t &result)
298 {
299     bool hasProperty = false;
300     if (napi_has_named_property(env, object, filedStr, &hasProperty) != napi_ok) {
301         EDMLOGE("get js property failed.");
302         return false;
303     }
304     if (isNecessaryProp && !hasProperty) {
305         return false;
306     }
307     if (hasProperty) {
308         napi_value prop = nullptr;
309         return napi_get_named_property(env, object, filedStr, &prop) == napi_ok && ParseUint(env, result, prop);
310     }
311     return true;
312 }
313 
JsObjectToLong(napi_env env,napi_value object,const char * filedStr,bool isNecessaryProp,int64_t & result)314 bool JsObjectToLong(napi_env env, napi_value object, const char *filedStr, bool isNecessaryProp, int64_t &result)
315 {
316     bool hasProperty = false;
317     if (napi_has_named_property(env, object, filedStr, &hasProperty) != napi_ok) {
318         EDMLOGE("get js property failed.");
319         return false;
320     }
321     if (isNecessaryProp && !hasProperty) {
322         return false;
323     }
324     if (hasProperty) {
325         napi_value prop = nullptr;
326         return napi_get_named_property(env, object, filedStr, &prop) == napi_ok && ParseLong(env, result, prop);
327     }
328     return true;
329 }
330 
JsObjectToBool(napi_env env,napi_value object,const char * filedStr,bool isNecessaryProp,bool & result)331 bool JsObjectToBool(napi_env env, napi_value object, const char *filedStr, bool isNecessaryProp, bool &result)
332 {
333     bool hasProperty = false;
334     if (napi_has_named_property(env, object, filedStr, &hasProperty) != napi_ok) {
335         EDMLOGE("get js property failed.");
336         return false;
337     }
338     if (isNecessaryProp && !hasProperty) {
339         return false;
340     }
341     if (hasProperty) {
342         napi_value prop = nullptr;
343         return napi_get_named_property(env, object, filedStr, &prop) == napi_ok && ParseBool(env, result, prop);
344     }
345     return true;
346 }
347 
JsObjectToString(napi_env env,napi_value object,const char * filedStr,bool isNecessaryProp,std::string & resultStr)348 bool JsObjectToString(napi_env env, napi_value object, const char *filedStr, bool isNecessaryProp,
349     std::string &resultStr)
350 {
351     bool hasProperty = false;
352     if (napi_has_named_property(env, object, filedStr, &hasProperty) != napi_ok) {
353         EDMLOGE("get js property failed.");
354         return false;
355     }
356     if (isNecessaryProp && !hasProperty) {
357         return false;
358     }
359     if (hasProperty) {
360         napi_value prop = nullptr;
361         return napi_get_named_property(env, object, filedStr, &prop) == napi_ok && ParseString(env, resultStr, prop);
362     }
363     return true;
364 }
365 
JsObjectToCharArray(napi_env env,napi_value object,const char * filedStr,std::tuple<int,bool> charArrayProp,std::vector<char> & ret)366 bool JsObjectToCharArray(napi_env env, napi_value object, const char *filedStr, std::tuple<int, bool> charArrayProp,
367     std::vector<char> &ret)
368 {
369     bool hasProperty = false;
370     if (napi_has_named_property(env, object, filedStr, &hasProperty) != napi_ok) {
371         EDMLOGE("get js property failed.");
372         return false;
373     }
374     int maxLength = 0;
375     bool isNecessaryProp = false;
376     std::tie(maxLength, isNecessaryProp) = charArrayProp;
377     if (isNecessaryProp && !hasProperty) {
378         return false;
379     }
380     if (hasProperty) {
381         napi_value prop = nullptr;
382         return napi_get_named_property(env, object, filedStr, &prop) == napi_ok &&
383             ParseCharArray(env, prop, maxLength, ret);
384     }
385     return true;
386 }
387 
GetJsProperty(napi_env env,napi_value object,const char * filedStr,napi_value & result)388 bool GetJsProperty(napi_env env, napi_value object, const char *filedStr, napi_value &result)
389 {
390     bool hasProperty = false;
391     if (napi_has_named_property(env, object, filedStr, &hasProperty) != napi_ok || !hasProperty ||
392         napi_get_named_property(env, object, filedStr, &result) != napi_ok) {
393         EDMLOGE("Js has no property");
394         return false;
395     }
396     return true;
397 }
398 
JsObjectToU8Vector(napi_env env,napi_value object,const char * fieldStr,std::vector<uint8_t> & certVector)399 bool JsObjectToU8Vector(napi_env env, napi_value object, const char *fieldStr, std::vector<uint8_t> &certVector)
400 {
401     napi_value certEntry;
402     if (!GetJsProperty(env, object, fieldStr, certEntry)) {
403         return false;
404     }
405     bool isTypedArray = false;
406     if (napi_is_typedarray(env, certEntry, &isTypedArray) != napi_ok || !isTypedArray) {
407         EDMLOGE("js property is not typedarray");
408         return false;
409     }
410     size_t length = 0;
411     size_t offset = 0;
412     napi_typedarray_type type;
413     napi_value buffer = nullptr;
414     void *data = nullptr;
415     if (napi_get_typedarray_info(env, certEntry, &type, &length, &data, &buffer, &offset) != napi_ok ||
416         type != napi_uint8_array || buffer == nullptr) {
417         EDMLOGE("js object type is not uint8 array");
418         return false;
419     }
420     if (length > NAPI_MAX_DATA_LEN) {
421         EDMLOGE("uint8 array range failed");
422         return false;
423     }
424     if (data == nullptr) {
425         EDMLOGE("uint8 array data failed");
426         return false;
427     }
428     certVector.clear();
429     certVector.assign(static_cast<uint8_t *>(data), (static_cast<uint8_t *>(data) + length));
430     return true;
431 }
432 
JsObjectToStringVector(napi_env env,napi_value object,const char * filedStr,bool isNecessaryProp,std::vector<std::string> & vec)433 bool JsObjectToStringVector(napi_env env, napi_value object, const char *filedStr, bool isNecessaryProp,
434     std::vector<std::string> &vec)
435 {
436     bool hasProperty = false;
437     if (napi_has_named_property(env, object, filedStr, &hasProperty) != napi_ok) {
438         EDMLOGE("get js property failed.");
439         return false;
440     }
441     if (isNecessaryProp && !hasProperty) {
442         EDMLOGE("no yaobaohua hasProperty.");
443         return false;
444     }
445     if (hasProperty) {
446         napi_value prop = nullptr;
447         return napi_get_named_property(env, object, filedStr, &prop) == napi_ok && ParseStringArray(env, vec, prop);
448     }
449     return true;
450 }
451 
NativeVoidCallbackComplete(napi_env env,napi_status status,void * data)452 void NativeVoidCallbackComplete(napi_env env, napi_status status, void *data)
453 {
454     if (data == nullptr) {
455         EDMLOGE("data is nullptr");
456         return;
457     }
458     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
459     napi_value error = nullptr;
460     if (asyncCallbackInfo->callback == nullptr) {
461         EDMLOGD("asyncCallbackInfo->deferred != nullptr");
462         if (asyncCallbackInfo->ret == ERR_OK) {
463             napi_get_null(env, &error);
464             napi_resolve_deferred(env, asyncCallbackInfo->deferred, error);
465         } else {
466             if (asyncCallbackInfo->innerCodeMsg.empty()) {
467                 napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateError(env, asyncCallbackInfo->ret));
468             } else {
469                 napi_reject_deferred(env, asyncCallbackInfo->deferred,
470                     CreateErrorWithInnerCode(env, asyncCallbackInfo->ret, asyncCallbackInfo->innerCodeMsg));
471             }
472         }
473     } else {
474         EDMLOGD("asyncCallbackInfo->callback != nullptr");
475         if (asyncCallbackInfo->ret == ERR_OK) {
476             napi_get_null(env, &error);
477         } else {
478             if (asyncCallbackInfo->innerCodeMsg.empty()) {
479                 error = CreateError(env, asyncCallbackInfo->ret);
480             } else {
481                 error = CreateErrorWithInnerCode(env, asyncCallbackInfo->ret, asyncCallbackInfo->innerCodeMsg);
482             }
483         }
484         napi_value callback = nullptr;
485         napi_value result = nullptr;
486         napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
487         napi_call_function(env, nullptr, callback, ARGS_SIZE_ONE, &error, &result);
488         napi_delete_reference(env, asyncCallbackInfo->callback);
489     }
490     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
491     delete asyncCallbackInfo;
492 }
493 
HandleAsyncWork(napi_env env,AsyncCallbackInfo * context,const std::string & workName,napi_async_execute_callback execute,napi_async_complete_callback complete)494 napi_value HandleAsyncWork(napi_env env, AsyncCallbackInfo *context, const std::string &workName,
495     napi_async_execute_callback execute, napi_async_complete_callback complete)
496 {
497     napi_value result = nullptr;
498     if (context->callback == nullptr) {
499         napi_create_promise(env, &context->deferred, &result);
500     } else {
501         napi_get_undefined(env, &result);
502     }
503     napi_value resource = nullptr;
504     napi_get_undefined(env, &resource);
505     napi_value resourceName = nullptr;
506     napi_create_string_utf8(env, workName.data(), NAPI_AUTO_LENGTH, &resourceName);
507     napi_create_async_work(env, resource, resourceName, execute, complete, static_cast<void *>(context),
508         &context->asyncWork);
509     napi_queue_async_work(env, context->asyncWork);
510     return result;
511 }
512 
NativeBoolCallbackComplete(napi_env env,napi_status status,void * data)513 void NativeBoolCallbackComplete(napi_env env, napi_status status, void *data)
514 {
515     if (data == nullptr) {
516         EDMLOGE("data is nullptr");
517         return;
518     }
519     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
520     napi_value result = nullptr;
521     napi_get_boolean(env, asyncCallbackInfo->boolRet, &result);
522     NativeCallbackComplete(env, status, asyncCallbackInfo, result);
523     delete asyncCallbackInfo;
524 }
525 
NativeNumberCallbackComplete(napi_env env,napi_status status,void * data)526 void NativeNumberCallbackComplete(napi_env env, napi_status status, void *data)
527 {
528     if (data == nullptr) {
529         EDMLOGE("data is nullptr");
530         return;
531     }
532     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
533     napi_value result = nullptr;
534     napi_create_int32(env, asyncCallbackInfo->intRet, &result);
535     NativeCallbackComplete(env, status, asyncCallbackInfo, result);
536     delete asyncCallbackInfo;
537 }
538 
NativeStringCallbackComplete(napi_env env,napi_status status,void * data)539 void NativeStringCallbackComplete(napi_env env, napi_status status, void *data)
540 {
541     if (data == nullptr) {
542         EDMLOGE("data is nullptr");
543         return;
544     }
545     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
546     napi_value result = nullptr;
547     napi_create_string_utf8(env, asyncCallbackInfo->stringRet.c_str(), NAPI_AUTO_LENGTH, &result);
548     NativeCallbackComplete(env, status, asyncCallbackInfo, result);
549     delete asyncCallbackInfo;
550 }
551 
NativeArrayStringCallbackComplete(napi_env env,napi_status status,void * data)552 void NativeArrayStringCallbackComplete(napi_env env, napi_status status, void *data)
553 {
554     if (data == nullptr) {
555         EDMLOGE("data is nullptr");
556         return;
557     }
558     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
559     napi_value result = nullptr;
560     napi_create_array(env, &result);
561     ConvertStringVectorToJS(env, asyncCallbackInfo->arrayStringRet, result);
562     NativeCallbackComplete(env, status, asyncCallbackInfo, result);
563     delete asyncCallbackInfo;
564 }
565 
ConvertStringVectorToJS(napi_env env,const std::vector<std::string> & stringVector,napi_value result)566 void ConvertStringVectorToJS(napi_env env, const std::vector<std::string> &stringVector, napi_value result)
567 {
568     EDMLOGD("vector size: %{public}zu", stringVector.size());
569     size_t idx = 0;
570     for (const auto &str : stringVector) {
571         napi_value obj = nullptr;
572         napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &obj);
573         napi_set_element(env, result, idx, obj);
574         idx++;
575     }
576 }
577 
CheckAdminWithUserIdParamType(napi_env env,size_t argc,napi_value * argv,bool & hasCallback,bool & hasUserId)578 bool CheckAdminWithUserIdParamType(napi_env env, size_t argc, napi_value *argv, bool &hasCallback, bool &hasUserId)
579 {
580     if (!MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object)) {
581         EDMLOGE("CheckAdminWithUserIdParamType admin type check failed");
582         return false;
583     }
584     EDMLOGI("argc = %{public}zu", argc);
585     if (argc == ARGS_SIZE_ONE) {
586         hasCallback = false;
587         hasUserId = false;
588         EDMLOGI("hasCallback = false; hasUserId = false;");
589         return true;
590     }
591 
592     if (argc == ARGS_SIZE_TWO) {
593         if (MatchValueType(env, argv[ARR_INDEX_ONE], napi_function)) {
594             hasCallback = true;
595             hasUserId = false;
596             EDMLOGI("hasCallback = true; hasUserId = false;");
597             return true;
598         } else {
599             hasCallback = false;
600             hasUserId = true;
601             EDMLOGI("hasCallback = false;  hasUserId = true;");
602             return MatchValueType(env, argv[ARR_INDEX_ONE], napi_number);
603         }
604     }
605     hasCallback = true;
606     hasUserId = true;
607     EDMLOGI("hasCallback = true; hasUserId = true;");
608     return MatchValueType(env, argv[ARR_INDEX_ONE], napi_number) &&
609         MatchValueType(env, argv[ARR_INDEX_TWO], napi_function);
610 }
611 
CheckGetPolicyAdminParam(napi_env env,napi_value value,bool & hasAdmin,OHOS::AppExecFwk::ElementName & elementName)612 bool CheckGetPolicyAdminParam(napi_env env, napi_value value, bool &hasAdmin,
613     OHOS::AppExecFwk::ElementName &elementName)
614 {
615     if (MatchValueType(env, value, napi_null)) {
616         hasAdmin = false;
617         return true;
618     }
619     if (MatchValueType(env, value, napi_object)) {
620         hasAdmin = true;
621         if (ParseElementName(env, elementName, value)) {
622             return true;
623         }
624     }
625     return false;
626 }
627 
ParseStringToInt(const std::string & strValue,int32_t & result)628 bool ParseStringToInt(const std::string &strValue, int32_t &result)
629 {
630     int64_t temp = 0;
631     if (!ParseStringToLong(strValue, temp)) {
632         EDMLOGE("ParseStringToInt: parse str failed");
633         return false;
634     }
635     if (temp < INT_MIN || temp > INT_MAX) {
636         EDMLOGE("ParseStringToInt: parse failed, int32 expected.");
637         return false;
638     }
639     result = temp;
640     return true;
641 }
642 
ParseStringToLong(const std::string & strValue,int64_t & result)643 bool ParseStringToLong(const std::string &strValue, int64_t &result)
644 {
645     char *end = nullptr;
646     const char *p = strValue.c_str();
647     errno = 0;
648     result = strtoll(p, &end, EdmConstants::DECIMAL);
649     if (errno == ERANGE || end == p || *end != '\0') {
650         EDMLOGE("ParseStringToLong: parse str failed: %{public}s", p);
651         return false;
652     }
653     return true;
654 }
655 } // namespace EDM
656 } // namespace OHOS