1 /*
2 * Copyright (c) 2022-2023 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 "devicestatus_napi.h"
17
18 #include <js_native_api.h>
19
20 #include "napi/native_api.h"
21 #include "napi/native_node_api.h"
22
23 #include "devicestatus_client.h"
24 #include "devicestatus_define.h"
25 #include "devicestatus_napi_error.h"
26 #include "stationary_manager.h"
27
28 #undef LOG_TAG
29 #define LOG_TAG "DeviceStatusNapi"
30
31 namespace OHOS {
32 namespace Msdp {
33 namespace DeviceStatus {
34 namespace {
35 constexpr size_t ARG_0 { 0 };
36 constexpr size_t ARG_1 { 1 };
37 constexpr size_t ARG_2 { 2 };
38 constexpr size_t ARG_3 { 3 };
39 constexpr size_t ARG_4 { 4 };
40 constexpr int32_t NAPI_BUF_LENGTH { 256 };
41 const std::vector<std::string> vecDeviceStatusValue {
42 "VALUE_ENTER", "VALUE_EXIT"
43 };
44 thread_local DeviceStatusNapi *g_obj = nullptr;
45 } // namespace
46 std::map<int32_t, sptr<IRemoteDevStaCallback>> DeviceStatusNapi::callbacks_;
47 napi_ref DeviceStatusNapi::devicestatusValueRef_ = nullptr;
48
OnDeviceStatusChanged(const Data & devicestatusData)49 void DeviceStatusCallback::OnDeviceStatusChanged(const Data &devicestatusData)
50 {
51 CALL_DEBUG_ENTER;
52 std::lock_guard<std::mutex> guard(mutex_);
53 uv_loop_s *loop = nullptr;
54 napi_get_uv_event_loop(env_, &loop);
55 CHKPV(loop);
56 uv_work_t *work = new (std::nothrow) uv_work_t;
57 CHKPV(work);
58 FI_HILOGD("devicestatusData.type:%{public}d, devicestatusData.value:%{public}d",
59 devicestatusData.type, devicestatusData.value);
60 data_ = devicestatusData;
61 work->data = static_cast<void *>(&data_);
62 int32_t ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) {}, EmitOnEvent, uv_qos_default);
63 if (ret != 0) {
64 FI_HILOGE("Failed to uv_queue_work_with_qos");
65 }
66 }
67
EmitOnEvent(uv_work_t * work,int32_t status)68 void DeviceStatusCallback::EmitOnEvent(uv_work_t *work, int32_t status)
69 {
70 CHKPV(work);
71 Data* data = static_cast<Data*>(work->data);
72 delete work;
73 CHKPV(data);
74 DeviceStatusNapi* deviceStatusNapi = DeviceStatusNapi::GetDeviceStatusNapi();
75 CHKPV(deviceStatusNapi);
76 int32_t type = static_cast<int32_t>(data->type);
77 int32_t value = static_cast<int32_t>(data->value);
78 FI_HILOGD("type:%{public}d, value:%{public}d", type, value);
79 deviceStatusNapi->OnDeviceStatusChangedDone(type, value, false);
80 }
81
GetDeviceStatusNapi()82 DeviceStatusNapi* DeviceStatusNapi::GetDeviceStatusNapi()
83 {
84 return g_obj;
85 }
86
DeviceStatusNapi(napi_env env)87 DeviceStatusNapi::DeviceStatusNapi(napi_env env) : DeviceStatusEvent(env)
88 {
89 env_ = env;
90 devicestatusValueRef_ = nullptr;
91 DeviceStatusClient::GetInstance().RegisterDeathListener([this] {
92 FI_HILOGI("Receive death notification");
93 callbacks_.clear();
94 ClearEventMap();
95 });
96 }
97
~DeviceStatusNapi()98 DeviceStatusNapi::~DeviceStatusNapi()
99 {
100 if (devicestatusValueRef_ != nullptr) {
101 napi_delete_reference(env_, devicestatusValueRef_);
102 }
103 if (g_obj != nullptr) {
104 delete g_obj;
105 g_obj = nullptr;
106 }
107 }
108
OnDeviceStatusChangedDone(int32_t type,int32_t value,bool isOnce)109 void DeviceStatusNapi::OnDeviceStatusChangedDone(int32_t type, int32_t value, bool isOnce)
110 {
111 CALL_DEBUG_ENTER;
112 FI_HILOGD("value:%{public}d", value);
113 OnEvent(type, ARG_1, value, isOnce);
114 }
115
ConvertTypeToInt(const std::string & type)116 int32_t DeviceStatusNapi::ConvertTypeToInt(const std::string &type)
117 {
118 if (type == "absoluteStill") {
119 return Type::TYPE_ABSOLUTE_STILL;
120 } else if (type == "horizontalPosition") {
121 return Type::TYPE_HORIZONTAL_POSITION;
122 } else if (type == "verticalPosition") {
123 return Type::TYPE_VERTICAL_POSITION;
124 } else if (type == "still") {
125 return Type::TYPE_STILL;
126 } else if (type == "relativeStill") {
127 return Type::TYPE_RELATIVE_STILL;
128 } else if (type == "carBluetooth") {
129 return Type::TYPE_CAR_BLUETOOTH;
130 } else {
131 return Type::TYPE_INVALID;
132 }
133 }
134
CheckArguments(napi_env env,napi_callback_info info)135 bool DeviceStatusNapi::CheckArguments(napi_env env, napi_callback_info info)
136 {
137 CALL_DEBUG_ENTER;
138 int32_t arr[ARG_4] = { 0 };
139 size_t argc = ARG_4;
140 napi_value args[ARG_4] = { nullptr };
141 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
142 if (status != napi_ok) {
143 FI_HILOGE("Failed to get_cb_info");
144 return false;
145 }
146 for (size_t i = 0; i < ARG_4; i++) {
147 napi_valuetype valueType = napi_undefined;
148 status = napi_typeof(env, args[i], &valueType);
149 if (status != napi_ok) {
150 FI_HILOGE("Failed to get valueType");
151 return false;
152 }
153 FI_HILOGD("valueType:%{public}d", valueType);
154 arr[i] = valueType;
155 }
156 if (arr[ARG_0] != napi_string || arr[ARG_1] != napi_number || arr[ARG_2] != napi_number ||
157 arr[ARG_3] != napi_function) {
158 FI_HILOGE("Failed to get arguements");
159 return false;
160 }
161 return true;
162 }
163
IsMatchType(napi_env env,napi_value value,napi_valuetype type)164 bool DeviceStatusNapi::IsMatchType(napi_env env, napi_value value, napi_valuetype type)
165 {
166 CALL_DEBUG_ENTER;
167 napi_valuetype valueType = napi_undefined;
168 napi_status status = napi_typeof(env, value, &valueType);
169 if (status != napi_ok) {
170 FI_HILOGE("Failed to get valueType");
171 return false;
172 }
173 return valueType == type;
174 }
175
CheckGetArguments(napi_env env,napi_callback_info info)176 bool DeviceStatusNapi::CheckGetArguments(napi_env env, napi_callback_info info)
177 {
178 CALL_DEBUG_ENTER;
179 int32_t arr[ARG_2] = { 0 };
180 size_t argc = ARG_2;
181 napi_value args[ARG_2] = { nullptr };
182 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
183 if (status != napi_ok) {
184 FI_HILOGE("Failed to get_cb_info");
185 return false;
186 }
187 for (size_t i = 0; i < ARG_2; i++) {
188 napi_valuetype valueType = napi_undefined;
189 status = napi_typeof(env, args[i], &valueType);
190 if (status != napi_ok) {
191 FI_HILOGE("Failed to get valueType");
192 return false;
193 }
194 FI_HILOGD("valueType:%{public}d", valueType);
195 arr[i] = valueType;
196 }
197 if (arr[ARG_0] != napi_string || arr[ARG_1] != napi_function) {
198 FI_HILOGE("Failed to get arguements");
199 return false;
200 }
201 return true;
202 }
203
CheckSubscribeParam(napi_env env,napi_callback_info info)204 std::tuple<bool, napi_value, std::string, int32_t, int32_t> DeviceStatusNapi::CheckSubscribeParam(napi_env env,
205 napi_callback_info info)
206 {
207 std::tuple<bool, napi_value, std::string, int32_t, int32_t> result { false, nullptr, "", -1, -1 };
208 size_t argc = ARG_4;
209 napi_value args[ARG_4] = { nullptr };
210 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
211 if ((status != napi_ok) || (argc < ARG_4)) {
212 ThrowErr(env, PARAM_ERROR, "Bad parameters");
213 return result;
214 }
215 if (!CheckArguments(env, info)) {
216 ThrowErr(env, PARAM_ERROR, "Failed to get on arguments");
217 return result;
218 }
219 size_t modLen = 0;
220 status = napi_get_value_string_utf8(env, args[ARG_0], nullptr, 0, &modLen);
221 if (status != napi_ok) {
222 ThrowErr(env, PARAM_ERROR, "Failed to get string item");
223 return result;
224 }
225 char mode[NAPI_BUF_LENGTH] = { 0 };
226 status = napi_get_value_string_utf8(env, args[ARG_0], mode, modLen + 1, &modLen);
227 if (status != napi_ok) {
228 ThrowErr(env, PARAM_ERROR, "Failed to get mode");
229 return result;
230 }
231 int32_t eventMode = 0;
232 status = napi_get_value_int32(env, args[ARG_1], &eventMode);
233 if (status != napi_ok) {
234 ThrowErr(env, PARAM_ERROR, "Failed to get event value item");
235 return result;
236 }
237 int32_t latencyMode = 0;
238 status = napi_get_value_int32(env, args[ARG_2], &latencyMode);
239 if (status != napi_ok) {
240 ThrowErr(env, PARAM_ERROR, "Failed to get latency value item");
241 return result;
242 }
243 return std::make_tuple(true, args[ARG_3], std::string(mode), eventMode, latencyMode);
244 }
245
CheckGetParam(napi_env env,napi_callback_info info)246 std::tuple<bool, napi_value, int32_t> DeviceStatusNapi::CheckGetParam(napi_env env, napi_callback_info info)
247 {
248 std::tuple<bool, napi_value, int32_t> result { false, nullptr, -1 };
249 size_t argc = ARG_2;
250 napi_value args[ARG_2] = { nullptr };
251 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
252 if ((status != napi_ok) || (argc < ARG_2)) {
253 ThrowErr(env, PARAM_ERROR, "Bad parameters");
254 return result;
255 }
256 if (!CheckGetArguments(env, info)) {
257 ThrowErr(env, PARAM_ERROR, "Failed to get once arguments");
258 return result;
259 }
260 size_t modLen = 0;
261 napi_status napiStatus = napi_get_value_string_utf8(env, args[ARG_0], nullptr, 0, &modLen);
262 if (napiStatus != napi_ok) {
263 ThrowErr(env, PARAM_ERROR, "Failed to get string item");
264 return result;
265 }
266 char mode[NAPI_BUF_LENGTH] = { 0 };
267 napiStatus = napi_get_value_string_utf8(env, args[ARG_0], mode, modLen + 1, &modLen);
268 if (napiStatus != napi_ok) {
269 ThrowErr(env, PARAM_ERROR, "Failed to get mode");
270 return result;
271 }
272 int32_t type = ConvertTypeToInt(mode);
273 if ((type < Type::TYPE_ABSOLUTE_STILL) || (type > Type::TYPE_LID_OPEN)) {
274 ThrowErr(env, PARAM_ERROR, "Type is illegal");
275 return result;
276 }
277 return std::make_tuple(true, args[ARG_1], type);
278 }
279
GetParameters(napi_env env,size_t argc,const napi_value * args)280 napi_value DeviceStatusNapi::GetParameters(napi_env env, size_t argc, const napi_value* args)
281 {
282 CALL_DEBUG_ENTER;
283 size_t modLen = 0;
284 napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &modLen);
285 if (status != napi_ok) {
286 ThrowErr(env, PARAM_ERROR, "Failed to get string item");
287 return nullptr;
288 }
289 char mode[NAPI_BUF_LENGTH] = { 0 };
290 status = napi_get_value_string_utf8(env, args[0], mode, modLen + 1, &modLen);
291 if (status != napi_ok) {
292 ThrowErr(env, PARAM_ERROR, "Failed to get mode");
293 return nullptr;
294 }
295 int32_t type = DeviceStatusNapi::ConvertTypeToInt(mode);
296 if ((type < Type::TYPE_ABSOLUTE_STILL) || (type > Type::TYPE_LID_OPEN)) {
297 ThrowErr(env, PARAM_ERROR, "Type is illegal");
298 return nullptr;
299 }
300 int32_t event = 0;
301 status = napi_get_value_int32(env, args[1], &event);
302 if (status != napi_ok) {
303 ThrowErr(env, PARAM_ERROR, "Failed to get int32 item");
304 return nullptr;
305 }
306 if ((event < ActivityEvent::ENTER) || (event > ActivityEvent::ENTER_EXIT)) {
307 ThrowErr(env, PARAM_ERROR, "Event is illegal");
308 return nullptr;
309 }
310 if ((argc < 3) || IsMatchType(env, args[2], napi_undefined) || IsMatchType(env, args[2], napi_null)) {
311 if (!g_obj->RemoveAllCallback(type)) {
312 FI_HILOGE("Callback type is not exist");
313 return nullptr;
314 }
315 UnsubscribeCallback(env, type, event);
316 return nullptr;
317 }
318 FI_HILOGD("type:%{public}d, event:%{public}d", type, event);
319 if (!IsMatchType(env, args[2], napi_function)) {
320 ThrowErr(env, PARAM_ERROR, "get error callback type");
321 return nullptr;
322 }
323 if (!g_obj->Off(type, args[2])) {
324 FI_HILOGE("Not ready to unsubscribe for type:%{public}d", type);
325 return nullptr;
326 }
327 UnsubscribeCallback(env, type, event);
328 return nullptr;
329 }
330
SubscribeDeviceStatusCallback(napi_env env,napi_callback_info info,napi_value handler,int32_t type,int32_t event,int32_t latency)331 napi_value DeviceStatusNapi::SubscribeDeviceStatusCallback(napi_env env, napi_callback_info info, napi_value handler,
332 int32_t type, int32_t event, int32_t latency)
333 {
334 CALL_DEBUG_ENTER;
335 if (g_obj == nullptr) {
336 g_obj = new (std::nothrow) DeviceStatusNapi(env);
337 CHKPP(g_obj);
338 FI_HILOGD("Didn't find object, so created it");
339 }
340 napi_wrap(env, nullptr, reinterpret_cast<void *>(g_obj),
341 [](napi_env env, void *data, void *hint) {
342 (void)env;
343 (void)hint;
344 DeviceStatusNapi *devicestatus = static_cast<DeviceStatusNapi *>(data);
345 delete devicestatus;
346 },
347 nullptr, nullptr);
348 if (!g_obj->On(type, handler, false)) {
349 FI_HILOGE("type:%{public}d already exists", type);
350 return nullptr;
351 }
352 std::lock_guard<std::mutex> guard(g_obj->mutex_);
353 auto callbackIter = callbacks_.find(type);
354 if (callbackIter != callbacks_.end()) {
355 FI_HILOGD("Callback exists");
356 return nullptr;
357 }
358 sptr<IRemoteDevStaCallback> callback = new (std::nothrow) DeviceStatusCallback(env);
359 CHKPP(callback);
360 int32_t subscribeRet = StationaryManager::GetInstance()->SubscribeCallback(static_cast<Type>(type),
361 static_cast<ActivityEvent>(event), static_cast<ReportLatencyNs>(latency), callback);
362 if (subscribeRet != RET_OK) {
363 ThrowErr(env, SERVICE_EXCEPTION, "On:Failed to SubscribeCallback");
364 return nullptr;
365 }
366 auto ret = callbacks_.insert(std::pair<int32_t, sptr<IRemoteDevStaCallback>>(type, callback));
367 if (!ret.second) {
368 FI_HILOGE("Failed to insert");
369 }
370 return nullptr;
371 }
372
SubscribeDeviceStatus(napi_env env,napi_callback_info info)373 napi_value DeviceStatusNapi::SubscribeDeviceStatus(napi_env env, napi_callback_info info)
374 {
375 CALL_DEBUG_ENTER;
376 const auto [ret, handler, typeMode, event, latency] = CheckSubscribeParam(env, info);
377 if (!ret) {
378 FI_HILOGE("On:Failed to SubscribeDeviceStatus");
379 return nullptr;
380 }
381 int32_t type = ConvertTypeToInt(typeMode);
382 FI_HILOGD("type:%{public}d, event:%{public}d, latency:%{public}d", type, event, latency);
383 if ((type < Type::TYPE_ABSOLUTE_STILL) || (type > Type::TYPE_LID_OPEN)) {
384 ThrowErr(env, PARAM_ERROR, "Type is illegal");
385 return nullptr;
386 }
387 if ((event < ActivityEvent::ENTER) || (event > ActivityEvent::ENTER_EXIT)) {
388 ThrowErr(env, PARAM_ERROR, "Event is illegal");
389 return nullptr;
390 }
391 if ((latency < ReportLatencyNs::SHORT) || (latency > ReportLatencyNs::LONG)) {
392 ThrowErr(env, PARAM_ERROR, "Latency is illegal");
393 return nullptr;
394 }
395 return SubscribeDeviceStatusCallback(env, info, handler, type, event, latency);
396 }
397
UnsubscribeDeviceStatus(napi_env env,napi_callback_info info)398 napi_value DeviceStatusNapi::UnsubscribeDeviceStatus(napi_env env, napi_callback_info info)
399 {
400 CALL_DEBUG_ENTER;
401 CHKPP(g_obj);
402 size_t argc = 3;
403 napi_value args[3] = { nullptr };
404 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
405 if (status != napi_ok) {
406 ThrowErr(env, PARAM_ERROR, "Bad parameters");
407 return nullptr;
408 }
409 if (argc < 2) {
410 ThrowErr(env, PARAM_ERROR, "Param number is invalid");
411 return nullptr;
412 }
413 return GetParameters(env, argc, args);
414 }
415
UnsubscribeCallback(napi_env env,int32_t type,int32_t event)416 napi_value DeviceStatusNapi::UnsubscribeCallback(napi_env env, int32_t type, int32_t event)
417 {
418 CALL_DEBUG_ENTER;
419 std::lock_guard<std::mutex> guard(g_obj->mutex_);
420 auto callbackIter = callbacks_.find(type);
421 if (callbackIter == callbacks_.end()) {
422 NAPI_ASSERT(env, false, "No existed callback");
423 return nullptr;
424 }
425 int32_t unsubscribeRet = StationaryManager::GetInstance()->UnsubscribeCallback(static_cast<Type>(type),
426 static_cast<ActivityEvent>(event), callbackIter->second);
427 if (unsubscribeRet != RET_OK) {
428 ThrowErr(env, SERVICE_EXCEPTION, "Off:Failed to UnsubscribeCallback");
429 }
430 callbacks_.erase(type);
431 return nullptr;
432 }
433
GetDeviceStatus(napi_env env,napi_callback_info info)434 napi_value DeviceStatusNapi::GetDeviceStatus(napi_env env, napi_callback_info info)
435 {
436 CALL_DEBUG_ENTER;
437 const auto [ret, handler, type] = CheckGetParam(env, info);
438 if (!ret) {
439 FI_HILOGE("Once:Failed to GetDeviceStatus");
440 return nullptr;
441 }
442 if (g_obj == nullptr) {
443 g_obj = new (std::nothrow) DeviceStatusNapi(env);
444 CHKPP(g_obj);
445 napi_wrap(env, nullptr, reinterpret_cast<void *>(g_obj),
446 [](napi_env env, void *data, void *hint) {
447 (void)env;
448 (void)hint;
449 DeviceStatusNapi *devicestatus = static_cast<DeviceStatusNapi *>(data);
450 delete devicestatus;
451 },
452 nullptr, nullptr);
453 }
454 if (!g_obj->On(type, handler, true)) {
455 FI_HILOGE("type:%{public}d already exists", type);
456 return nullptr;
457 }
458 Data devicestatusData = StationaryManager::GetInstance()->GetDeviceStatusData(static_cast<Type>(type));
459 if (devicestatusData.type == Type::TYPE_INVALID) {
460 ThrowErr(env, SERVICE_EXCEPTION, "Once:Failed to get device status data");
461 }
462 g_obj->OnDeviceStatusChangedDone(devicestatusData.type, devicestatusData.value, true);
463 g_obj->OffOnce(devicestatusData.type, handler);
464 return nullptr;
465 }
466
EnumActivityEventConstructor(napi_env env,napi_callback_info info)467 napi_value DeviceStatusNapi::EnumActivityEventConstructor(napi_env env, napi_callback_info info)
468 {
469 CALL_DEBUG_ENTER;
470 napi_value thisArg = nullptr;
471 void *data = nullptr;
472 napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, &data);
473 if (status != napi_ok) {
474 FI_HILOGE("Failed to get_cb_info item");
475 return nullptr;
476 }
477 napi_value global = nullptr;
478 status = napi_get_global(env, &global);
479 if (status != napi_ok) {
480 FI_HILOGE("Failed to get_global item");
481 return nullptr;
482 }
483 return thisArg;
484 }
485
DeclareEventTypeInterface(napi_env env,napi_value exports)486 napi_value DeviceStatusNapi::DeclareEventTypeInterface(napi_env env, napi_value exports)
487 {
488 CALL_DEBUG_ENTER;
489 napi_value enter = nullptr;
490 napi_status status = napi_create_int32(env, static_cast<int32_t>(ActivityEvent::ENTER), &enter);
491 if (status != napi_ok) {
492 FI_HILOGE("Failed to create ENTER item");
493 return nullptr;
494 }
495 napi_value exit = nullptr;
496 status = napi_create_int32(env, static_cast<int32_t>(ActivityEvent::EXIT), &exit);
497 if (status != napi_ok) {
498 FI_HILOGE("Failed to create EXIT item");
499 return nullptr;
500 }
501 napi_value enter_exit = nullptr;
502 status = napi_create_int32(env, static_cast<int32_t>(ActivityEvent::ENTER_EXIT), &enter_exit);
503 if (status != napi_ok) {
504 FI_HILOGE("Failed to create ENTER_EXIT item");
505 return nullptr;
506 }
507 napi_property_descriptor desc[] = {
508 DECLARE_NAPI_STATIC_PROPERTY("ENTER", enter),
509 DECLARE_NAPI_STATIC_PROPERTY("EXIT", exit),
510 DECLARE_NAPI_STATIC_PROPERTY("ENTER_EXIT", enter_exit)
511 };
512 napi_value result = nullptr;
513 status = napi_define_class(env, "ActivityEvent", NAPI_AUTO_LENGTH,
514 EnumActivityEventConstructor, nullptr, sizeof(desc) / sizeof(*desc), desc, &result);
515 if (status != napi_ok) {
516 FI_HILOGE("Failed to define_class item");
517 return nullptr;
518 }
519 status = napi_set_named_property(env, exports, "ActivityEvent", result);
520 if (status != napi_ok) {
521 FI_HILOGE("Failed to set_named_property item");
522 return nullptr;
523 }
524 return exports;
525 }
526
Init(napi_env env,napi_value exports)527 napi_value DeviceStatusNapi::Init(napi_env env, napi_value exports)
528 {
529 CALL_DEBUG_ENTER;
530 napi_property_descriptor desc[] = {
531 DECLARE_NAPI_FUNCTION("on", SubscribeDeviceStatus),
532 DECLARE_NAPI_FUNCTION("off", UnsubscribeDeviceStatus),
533 DECLARE_NAPI_FUNCTION("once", GetDeviceStatus)
534 };
535 DeclareEventTypeInterface(env, exports);
536 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
537 return exports;
538 }
539
540 EXTERN_C_START
541 /*
542 * function for module exports
543 */
DeviceStatusInit(napi_env env,napi_value exports)544 static napi_value DeviceStatusInit(napi_env env, napi_value exports)
545 {
546 CALL_DEBUG_ENTER;
547 napi_value ret = DeviceStatusNapi::Init(env, exports);
548 return ret;
549 }
550 EXTERN_C_END
551
552 /*
553 * Module definition
554 */
555 static napi_module g_module = {
556 .nm_version = 1,
557 .nm_flags = 0,
558 .nm_filename = "stationary",
559 .nm_register_func = DeviceStatusInit,
560 .nm_modname = "stationary",
561 .nm_priv = (static_cast<void *>(0)),
562 .reserved = {0}
563 };
564
565 /*
566 * Module registration
567 */
RegisterModule(void)568 extern "C" __attribute__((constructor)) void RegisterModule(void)
569 {
570 napi_module_register(&g_module);
571 }
572 } // namespace DeviceStatus
573 } // namespace Msdp
574 } // namespace OHOS
575