• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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