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