1 /*
2  * Copyright (c) 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 #include "sensor_js.h"
16 
17 #include <algorithm>
18 #include <cinttypes>
19 #include <cstdlib>
20 #include <cmath>
21 #include <string>
22 #include <unistd.h>
23 
24 #include "refbase.h"
25 #include "securec.h"
26 
27 #include "geomagnetic_field.h"
28 #include "sensor_algorithm.h"
29 #include "sensor_napi_error.h"
30 #include "sensor_napi_utils.h"
31 #include "sensor_system_js.h"
32 
33 namespace OHOS {
34 namespace Sensors {
35 namespace {
36 constexpr int32_t QUATERNION_LENGTH = 4;
37 constexpr int32_t ROTATION_VECTOR_LENGTH = 3;
38 constexpr int32_t REPORTING_INTERVAL = 200000000;
39 constexpr int32_t INVALID_SENSOR_ID = -1;
40 constexpr int32_t SENSOR_SUBSCRIBE_FAILURE = 1001;
41 constexpr int32_t INPUT_ERROR = 202;
42 constexpr float BODY_STATE_EXCEPT = 1.0f;
43 constexpr float THRESHOLD = 0.000001f;
44 constexpr uint32_t COMPATIBILITY_CHANGE_VERSION_API12 = 12;
45 } // namespace
46 static std::map<std::string, int64_t> g_samplingPeriod = {
47     {"normal", 200000000},
48     {"ui", 60000000},
49     {"game", 20000000},
50 };
51 static std::mutex g_mutex;
52 static std::mutex g_bodyMutex;
53 static float g_bodyState = -1.0f;
54 static std::map<int32_t, std::vector<sptr<AsyncCallbackInfo>>> g_subscribeCallbacks;
55 static std::mutex g_onMutex;
56 static std::mutex g_onceMutex;
57 static std::map<int32_t, std::vector<sptr<AsyncCallbackInfo>>> g_onceCallbackInfos;
58 static std::map<int32_t, std::vector<sptr<AsyncCallbackInfo>>> g_onCallbackInfos;
59 
CheckSubscribe(int32_t sensorTypeId)60 static bool CheckSubscribe(int32_t sensorTypeId)
61 {
62     std::lock_guard<std::mutex> onCallbackLock(g_onMutex);
63     auto iter = g_onCallbackInfos.find(sensorTypeId);
64     return iter != g_onCallbackInfos.end();
65 }
66 
copySensorData(sptr<AsyncCallbackInfo> callbackInfo,SensorEvent * event)67 static bool copySensorData(sptr<AsyncCallbackInfo> callbackInfo, SensorEvent *event)
68 {
69     CHKPF(callbackInfo);
70     CHKPF(event);
71     int32_t sensorTypeId = event->sensorTypeId;
72     callbackInfo->data.sensorData.sensorTypeId = sensorTypeId;
73     callbackInfo->data.sensorData.dataLength = event->dataLen;
74     callbackInfo->data.sensorData.timestamp = event->timestamp;
75     callbackInfo->data.sensorData.sensorAccuracy = event->option;
76     CHKPF(event->data);
77     if (event->dataLen < sizeof(float)) {
78         SEN_HILOGE("Event dataLen less than float size");
79         return false;
80     }
81     auto data = reinterpret_cast<float *>(event->data);
82     if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && callbackInfo->type == SUBSCRIBE_CALLBACK) {
83         std::lock_guard<std::mutex> onBodyLock(g_bodyMutex);
84         g_bodyState = *data;
85         callbackInfo->data.sensorData.data[0] =
86             (fabs(g_bodyState - BODY_STATE_EXCEPT) < THRESHOLD) ? true : false;
87         return true;
88     }
89     if (memcpy_s(callbackInfo->data.sensorData.data, sizeof(callbackInfo->data.sensorData.data),
90         data, event->dataLen) != EOK) {
91         SEN_HILOGE("Copy data failed");
92         return false;
93     }
94     return true;
95 }
96 
CheckSystemSubscribe(int32_t sensorTypeId)97 static bool CheckSystemSubscribe(int32_t sensorTypeId)
98 {
99     std::lock_guard<std::mutex> subscribeLock(g_mutex);
100     auto iter = g_subscribeCallbacks.find(sensorTypeId);
101     if (iter == g_subscribeCallbacks.end()) {
102         return false;
103     }
104     return true;
105 }
106 
EmitSubscribeCallback(SensorEvent * event)107 static void EmitSubscribeCallback(SensorEvent *event)
108 {
109     CHKPV(event);
110     int32_t sensorTypeId = event->sensorTypeId;
111     if (!CheckSystemSubscribe(sensorTypeId)) {
112         return;
113     }
114     std::lock_guard<std::mutex> subscribeLock(g_mutex);
115     auto callbacks = g_subscribeCallbacks[sensorTypeId];
116     for (auto &callback : callbacks) {
117         if (!copySensorData(callback, event)) {
118             SEN_HILOGE("Copy sensor data failed");
119             continue;
120         }
121         EmitUvEventLoop(callback);
122     }
123 }
124 
EmitOnCallback(SensorEvent * event)125 static void EmitOnCallback(SensorEvent *event)
126 {
127     CHKPV(event);
128     int32_t sensorTypeId = event->sensorTypeId;
129     if (!CheckSubscribe(sensorTypeId)) {
130         return;
131     }
132     std::lock_guard<std::mutex> onCallbackLock(g_onMutex);
133     auto onCallbackInfos = g_onCallbackInfos[sensorTypeId];
134     for (auto &onCallbackInfo : onCallbackInfos) {
135         if (!copySensorData(onCallbackInfo, event)) {
136             SEN_HILOGE("Copy sensor data failed");
137             continue;
138         }
139         EmitUvEventLoop(onCallbackInfo);
140     }
141 }
142 
EmitOnceCallback(SensorEvent * event)143 static void EmitOnceCallback(SensorEvent *event)
144 {
145     CHKPV(event);
146     int32_t sensorTypeId = event->sensorTypeId;
147     std::lock_guard<std::mutex> onceCallbackLock(g_onceMutex);
148     auto iter = g_onceCallbackInfos.find(sensorTypeId);
149     if (iter == g_onceCallbackInfos.end()) {
150         return;
151     }
152     auto &onceCallbackInfos = iter->second;
153     while (!onceCallbackInfos.empty()) {
154         auto onceCallbackInfo = onceCallbackInfos.front();
155         auto beginIter = onceCallbackInfos.begin();
156         onceCallbackInfos.erase(beginIter);
157         if (!copySensorData(onceCallbackInfo, event)) {
158             SEN_HILOGE("Copy sensor data failed");
159             continue;
160         }
161         EmitUvEventLoop(std::move(onceCallbackInfo));
162     }
163     g_onceCallbackInfos.erase(sensorTypeId);
164 
165     CHKCV((!CheckSubscribe(sensorTypeId)), "Has client subscribe, not need cancel subscribe");
166     CHKCV((!CheckSystemSubscribe(sensorTypeId)), "Has client subscribe system api, not need cancel subscribe");
167     UnsubscribeSensor(sensorTypeId);
168 }
169 
DataCallbackImpl(SensorEvent * event)170 void DataCallbackImpl(SensorEvent *event)
171 {
172     CHKPV(event);
173     EmitOnCallback(event);
174     EmitSubscribeCallback(event);
175     EmitOnceCallback(event);
176 }
177 
178 const SensorUser user = {
179     .callback = DataCallbackImpl
180 };
181 
UnsubscribeSensor(int32_t sensorTypeId)182 int32_t UnsubscribeSensor(int32_t sensorTypeId)
183 {
184     CALL_LOG_ENTER;
185     int32_t ret = DeactivateSensor(sensorTypeId, &user);
186     if (ret != ERR_OK) {
187         SEN_HILOGE("DeactivateSensor failed");
188         return ret;
189     }
190     return UnsubscribeSensor(sensorTypeId, &user);
191 }
192 
SubscribeSensor(int32_t sensorTypeId,int64_t interval,RecordSensorCallback callback)193 int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback)
194 {
195     CALL_LOG_ENTER;
196     int32_t ret = SubscribeSensor(sensorTypeId, &user);
197     if (ret != ERR_OK) {
198         SEN_HILOGE("SubscribeSensor failed");
199         return ret;
200     }
201     ret = SetBatch(sensorTypeId, &user, interval, 0);
202     if (ret != ERR_OK) {
203         SEN_HILOGE("SetBatch failed");
204         return ret;
205     }
206     return ActivateSensor(sensorTypeId, &user);
207 }
208 
CleanCallbackInfo(napi_env env,std::map<int32_t,std::vector<sptr<AsyncCallbackInfo>>> & callbackInfo)209 void CleanCallbackInfo(napi_env env, std::map<int32_t, std::vector<sptr<AsyncCallbackInfo>>> &callbackInfo)
210 {
211     for (auto &event : callbackInfo) {
212         auto &vecCallbackInfo = event.second;
213         // Automatically call the destructor of the AsyncCallbackInfo
214         vecCallbackInfo.erase(std::remove_if(vecCallbackInfo.begin(), vecCallbackInfo.end(),
215             [&env](const sptr<AsyncCallbackInfo> &myCallbackInfo) {
216                 return env == myCallbackInfo->env;
217             }), vecCallbackInfo.end());
218     }
219 }
220 
CleanOnCallbackInfo(napi_env env)221 void CleanOnCallbackInfo(napi_env env)
222 {
223     std::lock_guard<std::mutex> onCallbackLock(g_onMutex);
224     CleanCallbackInfo(env, g_onCallbackInfos);
225 }
226 
CleanOnceCallbackInfo(napi_env env)227 void CleanOnceCallbackInfo(napi_env env)
228 {
229     std::lock_guard<std::mutex> onceCallbackLock(g_onceMutex);
230     CleanCallbackInfo(env, g_onceCallbackInfos);
231 }
232 
CleanSubscribeCallbackInfo(napi_env env)233 void CleanSubscribeCallbackInfo(napi_env env)
234 {
235     std::lock_guard<std::mutex> subscribeLock(g_mutex);
236     CleanCallbackInfo(env, g_subscribeCallbacks);
237 }
238 
CleanUp(void * data)239 void CleanUp(void *data)
240 {
241     auto env = *(reinterpret_cast<napi_env*>(data));
242     CleanOnCallbackInfo(env);
243     CleanOnceCallbackInfo(env);
244     CleanSubscribeCallbackInfo(env);
245     delete reinterpret_cast<napi_env*>(data);
246     data = nullptr;
247 }
248 
IsOnceSubscribed(napi_env env,int32_t sensorTypeId,napi_value callback)249 static bool IsOnceSubscribed(napi_env env, int32_t sensorTypeId, napi_value callback)
250 {
251     CALL_LOG_ENTER;
252     if (auto iter = g_onceCallbackInfos.find(sensorTypeId); iter == g_onceCallbackInfos.end()) {
253         SEN_HILOGW("Already subscribed, sensorTypeId:%{public}d", sensorTypeId);
254         return false;
255     }
256     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onceCallbackInfos[sensorTypeId];
257     for (auto callbackInfo : callbackInfos) {
258         CHKPC(callbackInfo);
259         if (callbackInfo->env != env) {
260             continue;
261         }
262         napi_value sensorCallback = nullptr;
263         CHKNRF(env, napi_get_reference_value(env, callbackInfo->callback[0], &sensorCallback),
264             "napi_get_reference_value");
265         if (IsSameValue(env, callback, sensorCallback)) {
266             return true;
267         }
268     }
269     return false;
270 }
271 
UpdateOnceCallback(napi_env env,int32_t sensorTypeId,napi_value callback)272 static void UpdateOnceCallback(napi_env env, int32_t sensorTypeId, napi_value callback)
273 {
274     CALL_LOG_ENTER;
275     std::lock_guard<std::mutex> onceCallbackLock(g_onceMutex);
276     CHKCV((!IsOnceSubscribed(env, sensorTypeId, callback)), "The callback has been subscribed");
277     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, ONCE_CALLBACK);
278     CHKPV(asyncCallbackInfo);
279     napi_status status = napi_create_reference(env, callback, 1, &asyncCallbackInfo->callback[0]);
280     if (status != napi_ok) {
281         ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail");
282         return;
283     }
284     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onceCallbackInfos[sensorTypeId];
285     callbackInfos.push_back(asyncCallbackInfo);
286     g_onceCallbackInfos[sensorTypeId] = callbackInfos;
287 }
288 
Once(napi_env env,napi_callback_info info)289 static napi_value Once(napi_env env, napi_callback_info info)
290 {
291     CALL_LOG_ENTER;
292     size_t argc = 2;
293     napi_value args[2] = { 0 };
294     napi_value thisVar = nullptr;
295     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
296     if (status != napi_ok || argc < 2) {
297         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
298         return nullptr;
299     }
300     if ((!IsMatchType(env, args[0], napi_number)) || (!IsMatchType(env, args[1], napi_function))) {
301         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type");
302         return nullptr;
303     }
304     int32_t sensorTypeId = INVALID_SENSOR_ID;
305     if (!GetNativeInt32(env, args[0], sensorTypeId)) {
306         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get number fail");
307         return nullptr;
308     }
309     if (!CheckSubscribe(sensorTypeId)) {
310         SEN_HILOGD("No subscription to change sensor data, registration is required");
311         int32_t ret = SubscribeSensor(sensorTypeId, REPORTING_INTERVAL, DataCallbackImpl);
312         if (ret != ERR_OK) {
313             ThrowErr(env, ret, "SubscribeSensor fail");
314             return nullptr;
315         }
316     }
317     UpdateOnceCallback(env, sensorTypeId, args[1]);
318     return nullptr;
319 }
320 
IsSubscribed(napi_env env,int32_t sensorTypeId,napi_value callback)321 static bool IsSubscribed(napi_env env, int32_t sensorTypeId, napi_value callback)
322 {
323     CALL_LOG_ENTER;
324     if (auto iter = g_onCallbackInfos.find(sensorTypeId); iter == g_onCallbackInfos.end()) {
325         SEN_HILOGW("No client subscribe, sensorTypeId:%{public}d", sensorTypeId);
326         return false;
327     }
328     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId];
329     for (auto callbackInfo : callbackInfos) {
330         CHKPC(callbackInfo);
331         if (callbackInfo->env != env) {
332             continue;
333         }
334         napi_value sensorCallback = nullptr;
335         CHKNRF(env, napi_get_reference_value(env, callbackInfo->callback[0], &sensorCallback),
336             "napi_get_reference_value");
337         if (IsSameValue(env, callback, sensorCallback)) {
338             return true;
339         }
340     }
341     return false;
342 }
343 
UpdateCallbackInfos(napi_env env,int32_t sensorTypeId,napi_value callback)344 static void UpdateCallbackInfos(napi_env env, int32_t sensorTypeId, napi_value callback)
345 {
346     CALL_LOG_ENTER;
347     std::lock_guard<std::mutex> onCallbackLock(g_onMutex);
348     CHKCV((!IsSubscribed(env, sensorTypeId, callback)), "The callback has been subscribed");
349     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, ON_CALLBACK);
350     CHKPV(asyncCallbackInfo);
351     napi_status status = napi_create_reference(env, callback, 1, &asyncCallbackInfo->callback[0]);
352     if (status != napi_ok) {
353         ThrowErr(env, PARAMETER_ERROR, "napi_create_reference fail");
354         return;
355     }
356     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId];
357     callbackInfos.push_back(asyncCallbackInfo);
358     g_onCallbackInfos[sensorTypeId] = callbackInfos;
359 }
360 
GetInterval(napi_env env,napi_value value,int64_t & interval)361 static bool GetInterval(napi_env env, napi_value value, int64_t &interval)
362 {
363     napi_value napiInterval = GetNamedProperty(env, value, "interval");
364     if (IsMatchType(env, napiInterval, napi_number)) {
365         if (!GetNativeInt64(env, napiInterval, interval)) {
366             SEN_HILOGE("GetNativeInt64 failed");
367             return false;
368         }
369     } else if (IsMatchType(env, napiInterval, napi_string)) {
370         std::string mode;
371         if (!GetStringValue(env, napiInterval, mode)) {
372             SEN_HILOGE("GetStringValue failed");
373             return false;
374         }
375         auto iter = g_samplingPeriod.find(mode);
376         if (iter == g_samplingPeriod.end()) {
377             SEN_HILOGE("Find interval mode failed");
378             return false;
379         }
380         interval = iter->second;
381         SEN_HILOGI("%{public}s", mode.c_str());
382     } else {
383         SEN_HILOGE("Interval failed");
384         return false;
385     }
386     return true;
387 }
388 
On(napi_env env,napi_callback_info info)389 static napi_value On(napi_env env, napi_callback_info info)
390 {
391     CALL_LOG_ENTER;
392     size_t argc = 3;
393     napi_value args[3] = { 0 };
394     napi_value thisVar = nullptr;
395     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
396     if (status != napi_ok || argc < 2) {
397         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
398         return nullptr;
399     }
400     if ((!IsMatchType(env, args[0], napi_number)) || (!IsMatchType(env, args[1], napi_function))) {
401         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type");
402         return nullptr;
403     }
404     int32_t sensorTypeId = INVALID_SENSOR_ID;
405     if (!GetNativeInt32(env, args[0], sensorTypeId)) {
406         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get number fail");
407         return nullptr;
408     }
409     int64_t interval = REPORTING_INTERVAL;
410     if (argc >= 3 && IsMatchType(env, args[2], napi_object)) {
411         if (!GetInterval(env, args[2], interval)) {
412             SEN_HILOGW("Get interval failed");
413         }
414     }
415     SEN_HILOGD("Interval is %{public}" PRId64, interval);
416     int32_t ret = SubscribeSensor(sensorTypeId, interval, DataCallbackImpl);
417     if (ret != ERR_OK) {
418         ThrowErr(env, ret, "SubscribeSensor fail");
419         return nullptr;
420     }
421     UpdateCallbackInfos(env, sensorTypeId, args[1]);
422     return nullptr;
423 }
424 
RemoveAllCallback(napi_env env,int32_t sensorTypeId)425 static int32_t RemoveAllCallback(napi_env env, int32_t sensorTypeId)
426 {
427     CALL_LOG_ENTER;
428     std::lock_guard<std::mutex> onCallbackLock(g_onMutex);
429     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId];
430     for (auto iter = callbackInfos.begin(); iter != callbackInfos.end();) {
431         CHKPC(*iter);
432         if ((*iter)->env != env) {
433             ++iter;
434             continue;
435         }
436         iter = callbackInfos.erase(iter);
437     }
438     if (callbackInfos.empty()) {
439         SEN_HILOGD("No subscription to change sensor data");
440         g_onCallbackInfos.erase(sensorTypeId);
441         return 0;
442     }
443     g_onCallbackInfos[sensorTypeId] = callbackInfos;
444     return callbackInfos.size();
445 }
446 
RemoveCallback(napi_env env,int32_t sensorTypeId,napi_value callback)447 static int32_t RemoveCallback(napi_env env, int32_t sensorTypeId, napi_value callback)
448 {
449     CALL_LOG_ENTER;
450     std::lock_guard<std::mutex> onCallbackLock(g_onMutex);
451     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId];
452     for (auto iter = callbackInfos.begin(); iter != callbackInfos.end();) {
453         CHKPC(*iter);
454         if ((*iter)->env != env) {
455             continue;
456         }
457         napi_value sensorCallback = nullptr;
458         if (napi_get_reference_value(env, (*iter)->callback[0], &sensorCallback) != napi_ok) {
459             SEN_HILOGE("napi_get_reference_value fail");
460             continue;
461         }
462         if (IsSameValue(env, callback, sensorCallback)) {
463             iter = callbackInfos.erase(iter);
464             SEN_HILOGD("Remove callback success");
465             break;
466         } else {
467             ++iter;
468         }
469     }
470     if (callbackInfos.empty()) {
471         SEN_HILOGD("No subscription to change sensor data");
472         g_onCallbackInfos.erase(sensorTypeId);
473         return 0;
474     }
475     g_onCallbackInfos[sensorTypeId] = callbackInfos;
476     return callbackInfos.size();
477 }
478 
Off(napi_env env,napi_callback_info info)479 static napi_value Off(napi_env env, napi_callback_info info)
480 {
481     CALL_LOG_ENTER;
482     size_t argc = 2;
483     napi_value args[2] = { 0 };
484     napi_value thisVar = nullptr;
485     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
486     if (status != napi_ok || argc < 1) {
487         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
488         return nullptr;
489     }
490     int32_t sensorTypeId = INVALID_SENSOR_ID;
491     if ((!IsMatchType(env, args[0], napi_number)) || (!GetNativeInt32(env, args[0], sensorTypeId))) {
492         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type or get number fail");
493         return nullptr;
494     }
495     int32_t subscribeSize = -1;
496     if (argc == 1) {
497         subscribeSize = RemoveAllCallback(env, sensorTypeId);
498     } else if (IsMatchType(env, args[1], napi_undefined) || IsMatchType(env, args[1], napi_null)) {
499         subscribeSize = RemoveAllCallback(env, sensorTypeId);
500     } else if (IsMatchType(env, args[1], napi_function)) {
501         subscribeSize = RemoveCallback(env, sensorTypeId, args[1]);
502     } else {
503         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, args[1] should is napi_function");
504         return nullptr;
505     }
506     if (CheckSystemSubscribe(sensorTypeId) || (subscribeSize > 0)) {
507         SEN_HILOGW("There are other client subscribe system js api as well, not need unsubscribe");
508         return nullptr;
509     }
510     int32_t ret = UnsubscribeSensor(sensorTypeId);
511     if (ret == PARAMETER_ERROR || ret == PERMISSION_DENIED) {
512         ThrowErr(env, ret, "UnsubscribeSensor fail");
513     }
514     return nullptr;
515 }
516 
EmitAsyncWork(napi_value param,sptr<AsyncCallbackInfo> info)517 static napi_value EmitAsyncWork(napi_value param, sptr<AsyncCallbackInfo> info)
518 {
519     CHKPP(info);
520     napi_status status = napi_generic_failure;
521     if (param != nullptr) {
522         status = napi_create_reference(info->env, param, 1, &info->callback[0]);
523         if (status != napi_ok) {
524             SEN_HILOGE("napi_create_reference fail");
525             return nullptr;
526         }
527         EmitAsyncCallbackWork(info);
528         return nullptr;
529     }
530     napi_value promise = nullptr;
531     status = napi_create_promise(info->env, &info->deferred, &promise);
532     if (status != napi_ok) {
533         SEN_HILOGE("napi_create_promise fail");
534         return nullptr;
535     }
536     EmitPromiseWork(info);
537     return promise;
538 }
539 
GetGeomagneticField(napi_env env,napi_callback_info info)540 static napi_value GetGeomagneticField(napi_env env, napi_callback_info info)
541 {
542     CALL_LOG_ENTER;
543     size_t argc = 3;
544     napi_value args[3] = { 0 };
545     napi_value thisVar = nullptr;
546     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
547     if (status != napi_ok || argc < 2) {
548         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
549         return nullptr;
550     }
551     if ((!IsMatchType(env, args[0], napi_object)) || (!IsMatchType(env, args[1], napi_number))) {
552         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type");
553         return nullptr;
554     }
555     napi_value napiLatitude = GetNamedProperty(env, args[0], "latitude");
556     if (napiLatitude == nullptr) {
557         ThrowErr(env, PARAMETER_ERROR, "napiLatitude is null");
558         return nullptr;
559     }
560     double latitude = 0;
561     if (!GetNativeDouble(env, napiLatitude, latitude)) {
562         ThrowErr(env, PARAMETER_ERROR, "Get latitude fail");
563         return nullptr;
564     }
565     napi_value napiLongitude = GetNamedProperty(env, args[0], "longitude");
566     if (napiLongitude == nullptr) {
567         ThrowErr(env, PARAMETER_ERROR, "napiLongitude is null");
568         return nullptr;
569     }
570     double longitude = 0;
571     if (!GetNativeDouble(env, napiLongitude, longitude)) {
572         ThrowErr(env, PARAMETER_ERROR, "Get longitude fail");
573         return nullptr;
574     }
575     napi_value napiAltitude = GetNamedProperty(env, args[0], "altitude");
576     if (napiAltitude == nullptr) {
577         ThrowErr(env, PARAMETER_ERROR, "napiAltitude is null");
578         return nullptr;
579     }
580     double altitude = 0;
581     if (!GetNativeDouble(env, napiAltitude, altitude)) {
582         ThrowErr(env, PARAMETER_ERROR, "Get altitude fail");
583         return nullptr;
584     }
585     int64_t timeMillis = 0;
586     if (!GetNativeInt64(env, args[1], timeMillis)) {
587         ThrowErr(env, PARAMETER_ERROR, "Get timeMillis fail");
588         return nullptr;
589     }
590     GeomagneticField geomagneticField(latitude, longitude, altitude, timeMillis);
591     sptr<AsyncCallbackInfo> asyncCallbackInfo =
592         new (std::nothrow) AsyncCallbackInfo(env, GET_GEOMAGNETIC_FIELD);
593     CHKPP(asyncCallbackInfo);
594     asyncCallbackInfo->data.geomagneticData = {
595         .x = geomagneticField.ObtainX(),
596         .y = geomagneticField.ObtainY(),
597         .z = geomagneticField.ObtainZ(),
598         .geomagneticDip = geomagneticField.ObtainGeomagneticDip(),
599         .deflectionAngle = geomagneticField.ObtainDeflectionAngle(),
600         .levelIntensity = geomagneticField.ObtainLevelIntensity(),
601         .totalIntensity = geomagneticField.ObtainTotalIntensity(),
602     };
603     if (argc >= 3 && IsMatchType(env, args[2], napi_function)) {
604         return EmitAsyncWork(args[2], asyncCallbackInfo);
605     }
606     return EmitAsyncWork(nullptr, asyncCallbackInfo);
607 }
608 
GetAxisX(napi_env env,napi_value value)609 static napi_value GetAxisX(napi_env env, napi_value value)
610 {
611     return GetNamedProperty(env, value, "x");
612 }
613 
GetAxisY(napi_env env,napi_value value)614 static napi_value GetAxisY(napi_env env, napi_value value)
615 {
616     return GetNamedProperty(env, value, "y");
617 }
618 
TransformCoordinateSystem(napi_env env,napi_callback_info info)619 static napi_value TransformCoordinateSystem(napi_env env, napi_callback_info info)
620 {
621     CALL_LOG_ENTER;
622     size_t argc = 3;
623     napi_value args[3]  = { 0 };
624     napi_value thisVar = nullptr;
625     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
626     if (status != napi_ok || argc < 2) {
627         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
628         return nullptr;
629     }
630     if ((!IsMatchArrayType(env, args[0])) || (!IsMatchType(env, args[1], napi_object))) {
631         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type");
632         return nullptr;
633     }
634     std::vector<float> inRotationVector;
635     if (!GetFloatArray(env, args[0], inRotationVector)) {
636         ThrowErr(env, PARAMETER_ERROR, "Get inRotationVector fail");
637         return nullptr;
638     }
639     size_t length = inRotationVector.size();
640     if ((length != DATA_LENGTH) && (length != THREE_DIMENSIONAL_MATRIX_LENGTH)) {
641         ThrowErr(env, PARAMETER_ERROR, "Wrong inRotationVector length");
642         return nullptr;
643     }
644     napi_value napiAxisX = GetAxisX(env, args[1]);
645     if (napiAxisX == nullptr) {
646         ThrowErr(env, PARAMETER_ERROR, "napiAxisX is null");
647         return nullptr;
648     }
649     int32_t axisX = 0;
650     if (!GetNativeInt32(env, napiAxisX, axisX)) {
651         ThrowErr(env, PARAMETER_ERROR, "Get axisY fail");
652         return nullptr;
653     }
654     napi_value napiAxisY = GetAxisY(env, args[1]);
655     if (napiAxisY == nullptr) {
656         ThrowErr(env, PARAMETER_ERROR, "napiAxisY is null");
657         return nullptr;
658     }
659     int32_t axisY = 0;
660     if (!GetNativeInt32(env, napiAxisY, axisY)) {
661         ThrowErr(env, PARAMETER_ERROR, "Get axisY fail");
662         return nullptr;
663     }
664     sptr<AsyncCallbackInfo> asyncCallbackInfo =
665         new (std::nothrow) AsyncCallbackInfo(env, TRANSFORM_COORDINATE_SYSTEM);
666     CHKPP(asyncCallbackInfo);
667     std::vector<float> outRotationVector(length);
668     SensorAlgorithm sensorAlgorithm;
669     int32_t ret = sensorAlgorithm.TransformCoordinateSystem(inRotationVector, axisX, axisY, outRotationVector);
670     if (ret != OHOS::ERR_OK) {
671         ThrowErr(env, ret, "Transform coordinate system fail");
672         return nullptr;
673     } else {
674         for (size_t i = 0; i < length; ++i) {
675             asyncCallbackInfo->data.reserveData.reserve[i] = outRotationVector[i];
676         }
677         asyncCallbackInfo->data.reserveData.length = static_cast<int32_t>(length);
678     }
679     if (argc >= 3 && IsMatchType(env, args[2], napi_function)) {
680         return EmitAsyncWork(args[2], asyncCallbackInfo);
681     }
682     return EmitAsyncWork(nullptr, asyncCallbackInfo);
683 }
684 
GetAngleModify(napi_env env,napi_callback_info info)685 static napi_value GetAngleModify(napi_env env, napi_callback_info info)
686 {
687     CALL_LOG_ENTER;
688     size_t argc = 3;
689     napi_value args[3] = { 0 };
690     napi_value thisVar = nullptr;
691     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
692     if (status != napi_ok || argc < 2) {
693         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
694         return nullptr;
695     }
696     if (!IsMatchArrayType(env, args[0])) {
697         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array");
698         return nullptr;
699     }
700     if (!IsMatchArrayType(env, args[1])) {
701         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array");
702         return nullptr;
703     }
704     sptr<AsyncCallbackInfo> asyncCallbackInfo =
705         new (std::nothrow) AsyncCallbackInfo(env, GET_ANGLE_MODIFY);
706     CHKPP(asyncCallbackInfo);
707     std::vector<float> curRotationVector;
708     if (!GetFloatArray(env, args[0], curRotationVector)) {
709         ThrowErr(env, PARAMETER_ERROR, "Get curRotationVector fail");
710         return nullptr;
711     }
712     std::vector<float> preRotationVector;
713     if (!GetFloatArray(env, args[1], preRotationVector)) {
714         ThrowErr(env, PARAMETER_ERROR, "Get preRotationVector fail");
715         return nullptr;
716     }
717     std::vector<float> angleChange(ROTATION_VECTOR_LENGTH);
718     SensorAlgorithm sensorAlgorithm;
719     int32_t ret = sensorAlgorithm.GetAngleModify(curRotationVector, preRotationVector, angleChange);
720     if (ret != OHOS::ERR_OK) {
721         ThrowErr(env, ret, "Get angle modify fail");
722         return nullptr;
723     } else {
724         asyncCallbackInfo->data.reserveData.length = ROTATION_VECTOR_LENGTH;
725         for (int32_t i = 0; i < ROTATION_VECTOR_LENGTH; ++i) {
726             asyncCallbackInfo->data.reserveData.reserve[i] = angleChange[i];
727         }
728     }
729     if (argc >= 3 && IsMatchType(env, args[2], napi_function)) {
730         return EmitAsyncWork(args[2], asyncCallbackInfo);
731     }
732     return EmitAsyncWork(nullptr, asyncCallbackInfo);
733 }
734 
GetDirection(napi_env env,napi_callback_info info)735 static napi_value GetDirection(napi_env env, napi_callback_info info)
736 {
737     CALL_LOG_ENTER;
738     size_t argc = 3;
739     napi_value args[3] = { 0 };
740     napi_value thisVar = nullptr;
741     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
742     if (status != napi_ok || argc < 1) {
743         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
744         return nullptr;
745     }
746     if (!IsMatchArrayType(env, args[0])) {
747         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array");
748         return nullptr;
749     }
750     sptr<AsyncCallbackInfo> asyncCallbackInfo =
751         new (std::nothrow) AsyncCallbackInfo(env, GET_DIRECTION);
752     CHKPP(asyncCallbackInfo);
753     std::vector<float> rotationMatrix;
754     if (!GetFloatArray(env, args[0], rotationMatrix)) {
755         ThrowErr(env, PARAMETER_ERROR, "Get rotationMatrix fail");
756         return nullptr;
757     }
758     std::vector<float> rotationAngle(ROTATION_VECTOR_LENGTH);
759     SensorAlgorithm sensorAlgorithm;
760     int32_t ret = sensorAlgorithm.GetDirection(rotationMatrix, rotationAngle);
761     if (ret != OHOS::ERR_OK) {
762         ThrowErr(env, ret, "Get direction fail");
763         return nullptr;
764     } else {
765         asyncCallbackInfo->data.reserveData.length = ROTATION_VECTOR_LENGTH;
766         for (int32_t i = 0; i < ROTATION_VECTOR_LENGTH; ++i) {
767             asyncCallbackInfo->data.reserveData.reserve[i] = rotationAngle[i];
768         }
769     }
770     if (argc >= 2 && IsMatchType(env, args[1], napi_function)) {
771         return EmitAsyncWork(args[1], asyncCallbackInfo);
772     }
773     return EmitAsyncWork(nullptr, asyncCallbackInfo);
774 }
775 
CreateQuaternion(napi_env env,napi_callback_info info)776 static napi_value CreateQuaternion(napi_env env, napi_callback_info info)
777 {
778     CALL_LOG_ENTER;
779     size_t argc = 2;
780     napi_value args[2] = { 0 };
781     napi_value thisVar = nullptr;
782     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
783     if (status != napi_ok || argc < 1) {
784         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info failed or number of parameter invalid");
785         return nullptr;
786     }
787     if (!IsMatchArrayType(env, args[0])) {
788         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array");
789         return nullptr;
790     }
791     sptr<AsyncCallbackInfo> asyncCallbackInfo =
792         new (std::nothrow) AsyncCallbackInfo(env, CREATE_QUATERNION);
793     CHKPP(asyncCallbackInfo);
794     std::vector<float> rotationVector;
795     if (!GetFloatArray(env, args[0], rotationVector)) {
796         ThrowErr(env, PARAMETER_ERROR, "Get rotationVector failed");
797         return nullptr;
798     }
799     std::vector<float> quaternion(QUATERNION_LENGTH);
800     SensorAlgorithm sensorAlgorithm;
801     int32_t ret = sensorAlgorithm.CreateQuaternion(rotationVector, quaternion);
802     if (ret != OHOS::ERR_OK) {
803         ThrowErr(env, ret, "CreateQuaternion fail");
804         return nullptr;
805     } else {
806         asyncCallbackInfo->data.reserveData.length = QUATERNION_LENGTH;
807         for (int32_t i = 0; i < QUATERNION_LENGTH; ++i) {
808             asyncCallbackInfo->data.reserveData.reserve[i] = quaternion[i];
809         }
810     }
811     if (argc >= 2 && IsMatchType(env, args[1], napi_function)) {
812         return EmitAsyncWork(args[1], asyncCallbackInfo);
813     }
814     return EmitAsyncWork(nullptr, asyncCallbackInfo);
815 }
816 
GetAltitude(napi_env env,napi_callback_info info)817 static napi_value GetAltitude(napi_env env, napi_callback_info info)
818 {
819     CALL_LOG_ENTER;
820     size_t argc = 3;
821     napi_value args[3] = { 0 };
822     napi_value thisVar = nullptr;
823     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
824     if (status != napi_ok || argc < 2) {
825         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
826         return nullptr;
827     }
828     if ((!IsMatchType(env, args[0], napi_number)) || (!IsMatchType(env, args[1], napi_number))) {
829         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type");
830         return nullptr;
831     }
832     sptr<AsyncCallbackInfo> asyncCallbackInfo =
833         new (std::nothrow) AsyncCallbackInfo(env, GET_ALTITUDE);
834     CHKPP(asyncCallbackInfo);
835     float seaPressure = 0;
836     if (!GetNativeFloat(env, args[0], seaPressure)) {
837         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get seaPressure fail");
838         return nullptr;
839     }
840     float currentPressure = 0;
841     if (!GetNativeFloat(env, args[1], currentPressure)) {
842         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get currentPressure fail");
843         return nullptr;
844     }
845     float altitude = 0;
846     SensorAlgorithm sensorAlgorithm;
847     int32_t ret = sensorAlgorithm.GetAltitude(seaPressure, currentPressure, &altitude);
848     if (ret != OHOS::ERR_OK) {
849         ThrowErr(env, ret, "Get altitude fail");
850         return nullptr;
851     } else {
852         asyncCallbackInfo->data.reserveData.reserve[0] = altitude;
853     }
854     if (argc >= 3 && IsMatchType(env, args[2], napi_function)) {
855         return EmitAsyncWork(args[2], asyncCallbackInfo);
856     }
857     return EmitAsyncWork(nullptr, asyncCallbackInfo);
858 }
859 
GetGeomagneticDip(napi_env env,napi_callback_info info)860 static napi_value GetGeomagneticDip(napi_env env, napi_callback_info info)
861 {
862     CALL_LOG_ENTER;
863     size_t argc = 2;
864     napi_value args[2] = { 0 };
865     napi_value thisVar = nullptr;
866     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
867     if (status != napi_ok || argc < 1) {
868         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
869         return nullptr;
870     }
871     if (!IsMatchArrayType(env, args[0])) {
872         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array");
873         return nullptr;
874     }
875     sptr<AsyncCallbackInfo> asyncCallbackInfo =
876         new (std::nothrow) AsyncCallbackInfo(env, GET_GEOMAGNETIC_DIP);
877     CHKPP(asyncCallbackInfo);
878     std::vector<float> inclinationMatrix;
879     if (!GetFloatArray(env, args[0], inclinationMatrix)) {
880         ThrowErr(env, PARAMETER_ERROR, "Get inclinationMatrix fail");
881         return nullptr;
882     }
883     float geomagneticDip = 0;
884     SensorAlgorithm sensorAlgorithm;
885     int32_t ret = sensorAlgorithm.GetGeomagneticDip(inclinationMatrix, &geomagneticDip);
886     if (ret != OHOS::ERR_OK) {
887         ThrowErr(env, ret, "Get geomagnetic dip fail");
888         return nullptr;
889     } else {
890         asyncCallbackInfo->data.reserveData.reserve[0] = geomagneticDip;
891     }
892     if (argc >= 2 && IsMatchType(env, args[1], napi_function)) {
893         return EmitAsyncWork(args[1], asyncCallbackInfo);
894     }
895     return EmitAsyncWork(nullptr, asyncCallbackInfo);
896 }
897 
CreateRotationAndInclination(const napi_env & env,napi_value args[],size_t argc)898 static napi_value CreateRotationAndInclination(const napi_env &env, napi_value args[], size_t argc)
899 {
900     CALL_LOG_ENTER;
901     if (argc < 2) {
902         ThrowErr(env, PARAMETER_ERROR, "The number of parameters is not valid");
903         return nullptr;
904     }
905     std::vector<float> gravity;
906     if (!GetFloatArray(env, args[0], gravity)) {
907         ThrowErr(env, PARAMETER_ERROR, "Get gravity fail");
908         return nullptr;
909     }
910     std::vector<float> geomagnetic;
911     if (!GetFloatArray(env, args[1], geomagnetic)) {
912         ThrowErr(env, PARAMETER_ERROR, "Get geomagnetic fail");
913         return nullptr;
914     }
915     std::vector<float> rotation(THREE_DIMENSIONAL_MATRIX_LENGTH);
916     std::vector<float> inclination(THREE_DIMENSIONAL_MATRIX_LENGTH);
917     sptr<AsyncCallbackInfo> asyncCallbackInfo =
918         new (std::nothrow) AsyncCallbackInfo(env, ROTATION_INCLINATION_MATRIX);
919     CHKPP(asyncCallbackInfo);
920     SensorAlgorithm sensorAlgorithm;
921     int32_t ret = sensorAlgorithm.CreateRotationAndInclination(gravity, geomagnetic, rotation, inclination);
922     if (ret != OHOS::ERR_OK) {
923         ThrowErr(env, ret, "Create rotation and inclination matrix fail");
924         return nullptr;
925     } else {
926         asyncCallbackInfo->data.reserveData.length = THREE_DIMENSIONAL_MATRIX_LENGTH;
927         for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) {
928             asyncCallbackInfo->data.rationMatrixData.rotationMatrix[i] = rotation[i];
929         }
930         for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) {
931             asyncCallbackInfo->data.rationMatrixData.inclinationMatrix[i] = inclination[i];
932         }
933     }
934     if (argc >= 3 && IsMatchType(env, args[2], napi_function)) {
935         return EmitAsyncWork(args[2], asyncCallbackInfo);
936     }
937     return EmitAsyncWork(nullptr, asyncCallbackInfo);
938 }
939 
GetRotationMatrix(const napi_env & env,napi_value args[],size_t argc)940 static napi_value GetRotationMatrix(const napi_env &env, napi_value args[], size_t argc)
941 {
942     CALL_LOG_ENTER;
943     if (argc < 1) {
944         ThrowErr(env, PARAMETER_ERROR, "The number of parameters is not valid");
945         return nullptr;
946     }
947     std::vector<float> rotationVector;
948     if (!GetFloatArray(env, args[0], rotationVector)) {
949         ThrowErr(env, PARAMETER_ERROR, "Get rotationVector fail");
950         return nullptr;
951     }
952     sptr<AsyncCallbackInfo> asyncCallbackInfo =
953         new (std::nothrow) AsyncCallbackInfo(env, CREATE_ROTATION_MATRIX);
954     CHKPP(asyncCallbackInfo);
955     std::vector<float> rotationMatrix(THREE_DIMENSIONAL_MATRIX_LENGTH);
956     SensorAlgorithm sensorAlgorithm;
957     int32_t ret = sensorAlgorithm.CreateRotationMatrix(rotationVector, rotationMatrix);
958     if (ret != OHOS::ERR_OK) {
959         ThrowErr(env, ret, "Create rotation matrix fail");
960         return nullptr;
961     } else {
962         asyncCallbackInfo->data.reserveData.length = THREE_DIMENSIONAL_MATRIX_LENGTH;
963         for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) {
964             asyncCallbackInfo->data.reserveData.reserve[i] = rotationMatrix[i];
965         }
966     }
967     if (argc >= 2 && IsMatchType(env, args[1], napi_function)) {
968         return EmitAsyncWork(args[1], asyncCallbackInfo);
969     }
970     return EmitAsyncWork(nullptr, asyncCallbackInfo);
971 }
972 
CreateRotationMatrix(napi_env env,napi_callback_info info)973 static napi_value CreateRotationMatrix(napi_env env, napi_callback_info info)
974 {
975     CALL_LOG_ENTER;
976     size_t argc = 3;
977     napi_value args[3] = { 0 };
978     napi_value thisVar = nullptr;
979     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
980     if (status != napi_ok || argc < 1) {
981         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
982         return nullptr;
983     }
984     if (!IsMatchArrayType(env, args[0])) {
985         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be array");
986         return nullptr;
987     }
988     if (argc >= 2 && IsMatchArrayType(env, args[1])) {
989         return CreateRotationAndInclination(env, args, argc);
990     } else {
991         return GetRotationMatrix(env, args, argc);
992     }
993 }
994 
GetSensorList(napi_env env,napi_callback_info info)995 static napi_value GetSensorList(napi_env env, napi_callback_info info)
996 {
997     CALL_LOG_ENTER;
998     size_t argc = 1;
999     napi_value args[1] = { 0 };
1000     napi_value thisVar = nullptr;
1001     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
1002     if (status != napi_ok) {
1003         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail");
1004         return nullptr;
1005     }
1006     sptr<AsyncCallbackInfo> asyncCallbackInfo =
1007         new (std::nothrow) AsyncCallbackInfo(env, GET_SENSOR_LIST);
1008     CHKPP(asyncCallbackInfo);
1009     SensorInfo *sensorInfos = nullptr;
1010     int32_t count = 0;
1011     int32_t ret = GetAllSensors(&sensorInfos, &count);
1012     if (ret != OHOS::ERR_OK) {
1013         SEN_HILOGE("Get sensor list fail");
1014         asyncCallbackInfo->type = FAIL;
1015         asyncCallbackInfo->error.code = ret;
1016     } else {
1017         for (int32_t i = 0; i < count; ++i) {
1018             if ((sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_AMBIENT_LIGHT1) ||
1019                 (sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_PROXIMITY1)) {
1020                 SEN_HILOGD("This sensor is secondary ambient light");
1021                 continue;
1022             }
1023             asyncCallbackInfo->sensorInfos.push_back(*(sensorInfos + i));
1024         }
1025     }
1026     if (argc >= 1 && IsMatchType(env, args[0], napi_function)) {
1027         return EmitAsyncWork(args[0], asyncCallbackInfo);
1028     }
1029     return EmitAsyncWork(nullptr, asyncCallbackInfo);
1030 }
1031 
GetSensorListSync(napi_env env,napi_callback_info info)1032 static napi_value GetSensorListSync(napi_env env, napi_callback_info info)
1033 {
1034     CALL_LOG_ENTER;
1035     size_t argc = 0;
1036     napi_value result = nullptr;
1037     napi_get_undefined(env, &result);
1038     napi_value thisVar = nullptr;
1039     napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1040     if (status != napi_ok) {
1041         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail");
1042         return result;
1043     }
1044     SensorInfo *sensorInfos = nullptr;
1045     int32_t count = 0;
1046     int32_t ret = GetAllSensors(&sensorInfos, &count);
1047     if (ret != OHOS::ERR_OK) {
1048         ThrowErr(env, ret, "Get sensor list fail");
1049         return result;
1050     }
1051     vector<SensorInfo> sensorInfoVec;
1052     for (int32_t i = 0; i < count; ++i) {
1053         if ((sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_AMBIENT_LIGHT1) ||
1054             (sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_PROXIMITY1)) {
1055             SEN_HILOGD("This sensor is secondary ambient light");
1056             continue;
1057         }
1058         sensorInfoVec.push_back(*(sensorInfos + i));
1059     }
1060     if (napi_create_array(env, &result) != napi_ok) {
1061         ThrowErr(env, PARAMETER_ERROR, "napi_create_array fail");
1062         return result;
1063     }
1064     for (uint32_t i = 0; i < sensorInfoVec.size(); ++i) {
1065         napi_value value = nullptr;
1066         if (!ConvertToSensorInfo(env, sensorInfoVec[i], value)) {
1067             ThrowErr(env, PARAMETER_ERROR, "Convert sensor info fail");
1068             return result;
1069         }
1070         if (napi_set_element(env, result, i, value) != napi_ok) {
1071             ThrowErr(env, PARAMETER_ERROR, "napi_set_element fail");
1072         }
1073     }
1074     return result;
1075 }
1076 
GetSingleSensor(napi_env env,napi_callback_info info)1077 static napi_value GetSingleSensor(napi_env env, napi_callback_info info)
1078 {
1079     CALL_LOG_ENTER;
1080     size_t argc = 2;
1081     napi_value args[2] = { 0 };
1082     napi_value thisVar = nullptr;
1083     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
1084     if (status != napi_ok || argc < 1) {
1085         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
1086         return nullptr;
1087     }
1088     int32_t sensorTypeId = INVALID_SENSOR_ID;
1089     if (!GetNativeInt32(env, args[0], sensorTypeId)) {
1090         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get number fail");
1091         return nullptr;
1092     }
1093     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_SINGLE_SENSOR);
1094     CHKPP(asyncCallbackInfo);
1095     SensorInfo *sensorInfos = nullptr;
1096     int32_t count = 0;
1097     int32_t ret = GetAllSensors(&sensorInfos, &count);
1098     if (ret != OHOS::ERR_OK) {
1099         SEN_HILOGE("Get sensor list fail");
1100         asyncCallbackInfo->type = FAIL;
1101         asyncCallbackInfo->error.code = ret;
1102     } else {
1103         for (int32_t i = 0; i < count; ++i) {
1104             if ((sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_AMBIENT_LIGHT1) ||
1105                 (sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_PROXIMITY1)) {
1106                 SEN_HILOGD("This sensor is secondary ambient light");
1107                 continue;
1108             }
1109             if (sensorInfos[i].sensorTypeId == sensorTypeId) {
1110                 asyncCallbackInfo->sensorInfos.push_back(*(sensorInfos + i));
1111                 break;
1112             }
1113         }
1114         if (asyncCallbackInfo->sensorInfos.empty()) {
1115             uint32_t targetVersion = 0;
1116             if (GetSelfTargetVersion(targetVersion) && (targetVersion < COMPATIBILITY_CHANGE_VERSION_API12)) {
1117                 ThrowErr(env, PARAMETER_ERROR, "The sensor is not supported by the device");
1118                 return nullptr;
1119             }
1120             ThrowErr(env, SENSOR_NO_SUPPORT, "The sensor is not supported by the device");
1121             return nullptr;
1122         }
1123     }
1124     if (argc >= 2 && IsMatchType(env, args[1], napi_function)) {
1125         return EmitAsyncWork(args[1], asyncCallbackInfo);
1126     }
1127     return EmitAsyncWork(nullptr, asyncCallbackInfo);
1128 }
1129 
GetSingleSensorSync(napi_env env,napi_callback_info info)1130 static napi_value GetSingleSensorSync(napi_env env, napi_callback_info info)
1131 {
1132     CALL_LOG_ENTER;
1133     size_t argc = 1;
1134     napi_value args[1] = { 0 };
1135     napi_value result = nullptr;
1136     napi_get_undefined(env, &result);
1137     napi_value thisVar = nullptr;
1138     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
1139     if (status != napi_ok) {
1140         ThrowErr(env, PARAMETER_ERROR, "Get the parameter info fail");
1141         return result;
1142     }
1143     if (argc == 0) {
1144         ThrowErr(env, PARAMETER_ERROR, "Number of parameter invalid");
1145         return result;
1146     }
1147     int32_t sensorTypeId = INVALID_SENSOR_ID;
1148     if (!GetNativeInt32(env, args[0], sensorTypeId)) {
1149         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, get number fail");
1150         return result;
1151     }
1152     SensorInfo *sensorInfos = nullptr;
1153     int32_t count = 0;
1154     int32_t ret = GetAllSensors(&sensorInfos, &count);
1155     if (ret != OHOS::ERR_OK) {
1156         ThrowErr(env, ret, "Get sensor list fail");
1157         return result;
1158     }
1159     vector<SensorInfo> sensorInfoVec;
1160     for (int32_t i = 0; i < count; ++i) {
1161         if ((sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_AMBIENT_LIGHT1) ||
1162             (sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_PROXIMITY1)) {
1163             SEN_HILOGD("This sensor is secondary ambient light");
1164             continue;
1165         }
1166         if (sensorInfos[i].sensorTypeId == sensorTypeId) {
1167             sensorInfoVec.push_back(*(sensorInfos + i));
1168             break;
1169         }
1170     }
1171     if (sensorInfoVec.empty()) {
1172         ThrowErr(env, SENSOR_NO_SUPPORT, "The sensor is not supported by the device");
1173         return result;
1174     }
1175     if (!ConvertToSensorInfo(env, sensorInfoVec[0], result)) {
1176         ThrowErr(env, PARAMETER_ERROR, "Convert sensor info fail");
1177     }
1178     return result;
1179 }
1180 
Subscribe(napi_env env,napi_callback_info info,int32_t sensorTypeId,CallbackDataType type)1181 napi_value Subscribe(napi_env env, napi_callback_info info, int32_t sensorTypeId, CallbackDataType type)
1182 {
1183     CALL_LOG_ENTER;
1184     size_t argc = 1;
1185     napi_value args[1] = { 0 };
1186     napi_value thisVar = nullptr;
1187     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
1188     if (status != napi_ok || argc < 1) {
1189         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
1190         return nullptr;
1191     }
1192     if (!IsMatchType(env, args[0], napi_object)) {
1193         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be object");
1194         return nullptr;
1195     }
1196     string interval = "normal";
1197     if ((sensorTypeId == SENSOR_TYPE_ID_ACCELEROMETER) ||
1198         ((sensorTypeId == SENSOR_TYPE_ID_ORIENTATION) && (type != SUBSCRIBE_COMPASS))
1199         || (sensorTypeId == SENSOR_TYPE_ID_GYROSCOPE)) {
1200         napi_value napiInterval = GetNamedProperty(env, args[0], "interval");
1201         CHKCP(GetStringValue(env, napiInterval, interval), "get interval fail");
1202     }
1203     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, type);
1204     CHKPP(asyncCallbackInfo);
1205     napi_value napiSuccess = GetNamedProperty(env, args[0], "success");
1206     CHKCP(IsMatchType(env, napiSuccess, napi_function), "get napiSuccess fail");
1207     CHKCP(RegisterNapiCallback(env, napiSuccess, asyncCallbackInfo->callback[0]), "register success callback fail");
1208     napi_value napiFail = GetNamedProperty(env, args[0], "fail");
1209     if (IsMatchType(env, napiFail, napi_function)) {
1210         SEN_HILOGD("Has fail callback");
1211         CHKCP(RegisterNapiCallback(env, napiFail, asyncCallbackInfo->callback[1]), "register fail callback fail");
1212     }
1213     if (auto iter = g_samplingPeriod.find(interval); iter == g_samplingPeriod.end()) {
1214         CHKCP(IsMatchType(env, napiFail, napi_function), "input error, interval is invalid");
1215         CreateFailMessage(SUBSCRIBE_FAIL, INPUT_ERROR, "input error", asyncCallbackInfo);
1216         EmitAsyncCallbackWork(asyncCallbackInfo);
1217         return nullptr;
1218     }
1219     int32_t ret = SubscribeSensor(sensorTypeId, g_samplingPeriod[interval], DataCallbackImpl);
1220     if (ret != OHOS::ERR_OK) {
1221         CHKCP(IsMatchType(env, napiFail, napi_function), "subscribe fail");
1222         CreateFailMessage(SUBSCRIBE_FAIL, SENSOR_SUBSCRIBE_FAILURE, "subscribe fail", asyncCallbackInfo);
1223         EmitAsyncCallbackWork(asyncCallbackInfo);
1224         return nullptr;
1225     }
1226     std::lock_guard<std::mutex> subscribeLock(g_mutex);
1227     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_subscribeCallbacks[sensorTypeId];
1228     callbackInfos.push_back(asyncCallbackInfo);
1229     g_subscribeCallbacks[sensorTypeId] = callbackInfos;
1230     return nullptr;
1231 }
1232 
RemoveSubscribeCallback(napi_env env,int32_t sensorTypeId)1233 static bool RemoveSubscribeCallback(napi_env env, int32_t sensorTypeId)
1234 {
1235     CALL_LOG_ENTER;
1236     std::lock_guard<std::mutex> subscribeCallbackLock(g_mutex);
1237     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_subscribeCallbacks[sensorTypeId];
1238     for (auto iter = callbackInfos.begin(); iter != callbackInfos.end();) {
1239         CHKPC(*iter);
1240         if ((*iter)->env != env) {
1241             ++iter;
1242             continue;
1243         }
1244         iter = callbackInfos.erase(iter);
1245     }
1246     if (callbackInfos.empty()) {
1247         g_subscribeCallbacks.erase(sensorTypeId);
1248         return true;
1249     }
1250     return false;
1251 }
1252 
Unsubscribe(napi_env env,napi_callback_info info,int32_t sensorTypeId)1253 napi_value Unsubscribe(napi_env env, napi_callback_info info, int32_t sensorTypeId)
1254 {
1255     CALL_LOG_ENTER;
1256     size_t argc = 1;
1257     napi_value args[1] = { 0 };
1258     napi_value thisVar = nullptr;
1259     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
1260     if (status != napi_ok) {
1261         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail");
1262         return nullptr;
1263     }
1264     if (!RemoveSubscribeCallback(env, sensorTypeId) || CheckSubscribe(sensorTypeId)) {
1265         SEN_HILOGW("There are other client subscribe as well, not need unsubscribe");
1266         return nullptr;
1267     }
1268     if (UnsubscribeSensor(sensorTypeId) != OHOS::ERR_OK) {
1269         SEN_HILOGW("UnsubscribeSensor failed");
1270         return nullptr;
1271     }
1272     return nullptr;
1273 }
1274 
GetBodyState(napi_env env,napi_callback_info info)1275 napi_value GetBodyState(napi_env env, napi_callback_info info)
1276 {
1277     CALL_LOG_ENTER;
1278     size_t argc = 1;
1279     napi_value args[1] = { 0 };
1280     napi_value thisVar = nullptr;
1281     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr);
1282     if (status != napi_ok || argc < 1) {
1283         ThrowErr(env, PARAMETER_ERROR, "napi_get_cb_info fail or number of parameter invalid");
1284         return nullptr;
1285     }
1286     if (!IsMatchType(env, args[0], napi_object)) {
1287         ThrowErr(env, PARAMETER_ERROR, "Wrong argument type, should be object");
1288         return nullptr;
1289     }
1290     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_BODY_STATE);
1291     CHKPP(asyncCallbackInfo);
1292     napi_value napiSuccess = GetNamedProperty(env, args[0], "success");
1293     CHKCP(IsMatchType(env, napiSuccess, napi_function), "get napiSuccess fail");
1294     CHKCP(RegisterNapiCallback(env, napiSuccess, asyncCallbackInfo->callback[0]),
1295         "register success callback fail");
1296     std::lock_guard<std::mutex> onBodyLock(g_bodyMutex);
1297     asyncCallbackInfo->data.sensorData.data[0] =
1298         (fabs(g_bodyState - BODY_STATE_EXCEPT) < THRESHOLD) ? true : false;
1299     EmitUvEventLoop(asyncCallbackInfo);
1300     return nullptr;
1301 }
1302 
EnumClassConstructor(napi_env env,napi_callback_info info)1303 static napi_value EnumClassConstructor(napi_env env, napi_callback_info info)
1304 {
1305     size_t argc = 0;
1306     napi_value args[1] = {0};
1307     napi_value ret = nullptr;
1308     void *data = nullptr;
1309     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &ret, &data), "napi_get_cb_info");
1310     return ret;
1311 }
1312 
CreateEnumSensorType(napi_env env,napi_value exports)1313 static napi_value CreateEnumSensorType(napi_env env, napi_value exports)
1314 {
1315     napi_property_descriptor desc[] = {
1316         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ACCELEROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER)),
1317         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GYROSCOPE", GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE)),
1318         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_AMBIENT_LIGHT", GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_LIGHT)),
1319         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_MAGNETIC_FIELD", GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD)),
1320         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_BAROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_BAROMETER)),
1321         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HALL", GetNapiInt32(env, SENSOR_TYPE_ID_HALL)),
1322         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_TEMPERATURE", GetNapiInt32(env, SENSOR_TYPE_ID_TEMPERATURE)),
1323         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PROXIMITY", GetNapiInt32(env, SENSOR_TYPE_ID_PROXIMITY)),
1324         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HUMIDITY", GetNapiInt32(env, SENSOR_TYPE_ID_HUMIDITY)),
1325         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_COLOR", GetNapiInt32(env, SENSOR_TYPE_ID_COLOR)),
1326         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_SAR", GetNapiInt32(env, SENSOR_TYPE_ID_SAR)),
1327         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ORIENTATION", GetNapiInt32(env, SENSOR_TYPE_ID_ORIENTATION)),
1328         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GRAVITY", GetNapiInt32(env, SENSOR_TYPE_ID_GRAVITY)),
1329         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_LINEAR_ACCELERATION",
1330             GetNapiInt32(env, SENSOR_TYPE_ID_LINEAR_ACCELERATION)),
1331         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ROTATION_VECTOR",
1332             GetNapiInt32(env, SENSOR_TYPE_ID_ROTATION_VECTOR)),
1333         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_AMBIENT_TEMPERATURE",
1334             GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_TEMPERATURE)),
1335         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED",
1336             GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED)),
1337         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED",
1338             GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED)),
1339         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_SIGNIFICANT_MOTION",
1340             GetNapiInt32(env, SENSOR_TYPE_ID_SIGNIFICANT_MOTION)),
1341         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PEDOMETER_DETECTION",
1342             GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER_DETECTION)),
1343         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PEDOMETER", GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER)),
1344         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HEART_RATE", GetNapiInt32(env, SENSOR_TYPE_ID_HEART_RATE)),
1345         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_WEAR_DETECTION", GetNapiInt32(env, SENSOR_TYPE_ID_WEAR_DETECTION)),
1346         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED",
1347             GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED)),
1348     };
1349     napi_value result = nullptr;
1350     CHKNRP(env, napi_define_class(env, "SensorType", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
1351         sizeof(desc) / sizeof(*desc), desc, &result), "napi_define_class");
1352     CHKNRP(env, napi_set_named_property(env, exports, "SensorType", result), "napi_set_named_property fail");
1353     return exports;
1354 }
1355 
CreateEnumSensorId(napi_env env,napi_value exports)1356 static napi_value CreateEnumSensorId(napi_env env, napi_value exports)
1357 {
1358     napi_property_descriptor desc[] = {
1359         DECLARE_NAPI_STATIC_PROPERTY("ACCELEROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER)),
1360         DECLARE_NAPI_STATIC_PROPERTY("GYROSCOPE", GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE)),
1361         DECLARE_NAPI_STATIC_PROPERTY("AMBIENT_LIGHT", GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_LIGHT)),
1362         DECLARE_NAPI_STATIC_PROPERTY("MAGNETIC_FIELD", GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD)),
1363         DECLARE_NAPI_STATIC_PROPERTY("BAROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_BAROMETER)),
1364         DECLARE_NAPI_STATIC_PROPERTY("HALL", GetNapiInt32(env, SENSOR_TYPE_ID_HALL)),
1365         DECLARE_NAPI_STATIC_PROPERTY("TEMPERATURE", GetNapiInt32(env, SENSOR_TYPE_ID_TEMPERATURE)),
1366         DECLARE_NAPI_STATIC_PROPERTY("PROXIMITY", GetNapiInt32(env, SENSOR_TYPE_ID_PROXIMITY)),
1367         DECLARE_NAPI_STATIC_PROPERTY("HUMIDITY", GetNapiInt32(env, SENSOR_TYPE_ID_HUMIDITY)),
1368         DECLARE_NAPI_STATIC_PROPERTY("COLOR", GetNapiInt32(env, SENSOR_TYPE_ID_COLOR)),
1369         DECLARE_NAPI_STATIC_PROPERTY("SAR", GetNapiInt32(env, SENSOR_TYPE_ID_SAR)),
1370         DECLARE_NAPI_STATIC_PROPERTY("ORIENTATION", GetNapiInt32(env, SENSOR_TYPE_ID_ORIENTATION)),
1371         DECLARE_NAPI_STATIC_PROPERTY("GRAVITY", GetNapiInt32(env, SENSOR_TYPE_ID_GRAVITY)),
1372         DECLARE_NAPI_STATIC_PROPERTY("LINEAR_ACCELEROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_LINEAR_ACCELERATION)),
1373         DECLARE_NAPI_STATIC_PROPERTY("ROTATION_VECTOR", GetNapiInt32(env, SENSOR_TYPE_ID_ROTATION_VECTOR)),
1374         DECLARE_NAPI_STATIC_PROPERTY("AMBIENT_TEMPERATURE", GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_TEMPERATURE)),
1375         DECLARE_NAPI_STATIC_PROPERTY("MAGNETIC_FIELD_UNCALIBRATED",
1376             GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED)),
1377         DECLARE_NAPI_STATIC_PROPERTY("GYROSCOPE_UNCALIBRATED",
1378             GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED)),
1379         DECLARE_NAPI_STATIC_PROPERTY("SIGNIFICANT_MOTION", GetNapiInt32(env, SENSOR_TYPE_ID_SIGNIFICANT_MOTION)),
1380         DECLARE_NAPI_STATIC_PROPERTY("PEDOMETER_DETECTION", GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER_DETECTION)),
1381         DECLARE_NAPI_STATIC_PROPERTY("PEDOMETER", GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER)),
1382         DECLARE_NAPI_STATIC_PROPERTY("HEART_RATE", GetNapiInt32(env, SENSOR_TYPE_ID_HEART_RATE)),
1383         DECLARE_NAPI_STATIC_PROPERTY("WEAR_DETECTION", GetNapiInt32(env, SENSOR_TYPE_ID_WEAR_DETECTION)),
1384         DECLARE_NAPI_STATIC_PROPERTY("ACCELEROMETER_UNCALIBRATED",
1385             GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED)),
1386     };
1387     napi_value result = nullptr;
1388     CHKNRP(env, napi_define_class(env, "SensorId", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
1389         sizeof(desc) / sizeof(*desc), desc, &result), "napi_define_class");
1390     CHKNRP(env, napi_set_named_property(env, exports, "SensorId", result), "napi_set_named_property fail");
1391     return exports;
1392 }
1393 
CreateEnumSensorAccuracy(napi_env env,napi_value exports)1394 static napi_value CreateEnumSensorAccuracy(napi_env env, napi_value exports)
1395 {
1396     napi_property_descriptor desc[] = {
1397         DECLARE_NAPI_STATIC_PROPERTY("ACCURACY_UNRELIABLE", GetNapiInt32(env, ACCURACY_UNRELIABLE)),
1398         DECLARE_NAPI_STATIC_PROPERTY("ACCURACY_LOW", GetNapiInt32(env, ACCURACY_LOW)),
1399         DECLARE_NAPI_STATIC_PROPERTY("ACCURACY_MEDIUM", GetNapiInt32(env, ACCURACY_MEDIUM)),
1400         DECLARE_NAPI_STATIC_PROPERTY("ACCURACY_HIGH", GetNapiInt32(env, ACCURACY_HIGH)),
1401     };
1402     napi_value result = nullptr;
1403     CHKNRP(env, napi_define_class(env, "SensorAccuracy", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
1404         sizeof(desc) / sizeof(*desc), desc, &result), "napi_define_class");
1405     CHKNRP(env, napi_set_named_property(env, exports, "SensorAccuracy", result), "napi_set_named_property fail");
1406     return exports;
1407 }
1408 
Init(napi_env env,napi_value exports)1409 static napi_value Init(napi_env env, napi_value exports)
1410 {
1411     napi_property_descriptor desc[] = {
1412         DECLARE_NAPI_FUNCTION("on", On),
1413         DECLARE_NAPI_FUNCTION("once", Once),
1414         DECLARE_NAPI_FUNCTION("off", Off),
1415         DECLARE_NAPI_FUNCTION("getGeomagneticField", GetGeomagneticField),
1416         DECLARE_NAPI_FUNCTION("getGeomagneticInfo", GetGeomagneticField),
1417         DECLARE_NAPI_FUNCTION("transformCoordinateSystem", TransformCoordinateSystem),
1418         DECLARE_NAPI_FUNCTION("transformRotationMatrix", TransformCoordinateSystem),
1419         DECLARE_NAPI_FUNCTION("getAngleModify", GetAngleModify),
1420         DECLARE_NAPI_FUNCTION("getAngleVariation", GetAngleModify),
1421         DECLARE_NAPI_FUNCTION("getDirection", GetDirection),
1422         DECLARE_NAPI_FUNCTION("getOrientation", GetDirection),
1423         DECLARE_NAPI_FUNCTION("createQuaternion", CreateQuaternion),
1424         DECLARE_NAPI_FUNCTION("getQuaternion", CreateQuaternion),
1425         DECLARE_NAPI_FUNCTION("getAltitude", GetAltitude),
1426         DECLARE_NAPI_FUNCTION("getDeviceAltitude", GetAltitude),
1427         DECLARE_NAPI_FUNCTION("getGeomagneticDip", GetGeomagneticDip),
1428         DECLARE_NAPI_FUNCTION("getInclination", GetGeomagneticDip),
1429         DECLARE_NAPI_FUNCTION("createRotationMatrix", CreateRotationMatrix),
1430         DECLARE_NAPI_FUNCTION("getRotationMatrix", CreateRotationMatrix),
1431         DECLARE_NAPI_FUNCTION("getSensorList", GetSensorList),
1432         DECLARE_NAPI_FUNCTION("getSensorListSync", GetSensorListSync),
1433         DECLARE_NAPI_FUNCTION("getSingleSensor", GetSingleSensor),
1434         DECLARE_NAPI_FUNCTION("getSingleSensorSync", GetSingleSensorSync),
1435         DECLARE_NAPI_FUNCTION("subscribeAccelerometer", SubscribeAccelerometer),
1436         DECLARE_NAPI_FUNCTION("unsubscribeAccelerometer", UnsubscribeAccelerometer),
1437         DECLARE_NAPI_FUNCTION("subscribeCompass", SubscribeCompass),
1438         DECLARE_NAPI_FUNCTION("unsubscribeCompass", UnsubscribeCompass),
1439         DECLARE_NAPI_FUNCTION("subscribeProximity", SubscribeProximity),
1440         DECLARE_NAPI_FUNCTION("unsubscribeProximity", UnsubscribeProximity),
1441         DECLARE_NAPI_FUNCTION("subscribeLight", SubscribeLight),
1442         DECLARE_NAPI_FUNCTION("unsubscribeLight", UnsubscribeLight),
1443         DECLARE_NAPI_FUNCTION("subscribeStepCounter", SubscribeStepCounter),
1444         DECLARE_NAPI_FUNCTION("unsubscribeStepCounter", UnsubscribeStepCounter),
1445         DECLARE_NAPI_FUNCTION("subscribeBarometer", SubscribeBarometer),
1446         DECLARE_NAPI_FUNCTION("unsubscribeBarometer", UnsubscribeBarometer),
1447         DECLARE_NAPI_FUNCTION("subscribeHeartRate", SubscribeHeartRate),
1448         DECLARE_NAPI_FUNCTION("unsubscribeHeartRate", UnsubscribeHeartRate),
1449         DECLARE_NAPI_FUNCTION("subscribeOnBodyState", SubscribeOnBodyState),
1450         DECLARE_NAPI_FUNCTION("unsubscribeOnBodyState", UnsubscribeOnBodyState),
1451         DECLARE_NAPI_FUNCTION("getOnBodyState", GetOnBodyState),
1452         DECLARE_NAPI_FUNCTION("subscribeDeviceOrientation", SubscribeDeviceOrientation),
1453         DECLARE_NAPI_FUNCTION("unsubscribeDeviceOrientation", UnsubscribeDeviceOrientation),
1454         DECLARE_NAPI_FUNCTION("subscribeGyroscope", SubscribeGyroscope),
1455         DECLARE_NAPI_FUNCTION("unsubscribeGyroscope", UnsubscribeGyroscope),
1456         DECLARE_NAPI_FUNCTION("subscribeGravity", SubscribeGravity),
1457         DECLARE_NAPI_FUNCTION("unsubscribeGravity", UnsubscribeGravity),
1458         DECLARE_NAPI_FUNCTION("subscribeMagnetic", SubscribeMagnetic),
1459         DECLARE_NAPI_FUNCTION("unsubscribeMagnetic", UnsubscribeMagnetic),
1460         DECLARE_NAPI_FUNCTION("subscribeHall", SubscribeHall),
1461         DECLARE_NAPI_FUNCTION("unsubscribeHall", UnsubscribeHall),
1462     };
1463     CHKNRP(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc),
1464         "napi_define_properties");
1465     CHKCP(CreateEnumSensorType(env, exports), "Create enum sensor type fail");
1466     CHKCP(CreateEnumSensorId(env, exports), "Create enum sensor id fail");
1467     CHKCP(CreateEnumSensorAccuracy(env, exports), "Create enum sensor accuracy fail");
1468     // 注册env清理钩子函数
1469     napi_env *pEnv = new (std::nothrow) napi_env;
1470     if (pEnv == nullptr) {
1471         SEN_HILOGE("Init, pEnv is nullptr");
1472         return exports;
1473     }
1474     *pEnv = env;
1475     auto ret = napi_add_env_cleanup_hook(env, CleanUp, reinterpret_cast<void*>(pEnv));
1476     if (ret != napi_status::napi_ok) {
1477         SEN_HILOGE("Init, napi_add_env_cleanup_hook failed");
1478     }
1479 
1480     return exports;
1481 }
1482 
1483 static napi_module _module = {
1484     .nm_version = 1,
1485     .nm_flags = 0,
1486     .nm_filename = nullptr,
1487     .nm_register_func = Init,
1488     .nm_modname = "sensor",
1489     .nm_priv = ((void *)0),
1490     .reserved = {0}
1491 };
1492 
RegisterModule(void)1493 extern "C" __attribute__((constructor)) void RegisterModule(void)
1494 {
1495     napi_module_register(&_module);
1496 }
1497 } // namespace Sensors
1498 } // namespace OHOS