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