• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 "wifi_napi_utils.h"
17 #include "securec.h"
18 #include "wifi_logger.h"
19 #include "context.h"
20 
21 namespace OHOS {
22 namespace Wifi {
23 DEFINE_WIFILOG_LABEL("WifiNAPIUtils");
24 
TraceFuncCall(std::string funcName)25 TraceFuncCall::TraceFuncCall(std::string funcName): m_funcName(funcName)
26 {
27     if (m_isTrace) {
28         m_startTime = std::chrono::steady_clock::now();
29         WIFI_LOGD("Call wifi func: %{public}s (start)", m_funcName.c_str());
30     }
31 }
32 
~TraceFuncCall()33 TraceFuncCall::~TraceFuncCall()
34 {
35     if (m_isTrace) {
36         auto us = std::chrono::duration_cast<std::chrono::microseconds>
37             (std::chrono::steady_clock::now() - m_startTime).count();
38         constexpr int usForPerMs = 1000;
39         WIFI_LOGD("Call wifi func: %{public}s (end), time cost:%{public}lldus, %{public}lldms",
40             m_funcName.c_str(), us, us / usForPerMs);
41     }
42 }
43 
UndefinedNapiValue(const napi_env & env)44 napi_value UndefinedNapiValue(const napi_env& env)
45 {
46     napi_value result;
47     napi_get_undefined(env, &result);
48     return result;
49 }
50 
JsObjectToString(const napi_env & env,const napi_value & object,const char * fieldStr,const int bufLen,std::string & fieldRef)51 napi_value JsObjectToString(const napi_env& env, const napi_value& object,
52     const char* fieldStr, const int bufLen, std::string& fieldRef)
53 {
54     bool hasProperty = false;
55     NAPI_CALL(env, napi_has_named_property(env, object, fieldStr, &hasProperty));
56     if (hasProperty) {
57         napi_value field;
58         napi_valuetype valueType;
59 
60         napi_get_named_property(env, object, fieldStr, &field);
61         NAPI_CALL(env, napi_typeof(env, field, &valueType));
62         NAPI_ASSERT(env, valueType == napi_string, "Wrong argument type. String expected.");
63         if (bufLen <= 0) {
64             goto error;
65         }
66         char *buf = (char *)malloc(bufLen);
67         if (buf == nullptr) {
68             WIFI_LOGE("Js object to str malloc failed");
69             goto error;
70         }
71         (void)memset_s(buf, bufLen, 0, bufLen);
72         size_t result = 0;
73         NAPI_CALL(env, napi_get_value_string_utf8(env, field, buf, bufLen, &result));
74         fieldRef = buf;
75         free(buf);
76         buf = nullptr;
77     } else {
78         WIFI_LOGW("Js obj to str no property: %{public}s", fieldStr);
79     }
80 
81 error:
82     return UndefinedNapiValue(env);
83 }
84 
JsObjectToInt(const napi_env & env,const napi_value & object,const char * fieldStr,int & fieldRef)85 napi_value JsObjectToInt(const napi_env& env, const napi_value& object, const char* fieldStr, int& fieldRef)
86 {
87     bool hasProperty = false;
88     NAPI_CALL(env, napi_has_named_property(env, object, fieldStr, &hasProperty));
89     if (hasProperty) {
90         napi_value field;
91         napi_valuetype valueType;
92 
93         napi_get_named_property(env, object, fieldStr, &field);
94         NAPI_CALL(env, napi_typeof(env, field, &valueType));
95         NAPI_ASSERT(env, valueType == napi_number, "Wrong argument type. Number expected.");
96         napi_get_value_int32(env, field, &fieldRef);
97     } else {
98         WIFI_LOGW("Js to int no property: %{public}s", fieldStr);
99     }
100     return UndefinedNapiValue(env);
101 }
102 
JsObjectToBool(const napi_env & env,const napi_value & object,const char * fieldStr,bool & fieldRef)103 napi_value JsObjectToBool(const napi_env& env, const napi_value& object, const char* fieldStr, bool& fieldRef)
104 {
105     bool hasProperty = false;
106     NAPI_CALL(env, napi_has_named_property(env, object, fieldStr, &hasProperty));
107     if (hasProperty) {
108         napi_value field;
109         napi_valuetype valueType;
110 
111         napi_get_named_property(env, object, fieldStr, &field);
112         NAPI_CALL(env, napi_typeof(env, field, &valueType));
113         NAPI_ASSERT(env, valueType == napi_boolean, "Wrong argument type. Bool expected.");
114         napi_get_value_bool(env, field, &fieldRef);
115     } else {
116         WIFI_LOGW("Js to bool no property: %{public}s", fieldStr);
117     }
118     return UndefinedNapiValue(env);
119 }
120 
SetValueUtf8String(const napi_env & env,const char * fieldStr,const char * str,napi_value & result)121 napi_status SetValueUtf8String(const napi_env& env, const char* fieldStr, const char* str, napi_value& result)
122 {
123     napi_value value;
124     napi_status status = napi_create_string_utf8(env, str, NAPI_AUTO_LENGTH, &value);
125     if (status != napi_ok) {
126         WIFI_LOGE("Set value create utf8 string error! field: %{public}s", fieldStr);
127         return status;
128     }
129     status = napi_set_named_property(env, result, fieldStr, value);
130     if (status != napi_ok) {
131         WIFI_LOGE("Set utf8 string named property error! field: %{public}s", fieldStr);
132     }
133     return status;
134 }
135 
SetValueInt32(const napi_env & env,const char * fieldStr,const int intValue,napi_value & result)136 napi_status SetValueInt32(const napi_env& env, const char* fieldStr, const int intValue, napi_value& result)
137 {
138     napi_value value;
139     napi_status status = napi_create_int32(env, intValue, &value);
140     if (status != napi_ok) {
141         WIFI_LOGE("Set value create int32 error! field: %{public}s", fieldStr);
142         return status;
143     }
144     status = napi_set_named_property(env, result, fieldStr, value);
145     if (status != napi_ok) {
146         WIFI_LOGE("Set int32 named property error! field: %{public}s", fieldStr);
147     }
148     return status;
149 }
150 
SetValueUnsignedInt32(const napi_env & env,const char * fieldStr,const int intValue,napi_value & result)151 napi_status SetValueUnsignedInt32(const napi_env& env, const char* fieldStr, const int intValue, napi_value& result)
152 {
153     napi_value value;
154     napi_status status = napi_create_uint32(env, intValue, &value);
155     if (status != napi_ok) {
156         WIFI_LOGE("Set value create unsigned int32 error! field: %{public}s", fieldStr);
157         return status;
158     }
159     status = napi_set_named_property(env, result, fieldStr, value);
160     if (status != napi_ok) {
161         WIFI_LOGE("Set unsigned int32 named property error! field: %{public}s", fieldStr);
162     }
163     return status;
164 }
165 
SetValueInt64(const napi_env & env,const char * fieldStr,const int64_t intValue,napi_value & result)166 napi_status SetValueInt64(const napi_env& env, const char* fieldStr, const int64_t intValue, napi_value& result)
167 {
168     napi_value value;
169     napi_status status = napi_create_int64(env, intValue, &value);
170     if (status != napi_ok) {
171         WIFI_LOGE("Set value create int64 error! field: %{public}s", fieldStr);
172         return status;
173     }
174     status = napi_set_named_property(env, result, fieldStr, value);
175     if (status != napi_ok) {
176         WIFI_LOGE("Set int64 named property error! field: %{public}s", fieldStr);
177     }
178     return status;
179 }
180 
SetValueBool(const napi_env & env,const char * fieldStr,const bool boolvalue,napi_value & result)181 napi_status SetValueBool(const napi_env& env, const char* fieldStr, const bool boolvalue, napi_value& result)
182 {
183     napi_value value;
184     napi_status status = napi_get_boolean(env, boolvalue, &value);
185     if (status != napi_ok) {
186         WIFI_LOGE("Set value create boolean error! field: %{public}s", fieldStr);
187         return status;
188     }
189     status = napi_set_named_property(env, result, fieldStr, value);
190     if (status != napi_ok) {
191         WIFI_LOGE("Set boolean named property error! field: %{public}s", fieldStr);
192     }
193     return status;
194 }
195 
InitAsyncCallBackEnv(const napi_env & env,AsyncContext * asyncContext,const size_t argc,const napi_value * argv,const size_t nonCallbackArgNum)196 static napi_value InitAsyncCallBackEnv(const napi_env& env, AsyncContext *asyncContext,
197     const size_t argc, const napi_value *argv, const size_t nonCallbackArgNum)
198 {
199     for (size_t i = nonCallbackArgNum; i != argc; ++i) {
200         napi_valuetype valuetype;
201         NAPI_CALL(env, napi_typeof(env, argv[i], &valuetype));
202         NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected.");
203         napi_create_reference(env, argv[i], 1, &asyncContext->callback[i - nonCallbackArgNum]);
204     }
205     return nullptr;
206 }
207 
InitAsyncPromiseEnv(const napi_env & env,AsyncContext * asyncContext,napi_value & promise)208 static napi_value InitAsyncPromiseEnv(const napi_env& env, AsyncContext *asyncContext, napi_value& promise)
209 {
210     napi_deferred deferred;
211     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
212     asyncContext->deferred = deferred;
213     return nullptr;
214 }
215 
DoCallBackAsyncWork(const napi_env & env,AsyncContext * asyncContext)216 static napi_value DoCallBackAsyncWork(const napi_env& env, AsyncContext *asyncContext)
217 {
218     napi_create_async_work(
219         env,
220         nullptr,
221         asyncContext->resourceName,
222         [](napi_env env, void* data) {
223             if (data == nullptr) {
224                 WIFI_LOGE("Async data parameter is null");
225                 return;
226             }
227             AsyncContext *context = (AsyncContext *)data;
228             context->executeFunc(context);
229         },
230         [](napi_env env, napi_status status, void* data) {
231             if (data == nullptr) {
232                 WIFI_LOGE("Async data parameter is null");
233                 return;
234             }
235             AsyncContext *context = (AsyncContext *)data;
236             napi_value undefine;
237             napi_get_undefined(env, &undefine);
238             napi_value callback;
239             context->completeFunc(data);
240             constexpr int ARGS_TWO = 2;
241             napi_value result[ARGS_TWO] = {nullptr};
242             napi_create_uint32(env, context->errorCode, &result[0]);
243             result[1] = context->result;
244             if (context->errorCode == ERR_CODE_SUCCESS) {
245                 napi_get_reference_value(env, context->callback[0], &callback);
246                 napi_call_function(env, nullptr, callback, ARGS_TWO, result, &undefine);
247             } else {
248                 if (context->callback[1]) {
249                     napi_get_reference_value(env, context->callback[1], &callback);
250                     napi_call_function(env, nullptr, callback, ARGS_TWO, result, &undefine);
251                 } else {
252                     WIFI_LOGE("Get callback func[1] is null");
253                 }
254             }
255             if (context->callback[0] != nullptr) {
256                 napi_delete_reference(env, context->callback[0]);
257             }
258             if (context->callback[1] != nullptr) {
259                 napi_delete_reference(env, context->callback[1]);
260             }
261             napi_delete_async_work(env, context->work);
262             delete context;
263         },
264         (void *)asyncContext,
265         &asyncContext->work);
266     NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
267     return UndefinedNapiValue(env);
268 }
269 
DoPromiseAsyncWork(const napi_env & env,AsyncContext * asyncContext)270 static napi_value DoPromiseAsyncWork(const napi_env& env, AsyncContext *asyncContext)
271 {
272     napi_create_async_work(
273         env,
274         nullptr,
275         asyncContext->resourceName,
276         [](napi_env env, void *data) {
277             if (data == nullptr) {
278                 WIFI_LOGE("Async data parameter is null");
279                 return;
280             }
281             AsyncContext *context = (AsyncContext *)data;
282             context->executeFunc(context);
283         },
284         [](napi_env env, napi_status status, void *data) {
285             if (data == nullptr) {
286                 WIFI_LOGE("Async data parameter is null");
287                 return;
288             }
289             AsyncContext *context = (AsyncContext *)data;
290             context->completeFunc(data);
291             if (context->errorCode == ERR_CODE_SUCCESS) {
292                 napi_resolve_deferred(context->env, context->deferred, context->result);
293             } else {
294                 napi_reject_deferred(context->env, context->deferred, context->result);
295             }
296             napi_delete_async_work(env, context->work);
297             delete context;
298         },
299         (void *)asyncContext,
300         &asyncContext->work);
301     napi_queue_async_work(env, asyncContext->work);
302     return UndefinedNapiValue(env);
303 }
304 
DoAsyncWork(const napi_env & env,AsyncContext * asyncContext,const size_t argc,const napi_value * argv,const size_t nonCallbackArgNum)305 napi_value DoAsyncWork(const napi_env& env, AsyncContext *asyncContext,
306     const size_t argc, const napi_value *argv, const size_t nonCallbackArgNum)
307 {
308     if (argc > nonCallbackArgNum) {
309         InitAsyncCallBackEnv(env, asyncContext, argc, argv, nonCallbackArgNum);
310         return DoCallBackAsyncWork(env, asyncContext);
311     } else {
312         napi_value promise;
313         InitAsyncPromiseEnv(env, asyncContext, promise);
314         DoPromiseAsyncWork(env, asyncContext);
315         return promise;
316     }
317 }
318 
JsAbilityGetBundleName()319 std::string JsAbilityGetBundleName()
320 {
321     std::shared_ptr<AbilityRuntime::Context> appContext = AbilityRuntime::Context::GetApplicationContext();
322     if (appContext == nullptr) {
323         WIFI_LOGE("Get boundle name context is null");
324         return "";
325     }
326     return appContext->GetBundleName();
327 }
328 }  // namespace Wifi
329 }  // namespace OHOS
330