• 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 <cinttypes>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <map>
22 #include <memory.h>
23 #include <pthread.h>
24 #include <string>
25 #include <thread>
26 #include <unistd.h>
27 
28 #include "geomagnetic_field.h"
29 #include "refbase.h"
30 #include "securec.h"
31 #include "sensor_algorithm.h"
32 #include "sensor_napi_utils.h"
33 #include "sensor_system_js.h"
34 namespace OHOS {
35 namespace Sensors {
36 namespace {
37 constexpr int32_t QUATERNION_LENGTH = 4;
38 constexpr int32_t ROTATION_VECTOR_LENGTH = 3;
39 constexpr int32_t REPORTING_INTERVAL = 200000000;
40 constexpr int32_t INVALID_SENSOR_ID = -1;
41 constexpr int32_t SENSOR_SUBSCRIBE_FAILURE = 1001;
42 constexpr int32_t INPUT_ERROR = 202;
43 constexpr float BODY_STATE_EXCEPT = 1.0f;
44 constexpr float THREESHOLD = 0.000001f;
45 }
46 static std::map<std::string, int64_t> g_samplingPeriod = {
47     {"normal", 200000000},
48     {"ui", 60000000},
49     {"game", 20000000},
50 };
51 static std::mutex mutex_;
52 static std::mutex bodyMutex_;
53 static float g_bodyState = -1.0f;
54 static std::map<int32_t, sptr<AsyncCallbackInfo>> g_subscribeCallbacks;
55 static std::mutex onMutex_;
56 static std::mutex 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(onMutex_);
63     auto iter = g_onCallbackInfos.find(sensorTypeId);
64     CHKCF((iter != g_onCallbackInfos.end()), "No client subscribe");
65     return true;
66 }
67 
copySensorData(sptr<AsyncCallbackInfo> callbackInfo,SensorEvent * event)68 static bool copySensorData(sptr<AsyncCallbackInfo> callbackInfo, SensorEvent *event)
69 {
70     CHKPF(callbackInfo);
71     CHKPF(event);
72     int32_t sensorTypeId = event->sensorTypeId;
73     callbackInfo->data.sensorData.sensorTypeId = sensorTypeId;
74     callbackInfo->data.sensorData.dataLength = event->dataLen;
75     callbackInfo->data.sensorData.timestamp = event->timestamp;
76     auto data = reinterpret_cast<float *>(event->data);
77     if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && callbackInfo->type == SUBSCRIBE_CALLBACK) {
78         std::lock_guard<std::mutex> onBodyLock(bodyMutex_);
79         g_bodyState = *data;
80         callbackInfo->data.sensorData.data[0] =
81             (fabs(g_bodyState - BODY_STATE_EXCEPT) < THREESHOLD) ? true : false;
82         return true;
83     }
84     CHKPF(data);
85     if (memcpy_s(callbackInfo->data.sensorData.data, event->dataLen, data, event->dataLen) != EOK) {
86         SEN_HILOGE("Copy data failed");
87         return false;
88     }
89     return true;
90 }
91 
CheckSystemSubscribe(int32_t sensorTypeId)92 static bool CheckSystemSubscribe(int32_t sensorTypeId)
93 {
94     std::lock_guard<std::mutex> subscribeLock(mutex_);
95     auto iter = g_subscribeCallbacks.find(sensorTypeId);
96     CHKCF((iter != g_subscribeCallbacks.end()), "No client subscribe");
97     return true;
98 }
99 
EmitSubscribeCallback(SensorEvent * event)100 static void EmitSubscribeCallback(SensorEvent *event)
101 {
102     CHKPV(event);
103     int32_t sensorTypeId = event->sensorTypeId;
104     CHKCV(CheckSystemSubscribe(sensorTypeId), "No client subscribe");
105 
106     std::lock_guard<std::mutex> subscribeLock(mutex_);
107     auto callback = g_subscribeCallbacks[sensorTypeId];
108     CHKCV(copySensorData(callback, event), "Copy sensor data failed");
109     EmitUvEventLoop(callback);
110 }
111 
EmitOnCallback(SensorEvent * event)112 static void EmitOnCallback(SensorEvent *event)
113 {
114     CHKPV(event);
115     int32_t sensorTypeId = event->sensorTypeId;
116     CHKCV(CheckSubscribe(sensorTypeId), "No client subscribe");
117 
118     std::lock_guard<std::mutex> onCallbackLock(onMutex_);
119     auto onCallbackInfos = g_onCallbackInfos[sensorTypeId];
120     for (auto &onCallbackInfo : onCallbackInfos) {
121         if (!copySensorData(onCallbackInfo, event)) {
122             SEN_HILOGE("Copy sensor data failed");
123             continue;
124         }
125         EmitUvEventLoop(onCallbackInfo);
126     }
127 }
128 
EmitOnceCallback(SensorEvent * event)129 static void EmitOnceCallback(SensorEvent *event)
130 {
131     CHKPV(event);
132     int32_t sensorTypeId = event->sensorTypeId;
133     std::lock_guard<std::mutex> onceCallbackLock(onceMutex_);
134     auto iter = g_onceCallbackInfos.find(sensorTypeId);
135     CHKCV((iter != g_onceCallbackInfos.end()), "No client subscribe once");
136 
137     auto onceCallbackInfos = g_onceCallbackInfos[sensorTypeId];
138     for (auto &onceCallbackInfo : onceCallbackInfos) {
139         if (!copySensorData(onceCallbackInfo, event)) {
140             SEN_HILOGE("Copy sensor data failed");
141             continue;
142         }
143         EmitUvEventLoop(onceCallbackInfo);
144     }
145     g_onceCallbackInfos[sensorTypeId].clear();
146     g_onceCallbackInfos.erase(sensorTypeId);
147 
148     CHKCV((!CheckSubscribe(sensorTypeId)), "Has client subscribe, not need cancel subscribe");
149     CHKCV((!CheckSystemSubscribe(sensorTypeId)), "Has client subscribe system api, not need cancel subscribe");
150     UnsubscribeSensor(sensorTypeId);
151 }
152 
DataCallbackImpl(SensorEvent * event)153 void DataCallbackImpl(SensorEvent *event)
154 {
155     CHKPV(event);
156     EmitOnCallback(event);
157     EmitSubscribeCallback(event);
158     EmitOnceCallback(event);
159 }
160 
161 const SensorUser user = {
162     .callback = DataCallbackImpl
163 };
164 
UnsubscribeSensor(int32_t sensorTypeId)165 bool UnsubscribeSensor(int32_t sensorTypeId)
166 {
167     CALL_LOG_ENTER;
168     CHKCF((DeactivateSensor(sensorTypeId, &user) == SUCCESS), "DeactivateSensor failed");
169     CHKCF((UnsubscribeSensor(sensorTypeId, &user) == SUCCESS), "UnsubscribeSensor failed");
170     return true;
171 }
172 
SubscribeSensor(int32_t sensorTypeId,int64_t interval,RecordSensorCallback callback)173 bool SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback)
174 {
175     CALL_LOG_ENTER;
176     CHKCF((SubscribeSensor(sensorTypeId, &user) == ERR_OK), "SubscribeSensor failed");
177     CHKCF((SetBatch(sensorTypeId, &user, interval, 0) == ERR_OK), "Set batch failed");
178     CHKCF((ActivateSensor(sensorTypeId, &user) == ERR_OK), "ActivateSensor failed");
179     return true;
180 }
181 
IsOnceSubscribed(napi_env env,int32_t sensorTypeId,napi_value callback)182 static bool IsOnceSubscribed(napi_env env, int32_t sensorTypeId, napi_value callback)
183 {
184     CALL_LOG_ENTER;
185     if (auto iter = g_onceCallbackInfos.find(sensorTypeId); iter == g_onceCallbackInfos.end()) {
186         SEN_HILOGW("already subscribed, sensorTypeId: %{public}d", sensorTypeId);
187         return false;
188     }
189 
190     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onceCallbackInfos[sensorTypeId];
191     for (auto callbackInfo : callbackInfos) {
192         CHKNCC(env, (callbackInfo != nullptr), "callbackInfo is null");
193         napi_value sensorCallback = nullptr;
194         CHKNRF(env, napi_get_reference_value(env, callbackInfo->callback[0], &sensorCallback),
195             "napi_get_reference_value");
196         if (IsSameValue(env, callback, sensorCallback)) {
197             return true;
198         }
199     }
200     return false;
201 }
202 
UpdateOnceCallback(napi_env env,int32_t sensorTypeId,napi_value callback)203 static void UpdateOnceCallback(napi_env env, int32_t sensorTypeId, napi_value callback)
204 {
205     CALL_LOG_ENTER;
206     std::lock_guard<std::mutex> onceCallbackLock(onceMutex_);
207     CHKNCV(env, !IsOnceSubscribed(env, sensorTypeId, callback), "The callback has been subscribed");
208 
209     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, ONCE_CALLBACK);
210     CHKPV(asyncCallbackInfo);
211     CHKNRV(env, napi_create_reference(env, callback, 1, &asyncCallbackInfo->callback[0]),
212         "napi_create_reference");
213     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onceCallbackInfos[sensorTypeId];
214     callbackInfos.push_back(asyncCallbackInfo);
215     g_onceCallbackInfos[sensorTypeId] = callbackInfos;
216 }
217 
Once(napi_env env,napi_callback_info info)218 static napi_value Once(napi_env env, napi_callback_info info)
219 {
220     CALL_LOG_ENTER;
221     size_t argc = 2;
222     napi_value args[2] = { 0 };
223     napi_value thisVar = nullptr;
224     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
225     CHKNCP(env, (argc == 2), "The number of parameters is not valid");
226     CHKNCP(env, IsMatchType(env, args[0], napi_number), "Wrong argument type, should be number");
227     CHKNCP(env, IsMatchType(env, args[1], napi_function), "Wrong argument type, should be function");
228     int32_t sensorTypeId = INVALID_SENSOR_ID;
229     CHKNCP(env, GetCppInt32(env, args[0], sensorTypeId), "Wrong argument type, get number fail");
230 
231     if (!CheckSubscribe(sensorTypeId)) {
232         SEN_HILOGD("No subscription to change sensor data, registration is required");
233         CHKNCP(env, SubscribeSensor(sensorTypeId, REPORTING_INTERVAL, DataCallbackImpl), "SubscribeSensor failed");
234     }
235     UpdateOnceCallback(env, sensorTypeId, args[1]);
236     return nullptr;
237 }
238 
IsSubscribed(napi_env env,int32_t sensorTypeId,napi_value callback)239 static bool IsSubscribed(napi_env env, int32_t sensorTypeId, napi_value callback)
240 {
241     CALL_LOG_ENTER;
242     if (auto iter = g_onCallbackInfos.find(sensorTypeId); iter == g_onCallbackInfos.end()) {
243         SEN_HILOGW("no client subscribe, sensorTypeId: %{public}d", sensorTypeId);
244         return false;
245     }
246     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId];
247     for (auto callbackInfo : callbackInfos) {
248         CHKNCC(env, (callbackInfo != nullptr), "callbackInfo is null");
249         napi_value sensorCallback = nullptr;
250         CHKNRF(env, napi_get_reference_value(env, callbackInfo->callback[0], &sensorCallback),
251             "napi_get_reference_value");
252         if (IsSameValue(env, callback, sensorCallback)) {
253             return true;
254         }
255     }
256     return false;
257 }
258 
UpdateCallbackInfos(napi_env env,int32_t sensorTypeId,napi_value callback)259 static void UpdateCallbackInfos(napi_env env, int32_t sensorTypeId, napi_value callback)
260 {
261     CALL_LOG_ENTER;
262     std::lock_guard<std::mutex> onCallbackLock(onMutex_);
263     CHKNCV(env, !IsSubscribed(env, sensorTypeId, callback), "This callback has been subscribed");
264     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, ON_CALLBACK);
265     CHKPV(asyncCallbackInfo);
266     CHKNRV(env, napi_create_reference(env, callback, 1, &asyncCallbackInfo->callback[0]),
267         "napi_create_reference");
268     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId];
269     callbackInfos.push_back(asyncCallbackInfo);
270     g_onCallbackInfos[sensorTypeId] = callbackInfos;
271 }
272 
On(napi_env env,napi_callback_info info)273 static napi_value On(napi_env env, napi_callback_info info)
274 {
275     CALL_LOG_ENTER;
276     size_t argc = 3;
277     napi_value args[3] = { 0 };
278     napi_value thisVar = nullptr;
279     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
280     CHKNCP(env, ((argc == 2) || (argc == 3)), "The number of parameters is not valid");
281     CHKNCP(env, IsMatchType(env, args[0], napi_number), "Wrong argument type, should be number");
282     CHKNCP(env, IsMatchType(env, args[1], napi_function), "Wrong argument type, should be function");
283 
284     int32_t sensorTypeId = INVALID_SENSOR_ID;
285     CHKNCP(env, GetCppInt32(env, args[0], sensorTypeId), "Wrong argument type, get number fail");
286     int64_t interval = REPORTING_INTERVAL;
287 
288     if (argc == 3) {
289         napi_value value = GetNamedProperty(env, args[2], "interval");
290         CHKNCP(env, IsMatchType(env, value, napi_number), "Wrong argument type, interval should be number");
291         CHKNCP(env, GetCppInt64(env, value, interval), "Wrong argument type, get INT64 number fail");
292         SEN_HILOGD("Interval is %{public}" PRId64, interval);
293     }
294     CHKNCP(env, SubscribeSensor(sensorTypeId, interval, DataCallbackImpl), "SubscribeSensor failed");
295     UpdateCallbackInfos(env, sensorTypeId, args[1]);
296     return nullptr;
297 }
298 
RemoveAllCallback(napi_env env,int32_t sensorTypeId)299 static void RemoveAllCallback(napi_env env, int32_t sensorTypeId)
300 {
301     CALL_LOG_ENTER;
302     std::lock_guard<std::mutex> onCallbackLock(onMutex_);
303     g_onCallbackInfos[sensorTypeId].clear();
304     g_onCallbackInfos.erase(sensorTypeId);
305 }
306 
RemoveCallback(napi_env env,int32_t sensorTypeId,napi_value callback)307 static uint32_t RemoveCallback(napi_env env, int32_t sensorTypeId, napi_value callback)
308 {
309     CALL_LOG_ENTER;
310     std::lock_guard<std::mutex> onCallbackLock(onMutex_);
311     std::vector<sptr<AsyncCallbackInfo>> callbackInfos = g_onCallbackInfos[sensorTypeId];
312     for (auto iter = callbackInfos.begin(); iter != callbackInfos.end(); ++iter) {
313         CHKPC(*iter);
314         napi_value sensorCallback = nullptr;
315         CHKNRC(env, napi_get_reference_value(env, (*iter)->callback[0], &sensorCallback),
316             "napi_get_reference_value");
317         if (IsSameValue(env, callback, sensorCallback)) {
318             callbackInfos.erase(iter++);
319             SEN_HILOGD("Remove callback success");
320             break;
321         }
322     }
323     if (callbackInfos.empty()) {
324         SEN_HILOGD("No subscription to change sensor data");
325         g_onCallbackInfos.erase(sensorTypeId);
326         return 0;
327     }
328     g_onCallbackInfos[sensorTypeId] = callbackInfos;
329     return callbackInfos.size();
330 }
331 
Off(napi_env env,napi_callback_info info)332 static napi_value Off(napi_env env, napi_callback_info info)
333 {
334     CALL_LOG_ENTER;
335     size_t argc = 2;
336     napi_value args[2] = { 0 };
337     napi_value thisVar = nullptr;
338     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
339     CHKNCP(env, ((argc == 1) || (argc == 2)), "The number of parameters is not valid");
340     CHKNCP(env, IsMatchType(env, args[0], napi_number), "Wrong argument type, should be number");
341     int32_t sensorTypeId = INVALID_SENSOR_ID;
342     CHKNCP(env, GetCppInt32(env, args[0], sensorTypeId), "Wrong argument type, get number fail");
343     CHKNCP(env, (CheckSubscribe(sensorTypeId)), "Should subscribe first");
344 
345     if (argc == 1) {
346         RemoveAllCallback(env, sensorTypeId);
347     } else {
348         CHKNCP(env, IsMatchType(env, args[1], napi_function), "Wrong argument type, should be function");
349         CHKNCP(env, (RemoveCallback(env, sensorTypeId, args[1]) == 0),
350             "There are other client subscribe as well, not need unsubscribe");
351     }
352     if (CheckSystemSubscribe(sensorTypeId)) {
353         SEN_HILOGW("There are other client subscribe system js api as well, not need unsubscribe");
354         return nullptr;
355     }
356     CHKNCP(env, UnsubscribeSensor(sensorTypeId), "UnsubscribeSensor failed");
357     return nullptr;
358 }
359 
GetGeomagneticField(napi_env env,napi_callback_info info)360 static napi_value GetGeomagneticField(napi_env env, napi_callback_info info)
361 {
362     CALL_LOG_ENTER;
363     size_t argc = 3;
364     napi_value args[3] = { 0 };
365     napi_value thisVar = nullptr;
366     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
367     CHKNCP(env, ((argc == 2) || (argc == 3)), "The number of parameters is not valid");
368     CHKNCP(env, IsMatchType(env, args[0], napi_object), "Wrong argument type, should be object");
369     CHKNCP(env, IsMatchType(env, args[1], napi_number), "Wrong argument type, should be number");
370 
371     napi_value napiLatitude = GetNamedProperty(env, args[0], "latitude");
372     CHKNCP(env, (napiLatitude != nullptr), "napiLatitude is null");
373     double latitude = 0;
374     CHKNCP(env, GetCppDouble(env, napiLatitude, latitude), "Get latitude fail");
375     napi_value napiLongitude = GetNamedProperty(env, args[0], "longitude");
376     CHKNCP(env, (napiLongitude != nullptr), "napiLongitude is null");
377     double longitude = 0;
378     CHKNCP(env, GetCppDouble(env, napiLongitude, longitude), "Get longitude fail");
379     napi_value napiAltitude = GetNamedProperty(env, args[0], "altitude");
380     CHKNCP(env, (napiAltitude != nullptr), "napiAltitude is null");
381     double altitude = 0;
382     CHKNCP(env, GetCppDouble(env, napiAltitude, altitude), "Get altitude fail");
383     int64_t timeMillis = 0;
384     CHKNCP(env, GetCppInt64(env, args[1], timeMillis), "Get timeMillis fail");
385 
386     GeomagneticField geomagneticField(latitude, longitude, altitude, timeMillis);
387     sptr<AsyncCallbackInfo> asyncCallbackInfo =
388         new (std::nothrow) AsyncCallbackInfo(env, GET_GEOMAGNETIC_FIELD);
389     CHKPP(asyncCallbackInfo);
390     asyncCallbackInfo->data.geomagneticData = {
391         .x = geomagneticField.ObtainX(),
392         .y = geomagneticField.ObtainY(),
393         .z = geomagneticField.ObtainZ(),
394         .geomagneticDip = geomagneticField.ObtainGeomagneticDip(),
395         .deflectionAngle = geomagneticField.ObtainDeflectionAngle(),
396         .levelIntensity = geomagneticField.ObtainLevelIntensity(),
397         .totalIntensity = geomagneticField.ObtainTotalIntensity(),
398     };
399 
400     if (argc == 2) {
401         napi_value promise = nullptr;
402         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
403             "napi_create_promise");
404         EmitPromiseWork(asyncCallbackInfo);
405         return promise;
406     }
407     CHKNCP(env, IsMatchType(env, args[2], napi_function), "Wrong argument type, should be function");
408     CHKNRP(env, napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]),
409         "napi_create_reference");
410     EmitAsyncCallbackWork(asyncCallbackInfo);
411     return nullptr;
412 }
413 
TransformCoordinateSystem(napi_env env,napi_callback_info info)414 static napi_value TransformCoordinateSystem(napi_env env, napi_callback_info info)
415 {
416     CALL_LOG_ENTER;
417     size_t argc = 3;
418     napi_value args[3]  = { 0 };
419     napi_value thisVar = nullptr;
420     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
421     CHKNCP(env, ((argc == 2) || (argc == 3)), "The number of parameters is not valid");
422     CHKNCP(env, IsMatchArrayType(env, args[0]), "Wrong argument type, should be array");
423     CHKNCP(env, IsMatchType(env, args[1], napi_object), "Wrong argument type, should be object");
424 
425     std::vector<float> inRotationVector;
426     CHKNCP(env, GetFloatArray(env, args[0], inRotationVector), "Wrong argument type, get inRotationVector fail");
427     napi_value napiAxisX = GetNamedProperty(env, args[1], "x");
428     CHKNCP(env, (napiAxisX != nullptr), "napiAxisX is null");
429     int32_t axisX = 0;
430     CHKNCP(env, GetCppInt32(env, napiAxisX, axisX), "Get axisY fail");
431     napi_value napiAxisY = GetNamedProperty(env, args[1], "y");
432     CHKNCP(env, (napiAxisY != nullptr), "napiAxisY is null");
433     int32_t axisY = 0;
434     CHKNCP(env, GetCppInt32(env, napiAxisY, axisY), "Get axisY fail");
435 
436     sptr<AsyncCallbackInfo> asyncCallbackInfo =
437         new (std::nothrow) AsyncCallbackInfo(env, TRANSFORM_COORDINATE_SYSTEM);
438     CHKPP(asyncCallbackInfo);
439     size_t length = inRotationVector.size();
440     std::vector<float> outRotationVector(length);
441     SensorAlgorithm sensorAlgorithm;
442     int32_t ret = sensorAlgorithm.transformCoordinateSystem(inRotationVector, axisX, axisY, outRotationVector);
443     if (ret != OHOS::ERR_OK) {
444         SEN_HILOGE("Transform coordinate system fail");
445         asyncCallbackInfo->type = FAIL;
446         asyncCallbackInfo->error.code = ret;
447     } else {
448         for (size_t i = 0; i < length; ++i) {
449             asyncCallbackInfo->data.reserveData.reserve[i] = outRotationVector[i];
450         }
451         asyncCallbackInfo->data.reserveData.length = static_cast<int32_t>(length);
452     }
453     if (argc == 2) {
454         napi_value promise = nullptr;
455         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise), "napi_create_promise");
456         EmitPromiseWork(asyncCallbackInfo);
457         return promise;
458     }
459     CHKNCP(env, IsMatchType(env, args[2], napi_function), "Wrong argument type, should be function");
460     CHKNRP(env, napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]),
461         "napi_create_reference");
462     EmitAsyncCallbackWork(asyncCallbackInfo);
463     return nullptr;
464 }
465 
GetAngleModify(napi_env env,napi_callback_info info)466 static napi_value GetAngleModify(napi_env env, napi_callback_info info)
467 {
468     CALL_LOG_ENTER;
469     size_t argc = 3;
470     napi_value args[3] = { 0 };
471     napi_value thisVar = nullptr;
472     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
473     CHKNCP(env, ((argc == 2) || (argc == 3)), "The number of parameters is not valid");
474     CHKNCP(env, IsMatchArrayType(env, args[0]), "Wrong argument type, the first parameter should be array");
475     CHKNCP(env, IsMatchArrayType(env, args[1]), "Wrong argument type, the second parameter should be array");
476 
477     sptr<AsyncCallbackInfo> asyncCallbackInfo =
478         new (std::nothrow) AsyncCallbackInfo(env, GET_ANGLE_MODIFY);
479     CHKPP(asyncCallbackInfo);
480     std::vector<float> curRotationVector;
481     CHKNCP(env, GetFloatArray(env, args[0], curRotationVector), "Wrong argument type, get curRotationVector fail");
482     std::vector<float> preRotationVector;
483     CHKNCP(env, GetFloatArray(env, args[1], preRotationVector), "Wrong argument type, get preRotationVector fail");
484 
485     std::vector<float> angleChange(ROTATION_VECTOR_LENGTH);
486     SensorAlgorithm sensorAlgorithm;
487     int32_t ret = sensorAlgorithm.getAngleModify(curRotationVector, preRotationVector, angleChange);
488     if (ret != OHOS::ERR_OK) {
489         SEN_HILOGE("Get angle modify fail");
490         asyncCallbackInfo->type = FAIL;
491         asyncCallbackInfo->error.code = ret;
492     } else {
493         asyncCallbackInfo->data.reserveData.length = ROTATION_VECTOR_LENGTH;
494         for (int32_t i = 0; i < ROTATION_VECTOR_LENGTH; ++i) {
495             asyncCallbackInfo->data.reserveData.reserve[i] = angleChange[i];
496         }
497     }
498     if (argc == 2) {
499         napi_value promise = nullptr;
500         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
501             "napi_create_promise");
502         EmitPromiseWork(asyncCallbackInfo);
503         return promise;
504     }
505     CHKNCP(env, IsMatchType(env, args[2], napi_function), "Wrong argument type, should be function");
506     CHKNRP(env, napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]),
507         "napi_create_reference");
508     EmitAsyncCallbackWork(asyncCallbackInfo);
509     return nullptr;
510 }
511 
GetDirection(napi_env env,napi_callback_info info)512 static napi_value GetDirection(napi_env env, napi_callback_info info)
513 {
514     CALL_LOG_ENTER;
515     size_t argc = 3;
516     napi_value args[3] = { 0 };
517     napi_value thisVar = nullptr;
518     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info fail");
519     CHKNCP(env, ((argc == 1) || (argc == 2)), "The number of parameters is not valid");
520     CHKNCP(env, IsMatchArrayType(env, args[0]), "Wrong argument type, should be array");
521 
522     sptr<AsyncCallbackInfo> asyncCallbackInfo =
523         new (std::nothrow) AsyncCallbackInfo(env, GET_DIRECTION);
524     CHKPP(asyncCallbackInfo);
525     std::vector<float> rotationMatrix;
526     CHKNCP(env, GetFloatArray(env, args[0], rotationMatrix), "Wrong argument type, get rotationMatrix fail");
527     std::vector<float> rotationAngle(ROTATION_VECTOR_LENGTH);
528     SensorAlgorithm sensorAlgorithm;
529     int32_t ret = sensorAlgorithm.getDirection(rotationMatrix, rotationAngle);
530     if (ret != OHOS::ERR_OK) {
531         SEN_HILOGE("Get direction fail");
532         asyncCallbackInfo->type = FAIL;
533         asyncCallbackInfo->error.code = ret;
534     } else {
535         asyncCallbackInfo->data.reserveData.length = ROTATION_VECTOR_LENGTH;
536         for (int32_t i = 0; i < ROTATION_VECTOR_LENGTH; ++i) {
537             asyncCallbackInfo->data.reserveData.reserve[i] = rotationAngle[i];
538         }
539     }
540     if (argc == 1) {
541         napi_value promise = nullptr;
542         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
543             "napi_create_promise");
544         EmitPromiseWork(asyncCallbackInfo);
545         return promise;
546     }
547     CHKNCP(env, IsMatchType(env, args[1], napi_function), "Wrong argument type, should be function");
548     CHKNRP(env, napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]),
549         "napi_create_reference");
550     EmitAsyncCallbackWork(asyncCallbackInfo);
551     return nullptr;
552 }
553 
CreateQuaternion(napi_env env,napi_callback_info info)554 static napi_value CreateQuaternion(napi_env env, napi_callback_info info)
555 {
556     CALL_LOG_ENTER;
557     size_t argc = 2;
558     napi_value args[2] = { 0 };
559     napi_value thisVar = nullptr;
560     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
561     CHKNCP(env, ((argc == 1) || (argc == 2)), "The number of parameters is not valid");
562     CHKNCP(env, IsMatchArrayType(env, args[0]), "Wrong argument type, should be array");
563 
564     sptr<AsyncCallbackInfo> asyncCallbackInfo =
565         new (std::nothrow) AsyncCallbackInfo(env, CREATE_QUATERNION);
566     CHKPP(asyncCallbackInfo);
567     std::vector<float> rotationVector;
568     CHKNCP(env, GetFloatArray(env, args[0], rotationVector),
569         "Wrong argument type, get rotationVector fail");
570     std::vector<float> quaternion(QUATERNION_LENGTH);
571     SensorAlgorithm sensorAlgorithm;
572     int32_t ret = sensorAlgorithm.createQuaternion(rotationVector, quaternion);
573     if (ret != OHOS::ERR_OK) {
574         SEN_HILOGE("Create quaternin fail");
575         asyncCallbackInfo->type = FAIL;
576         asyncCallbackInfo->error.code = ret;
577     } else {
578         asyncCallbackInfo->data.reserveData.length = QUATERNION_LENGTH;
579         for (int32_t i = 0; i < QUATERNION_LENGTH; ++i) {
580             asyncCallbackInfo->data.reserveData.reserve[i] = quaternion[i];
581         }
582     }
583     if (argc == 1) {
584         napi_value promise = nullptr;
585         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
586             "napi_create_promise");
587         EmitPromiseWork(asyncCallbackInfo);
588         return promise;
589     }
590     CHKNCP(env, IsMatchType(env, args[1], napi_function), "Wrong argument type, should be function");
591     CHKNRP(env, napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]),
592         "napi_create_reference");
593     EmitAsyncCallbackWork(asyncCallbackInfo);
594     return nullptr;
595 }
596 
GetAltitude(napi_env env,napi_callback_info info)597 static napi_value GetAltitude(napi_env env, napi_callback_info info)
598 {
599     CALL_LOG_ENTER;
600     size_t argc = 3;
601     napi_value args[3] = { 0 };
602     napi_value thisVar = nullptr;
603     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
604     CHKNCP(env, ((argc == 2) || (argc == 3)), "The number of parameters is not valid");
605     CHKNCP(env, IsMatchType(env, args[0], napi_number), "Wrong argument type, should be number");
606     CHKNCP(env, IsMatchType(env, args[1], napi_number), "Wrong argument type, should be number");
607 
608     sptr<AsyncCallbackInfo> asyncCallbackInfo =
609         new (std::nothrow) AsyncCallbackInfo(env, GET_ALTITUDE);
610     CHKPP(asyncCallbackInfo);
611     float seaPressure = 0;
612     CHKNCP(env, GetCppFloat(env, args[0], seaPressure), "Wrong argument type, get seaPressure fail");
613     float currentPressure = 0;
614     CHKNCP(env, GetCppFloat(env, args[1], currentPressure), "Wrong argument type, get currentPressure fail");
615     float altitude = 0;
616     SensorAlgorithm sensorAlgorithm;
617     int32_t ret = sensorAlgorithm.getAltitude(seaPressure, currentPressure, &altitude);
618     if (ret != OHOS::ERR_OK) {
619         SEN_HILOGE("Get altitude fail");
620         asyncCallbackInfo->type = FAIL;
621         asyncCallbackInfo->error.code = ret;
622     } else {
623         asyncCallbackInfo->data.reserveData.reserve[0] = altitude;
624     }
625     if (argc == 2) {
626         napi_value promise = nullptr;
627         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
628             "napi_create_promise");
629         EmitPromiseWork(asyncCallbackInfo);
630         return promise;
631     }
632     CHKNCP(env, IsMatchType(env, args[2], napi_function), "Wrong argument type, should be function");
633     CHKNRP(env, napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]),
634         "napi_create_reference");
635     EmitAsyncCallbackWork(asyncCallbackInfo);
636     return nullptr;
637 }
638 
GetGeomagneticDip(napi_env env,napi_callback_info info)639 static napi_value GetGeomagneticDip(napi_env env, napi_callback_info info)
640 {
641     CALL_LOG_ENTER;
642     size_t argc = 2;
643     napi_value args[2] = { 0 };
644     napi_value thisVar = nullptr;
645     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
646     CHKNCP(env, ((argc == 1) || (argc == 2)), "The number of parameters is not valid");
647     CHKNCP(env, IsMatchArrayType(env, args[0]), "Wrong argument type, should be array");
648 
649     sptr<AsyncCallbackInfo> asyncCallbackInfo =
650         new (std::nothrow) AsyncCallbackInfo(env, GET_GEOMAGNITIC_DIP);
651     CHKPP(asyncCallbackInfo);
652     std::vector<float> inclinationMatrix;
653     CHKNCP(env, GetFloatArray(env, args[0], inclinationMatrix),
654         "Wrong argument type, get inclinationMatrix fail");
655     float geomagneticDip = 0;
656     SensorAlgorithm sensorAlgorithm;
657     int32_t ret = sensorAlgorithm.getGeomagneticDip(inclinationMatrix, &geomagneticDip);
658     if (ret != OHOS::ERR_OK) {
659         SEN_HILOGE("Get geomagnetic dip fail");
660         asyncCallbackInfo->type = FAIL;
661         asyncCallbackInfo->error.code = ret;
662     } else {
663         asyncCallbackInfo->data.reserveData.reserve[0] = geomagneticDip;
664     }
665     if (argc == 1) {
666         napi_value promise = nullptr;
667         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
668             "napi_create_promise");
669         EmitPromiseWork(asyncCallbackInfo);
670         return promise;
671     }
672     CHKNCP(env, IsMatchType(env, args[1], napi_function), "Wrong argument type, should be function");
673     CHKNRP(env, napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]),
674         "napi_create_reference");
675     EmitAsyncCallbackWork(asyncCallbackInfo);
676     return nullptr;
677 }
678 
createRotationAndInclination(const napi_env & env,napi_value args[],size_t argc)679 static napi_value createRotationAndInclination(const napi_env &env, napi_value args[], size_t argc)
680 {
681     CALL_LOG_ENTER;
682     CHKNCP(env, ((argc == 2) || (argc == 3)), "The number of parameters is not valid");
683     std::vector<float> gravity;
684     CHKNCP(env, GetFloatArray(env, args[0], gravity), "Wrong argument type, get gravity fail");
685     std::vector<float> geomagnetic;
686     CHKNCP(env, GetFloatArray(env, args[1], geomagnetic), "Wrong argument type, get geomagnetic fail");
687     std::vector<float> rotation(THREE_DIMENSIONAL_MATRIX_LENGTH);
688     std::vector<float> inclination(THREE_DIMENSIONAL_MATRIX_LENGTH);
689     sptr<AsyncCallbackInfo> asyncCallbackInfo =
690         new (std::nothrow) AsyncCallbackInfo(env, ROTATION_INCLINATION_MATRIX);
691     CHKPP(asyncCallbackInfo);
692     SensorAlgorithm sensorAlgorithm;
693     int32_t ret = sensorAlgorithm.createRotationAndInclination(gravity, geomagnetic, rotation, inclination);
694     if (ret != OHOS::ERR_OK) {
695         SEN_HILOGE("Create rotation and inclination matrix fail");
696         asyncCallbackInfo->type = FAIL;
697         asyncCallbackInfo->error.code = ret;
698     } else {
699         asyncCallbackInfo->data.reserveData.length = THREE_DIMENSIONAL_MATRIX_LENGTH;
700         for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) {
701             asyncCallbackInfo->data.rationMatrixData.rotationMatrix[i] = rotation[i];
702         }
703         for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) {
704             asyncCallbackInfo->data.rationMatrixData.inclinationMatrix[i] = inclination[i];
705         }
706     }
707     if (argc == 2) {
708         napi_value promise = nullptr;
709         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
710             "napi_create_promise");
711         EmitPromiseWork(asyncCallbackInfo);
712         return promise;
713     }
714     CHKNCP(env, IsMatchType(env, args[2], napi_function), "Wrong argument type, should be function");
715     CHKNRP(env, napi_create_reference(env, args[2], 1, &asyncCallbackInfo->callback[0]),
716         "napi_create_reference");
717     EmitAsyncCallbackWork(asyncCallbackInfo);
718     return nullptr;
719 }
720 
GetRotationMatrix(const napi_env & env,napi_value args[],size_t argc)721 static napi_value GetRotationMatrix(const napi_env &env, napi_value args[], size_t argc)
722 {
723     CALL_LOG_ENTER;
724     CHKNCP(env, ((argc == 1) || (argc == 2)), "The number of parameters is not valid");
725     std::vector<float> rotationVector;
726     CHKNCP(env, GetFloatArray(env, args[0], rotationVector),
727         "Wrong argument type, get rotationVector fail");
728 
729     sptr<AsyncCallbackInfo> asyncCallbackInfo =
730         new (std::nothrow) AsyncCallbackInfo(env, CREATE_ROTATION_MATRIX);
731     CHKPP(asyncCallbackInfo);
732     std::vector<float> rotationMatrix(THREE_DIMENSIONAL_MATRIX_LENGTH);
733     SensorAlgorithm sensorAlgorithm;
734     int32_t ret = sensorAlgorithm.createRotationMatrix(rotationVector, rotationMatrix);
735     if (ret != OHOS::ERR_OK) {
736         SEN_HILOGE("Create rotation matrix fail");
737         asyncCallbackInfo->type = FAIL;
738         asyncCallbackInfo->error.code = ret;
739     } else {
740         asyncCallbackInfo->data.reserveData.length = THREE_DIMENSIONAL_MATRIX_LENGTH;
741         for (int32_t i = 0; i < THREE_DIMENSIONAL_MATRIX_LENGTH; ++i) {
742             asyncCallbackInfo->data.reserveData.reserve[i] = rotationMatrix[i];
743         }
744     }
745 
746     if (argc == 1) {
747         napi_value promise = nullptr;
748         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
749             "napi_create_promise");
750         EmitPromiseWork(asyncCallbackInfo);
751         return promise;
752     }
753     CHKNCP(env, IsMatchType(env, args[1], napi_function), "Wrong argument type, should be function");
754     CHKNRP(env, napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]),
755         "napi_create_reference");
756     EmitAsyncCallbackWork(asyncCallbackInfo);
757     return nullptr;
758 }
759 
CreateRotationMatrix(napi_env env,napi_callback_info info)760 static napi_value CreateRotationMatrix(napi_env env, napi_callback_info info)
761 {
762     CALL_LOG_ENTER;
763     size_t argc = 3;
764     napi_value args[3] = { 0 };
765     napi_value thisVar = nullptr;
766     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
767     CHKNCP(env, ((argc >= 1) && (argc <= 3)), "The number of parameters is not valid");
768     CHKNCP(env, IsMatchArrayType(env, args[0]), "Wrong argument type, should be array");
769 
770     if (argc == 1 || (argc == 2 && IsMatchType(env, args[1], napi_function))) {
771         return GetRotationMatrix(env, args, argc);
772     } else if (IsMatchArrayType(env, args[1])) {
773         return createRotationAndInclination(env, args, argc);
774     }
775     return nullptr;
776 }
777 
GetSensorList(napi_env env,napi_callback_info info)778 static napi_value GetSensorList(napi_env env, napi_callback_info info)
779 {
780     CALL_LOG_ENTER;
781     size_t argc = 1;
782     napi_value args[1] = { 0 };
783     napi_value thisVar = nullptr;
784     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
785     CHKNCP(env, (argc <= 1), "The number of parameters is not valid");
786     sptr<AsyncCallbackInfo> asyncCallbackInfo =
787         new (std::nothrow) AsyncCallbackInfo(env, GET_SENSOR_LIST);
788     CHKPP(asyncCallbackInfo);
789 
790     SensorInfo *sensorInfos = nullptr;
791     int32_t count = 0;
792     int32_t ret = GetAllSensors(&sensorInfos, &count);
793     if (ret != OHOS::ERR_OK) {
794         SEN_HILOGE("Get sensor list fail");
795         asyncCallbackInfo->type = FAIL;
796         asyncCallbackInfo->error.code = ret;
797     } else {
798         for (int32_t i = 0; i < count; ++i) {
799             asyncCallbackInfo->sensorInfos.push_back(*(sensorInfos + i));
800         }
801         free(sensorInfos);
802         sensorInfos = nullptr;
803     }
804     if (argc == 0) {
805         napi_value promise = nullptr;
806         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise),
807             "napi_create_promise");
808         EmitPromiseWork(asyncCallbackInfo);
809         return promise;
810     }
811     CHKNCP(env, IsMatchType(env, args[0], napi_function), "Wrong argument type, should be function");
812     napi_create_reference(env, args[0], 1, &asyncCallbackInfo->callback[0]);
813     EmitAsyncCallbackWork(asyncCallbackInfo);
814     return nullptr;
815 }
816 
GetSingleSensor(napi_env env,napi_callback_info info)817 static napi_value GetSingleSensor(napi_env env, napi_callback_info info)
818 {
819     CALL_LOG_ENTER;
820     size_t argc = 2;
821     napi_value args[2] = { 0 };
822     napi_value thisVar = nullptr;
823     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
824     CHKNCP(env, ((argc == 1) || (argc == 2)), "The number of parameters is not valid");
825     int32_t sensorTypeId = INVALID_SENSOR_ID;
826     CHKNCP(env, GetCppInt32(env, args[0], sensorTypeId), "Wrong argument type, get number fail");
827 
828     sptr<AsyncCallbackInfo> asyncCallbackInfo =
829         new (std::nothrow) AsyncCallbackInfo(env, GET_SINGLE_SENSOR);
830     CHKPP(asyncCallbackInfo);
831     SensorInfo *sensorInfos = nullptr;
832     int32_t count = 0;
833     int32_t ret = GetAllSensors(&sensorInfos, &count);
834     if (ret != OHOS::ERR_OK) {
835         SEN_HILOGE("Get sensor list fail");
836         asyncCallbackInfo->type = FAIL;
837         asyncCallbackInfo->error.code = ret;
838     } else {
839         for (int32_t i = 0; i < count; ++i) {
840             if (sensorInfos[i].sensorTypeId == sensorTypeId) {
841                 asyncCallbackInfo->sensorInfos.push_back(*(sensorInfos + i));
842                 break;
843             }
844         }
845         if (asyncCallbackInfo->sensorInfos.empty()) {
846             SEN_HILOGE("Not find sensorTypeId: %{public}d", sensorTypeId);
847             asyncCallbackInfo->type = FAIL;
848         }
849         free(sensorInfos);
850         sensorInfos = nullptr;
851     }
852     if (argc == 1) {
853         napi_value promise = nullptr;
854         CHKNRP(env, napi_create_promise(env, &asyncCallbackInfo->deferred, &promise), "napi_create_promise");
855         EmitPromiseWork(asyncCallbackInfo);
856         return promise;
857     }
858     CHKNCP(env, IsMatchType(env, args[1], napi_function), "Wrong argument type, should be function");
859     napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]);
860     EmitAsyncCallbackWork(asyncCallbackInfo);
861     return nullptr;
862 }
863 
Subscribe(napi_env env,napi_callback_info info,int32_t sensorTypeId,CallbackDataType type)864 napi_value Subscribe(napi_env env, napi_callback_info info, int32_t sensorTypeId, CallbackDataType type)
865 {
866     CALL_LOG_ENTER;
867     size_t argc = 1;
868     napi_value args[1] = { 0 };
869     napi_value thisVar = nullptr;
870     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
871     CHKNCP(env, (argc == 1), "The number of parameters is not valid");
872     CHKNCP(env, IsMatchType(env, args[0], napi_object), "Wrong argument type, should be object");
873 
874     string interval = "normal";
875     if ((sensorTypeId == SENSOR_TYPE_ID_ACCELEROMETER) ||
876         ((sensorTypeId == SENSOR_TYPE_ID_ORIENTATION) && (type != SUBSCRIBE_COMPASS))
877         || (sensorTypeId == SENSOR_TYPE_ID_GYROSCOPE)) {
878         napi_value napiInterval = GetNamedProperty(env, args[0], "interval");
879         CHKNCP(env, GetStringValue(env, napiInterval, interval), "get interval fail");
880     }
881     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, type);
882     CHKPP(asyncCallbackInfo);
883     napi_value napiSuccess = GetNamedProperty(env, args[0], "success");
884     CHKNCP(env, (napiSuccess != nullptr), "get napiSuccess fail");
885     CHKNCP(env, RegisterNapiCallback(env, napiSuccess, asyncCallbackInfo->callback[0]),
886         "register callback fail");
887     napi_value napiFail = GetNamedProperty(env, args[0], "fail");
888     if (napiFail != nullptr) {
889         SEN_HILOGD("has fail callback");
890         CHKNCP(env, RegisterNapiCallback(env, napiFail, asyncCallbackInfo->callback[1]),
891             "register callback fail");
892     }
893     if (auto iter = g_samplingPeriod.find(interval); iter == g_samplingPeriod.end()) {
894         CHKNCP(env, (napiFail != nullptr), "input error, interval is invalid");
895         CreateFailMessage(SUBSCRIBE_FAIL, INPUT_ERROR, "input error", asyncCallbackInfo);
896         EmitAsyncCallbackWork(asyncCallbackInfo);
897         return nullptr;
898     }
899     std::lock_guard<std::mutex> subscribeCallbackLock(mutex_);
900     bool ret = SubscribeSensor(sensorTypeId, g_samplingPeriod[interval], DataCallbackImpl);
901     if (!ret) {
902         CHKNCP(env, (napiFail != nullptr), "subscribe fail");
903         CreateFailMessage(SUBSCRIBE_FAIL, SENSOR_SUBSCRIBE_FAILURE, "subscribe fail", asyncCallbackInfo);
904         EmitAsyncCallbackWork(asyncCallbackInfo);
905         return nullptr;
906     }
907     g_subscribeCallbacks[sensorTypeId] = asyncCallbackInfo;
908     return nullptr;
909 }
910 
Unsubscribe(napi_env env,napi_callback_info info,int32_t sensorTypeId)911 napi_value Unsubscribe(napi_env env, napi_callback_info info, int32_t sensorTypeId)
912 {
913     CALL_LOG_ENTER;
914     size_t argc = 1;
915     napi_value args[1] = { 0 };
916     napi_value thisVar = nullptr;
917     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
918     CHKNCP(env, (argc == 0), "The number of parameters is not valid");
919     std::lock_guard<std::mutex> subscribeCallbackLock(mutex_);
920     g_subscribeCallbacks[sensorTypeId] = nullptr;
921     if (CheckSubscribe(sensorTypeId)) {
922         SEN_HILOGW("There are other client subscribe as well, not need unsubscribe");
923         return nullptr;
924     }
925     CHKNCP(env, UnsubscribeSensor(sensorTypeId), "UnsubscribeSensor failed");
926     return nullptr;
927 }
928 
GetBodyState(napi_env env,napi_callback_info info)929 napi_value GetBodyState(napi_env env, napi_callback_info info)
930 {
931     CALL_LOG_ENTER;
932     size_t argc = 1;
933     napi_value args[1] = { 0 };
934     napi_value thisVar = nullptr;
935     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr), "napi_get_cb_info");
936     CHKNCP(env, (argc == 1), "The number of parameters is not valid");
937     CHKNCP(env, IsMatchType(env, args[0], napi_object), "Wrong argument type, should be object");
938     sptr<AsyncCallbackInfo> asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(env, GET_BODY_STATE);
939     CHKPP(asyncCallbackInfo);
940     napi_value napiSuccess = GetNamedProperty(env, args[0], "success");
941     CHKNCP(env, RegisterNapiCallback(env, napiSuccess, asyncCallbackInfo->callback[0]),
942         "register success callback fail");
943     std::lock_guard<std::mutex> onBodyLock(bodyMutex_);
944     asyncCallbackInfo->data.sensorData.data[0] =
945         (fabs(g_bodyState - BODY_STATE_EXCEPT) < THREESHOLD) ? true : false;
946     EmitUvEventLoop(asyncCallbackInfo);
947     return nullptr;
948 }
949 
EnumClassConstructor(napi_env env,napi_callback_info info)950 static napi_value EnumClassConstructor(napi_env env, napi_callback_info info)
951 {
952     size_t argc = 0;
953     napi_value args[1] = {0};
954     napi_value ret = nullptr;
955     void *data = nullptr;
956     CHKNRP(env, napi_get_cb_info(env, info, &argc, args, &ret, &data), "napi_get_cb_info");
957     return ret;
958 }
959 
CreateEnumSensorType(napi_env env,napi_value exports)960 static napi_value CreateEnumSensorType(napi_env env, napi_value exports)
961 {
962     napi_property_descriptor desc[] = {
963         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ACCELEROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER)),
964         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GYROSCOPE", GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE)),
965         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_AMBIENT_LIGHT", GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_LIGHT)),
966         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_MAGNETIC_FIELD", GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD)),
967         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_BAROMETER", GetNapiInt32(env, SENSOR_TYPE_ID_BAROMETER)),
968         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HALL", GetNapiInt32(env, SENSOR_TYPE_ID_HALL)),
969         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PROXIMITY", GetNapiInt32(env, SENSOR_TYPE_ID_PROXIMITY)),
970         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HUMIDITY", GetNapiInt32(env, SENSOR_TYPE_ID_HUMIDITY)),
971         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ORIENTATION", GetNapiInt32(env, SENSOR_TYPE_ID_ORIENTATION)),
972         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GRAVITY", GetNapiInt32(env, SENSOR_TYPE_ID_GRAVITY)),
973         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_LINEAR_ACCELERATION",
974             GetNapiInt32(env, SENSOR_TYPE_ID_LINEAR_ACCELERATION)),
975         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ROTATION_VECTOR",
976             GetNapiInt32(env, SENSOR_TYPE_ID_ROTATION_VECTOR)),
977         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_AMBIENT_TEMPERATURE",
978             GetNapiInt32(env, SENSOR_TYPE_ID_AMBIENT_TEMPERATURE)),
979         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED",
980             GetNapiInt32(env, SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED)),
981         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED",
982             GetNapiInt32(env, SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED)),
983         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_SIGNIFICANT_MOTION",
984             GetNapiInt32(env, SENSOR_TYPE_ID_SIGNIFICANT_MOTION)),
985         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PEDOMETER_DETECTION",
986             GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER_DETECTION)),
987         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_PEDOMETER", GetNapiInt32(env, SENSOR_TYPE_ID_PEDOMETER)),
988         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_HEART_RATE", GetNapiInt32(env, SENSOR_TYPE_ID_HEART_RATE)),
989         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_WEAR_DETECTION", GetNapiInt32(env, SENSOR_TYPE_ID_WEAR_DETECTION)),
990         DECLARE_NAPI_STATIC_PROPERTY("SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED",
991             GetNapiInt32(env, SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED)),
992     };
993     napi_value result = nullptr;
994     CHKNRP(env, napi_define_class(env, "SensorType", NAPI_AUTO_LENGTH, EnumClassConstructor, nullptr,
995         sizeof(desc) / sizeof(*desc), desc, &result), "napi_define_class");
996     CHKNRP(env, napi_set_named_property(env, exports, "SensorType", result), "napi_set_named_property fail");
997     return exports;
998 }
999 
Init(napi_env env,napi_value exports)1000 static napi_value Init(napi_env env, napi_value exports)
1001 {
1002     napi_property_descriptor desc[] = {
1003         DECLARE_NAPI_FUNCTION("on", On),
1004         DECLARE_NAPI_FUNCTION("once", Once),
1005         DECLARE_NAPI_FUNCTION("off", Off),
1006         DECLARE_NAPI_FUNCTION("getGeomagneticField", GetGeomagneticField),
1007         DECLARE_NAPI_FUNCTION("transformCoordinateSystem", TransformCoordinateSystem),
1008         DECLARE_NAPI_FUNCTION("getAngleModify", GetAngleModify),
1009         DECLARE_NAPI_FUNCTION("getDirection", GetDirection),
1010         DECLARE_NAPI_FUNCTION("createQuaternion", CreateQuaternion),
1011         DECLARE_NAPI_FUNCTION("getAltitude", GetAltitude),
1012         DECLARE_NAPI_FUNCTION("getGeomagneticDip", GetGeomagneticDip),
1013         DECLARE_NAPI_FUNCTION("createRotationMatrix", CreateRotationMatrix),
1014         DECLARE_NAPI_FUNCTION("getSensorList", GetSensorList),
1015         DECLARE_NAPI_FUNCTION("getSingleSensor", GetSingleSensor),
1016         DECLARE_NAPI_FUNCTION("subscribeAccelerometer", SubscribeAccelerometer),
1017         DECLARE_NAPI_FUNCTION("unsubscribeAccelerometer", UnsubscribeAccelerometer),
1018         DECLARE_NAPI_FUNCTION("subscribeCompass", SubscribeCompass),
1019         DECLARE_NAPI_FUNCTION("unsubscribeCompass", UnsubscribeCompass),
1020         DECLARE_NAPI_FUNCTION("subscribeProximity", SubscribeProximity),
1021         DECLARE_NAPI_FUNCTION("unsubscribeProximity", UnsubscribeProximity),
1022         DECLARE_NAPI_FUNCTION("subscribeLight", SubscribeLight),
1023         DECLARE_NAPI_FUNCTION("unsubscribeLight", UnsubscribeLight),
1024         DECLARE_NAPI_FUNCTION("subscribeStepCounter", SubscribeStepCounter),
1025         DECLARE_NAPI_FUNCTION("unsubscribeStepCounter", UnsubscribeStepCounter),
1026         DECLARE_NAPI_FUNCTION("subscribeBarometer", SubscribeBarometer),
1027         DECLARE_NAPI_FUNCTION("unsubscribeBarometer", UnsubscribeBarometer),
1028         DECLARE_NAPI_FUNCTION("subscribeHeartRate", SubscribeHeartRate),
1029         DECLARE_NAPI_FUNCTION("unsubscribeHeartRate", UnsubscribeHeartRate),
1030         DECLARE_NAPI_FUNCTION("subscribeOnBodyState", SubscribeOnBodyState),
1031         DECLARE_NAPI_FUNCTION("unsubscribeOnBodyState", UnsubscribeOnBodyState),
1032         DECLARE_NAPI_FUNCTION("getOnBodyState", GetOnBodyState),
1033         DECLARE_NAPI_FUNCTION("subscribeDeviceOrientation", SubscribeDeviceOrientation),
1034         DECLARE_NAPI_FUNCTION("unsubscribeDeviceOrientation", UnsubscribeDeviceOrientation),
1035         DECLARE_NAPI_FUNCTION("subscribeGyroscope", SubscribeGyroscope),
1036         DECLARE_NAPI_FUNCTION("unsubscribeGyroscope", UnsubscribeGyroscope),
1037         DECLARE_NAPI_FUNCTION("subscribeGravity", SubscribeGravity),
1038         DECLARE_NAPI_FUNCTION("unsubscribeGravity", UnsubscribeGravity),
1039         DECLARE_NAPI_FUNCTION("subscribeMagnetic", SubscribeMagnetic),
1040         DECLARE_NAPI_FUNCTION("unsubscribeMagnetic", UnsubscribeMagnetic),
1041         DECLARE_NAPI_FUNCTION("subscribeHall", SubscribeHall),
1042         DECLARE_NAPI_FUNCTION("unsubscribeHall", UnsubscribeHall),
1043     };
1044     CHKNRP(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc),
1045         "napi_define_properties");
1046     CHKNCP(env, CreateEnumSensorType(env, exports), "Create enum sensor type fail");
1047     return exports;
1048 }
1049 
1050 static napi_module _module = {
1051     .nm_version = 1,
1052     .nm_flags = 0,
1053     .nm_filename = nullptr,
1054     .nm_register_func = Init,
1055     .nm_modname = "sensor",
1056     .nm_priv = ((void *)0),
1057     .reserved = {0}
1058 };
1059 
RegisterModule(void)1060 extern "C" __attribute__((constructor)) void RegisterModule(void)
1061 {
1062     napi_module_register(&_module);
1063 }
1064 }  // namespace Sensors
1065 }  // namespace OHOS