• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "sensor_napi_utils.h"
17 
18 #include <map>
19 #include <string>
20 #include <vector>
21 
22 #include "bundle_mgr_proxy.h"
23 #include "ipc_skeleton.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26 
27 #include "sensor_napi_error.h"
28 
29 namespace OHOS {
30 namespace Sensors {
31 namespace {
32 constexpr int32_t STRING_LENGTH_MAX = 64;
33 constexpr int32_t RESULT_SIZE = 2;
34 } // namespace
35 static std::mutex g_sensorAttrListMutex;
IsSameValue(const napi_env & env,const napi_value & lhs,const napi_value & rhs)36 bool IsSameValue(const napi_env &env, const napi_value &lhs, const napi_value &rhs)
37 {
38     CALL_LOG_ENTER;
39     bool result = false;
40     CHKNRF(env, napi_strict_equals(env, lhs, rhs, &result), "napi_strict_equals");
41     return result;
42 }
43 
IsMatchType(const napi_env & env,const napi_value & value,const napi_valuetype & type)44 bool IsMatchType(const napi_env &env, const napi_value &value, const napi_valuetype &type)
45 {
46     CALL_LOG_ENTER;
47     napi_valuetype paramType = napi_undefined;
48     CHKNRF(env, napi_typeof(env, value, &paramType), "napi_typeof");
49     return paramType == type;
50 }
51 
IsMatchArrayType(const napi_env & env,const napi_value & value)52 bool IsMatchArrayType(const napi_env &env, const napi_value &value)
53 {
54     CALL_LOG_ENTER;
55     bool result = false;
56     CHKNRF(env, napi_is_array(env, value, &result), "napi_is_array");
57     return result;
58 }
59 
GetFloatArray(const napi_env & env,const napi_value & value,vector<float> & array)60 bool GetFloatArray(const napi_env &env, const napi_value &value, vector<float> &array)
61 {
62     CALL_LOG_ENTER;
63     uint32_t arrayLength = 0;
64     CHKNRF(env, napi_get_array_length(env, value, &arrayLength), "napi_get_array_length");
65     for (uint32_t i = 0; i < arrayLength; ++i) {
66         napi_value element = nullptr;
67         CHKNRF(env, napi_get_element(env, value, i, &element), "napi_get_element");
68         CHKNCF(env, IsMatchType(env, element, napi_number), "Wrong argument type. Number or function expected");
69         double number = 0;
70         CHKNCF(env, GetNativeDouble(env, element, number), "Wrong argument type. get double fail");
71         array.push_back(static_cast<float>(number));
72     }
73     return true;
74 }
75 
GetNamedProperty(const napi_env & env,const napi_value & object,string name)76 napi_value GetNamedProperty(const napi_env &env, const napi_value &object, string name)
77 {
78     CALL_LOG_ENTER;
79     bool status = false;
80     CHKNRP(env, napi_has_named_property(env, object, name.c_str(), &status), "napi_has_named_property");
81     if (!status) {
82         SEN_HILOGW("%{public}s not exists on the object", name.c_str());
83         return nullptr;
84     }
85     napi_value value = nullptr;
86     CHKNRP(env, napi_get_named_property(env, object, name.c_str(), &value),
87         "napi_get_named_property");
88     return value;
89 }
90 
GetNativeDouble(const napi_env & env,const napi_value & value,double & number)91 bool GetNativeDouble(const napi_env &env, const napi_value &value, double &number)
92 {
93     CALL_LOG_ENTER;
94     CHKNRF(env, napi_get_value_double(env, value, &number), "napi_get_value_double");
95     return true;
96 }
97 
GetNativeFloat(const napi_env & env,const napi_value & value,float & number)98 bool GetNativeFloat(const napi_env &env, const napi_value &value, float &number)
99 {
100     CALL_LOG_ENTER;
101     double result = 0;
102     CHKNCF(env, GetNativeDouble(env, value, result), "Get cpp double fail");
103     number = static_cast<float>(result);
104     return true;
105 }
106 
GetNativeInt32(const napi_env & env,const napi_value & value,int32_t & number)107 bool GetNativeInt32(const napi_env &env, const napi_value &value, int32_t &number)
108 {
109     CALL_LOG_ENTER;
110     CHKNRF(env, napi_get_value_int32(env, value, &number), "napi_get_value_int32");
111     return true;
112 }
113 
GetNativeInt64(const napi_env & env,const napi_value & value,int64_t & number)114 bool GetNativeInt64(const napi_env &env, const napi_value &value, int64_t &number)
115 {
116     CALL_LOG_ENTER;
117     CHKNRF(env, napi_get_value_int64(env, value, &number), "napi_get_value_int64");
118     return true;
119 }
120 
GetNativeBool(const napi_env & env,const napi_value & value)121 bool GetNativeBool(const napi_env &env, const napi_value &value)
122 {
123     CALL_LOG_ENTER;
124     bool number = false;
125     CHKNRF(env, napi_get_value_bool(env, value, &number), "napi_get_value_bool");
126     return number;
127 }
128 
GetNapiInt32(const napi_env & env,int32_t number)129 napi_value GetNapiInt32(const napi_env &env, int32_t number)
130 {
131     napi_value value = nullptr;
132     CHKNRP(env, napi_create_int32(env, number, &value), "napi_create_int32");
133     return value;
134 }
135 
GetStringValue(const napi_env & env,const napi_value & value,string & result)136 bool GetStringValue(const napi_env &env, const napi_value &value, string &result)
137 {
138     CALL_LOG_ENTER;
139     CHKNCF(env, IsMatchType(env, value, napi_string), "Wrong argument type. String or function expected");
140     char buf[STRING_LENGTH_MAX] = { 0 };
141     size_t copyLength = 0;
142     CHKNRF(env, napi_get_value_string_utf8(env, value, buf, STRING_LENGTH_MAX, &copyLength),
143         "napi_get_value_string_utf8");
144     result = std::string(buf);
145     return true;
146 }
147 
RegisterNapiCallback(const napi_env & env,const napi_value & value,napi_ref & callback)148 bool RegisterNapiCallback(const napi_env &env, const napi_value &value,
149     napi_ref &callback)
150 {
151     CHKNCF(env, IsMatchType(env, value, napi_function), "Wrong argument type, should be function");
152     CHKNRF(env, napi_create_reference(env, value, 1, &callback), "napi_create_reference");
153     return true;
154 }
155 
CreateFailMessage(CallbackDataType type,int32_t code,string message,sptr<AsyncCallbackInfo> & asyncCallbackInfo)156 bool CreateFailMessage(CallbackDataType type, int32_t code, string message,
157     sptr<AsyncCallbackInfo> &asyncCallbackInfo)
158 {
159     CHKPF(asyncCallbackInfo);
160     asyncCallbackInfo->type = type;
161     asyncCallbackInfo->error.code = code;
162     asyncCallbackInfo->error.message = message;
163     return true;
164 }
165 
166 std::map<int32_t, vector<string>> g_sensorAttributeList = {
167     { 0, { "x" } },
168     { SENSOR_TYPE_ID_ACCELEROMETER, { "x", "y", "z" } },
169     { SENSOR_TYPE_ID_GYROSCOPE, { "x", "y", "z" } },
170     { SENSOR_TYPE_ID_AMBIENT_LIGHT, { "intensity", "colorTemperature", "infraredLuminance" } },
171     { SENSOR_TYPE_ID_MAGNETIC_FIELD, { "x", "y", "z" } },
172     { SENSOR_TYPE_ID_BAROMETER, { "pressure" } },
173     { SENSOR_TYPE_ID_HALL, { "status" } },
174     { SENSOR_TYPE_ID_TEMPERATURE, { "temperature" } },
175     { SENSOR_TYPE_ID_PROXIMITY, { "distance" } },
176     { SENSOR_TYPE_ID_HUMIDITY, { "humidity" } },
177     { SENSOR_TYPE_ID_ORIENTATION, { "alpha", "beta", "gamma" } },
178     { SENSOR_TYPE_ID_GRAVITY, { "x", "y", "z" } },
179     { SENSOR_TYPE_ID_LINEAR_ACCELERATION, { "x", "y", "z" } },
180     { SENSOR_TYPE_ID_ROTATION_VECTOR, { "x", "y", "z", "w" } },
181     { SENSOR_TYPE_ID_AMBIENT_TEMPERATURE, { "temperature" } },
182     { SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } },
183     { SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } },
184     { SENSOR_TYPE_ID_SIGNIFICANT_MOTION, { "scalar" } },
185     { SENSOR_TYPE_ID_PEDOMETER_DETECTION, { "scalar" } },
186     { SENSOR_TYPE_ID_PEDOMETER, { "steps" } },
187     { SENSOR_TYPE_ID_HEART_RATE, { "heartRate" } },
188     { SENSOR_TYPE_ID_WEAR_DETECTION, { "value" } },
189     { SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } },
190     { SENSOR_TYPE_ID_COLOR, { "lightIntensity", "colorTemperature" } },
191     { SENSOR_TYPE_ID_SAR, { "absorptionRatio" } },
192     { SENSOR_TYPE_ID_FUSION_PRESSURE, { "fusionPressure" } },
193 };
194 
195 std::map<int32_t, ConvertDataFunc> g_convertfuncList = {
196     {FAIL, ConvertToFailData},
197     {GET_GEOMAGNETIC_FIELD, ConvertToGeomagneticData},
198     {GET_ALTITUDE, ConvertToNumber},
199     {GET_GEOMAGNETIC_DIP, ConvertToNumber},
200     {GET_ANGLE_MODIFY, ConvertToArray},
201     {CREATE_ROTATION_MATRIX, ConvertToArray},
202     {TRANSFORM_COORDINATE_SYSTEM, ConvertToArray},
203     {CREATE_QUATERNION, ConvertToArray},
204     {GET_DIRECTION, ConvertToArray},
205     {ROTATION_INCLINATION_MATRIX, ConvertToRotationMatrix},
206     {GET_SENSOR_LIST, ConvertToSensorInfos},
207     {GET_SINGLE_SENSOR, ConvertToSingleSensor},
208     {GET_BODY_STATE, ConvertToBodyData},
209     {SUBSCRIBE_COMPASS, ConvertToCompass},
210     {SENSOR_STATE_CHANGE, ConvertToSensorState},
211 };
212 
getJsonObject(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value & result)213 bool getJsonObject(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value &result)
214 {
215     CHKPF(asyncCallbackInfo);
216     CHKNRF(env, napi_create_object(env, &result), "napi_create_object");
217     napi_value value = nullptr;
218     CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.x, &value), "napi_create_double");
219     CHKNRF(env, napi_set_named_property(env, result, "x", value), "napi_set_named_property");
220     value = nullptr;
221     CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.y, &value), "napi_create_double");
222     CHKNRF(env, napi_set_named_property(env, result, "y", value), "napi_set_named_property");
223     value = nullptr;
224     CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.z, &value), "napi_create_double");
225     CHKNRF(env, napi_set_named_property(env, result, "z", value), "napi_set_named_property");
226     value = nullptr;
227     CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.geomagneticDip, &value),
228         "napi_create_double");
229     CHKNRF(env, napi_set_named_property(env, result, "geomagneticDip", value), "napi_set_named_property");
230     value = nullptr;
231     CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.deflectionAngle, &value),
232         "napi_create_double");
233     CHKNRF(env, napi_set_named_property(env, result, "deflectionAngle", value), "napi_set_named_property");
234     value = nullptr;
235     CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.levelIntensity, &value),
236         "napi_create_double");
237     CHKNRF(env, napi_set_named_property(env, result, "levelIntensity", value), "napi_set_named_property");
238     value = nullptr;
239     CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.totalIntensity, &value),
240         "napi_create_double");
241     CHKNRF(env, napi_set_named_property(env, result, "totalIntensity", value), "napi_set_named_property");
242     return true;
243 }
244 
ConvertToSensorInfo(const napi_env & env,const SensorInfo & sensorInfo,napi_value & result)245 bool ConvertToSensorInfo(const napi_env &env, const SensorInfo &sensorInfo, napi_value &result)
246 {
247     CALL_LOG_ENTER;
248     CHKNRF(env, napi_create_object(env, &result), "napi_create_object");
249     napi_value value = nullptr;
250     CHKNRF(env, napi_create_string_latin1(env, sensorInfo.sensorName, NAPI_AUTO_LENGTH, &value),
251         "napi_create_string_latin1");
252     CHKNRF(env, napi_set_named_property(env, result, "sensorName", value), "napi_set_named_property");
253     value = nullptr;
254     CHKNRF(env, napi_create_string_latin1(env, sensorInfo.vendorName, NAPI_AUTO_LENGTH, &value),
255         "napi_create_string_latin1");
256     CHKNRF(env, napi_set_named_property(env, result, "vendorName", value), "napi_set_named_property");
257     value = nullptr;
258     CHKNRF(env, napi_create_string_latin1(env, sensorInfo.firmwareVersion, NAPI_AUTO_LENGTH, &value),
259         "napi_create_string_latin1");
260     CHKNRF(env, napi_set_named_property(env, result, "firmwareVersion", value), "napi_set_named_property");
261     value = nullptr;
262     CHKNRF(env, napi_create_string_latin1(env, sensorInfo.hardwareVersion, NAPI_AUTO_LENGTH, &value),
263         "napi_create_string_latin1");
264     CHKNRF(env, napi_set_named_property(env, result, "hardwareVersion", value), "napi_set_named_property");
265     value = nullptr;
266     CHKNRF(env, napi_create_double(env, sensorInfo.sensorIndex, &value), "napi_create_double");
267     CHKNRF(env, napi_set_named_property(env, result, "sensorIndex", value), "napi_set_named_property");
268     value = nullptr;
269     CHKNRF(env, napi_create_double(env, sensorInfo.sensorTypeId, &value), "napi_create_double");
270     CHKNRF(env, napi_set_named_property(env, result, "sensorId", value), "napi_set_named_property");
271     value = nullptr;
272     CHKNRF(env, napi_create_double(env, sensorInfo.deviceId, &value), "napi_create_double");
273     CHKNRF(env, napi_set_named_property(env, result, "deviceId", value), "napi_set_named_property");
274     value = nullptr;
275     CHKNRF(env, napi_create_double(env, sensorInfo.location, &value), "napi_create_double");
276     CHKNRF(env, napi_set_named_property(env, result, "location", value), "napi_set_named_property");
277     value = nullptr;
278     CHKNRF(env, napi_create_double(env, sensorInfo.maxRange, &value), "napi_create_double");
279     CHKNRF(env, napi_set_named_property(env, result, "maxRange", value), "napi_set_named_property");
280     value = nullptr;
281     CHKNRF(env, napi_create_double(env, sensorInfo.precision, &value), "napi_create_double");
282     CHKNRF(env, napi_set_named_property(env, result, "precision", value), "napi_set_named_property");
283     value = nullptr;
284     CHKNRF(env, napi_create_double(env, sensorInfo.power, &value), "napi_create_double");
285     CHKNRF(env, napi_set_named_property(env, result, "power", value), "napi_set_named_property");
286     value = nullptr;
287     CHKNRF(env, napi_create_int64(env, sensorInfo.minSamplePeriod, &value), "napi_create_int64");
288     CHKNRF(env, napi_set_named_property(env, result, "minSamplePeriod", value), "napi_set_named_property");
289     value = nullptr;
290     CHKNRF(env, napi_create_int64(env, sensorInfo.maxSamplePeriod, &value), "napi_create_int64");
291     CHKNRF(env, napi_set_named_property(env, result, "maxSamplePeriod", value), "napi_set_named_property");
292     return true;
293 }
294 
ConvertToSingleSensor(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])295 bool ConvertToSingleSensor(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
296 {
297     CALL_LOG_ENTER;
298     CHKPF(asyncCallbackInfo);
299     return ConvertToSensorInfo(env, asyncCallbackInfo->sensorInfos[0], result[1]);
300 }
301 
ConvertToSensorInfos(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])302 bool ConvertToSensorInfos(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
303 {
304     CALL_LOG_ENTER;
305     CHKPF(asyncCallbackInfo);
306     CHKNRF(env, napi_create_array(env, &result[1]), "napi_create_array");
307     auto sensorInfos = asyncCallbackInfo->sensorInfos;
308     for (uint32_t i = 0; i < sensorInfos.size(); ++i) {
309         napi_value value = nullptr;
310         CHKNCF(env, ConvertToSensorInfo(env, sensorInfos[i], value), "Convert sensor info fail");
311         CHKNRF(env, napi_set_element(env, result[1], i, value), "napi_set_element");
312     }
313     return true;
314 }
315 
ConvertToFailData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])316 bool ConvertToFailData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
317 {
318     CALL_LOG_ENTER;
319     CHKPF(asyncCallbackInfo);
320     int32_t code = asyncCallbackInfo->error.code;
321     auto msg = GetNapiError(code);
322     if (!msg) {
323         SEN_HILOGE("ErrCode:%{public}d is invalid", code);
324         return false;
325     }
326     result[0] = CreateBusinessError(env, code, msg.value());
327     return (result[0] != nullptr);
328 }
329 
ConvertToSensorState(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])330 bool ConvertToSensorState(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
331 {
332     CALL_LOG_ENTER;
333     CHKPF(asyncCallbackInfo);
334     CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
335     napi_value value = nullptr;
336     CHKNRF(env, napi_create_int64(env, asyncCallbackInfo->sensorStatusEvent.timestamp, &value),
337         "napi_create_int64");
338     CHKNRF(env, napi_set_named_property(env, result[1], "timestamp", value), "napi_set_named_property");
339     value = nullptr;
340     CHKNRF(env, napi_create_int32(env, asyncCallbackInfo->sensorStatusEvent.sensorType, &value),
341         "napi_create_int32");
342     CHKNRF(env, napi_set_named_property(env, result[1], "sensorId", value), "napi_set_named_property");
343     value = nullptr;
344     CHKNRF(env, napi_create_int32(env, asyncCallbackInfo->sensorStatusEvent.sensorId, &value),
345         "napi_create_int32");
346     CHKNRF(env, napi_set_named_property(env, result[1], "sensorIndex", value), "napi_set_named_property");
347     value = nullptr;
348     CHKNRF(env, napi_get_boolean(env, asyncCallbackInfo->sensorStatusEvent.isSensorOnline, &value),
349         "napi_get_boolean");
350     CHKNRF(env, napi_set_named_property(env, result[1], "isSensorOnline", value), "napi_set_named_property");
351     value = nullptr;
352     CHKNRF(env, napi_create_int32(env, asyncCallbackInfo->sensorStatusEvent.deviceId, &value),
353         "napi_create_int32");
354     CHKNRF(env, napi_set_named_property(env, result[1], "deviceId", value), "napi_set_named_property");
355     value = nullptr;
356     CHKNRF(env, napi_create_string_utf8(env, asyncCallbackInfo->sensorStatusEvent.deviceName.c_str(),
357         NAPI_AUTO_LENGTH, &value), "napi_create_string_utf8");
358     CHKNRF(env, napi_set_named_property(env, result[1], "deviceName", value), "napi_set_named_property");
359     value = nullptr;
360     CHKNRF(env, napi_get_boolean(env, asyncCallbackInfo->sensorStatusEvent.location, &value),
361         "napi_get_boolean");
362     CHKNRF(env, napi_set_named_property(env, result[1], "isLocalSensor", value), "napi_set_named_property");
363     return true;
364 }
365 
ConvertToSensorData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2],int32_t resultSize,std::shared_ptr<CallbackSensorData> data)366 bool ConvertToSensorData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2],
367     int32_t resultSize, std::shared_ptr<CallbackSensorData> data)
368 {
369     CHKPF(asyncCallbackInfo);
370     CHKPF(data);
371     CHKCF(!(resultSize < RESULT_SIZE), "result size Invalid");
372     int32_t sensorTypeId = data->sensorTypeId;
373     std::lock_guard<std::mutex> sensorAttrListLock(g_sensorAttrListMutex);
374     CHKNCF(env, (g_sensorAttributeList.find(sensorTypeId) != g_sensorAttributeList.end()), "Invalid sensor type");
375     if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && asyncCallbackInfo->type == SUBSCRIBE_CALLBACK) {
376         CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
377         napi_value status = nullptr;
378         CHKNRF(env, napi_get_boolean(env, data->data[0], &status),
379             "napi_get_boolean");
380         CHKNRF(env, napi_set_named_property(env, result[1], "value", status), "napi_set_named_property");
381         return true;
382     }
383     size_t size = g_sensorAttributeList[sensorTypeId].size();
384     uint32_t dataLength = data->dataLength / sizeof(float);
385     CHKNCF(env, (size <= dataLength), "Data length mismatch");
386 
387     CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
388     napi_value message = nullptr;
389     auto sensorAttributes = g_sensorAttributeList[sensorTypeId];
390     for (uint32_t i = 0; i < size; ++i) {
391         CHKNRF(env, napi_create_double(env, data->data[i], &message),
392             "napi_create_double");
393         CHKNRF(env, napi_set_named_property(env, result[1], sensorAttributes[i].c_str(), message),
394             "napi_set_named_property");
395         message = nullptr;
396     }
397     CHKNRF(env, napi_create_int64(env, data->timestamp, &message),
398         "napi_create_int64");
399     CHKNRF(env, napi_set_named_property(env, result[1], "timestamp", message), "napi_set_named_property");
400     message = nullptr;
401     CHKNRF(env, napi_create_int32(env, data->sensorAccuracy, &message),
402         "napi_create_int32");
403     CHKNRF(env, napi_set_named_property(env, result[1], "accuracy", message), "napi_set_named_property");
404     return true;
405 }
406 
ConvertToGeomagneticData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])407 bool ConvertToGeomagneticData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
408 {
409     CALL_LOG_ENTER;
410     return getJsonObject(env, asyncCallbackInfo, result[1]);
411 }
412 
ConvertToBodyData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])413 bool ConvertToBodyData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
414 {
415     CALL_LOG_ENTER;
416     CHKPF(asyncCallbackInfo);
417     CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
418     napi_value status = nullptr;
419     CHKNRF(env, napi_get_boolean(env, asyncCallbackInfo->data.sensorData.data[0], &status),
420         "napi_get_boolean");
421     CHKNRF(env, napi_set_named_property(env, result[1], "value", status), "napi_set_named_property");
422     return true;
423 }
424 
ConvertToCompass(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])425 bool ConvertToCompass(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
426 {
427     CALL_LOG_ENTER;
428     CHKPF(asyncCallbackInfo);
429     CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
430     napi_value message = nullptr;
431     CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.sensorData.data[0], &message),
432         "napi_create_double");
433     CHKNRF(env, napi_set_named_property(env, result[1], "direction", message), "napi_set_named_property");
434     return true;
435 }
436 
ConvertToNumber(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])437 bool ConvertToNumber(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
438 {
439     CALL_LOG_ENTER;
440     CHKPF(asyncCallbackInfo);
441     napi_status status =
442         napi_create_double(env, static_cast<double>(asyncCallbackInfo->data.reserveData.reserve[0]), &result[1]);
443     CHKNRF(env, status, "napi_create_double");
444     return true;
445 }
446 
ConvertToArray(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])447 bool ConvertToArray(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
448 {
449     CALL_LOG_ENTER;
450     CHKPF(asyncCallbackInfo);
451     bool ret = CreateNapiArray(env, asyncCallbackInfo->data.reserveData.reserve,
452         asyncCallbackInfo->data.reserveData.length, result[1]);
453     CHKNCF(env, ret, "Create napi array fail");
454     return true;
455 }
456 
ConvertToRotationMatrix(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])457 bool ConvertToRotationMatrix(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
458 {
459     CALL_LOG_ENTER;
460     CHKPF(asyncCallbackInfo);
461     napi_value rotation = nullptr;
462     bool ret = CreateNapiArray(env, asyncCallbackInfo->data.rationMatrixData.rotationMatrix,
463         THREE_DIMENSIONAL_MATRIX_LENGTH, rotation);
464     CHKNCF(env, ret, "Create napi array rotation fail");
465     napi_value inclination = nullptr;
466     ret = CreateNapiArray(env, asyncCallbackInfo->data.rationMatrixData.inclinationMatrix,
467         THREE_DIMENSIONAL_MATRIX_LENGTH, inclination);
468     CHKNCF(env, ret, "Create napi array inclination fail");
469     CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
470     CHKNRF(env, napi_set_named_property(env, result[1], "rotation", rotation),
471         "napi_set_named_property");
472     CHKNRF(env, napi_set_named_property(env, result[1], "inclination", inclination),
473         "napi_set_named_property");
474     return true;
475 }
476 
CreateNapiArray(const napi_env & env,float data[],int32_t dataLength,napi_value & result)477 bool CreateNapiArray(const napi_env &env, float data[], int32_t dataLength, napi_value &result)
478 {
479     CHKNRF(env, napi_create_array(env, &result), "napi_create_array");
480     for (int32_t i = 0; i < dataLength; ++i) {
481         napi_value message = nullptr;
482         CHKNRF(env, napi_create_double(env, data[i], &message), "napi_create_double");
483         CHKNRF(env, napi_set_element(env, result, i, message), "napi_set_element");
484     }
485     return true;
486 }
487 
ReleaseCallback(sptr<AsyncCallbackInfo> asyncCallbackInfo)488 void ReleaseCallback(sptr<AsyncCallbackInfo> asyncCallbackInfo)
489 {
490     CHKPV(asyncCallbackInfo);
491     if (asyncCallbackInfo->type == ONCE_CALLBACK) {
492         napi_env env = asyncCallbackInfo->env;
493         CHKPV(env);
494         napi_ref callback = asyncCallbackInfo->callback[0];
495         if (callback != nullptr) {
496             napi_delete_reference(env, callback);
497         }
498     }
499 }
500 
EmitAsyncCallbackWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)501 void EmitAsyncCallbackWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)
502 {
503     CALL_LOG_ENTER;
504     CHKPV(asyncCallbackInfo);
505     napi_value resourceName = nullptr;
506     napi_env env = asyncCallbackInfo->env;
507     napi_status ret = napi_create_string_latin1(env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName);
508     CHKCV((ret == napi_ok), "napi_create_string_latin1 fail");
509     asyncCallbackInfo->IncStrongRef(nullptr);
510     napi_status status = napi_create_async_work(env, nullptr, resourceName,
511         [](napi_env env, void *data) {},
512         [](napi_env env, napi_status status, void *data) {
513             CALL_LOG_ENTER;
514             sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(data));
515             /**
516              * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
517              * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
518              * asynchronous task is created, and subtract 1 from the reference count after the naked
519              * pointer is converted to a pointer when the asynchronous task is executed, the reference
520              * count of the smart pointer is guaranteed to be 1.
521              */
522             asyncCallbackInfo->DecStrongRef(nullptr);
523             napi_value callback = nullptr;
524             napi_value callResult = nullptr;
525             napi_value result[2] = {0};
526             if (asyncCallbackInfo->type == SUBSCRIBE_FAIL) {
527                 CHKCV((napi_get_reference_value(env, asyncCallbackInfo->callback[1], &callback) == napi_ok),
528                     "napi_get_reference_value fail");
529                 CHKCV((napi_create_string_utf8(env, asyncCallbackInfo->error.message.c_str(),
530                     NAPI_AUTO_LENGTH, &result[0]) == napi_ok), "napi_create_string_utf8 fail");
531                 CHKCV((napi_create_int32(env, asyncCallbackInfo->error.code, &result[1]) == napi_ok),
532                     "napi_create_int32 fail");
533                 CHKCV((napi_call_function(env, nullptr, callback, 2, result, &callResult) == napi_ok),
534                     "napi_call_function fail");
535                 return;
536             }
537             CHKCV((napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback) == napi_ok),
538                 "napi_get_reference_value fail");
539             CHKCV((g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end()),
540                 "Callback type invalid in async work");
541             bool ret = g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
542             CHKCV(ret, "Create napi data fail in async work");
543             CHKCV((napi_call_function(env, nullptr, callback, 2, result, &callResult) == napi_ok),
544                 "napi_call_function fail");
545         },
546         asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork);
547     if (status != napi_ok
548         || napi_queue_async_work_with_qos(
549             asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) {
550         SEN_HILOGE("Create async work fail");
551         asyncCallbackInfo->DecStrongRef(nullptr);
552     }
553 }
554 
DeleteWork(uv_work_t * work)555 void DeleteWork(uv_work_t *work)
556 {
557     CHKPV(work);
558     delete work;
559     work = nullptr;
560 }
561 
EmitUvEventLoop(sptr<AsyncCallbackInfo> asyncCallbackInfo,std::shared_ptr<CallbackSensorData> cb)562 void EmitUvEventLoop(sptr<AsyncCallbackInfo> asyncCallbackInfo, std::shared_ptr<CallbackSensorData> cb)
563 {
564     CHKPV(asyncCallbackInfo);
565     CHKPV(cb);
566     asyncCallbackInfo->IncStrongRef(nullptr);
567     auto event = asyncCallbackInfo.GetRefPtr();
568     auto task = [event, cb]() {
569         sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(event));
570         /**
571          * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
572          * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
573          * asynchronous task is created, and subtract 1 from the reference count after the naked
574          * pointer is converted to a pointer when the asynchronous task is executed, the reference
575          * count of the smart pointer is guaranteed to be 1.
576          */
577         asyncCallbackInfo->DecStrongRef(nullptr);
578         napi_handle_scope scope = nullptr;
579         napi_open_handle_scope(asyncCallbackInfo->env, &scope);
580         if (scope == nullptr) {
581             SEN_HILOGE("napi_handle_scope is nullptr");
582             ReleaseCallback(asyncCallbackInfo);
583             return;
584         }
585         napi_env env = asyncCallbackInfo->env;
586         napi_value callback = nullptr;
587         if (napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback) != napi_ok) {
588             SEN_HILOGE("napi_get_reference_value fail");
589             napi_throw_error(env, nullptr, "napi_get_reference_value fail");
590             ReleaseCallback(asyncCallbackInfo);
591             napi_close_handle_scope(asyncCallbackInfo->env, scope);
592             return;
593         }
594         napi_value callResult = nullptr;
595         napi_value result[2] = {0};
596         if (asyncCallbackInfo->type == ON_CALLBACK || asyncCallbackInfo->type == ONCE_CALLBACK ||
597             asyncCallbackInfo->type == SUBSCRIBE_CALLBACK) {
598             if (!ConvertToSensorData(env, asyncCallbackInfo, result, RESULT_SIZE, cb)) {
599                 SEN_HILOGE("ConvertToSensorData fail");
600                 napi_throw_error(env, nullptr, "ConvertToSensorData fail");
601                 ReleaseCallback(asyncCallbackInfo);
602                 napi_close_handle_scope(asyncCallbackInfo->env, scope);
603                 return;
604             }
605         } else {
606             if (!(g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end())) {
607                 SEN_HILOGE("asyncCallbackInfo type is invalid");
608                 napi_throw_error(env, nullptr, "asyncCallbackInfo type is invalid");
609                 ReleaseCallback(asyncCallbackInfo);
610                 napi_close_handle_scope(asyncCallbackInfo->env, scope);
611                 return;
612             }
613             g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
614         }
615         if (napi_call_function(env, nullptr, callback, 1, &result[1], &callResult) != napi_ok) {
616             SEN_HILOGE("napi_call_function callback fail");
617             napi_throw_error(env, nullptr, "napi_call_function callback fail");
618             ReleaseCallback(asyncCallbackInfo);
619             napi_close_handle_scope(asyncCallbackInfo->env, scope);
620             return;
621         }
622         ReleaseCallback(asyncCallbackInfo);
623         napi_close_handle_scope(asyncCallbackInfo->env, scope);
624     };
625     auto ret = napi_send_event(asyncCallbackInfo->env, task, napi_eprio_immediate);
626     if (ret != napi_ok) {
627         SEN_HILOGE("Failed to SendEvent, ret:%{public}d", ret);
628         asyncCallbackInfo->DecStrongRef(nullptr);
629         ReleaseCallback(asyncCallbackInfo);
630     }
631 }
632 
EmitPromiseWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)633 void EmitPromiseWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)
634 {
635     CALL_LOG_ENTER;
636     CHKPV(asyncCallbackInfo);
637     napi_value resourceName = nullptr;
638     napi_env env = asyncCallbackInfo->env;
639     napi_status ret = napi_create_string_latin1(env, "Promise", NAPI_AUTO_LENGTH, &resourceName);
640     CHKCV((ret == napi_ok), "napi_create_string_latin1 fail");
641     asyncCallbackInfo->IncStrongRef(nullptr);
642     napi_status status = napi_create_async_work(env, nullptr, resourceName,
643         [](napi_env env, void *data) {},
644         [](napi_env env, napi_status status, void *data) {
645             CALL_LOG_ENTER;
646             sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(data));
647             /**
648              * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
649              * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
650              * asynchronous task is created, and subtract 1 from the reference count after the naked
651              * pointer is converted to a pointer when the asynchronous task is executed, the reference
652              * count of the smart pointer is guaranteed to be 1.
653              */
654             asyncCallbackInfo->DecStrongRef(nullptr);
655             napi_value result[2] = {0};
656             CHKCV((g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end()),
657                 "Callback type invalid in promise");
658             bool ret = g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
659             CHKCV(ret, "Callback type invalid in promise");
660             if (asyncCallbackInfo->type == FAIL) {
661                 CHKCV((napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]) == napi_ok),
662                     "napi_reject_deferred fail");
663             } else {
664                 CHKCV((napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[1]) == napi_ok),
665                     "napi_resolve_deferred fail");
666             }
667         },
668         asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork);
669     if (status != napi_ok
670         || napi_queue_async_work_with_qos(
671             asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) {
672         SEN_HILOGE("Create async work fail");
673         asyncCallbackInfo->DecStrongRef(nullptr);
674     }
675 }
676 
GetSelfTargetVersion(uint32_t & targetVersion)677 bool GetSelfTargetVersion(uint32_t &targetVersion)
678 {
679     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
680     if (samgr == nullptr) {
681         SEN_HILOGE("Samgr error");
682         return false;
683     }
684     auto bundleObj = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
685     if (bundleObj == nullptr) {
686         SEN_HILOGE("BundleObj error");
687         return false;
688     }
689     auto bundleMgrProxy = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
690     if (bundleMgrProxy == nullptr) {
691         SEN_HILOGE("BundleMgrProxy error");
692         return false;
693     }
694     AppExecFwk::BundleInfo bundleInfo;
695     ErrCode ret = bundleMgrProxy->GetBundleInfoForSelf(OHOS::AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo);
696     if (ret != ERR_OK) {
697         SEN_HILOGE("GetBundleInfoForSelf error");
698         return false;
699     }
700     targetVersion = bundleInfo.targetVersion;
701     return true;
702 }
703 } // namespace Sensors
704 } // namespace OHOS