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