• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_utils.h"
17 
18 #include <atomic>
19 #include <cstring>
20 #include <initializer_list>
21 #include <memory>
22 #include <mutex>
23 #include <queue>
24 #include <unordered_set>
25 #include <unordered_map>
26 
27 #include "netmanager_base_log.h"
28 #include "securec.h"
29 
30 namespace OHOS {
31 namespace NetManagerStandard {
32 namespace NapiUtils {
33 namespace {
34 static constexpr const int MAX_STRING_LENGTH = 65536;
35 constexpr const char *CODE = "code";
36 constexpr const char *MSG = "message";
37 } // namespace
38 
39 static std::unordered_set<napi_env> unorderedSetEnv;
40 static std::recursive_mutex mutexForEnv;
41 
42 class WorkData {
43 public:
44     WorkData() = delete;
45 
WorkData(napi_env env,void * data,void (* handler)(napi_env env,napi_status status,void * data))46     WorkData(napi_env env, void *data, void (*handler)(napi_env env, napi_status status, void *data))
47         : env_(env), data_(data), handler_(handler)
48     {
49     }
50 
51     napi_env env_;
52     void *data_;
53     void (*handler_)(napi_env env, napi_status status, void *data);
54 };
55 
56 struct UvHandlerQueue : public std::queue<UvHandler> {
57     UvHandler Pop();
58     void Push(const UvHandler &handler);
59 
60 private:
61     std::mutex mutex;
62 };
63 
64 static std::mutex g_mutex;
65 static std::unordered_map<uint64_t, std::shared_ptr<UvHandlerQueue>> g_handlerQueueMap;
66 static const char *const HTTP_UV_SYNC_QUEUE_NAME = "NET_CONNECTION_UV_SYNC_QUEUE_NAME";
67 
Pop()68 UvHandler UvHandlerQueue::Pop()
69 {
70     std::lock_guard lock(mutex);
71     if (empty()) {
72         return {};
73     }
74     auto s = front();
75     pop();
76     return s;
77 }
78 
Push(const UvHandler & handler)79 void UvHandlerQueue::Push(const UvHandler &handler)
80 {
81     std::lock_guard lock(mutex);
82     push(handler);
83 }
84 
GetGlobal(napi_env env)85 napi_value GetGlobal(napi_env env)
86 {
87     napi_value undefined = GetUndefined(env);
88     napi_value global = nullptr;
89     NAPI_CALL_BASE(env, napi_get_global(env, &global), undefined);
90     return global;
91 }
92 
CreateUvHandlerQueue(napi_env env)93 uint64_t CreateUvHandlerQueue(napi_env env)
94 {
95     static std::atomic<uint64_t> id = 1; // start from 1
96     uint64_t newId = id++;
97     NETMANAGER_BASE_LOGI("newId = %{public}s, id = %{public}s", std::to_string(newId).c_str(),
98                          std::to_string(id).c_str());
99 
100     auto global = GetGlobal(env);
101     auto queueWrapper = CreateObject(env);
102     SetNamedProperty(env, global, HTTP_UV_SYNC_QUEUE_NAME, queueWrapper);
103     {
104         std::lock_guard lock(g_mutex);
105         g_handlerQueueMap.emplace(newId, std::make_shared<UvHandlerQueue>());
106     }
107     napi_wrap(
108         env, queueWrapper, reinterpret_cast<void *>(newId),
109         [](napi_env env, void *data, void *) {
110             auto id = reinterpret_cast<uint64_t>(data);
111             std::lock_guard lock(g_mutex);
112             g_handlerQueueMap.erase(id);
113         },
114         nullptr, nullptr);
115     auto envWrapper = new (std::nothrow) napi_env;
116     if (envWrapper == nullptr) {
117         return newId;
118     }
119     *envWrapper = env;
120     napi_add_env_cleanup_hook(
121         env,
122         [](void *data) {
123             auto envWrapper = reinterpret_cast<napi_env *>(data);
124             if (envWrapper == nullptr) {
125                 return;
126             }
127             auto env = *envWrapper;
128             delete envWrapper;
129             if (env == nullptr) {
130                 return;
131             }
132             auto queueWrapper = NapiUtils::GetValueFromGlobal(env, HTTP_UV_SYNC_QUEUE_NAME);
133             if (queueWrapper == nullptr) {
134                 return;
135             }
136             void *result = nullptr;
137             napi_remove_wrap(env, queueWrapper, &result);
138             auto id = reinterpret_cast<uint64_t>(result);
139             std::lock_guard lock(g_mutex);
140             g_handlerQueueMap.erase(id);
141         },
142         envWrapper);
143     return newId;
144 }
145 
GetValueFromGlobal(napi_env env,const std::string & className)146 napi_value GetValueFromGlobal(napi_env env, const std::string &className)
147 {
148     auto global = NapiUtils::GetGlobal(env);
149     if (NapiUtils::GetValueType(env, global) == napi_undefined) {
150         return GetUndefined(env);
151     }
152     return NapiUtils::GetNamedProperty(env, global, className);
153 }
154 
MakeUvCallback()155 static uv_after_work_cb MakeUvCallback()
156 {
157     return [](uv_work_t *work, int status) {
158         if (!work) {
159             return;
160         }
161         std::unique_ptr<uv_work_t> workHandle(work);
162 
163         if (!work->data) {
164             return;
165         }
166         auto env = reinterpret_cast<napi_env>(work->data);
167         if (!env) {
168             return;
169         }
170 
171         auto closeScope = [env](napi_handle_scope scope) { NapiUtils::CloseScope(env, scope); };
172         std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(NapiUtils::OpenScope(env), closeScope);
173         auto queueWrapper = GetValueFromGlobal(env, HTTP_UV_SYNC_QUEUE_NAME);
174         if (!queueWrapper) {
175             return;
176         }
177         void *theId = nullptr;
178         napi_unwrap(env, queueWrapper, &theId);
179         if (!theId) { // that is why moduleId is started from 1
180             return;
181         }
182         UvHandler handler;
183         {
184             std::lock_guard lock(g_mutex);
185             auto it = g_handlerQueueMap.find(reinterpret_cast<uint64_t>(theId));
186             if (it == g_handlerQueueMap.end()) {
187                 return;
188             }
189             handler = it->second->Pop();
190         }
191         if (handler) {
192             handler(env);
193         }
194     };
195 }
196 
CreateUvQueueWorkByModuleId(napi_env env,const UvHandler & handler,uint64_t id)197 void CreateUvQueueWorkByModuleId(napi_env env, const UvHandler &handler, uint64_t id)
198 {
199     uv_loop_s *loop = nullptr;
200     if (!IsEnvValid(env)) {
201         NETMANAGER_BASE_LOGE("the env is invalid");
202         return;
203     }
204     napi_get_uv_event_loop(env, &loop);
205     if (!loop) {
206         return;
207     }
208     uv_work_t *work = nullptr;
209     {
210         std::lock_guard lock(g_mutex);
211         auto it = g_handlerQueueMap.find(id);
212         if (it == g_handlerQueueMap.end()) {
213             return;
214         }
215         work = new (std::nothrow) uv_work_t;
216         if (work == nullptr) {
217             return;
218         }
219         work->data = env;
220         it->second->Push(handler);
221     }
222 
223     if (work) {
224         (void)uv_queue_work_with_qos(
225             loop, work, [](uv_work_t *) {}, MakeUvCallback(), uv_qos_default);
226     }
227 }
228 
GetValueType(napi_env env,napi_value value)229 napi_valuetype GetValueType(napi_env env, napi_value value)
230 {
231     if (value == nullptr) {
232         return napi_undefined;
233     }
234 
235     napi_valuetype valueType = napi_undefined;
236     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
237     return valueType;
238 }
239 
240 /* named property */
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)241 bool HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
242 {
243     bool hasProperty = false;
244     NAPI_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
245     return hasProperty;
246 }
247 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)248 napi_value GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
249 {
250     napi_value value = nullptr;
251     NAPI_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
252     return value;
253 }
254 
SetNamedProperty(napi_env env,napi_value object,const std::string & name,napi_value value)255 void SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value)
256 {
257     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, object, name.c_str(), value));
258 }
259 
GetPropertyNames(napi_env env,napi_value object)260 std::vector<std::string> GetPropertyNames(napi_env env, napi_value object)
261 {
262     std::vector<std::string> ret;
263     napi_value names = nullptr;
264     NAPI_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
265     uint32_t length = 0;
266     NAPI_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
267     for (uint32_t index = 0; index < length; ++index) {
268         napi_value name = nullptr;
269         if (napi_get_element(env, names, index, &name) != napi_ok) {
270             continue;
271         }
272         if (GetValueType(env, name) != napi_string) {
273             continue;
274         }
275         ret.emplace_back(GetStringFromValueUtf8(env, name));
276     }
277     return ret;
278 }
279 
280 /* UINT32 */
CreateUint32(napi_env env,uint32_t code)281 napi_value CreateUint32(napi_env env, uint32_t code)
282 {
283     napi_value value = nullptr;
284     if (napi_create_uint32(env, code, &value) != napi_ok) {
285         return nullptr;
286     }
287     return value;
288 }
289 
GetUint32FromValue(napi_env env,napi_value value)290 uint32_t GetUint32FromValue(napi_env env, napi_value value)
291 {
292     uint32_t ret = 0;
293     NAPI_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0);
294     return ret;
295 }
296 
GetUint32Property(napi_env env,napi_value object,const std::string & propertyName)297 uint32_t GetUint32Property(napi_env env, napi_value object, const std::string &propertyName)
298 {
299     if (!HasNamedProperty(env, object, propertyName)) {
300         return 0;
301     }
302     napi_value value = GetNamedProperty(env, object, propertyName);
303     return GetUint32FromValue(env, value);
304 }
305 
SetUint32Property(napi_env env,napi_value object,const std::string & name,uint32_t value)306 void SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value)
307 {
308     napi_value jsValue = CreateUint32(env, value);
309     if (GetValueType(env, jsValue) != napi_number) {
310         return;
311     }
312 
313     napi_set_named_property(env, object, name.c_str(), jsValue);
314 }
315 
316 /* INT32 */
CreateInt32(napi_env env,int32_t code)317 napi_value CreateInt32(napi_env env, int32_t code)
318 {
319     napi_value value = nullptr;
320     if (napi_create_int32(env, code, &value) != napi_ok) {
321         return nullptr;
322     }
323     return value;
324 }
325 
GetInt32FromValue(napi_env env,napi_value value)326 int32_t GetInt32FromValue(napi_env env, napi_value value)
327 {
328     int32_t ret = 0;
329     NAPI_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0);
330     return ret;
331 }
332 
GetInt32Property(napi_env env,napi_value object,const std::string & propertyName)333 int32_t GetInt32Property(napi_env env, napi_value object, const std::string &propertyName)
334 {
335     if (!HasNamedProperty(env, object, propertyName)) {
336         return 0;
337     }
338     napi_value value = GetNamedProperty(env, object, propertyName);
339     return GetInt32FromValue(env, value);
340 }
341 
SetInt32Property(napi_env env,napi_value object,const std::string & name,int32_t value)342 void SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value)
343 {
344     napi_value jsValue = CreateInt32(env, value);
345     if (GetValueType(env, jsValue) != napi_number) {
346         return;
347     }
348 
349     napi_set_named_property(env, object, name.c_str(), jsValue);
350 }
351 
352 /* INT64 */
CreateInt64(napi_env env,int64_t code)353 napi_value CreateInt64(napi_env env, int64_t code)
354 {
355     napi_value value = nullptr;
356     if (napi_create_int64(env, code, &value) != napi_ok) {
357         return nullptr;
358     }
359     return value;
360 }
361 
GetInt64Property(napi_env env,napi_value object,const std::string & propertyName)362 int64_t GetInt64Property(napi_env env, napi_value object, const std::string &propertyName)
363 {
364     if (!HasNamedProperty(env, object, propertyName)) {
365         return 0;
366     }
367     napi_value value = GetNamedProperty(env, object, propertyName);
368     return GetInt64FromValue(env, value);
369 }
GetInt64FromValue(napi_env env,napi_value value)370 int64_t GetInt64FromValue(napi_env env, napi_value value)
371 {
372     int64_t ret = 0;
373     NAPI_CALL_BASE(env, napi_get_value_int64(env, value, &ret), 0);
374     return ret;
375 }
SetInt64Property(napi_env env,napi_value object,const std::string & name,int64_t value)376 void SetInt64Property(napi_env env, napi_value object, const std::string &name, int64_t value)
377 {
378     napi_value jsValue = CreateInt64(env, value);
379     if (GetValueType(env, jsValue) != napi_number) {
380         return;
381     }
382 
383     napi_set_named_property(env, object, name.c_str(), jsValue);
384 }
385 
386 /* String UTF8 */
CreateStringUtf8(napi_env env,const std::string & str)387 napi_value CreateStringUtf8(napi_env env, const std::string &str)
388 {
389     napi_value value = nullptr;
390     if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) {
391         return nullptr;
392     }
393     return value;
394 }
395 
GetStringFromValueUtf8(napi_env env,napi_value value)396 std::string GetStringFromValueUtf8(napi_env env, napi_value value)
397 {
398     std::string result;
399     char str[MAX_STRING_LENGTH] = {0};
400     size_t length = 0;
401     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, str, MAX_STRING_LENGTH, &length), result);
402     if (length > MAX_STRING_LENGTH) {
403         result.append(str, MAX_STRING_LENGTH);
404         return result;
405     }
406     if (length > 0) {
407         return result.append(str, length);
408     }
409     return result;
410 }
411 
GetSecureDataFromValueUtf8(napi_env env,napi_value value)412 SecureData GetSecureDataFromValueUtf8(napi_env env, napi_value value)
413 {
414     SecureData result;
415     char str[MAX_STRING_LENGTH] = {0};
416     size_t length = 0;
417     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, str, MAX_STRING_LENGTH, &length), result);
418     if (length > 0) {
419         result.append(str, length);
420     }
421     return result;
422 }
423 
GetStringPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)424 std::string GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
425 {
426     if (!HasNamedProperty(env, object, propertyName)) {
427         return "";
428     }
429     napi_value value = GetNamedProperty(env, object, propertyName);
430     return GetStringFromValueUtf8(env, value);
431 }
432 
GetSecureDataPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)433 SecureData GetSecureDataPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
434 {
435     napi_value value = GetNamedProperty(env, object, propertyName);
436     return GetSecureDataFromValueUtf8(env, value);
437 }
438 
SetStringPropertyUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)439 void SetStringPropertyUtf8(napi_env env, napi_value object, const std::string &name, const std::string &value)
440 {
441     napi_value jsValue = CreateStringUtf8(env, value);
442     if (GetValueType(env, jsValue) != napi_string) {
443         return;
444     }
445     napi_set_named_property(env, object, name.c_str(), jsValue);
446 }
447 
448 /* array buffer */
ValueIsArrayBuffer(napi_env env,napi_value value)449 bool ValueIsArrayBuffer(napi_env env, napi_value value)
450 {
451     bool isArrayBuffer = false;
452     NAPI_CALL_BASE(env, napi_is_arraybuffer(env, value, &isArrayBuffer), false);
453     return isArrayBuffer;
454 }
455 
GetInfoFromArrayBufferValue(napi_env env,napi_value value,size_t * length)456 void *GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length)
457 {
458     if (length == nullptr) {
459         return nullptr;
460     }
461 
462     void *data = nullptr;
463     NAPI_CALL(env, napi_get_arraybuffer_info(env, value, &data, length));
464     return data;
465 }
466 
CreateArrayBuffer(napi_env env,size_t length,void ** data)467 napi_value CreateArrayBuffer(napi_env env, size_t length, void **data)
468 {
469     if (length == 0) {
470         return nullptr;
471     }
472     napi_value result = nullptr;
473     NAPI_CALL(env, napi_create_arraybuffer(env, length, data, &result));
474     return result;
475 }
476 
477 /* object */
CreateObject(napi_env env)478 napi_value CreateObject(napi_env env)
479 {
480     napi_value object = nullptr;
481     NAPI_CALL(env, napi_create_object(env, &object));
482     return object;
483 }
484 
485 /* undefined */
GetUndefined(napi_env env)486 napi_value GetUndefined(napi_env env)
487 {
488     napi_value undefined = nullptr;
489     NAPI_CALL(env, napi_get_undefined(env, &undefined));
490     return undefined;
491 }
492 
493 /* function */
CallFunction(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv)494 napi_value CallFunction(napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv)
495 {
496     napi_value res = nullptr;
497     NAPI_CALL(env, napi_call_function(env, recv, func, argc, argv, &res));
498     return res;
499 }
500 
CreateFunction(napi_env env,const std::string & name,napi_callback func,void * arg)501 napi_value CreateFunction(napi_env env, const std::string &name, napi_callback func, void *arg)
502 {
503     napi_value res = nullptr;
504     NAPI_CALL(env, napi_create_function(env, name.c_str(), strlen(name.c_str()), func, arg, &res));
505     return res;
506 }
507 
508 /* reference */
CreateReference(napi_env env,napi_value callback)509 napi_ref CreateReference(napi_env env, napi_value callback)
510 {
511     napi_ref callbackRef = nullptr;
512     NAPI_CALL(env, napi_create_reference(env, callback, 1, &callbackRef));
513     return callbackRef;
514 }
515 
GetReference(napi_env env,napi_ref callbackRef)516 napi_value GetReference(napi_env env, napi_ref callbackRef)
517 {
518     napi_value callback = nullptr;
519     NAPI_CALL(env, napi_get_reference_value(env, callbackRef, &callback));
520     return callback;
521 }
522 
DeleteReference(napi_env env,napi_ref callbackRef)523 void DeleteReference(napi_env env, napi_ref callbackRef)
524 {
525     (void)napi_delete_reference(env, callbackRef);
526 }
527 
528 /* boolean */
GetBooleanProperty(napi_env env,napi_value object,const std::string & propertyName)529 bool GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName)
530 {
531     if (!HasNamedProperty(env, object, propertyName)) {
532         return false;
533     }
534     napi_value value = GetNamedProperty(env, object, propertyName);
535     bool ret = false;
536     NAPI_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
537     return ret;
538 }
539 
SetBooleanProperty(napi_env env,napi_value object,const std::string & name,bool value)540 void SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value)
541 {
542     napi_value jsValue = nullptr;
543     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &jsValue));
544     if (GetValueType(env, jsValue) != napi_boolean) {
545         return;
546     }
547 
548     napi_set_named_property(env, object, name.c_str(), jsValue);
549 }
550 
GetBoolean(napi_env env,bool value)551 napi_value GetBoolean(napi_env env, bool value)
552 {
553     napi_value jsValue = nullptr;
554     NAPI_CALL(env, napi_get_boolean(env, value, &jsValue));
555     return jsValue;
556 }
557 
GetBooleanValue(napi_env env,napi_value value)558 bool GetBooleanValue(napi_env env, napi_value value)
559 {
560     bool ret = false;
561     NAPI_CALL_BASE(env, napi_get_value_bool(env, value, &ret), 0);
562     return ret;
563 }
564 
565 /* define properties */
DefineProperties(napi_env env,napi_value object,const std::initializer_list<napi_property_descriptor> & properties)566 void DefineProperties(napi_env env, napi_value object,
567                       const std::initializer_list<napi_property_descriptor> &properties)
568 {
569     napi_property_descriptor descriptors[properties.size()];
570     std::copy(properties.begin(), properties.end(), descriptors);
571 
572     (void)napi_define_properties(env, object, properties.size(), descriptors);
573 }
574 
575 /* array */
CreateArray(napi_env env,size_t length)576 napi_value CreateArray(napi_env env, size_t length)
577 {
578     if (length == 0) {
579         napi_value res = nullptr;
580         NAPI_CALL(env, napi_create_array(env, &res));
581         return res;
582     }
583     napi_value res = nullptr;
584     NAPI_CALL(env, napi_create_array_with_length(env, length, &res));
585     return res;
586 }
587 
SetArrayElement(napi_env env,napi_value array,uint32_t index,napi_value value)588 void SetArrayElement(napi_env env, napi_value array, uint32_t index, napi_value value)
589 {
590     (void)napi_set_element(env, array, index, value);
591 }
592 
IsArray(napi_env env,napi_value value)593 bool IsArray(napi_env env, napi_value value)
594 {
595     bool result = false;
596     NAPI_CALL_BASE(env, napi_is_array(env, value, &result), false);
597     return result;
598 }
599 
GetArrayLength(napi_env env,napi_value arr)600 uint32_t GetArrayLength(napi_env env, napi_value arr)
601 {
602     uint32_t arrayLength = 0;
603     NAPI_CALL_BASE(env, napi_get_array_length(env, arr, &arrayLength), 0);
604     return arrayLength;
605 }
606 
GetArrayElement(napi_env env,napi_value arr,uint32_t index)607 napi_value GetArrayElement(napi_env env, napi_value arr, uint32_t index)
608 {
609     napi_value elementValue = nullptr;
610     NAPI_CALL(env, napi_get_element(env, arr, index, &elementValue));
611     return elementValue;
612 }
613 
614 /* libuv */
CreateUvQueueWork(napi_env env,void * data,void (handler)(uv_work_t *,int status))615 void CreateUvQueueWork(napi_env env, void *data, void(handler)(uv_work_t *, int status))
616 {
617     uv_loop_s *loop = nullptr;
618     if (!IsEnvValid(env)) {
619         NETMANAGER_BASE_LOGE("the env is invalid");
620         return;
621     }
622     napi_get_uv_event_loop(env, &loop);
623     if (!loop) {
624         NETMANAGER_BASE_LOGE("napi get uv event loop is null");
625         return;
626     }
627     auto work = new uv_work_t;
628     work->data = data;
629 
630     (void)uv_queue_work_with_qos(
631         loop, work, [](uv_work_t *) {}, handler, uv_qos_default);
632 }
633 
634 /* scope */
OpenScope(napi_env env)635 napi_handle_scope OpenScope(napi_env env)
636 {
637     napi_handle_scope scope = nullptr;
638     NAPI_CALL(env, napi_open_handle_scope(env, &scope));
639     return scope;
640 }
641 
CloseScope(napi_env env,napi_handle_scope scope)642 void CloseScope(napi_env env, napi_handle_scope scope)
643 {
644     (void)napi_close_handle_scope(env, scope);
645 }
646 
CreateEnumConstructor(napi_env env,napi_callback_info info)647 napi_value CreateEnumConstructor(napi_env env, napi_callback_info info)
648 {
649     napi_value thisArg = nullptr;
650     void *data = nullptr;
651     napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, &data);
652     napi_value global = nullptr;
653     napi_get_global(env, &global);
654     return thisArg;
655 }
656 
657 /* error */
CreateErrorMessage(napi_env env,int32_t errorCode,const std::string & errorMessage)658 napi_value CreateErrorMessage(napi_env env, int32_t errorCode, const std::string &errorMessage)
659 {
660     napi_value result = CreateObject(env);
661     SetNamedProperty(env, result, CODE, CreateInt32(env, errorCode));
662     SetNamedProperty(env, result, MSG, CreateStringUtf8(env, errorMessage));
663     return result;
664 }
665 
HookForEnvCleanup(void * data)666 void HookForEnvCleanup(void *data)
667 {
668     std::lock_guard<std::recursive_mutex> lock(mutexForEnv);
669     auto envWrapper = reinterpret_cast<napi_env *>(data);
670     if (envWrapper == nullptr) {
671         return;
672     }
673     auto env = *envWrapper;
674     delete envWrapper;
675     if (env == nullptr) {
676         return;
677     }
678     auto pos = unorderedSetEnv.find(env);
679     if (pos == unorderedSetEnv.end()) {
680         NETMANAGER_BASE_LOGE("The env is not in the unordered set");
681         return;
682     }
683     NETMANAGER_BASE_LOGD("env clean up, erase from the unordered set");
684     unorderedSetEnv.erase(pos);
685 }
686 
SetEnvValid(napi_env env)687 void SetEnvValid(napi_env env)
688 {
689     std::lock_guard<std::recursive_mutex> lock(mutexForEnv);
690     unorderedSetEnv.emplace(env);
691 }
692 
IsEnvValid(napi_env env)693 bool IsEnvValid(napi_env env)
694 {
695     std::lock_guard<std::recursive_mutex> lock(mutexForEnv);
696     auto pos = unorderedSetEnv.find(env);
697     if (pos == unorderedSetEnv.end()) {
698         return false;
699     }
700     return true;
701 }
702 } // namespace NapiUtils
703 } // namespace NetManagerStandard
704 } // namespace OHOS
705