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 namespace OHOS {
29 namespace Msdp {
30 namespace DeviceStatus {
31 namespace {
32 constexpr ::OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "DeviceStatusNapi" };
33 constexpr size_t ARG_0 { 0 };
34 constexpr size_t ARG_1 { 1 };
35 constexpr size_t ARG_2 { 2 };
36 constexpr size_t ARG_3 { 3 };
37 constexpr size_t ARG_4 { 4 };
38 constexpr int32_t NAPI_BUF_LENGTH { 256 };
39 const std::vector<std::string> vecDeviceStatusValue {
40 "VALUE_ENTER", "VALUE_EXIT"
41 };
42 thread_local DeviceStatusNapi *g_obj = nullptr;
43 } // namespace
44 std::map<int32_t, sptr<IRemoteDevStaCallback>> DeviceStatusNapi::callbackMap_;
45 napi_ref DeviceStatusNapi::devicestatusValueRef_ = nullptr;
46
OnDeviceStatusChanged(const Data & devicestatusData)47 void DeviceStatusCallback::OnDeviceStatusChanged(const Data& devicestatusData)
48 {
49 CALL_DEBUG_ENTER;
50 std::lock_guard<std::mutex> guard(mutex_);
51 uv_loop_s *loop = nullptr;
52 napi_get_uv_event_loop(env_, &loop);
53 CHKPV(loop);
54 uv_work_t *work = new (std::nothrow) uv_work_t;
55 CHKPV(work);
56 FI_HILOGD("DevicestatusData.type:%{public}d, devicestatusData.value:%{public}d",
57 devicestatusData.type, devicestatusData.value);
58 data_ = devicestatusData;
59 work->data = static_cast<void *>(&data_);
60 int32_t ret = uv_queue_work(loop, work, [] (uv_work_t *work) {}, EmitOnEvent);
61 if (ret != 0) {
62 FI_HILOGE("Failed to execute work queue");
63 }
64 }
65
EmitOnEvent(uv_work_t * work,int32_t status)66 void DeviceStatusCallback::EmitOnEvent(uv_work_t *work, int32_t status)
67 {
68 CHKPV(work);
69 Data* data = static_cast<Data*>(work->data);
70 delete work;
71 CHKPV(data);
72 DeviceStatusNapi* deviceStatusNapi = DeviceStatusNapi::GetDeviceStatusNapi();
73 CHKPV(deviceStatusNapi);
74 int32_t type = static_cast<int32_t>(data->type);
75 int32_t value = static_cast<int32_t>(data->value);
76 FI_HILOGD("Type:%{public}d, Value:%{public}d", type, value);
77 deviceStatusNapi->OnDeviceStatusChangedDone(type, value, false);
78 }
79
GetDeviceStatusNapi()80 DeviceStatusNapi* DeviceStatusNapi::GetDeviceStatusNapi()
81 {
82 return g_obj;
83 }
84
DeviceStatusNapi(napi_env env)85 DeviceStatusNapi::DeviceStatusNapi(napi_env env) : DeviceStatusEvent(env)
86 {
87 env_ = env;
88 callbackRef_ = nullptr;
89 devicestatusValueRef_ = nullptr;
90 DeviceStatusClient::GetInstance().RegisterDeathListener([this] {
91 FI_HILOGI("Receive death notification");
92 callbackMap_.clear();
93 ClearEventMap();
94 });
95 }
96
~DeviceStatusNapi()97 DeviceStatusNapi::~DeviceStatusNapi()
98 {
99 if (callbackRef_ != nullptr) {
100 napi_delete_reference(env_, callbackRef_);
101 }
102 if (devicestatusValueRef_ != nullptr) {
103 napi_delete_reference(env_, devicestatusValueRef_);
104 }
105 if (g_obj != nullptr) {
106 delete g_obj;
107 g_obj = nullptr;
108 }
109 }
110
OnDeviceStatusChangedDone(int32_t type,int32_t value,bool isOnce)111 void DeviceStatusNapi::OnDeviceStatusChangedDone(int32_t type, int32_t value, bool isOnce)
112 {
113 CALL_DEBUG_ENTER;
114 FI_HILOGD("Value:%{public}d", value);
115 OnEvent(type, ARG_1, value, isOnce);
116 }
117
ConvertTypeToInt(const std::string & type)118 int32_t DeviceStatusNapi::ConvertTypeToInt(const std::string &type)
119 {
120 if (type == "absoluteStill") {
121 return Type::TYPE_ABSOLUTE_STILL;
122 } else if (type == "horizontalPosition") {
123 return Type::TYPE_HORIZONTAL_POSITION;
124 } else if (type == "verticalPosition") {
125 return Type::TYPE_VERTICAL_POSITION;
126 } else if (type == "still") {
127 return Type::TYPE_STILL;
128 } else if (type == "relativeStill") {
129 return Type::TYPE_RELATIVE_STILL;
130 } else if (type == "carBluetooth") {
131 return Type::TYPE_CAR_BLUETOOTH;
132 } else {
133 return Type::TYPE_INVALID;
134 }
135 }
136
CheckArguments(napi_env env,napi_callback_info info)137 bool DeviceStatusNapi::CheckArguments(napi_env env, napi_callback_info info)
138 {
139 CALL_DEBUG_ENTER;
140 int32_t arr[ARG_4] = {};
141 size_t argc = ARG_4;
142 napi_value args[ARG_4] = {};
143 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
144 if (status != napi_ok) {
145 FI_HILOGE("Failed to get_cb_info");
146 return false;
147 }
148 for (size_t i = 0; i < ARG_4; i++) {
149 napi_valuetype valueType = napi_undefined;
150 status = napi_typeof(env, args[i], &valueType);
151 if (status != napi_ok) {
152 FI_HILOGE("Failed to get valueType");
153 return false;
154 }
155 FI_HILOGD("ValueType:%{public}d", valueType);
156 arr[i] = valueType;
157 }
158 if (arr[ARG_0] != napi_string || arr[ARG_1] != napi_number || arr[ARG_2] != napi_number ||
159 arr[ARG_3] != napi_function) {
160 FI_HILOGE("Failed to get arguements");
161 return false;
162 }
163 return true;
164 }
165
IsMatchType(napi_env env,napi_value value,napi_valuetype type)166 bool DeviceStatusNapi::IsMatchType(napi_env env, napi_value value, napi_valuetype type)
167 {
168 CALL_DEBUG_ENTER;
169 napi_valuetype valueType = napi_undefined;
170 napi_status status = napi_typeof(env, value, &valueType);
171 if (status != napi_ok) {
172 FI_HILOGE("Failed to get valueType");
173 return false;
174 }
175 return valueType == type;
176 }
177
CheckGetArguments(napi_env env,napi_callback_info info)178 bool DeviceStatusNapi::CheckGetArguments(napi_env env, napi_callback_info info)
179 {
180 CALL_DEBUG_ENTER;
181 int32_t arr[ARG_2] = {};
182 size_t argc = ARG_2;
183 napi_value args[ARG_2] = {};
184 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
185 if (status != napi_ok) {
186 FI_HILOGE("Failed to get_cb_info");
187 return false;
188 }
189 for (size_t i = 0; i < ARG_2; i++) {
190 napi_valuetype valueType = napi_undefined;
191 status = napi_typeof(env, args[i], &valueType);
192 if (status != napi_ok) {
193 FI_HILOGE("Failed to get valueType");
194 return false;
195 }
196 FI_HILOGD("ValueType:%{public}d", valueType);
197 arr[i] = valueType;
198 }
199 if (arr[ARG_0] != napi_string || arr[ARG_1] != napi_function) {
200 FI_HILOGE("Failed to get arguements");
201 return false;
202 }
203 return true;
204 }
205
CheckSubscribeParam(napi_env env,napi_callback_info info)206 std::tuple<bool, napi_value, std::string, int32_t, int32_t> DeviceStatusNapi::CheckSubscribeParam(napi_env env,
207 napi_callback_info info)
208 {
209 std::tuple<bool, napi_value, std::string, int32_t, int32_t> result { false, nullptr, "", -1, -1 };
210 size_t argc = ARG_4;
211 napi_value args[ARG_4] = {};
212 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
213 if ((status != napi_ok) || (argc < ARG_4)) {
214 ThrowErr(env, PARAM_ERROR, "Bad parameters");
215 return result;
216 }
217 if (!CheckArguments(env, info)) {
218 ThrowErr(env, PARAM_ERROR, "Failed to get on arguments");
219 return result;
220 }
221 size_t modLen = 0;
222 status = napi_get_value_string_utf8(env, args[ARG_0], nullptr, 0, &modLen);
223 if (status != napi_ok) {
224 ThrowErr(env, PARAM_ERROR, "Failed to get string item");
225 return result;
226 }
227 char mode[NAPI_BUF_LENGTH] = {};
228 status = napi_get_value_string_utf8(env, args[ARG_0], mode, modLen + 1, &modLen);
229 if (status != napi_ok) {
230 ThrowErr(env, PARAM_ERROR, "Failed to get mode");
231 return result;
232 }
233 int32_t eventMode = 0;
234 status = napi_get_value_int32(env, args[ARG_1], &eventMode);
235 if (status != napi_ok) {
236 ThrowErr(env, PARAM_ERROR, "Failed to get event value item");
237 return result;
238 }
239 int32_t latencyMode = 0;
240 status = napi_get_value_int32(env, args[ARG_2], &latencyMode);
241 if (status != napi_ok) {
242 ThrowErr(env, PARAM_ERROR, "Failed to get latency value item");
243 return result;
244 }
245 return std::make_tuple(true, args[ARG_3], std::string(mode), eventMode, latencyMode);
246 }
247
CheckGetParam(napi_env env,napi_callback_info info)248 std::tuple<bool, napi_value, int32_t> DeviceStatusNapi::CheckGetParam(napi_env env, napi_callback_info info)
249 {
250 std::tuple<bool, napi_value, int32_t> result { false, nullptr, -1 };
251 size_t argc = ARG_2;
252 napi_value args[ARG_2] = {};
253 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
254 if ((status != napi_ok) || (argc < ARG_2)) {
255 ThrowErr(env, PARAM_ERROR, "Bad parameters");
256 return result;
257 }
258 if (!CheckGetArguments(env, info)) {
259 ThrowErr(env, PARAM_ERROR, "Failed to get once arguments");
260 return result;
261 }
262 size_t modLen = 0;
263 status = napi_get_value_string_utf8(env, args[ARG_0], nullptr, 0, &modLen);
264 if (status != napi_ok) {
265 ThrowErr(env, PARAM_ERROR, "Failed to get string item");
266 return result;
267 }
268 char mode[NAPI_BUF_LENGTH] = {};
269 status = napi_get_value_string_utf8(env, args[ARG_0], mode, modLen + 1, &modLen);
270 if (status != napi_ok) {
271 ThrowErr(env, PARAM_ERROR, "Failed to get mode");
272 return result;
273 }
274 int32_t type = ConvertTypeToInt(mode);
275 if ((type < Type::TYPE_ABSOLUTE_STILL) || (type > Type::TYPE_LID_OPEN)) {
276 ThrowErr(env, PARAM_ERROR, "Type is illegal");
277 return result;
278 }
279 return std::make_tuple(true, args[ARG_1], type);
280 }
281
GetParameters(napi_env env,size_t argc,const napi_value * args)282 napi_value DeviceStatusNapi::GetParameters(napi_env env, size_t argc, const napi_value* args)
283 {
284 CALL_DEBUG_ENTER;
285 size_t modLen = 0;
286 napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &modLen);
287 if (status != napi_ok) {
288 ThrowErr(env, PARAM_ERROR, "Failed to get string item");
289 return nullptr;
290 }
291 char mode[NAPI_BUF_LENGTH] = {};
292 status = napi_get_value_string_utf8(env, args[0], mode, modLen + 1, &modLen);
293 if (status != napi_ok) {
294 ThrowErr(env, PARAM_ERROR, "Failed to get mode");
295 return nullptr;
296 }
297 int32_t type = DeviceStatusNapi::ConvertTypeToInt(mode);
298 if ((type < Type::TYPE_ABSOLUTE_STILL) || (type > Type::TYPE_LID_OPEN)) {
299 ThrowErr(env, PARAM_ERROR, "Type is illegal");
300 return nullptr;
301 }
302 int32_t event = 0;
303 status = napi_get_value_int32(env, args[1], &event);
304 if (status != napi_ok) {
305 ThrowErr(env, PARAM_ERROR, "Failed to get int32 item");
306 return nullptr;
307 }
308 if ((event < ActivityEvent::ENTER) || (event > ActivityEvent::ENTER_EXIT)) {
309 ThrowErr(env, PARAM_ERROR, "Event is illegal");
310 return nullptr;
311 }
312 if ((argc < 3) || IsMatchType(env, args[2], napi_undefined) || IsMatchType(env, args[2], napi_null)) {
313 if (!g_obj->RemoveAllCallback(type)) {
314 FI_HILOGE("Callback type is not exist");
315 return nullptr;
316 }
317 UnsubscribeCallback(env, type, event);
318 return nullptr;
319 }
320 FI_HILOGD("type:%{public}d, event:%{public}d", type, event);
321 if (!IsMatchType(env, args[2], napi_function)) {
322 ThrowErr(env, PARAM_ERROR, "get error callback type");
323 return nullptr;
324 }
325 if (!g_obj->Off(type, args[2])) {
326 FI_HILOGE("Not ready to unsubscribe for type:%{public}d", type);
327 return nullptr;
328 }
329 UnsubscribeCallback(env, type, event);
330 return nullptr;
331 }
332
SubscribeDeviceStatusCallback(napi_env env,napi_callback_info info,napi_value handler,int32_t type,int32_t event,int32_t latency)333 napi_value DeviceStatusNapi::SubscribeDeviceStatusCallback(napi_env env, napi_callback_info info, napi_value handler,
334 int32_t type, int32_t event, int32_t latency)
335 {
336 CALL_DEBUG_ENTER;
337 if (g_obj == nullptr) {
338 g_obj = new (std::nothrow) DeviceStatusNapi(env);
339 CHKPP(g_obj);
340 FI_HILOGD("Didn't find object, so created it");
341 }
342 napi_wrap(env, nullptr, reinterpret_cast<void *>(g_obj),
343 [](napi_env env, void *data, void *hint) {
344 (void)env;
345 (void)hint;
346 DeviceStatusNapi *devicestatus = static_cast<DeviceStatusNapi *>(data);
347 delete devicestatus;
348 },
349 nullptr, &g_obj->callbackRef_);
350 if (!g_obj->On(type, handler, false)) {
351 FI_HILOGE("Type:%{public}d already exists", type);
352 return nullptr;
353 }
354 auto callbackIter = callbackMap_.find(type);
355 if (callbackIter != callbackMap_.end()) {
356 FI_HILOGD("Callback exists");
357 return nullptr;
358 }
359 sptr<IRemoteDevStaCallback> callback = new (std::nothrow) DeviceStatusCallback(env);
360 CHKPP(callback);
361 int32_t subscribeRet = StationaryManager::GetInstance()->SubscribeCallback(static_cast<Type>(type),
362 static_cast<ActivityEvent>(event), static_cast<ReportLatencyNs>(latency), callback);
363 if (subscribeRet != RET_OK) {
364 ThrowErr(env, SERVICE_EXCEPTION, "On:Failed to SubscribeCallback");
365 return nullptr;
366 }
367 auto ret = callbackMap_.insert(std::pair<int32_t, sptr<IRemoteDevStaCallback>>(type, callback));
368 if (!ret.second) {
369 FI_HILOGE("Failed to insert");
370 }
371 return nullptr;
372 }
373
SubscribeDeviceStatus(napi_env env,napi_callback_info info)374 napi_value DeviceStatusNapi::SubscribeDeviceStatus(napi_env env, napi_callback_info info)
375 {
376 CALL_DEBUG_ENTER;
377 const auto [ret, handler, typeMode, event, latency] = CheckSubscribeParam(env, info);
378 if (!ret) {
379 FI_HILOGE("On:SubscribeDeviceStatus is failed");
380 return nullptr;
381 }
382 int32_t type = ConvertTypeToInt(typeMode);
383 FI_HILOGD("Type:%{public}d, event:%{public}d, latency:%{public}d", type, event, latency);
384 if ((type < Type::TYPE_ABSOLUTE_STILL) || (type > Type::TYPE_LID_OPEN)) {
385 ThrowErr(env, PARAM_ERROR, "Type is illegal");
386 return nullptr;
387 }
388 if ((event < ActivityEvent::ENTER) || (event > ActivityEvent::ENTER_EXIT)) {
389 ThrowErr(env, PARAM_ERROR, "Event is illegal");
390 return nullptr;
391 }
392 if ((latency < ReportLatencyNs::SHORT) || (latency > ReportLatencyNs::LONG)) {
393 ThrowErr(env, PARAM_ERROR, "Latency is illegal");
394 return nullptr;
395 }
396 return SubscribeDeviceStatusCallback(env, info, handler, type, event, latency);
397 }
398
UnsubscribeDeviceStatus(napi_env env,napi_callback_info info)399 napi_value DeviceStatusNapi::UnsubscribeDeviceStatus(napi_env env, napi_callback_info info)
400 {
401 CALL_DEBUG_ENTER;
402 CHKPP(g_obj);
403 size_t argc = 3;
404 napi_value args[3] = {};
405 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
406 if (status != napi_ok) {
407 ThrowErr(env, PARAM_ERROR, "Bad parameters");
408 return nullptr;
409 }
410 if (argc < 2) {
411 ThrowErr(env, PARAM_ERROR, "Param number is invalid");
412 return nullptr;
413 }
414 return GetParameters(env, argc, args);
415 }
416
UnsubscribeCallback(napi_env env,int32_t type,int32_t event)417 napi_value DeviceStatusNapi::UnsubscribeCallback(napi_env env, int32_t type, int32_t event)
418 {
419 CALL_DEBUG_ENTER;
420 auto callbackIter = callbackMap_.find(type);
421 if (callbackIter == callbackMap_.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 callbackMap_.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:GetDeviceStatus is failed");
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, &g_obj->callbackRef_);
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