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 } // namespace
34 static std::mutex g_sensorAttrListMutex;
IsSameValue(const napi_env & env,const napi_value & lhs,const napi_value & rhs)35 bool IsSameValue(const napi_env &env, const napi_value &lhs, const napi_value &rhs)
36 {
37 CALL_LOG_ENTER;
38 bool result = false;
39 CHKNRF(env, napi_strict_equals(env, lhs, rhs, &result), "napi_strict_equals");
40 return result;
41 }
42
IsMatchType(const napi_env & env,const napi_value & value,const napi_valuetype & type)43 bool IsMatchType(const napi_env &env, const napi_value &value, const napi_valuetype &type)
44 {
45 CALL_LOG_ENTER;
46 napi_valuetype paramType = napi_undefined;
47 CHKNRF(env, napi_typeof(env, value, ¶mType), "napi_typeof");
48 return paramType == type;
49 }
50
IsMatchArrayType(const napi_env & env,const napi_value & value)51 bool IsMatchArrayType(const napi_env &env, const napi_value &value)
52 {
53 CALL_LOG_ENTER;
54 bool result = false;
55 CHKNRF(env, napi_is_array(env, value, &result), "napi_is_array");
56 return result;
57 }
58
GetFloatArray(const napi_env & env,const napi_value & value,vector<float> & array)59 bool GetFloatArray(const napi_env &env, const napi_value &value, vector<float> &array)
60 {
61 CALL_LOG_ENTER;
62 uint32_t arrayLength = 0;
63 CHKNRF(env, napi_get_array_length(env, value, &arrayLength), "napi_get_array_length");
64 for (size_t i = 0; i < arrayLength; ++i) {
65 napi_value element = nullptr;
66 CHKNRF(env, napi_get_element(env, value, i, &element), "napi_get_element");
67 CHKNCF(env, IsMatchType(env, element, napi_number), "Wrong argument type. Number or function expected");
68 double number = 0;
69 CHKNCF(env, GetNativeDouble(env, element, number), "Wrong argument type. get double fail");
70 array.push_back(static_cast<float>(number));
71 }
72 return true;
73 }
74
GetNamedProperty(const napi_env & env,const napi_value & object,string name)75 napi_value GetNamedProperty(const napi_env &env, const napi_value &object, string name)
76 {
77 CALL_LOG_ENTER;
78 bool status = false;
79 CHKNRP(env, napi_has_named_property(env, object, name.c_str(), &status), "napi_has_named_property");
80 if (!status) {
81 SEN_HILOGW("%{public}s not exists on the object", name.c_str());
82 return nullptr;
83 }
84 napi_value value = nullptr;
85 CHKNRP(env, napi_get_named_property(env, object, name.c_str(), &value),
86 "napi_get_named_property");
87 return value;
88 }
89
GetNativeDouble(const napi_env & env,const napi_value & value,double & number)90 bool GetNativeDouble(const napi_env &env, const napi_value &value, double &number)
91 {
92 CALL_LOG_ENTER;
93 CHKNRF(env, napi_get_value_double(env, value, &number), "napi_get_value_double");
94 return true;
95 }
96
GetNativeFloat(const napi_env & env,const napi_value & value,float & number)97 bool GetNativeFloat(const napi_env &env, const napi_value &value, float &number)
98 {
99 CALL_LOG_ENTER;
100 double result = 0;
101 CHKNCF(env, GetNativeDouble(env, value, result), "Get cpp double fail");
102 number = static_cast<float>(result);
103 return true;
104 }
105
GetNativeInt32(const napi_env & env,const napi_value & value,int32_t & number)106 bool GetNativeInt32(const napi_env &env, const napi_value &value, int32_t &number)
107 {
108 CALL_LOG_ENTER;
109 CHKNRF(env, napi_get_value_int32(env, value, &number), "napi_get_value_int32");
110 return true;
111 }
112
GetNativeInt64(const napi_env & env,const napi_value & value,int64_t & number)113 bool GetNativeInt64(const napi_env &env, const napi_value &value, int64_t &number)
114 {
115 CALL_LOG_ENTER;
116 CHKNRF(env, napi_get_value_int64(env, value, &number), "napi_get_value_int64");
117 return true;
118 }
119
GetNativeBool(const napi_env & env,const napi_value & value)120 bool GetNativeBool(const napi_env &env, const napi_value &value)
121 {
122 CALL_LOG_ENTER;
123 bool number = false;
124 CHKNRF(env, napi_get_value_bool(env, value, &number), "napi_get_value_bool");
125 return number;
126 }
127
GetNapiInt32(const napi_env & env,int32_t number)128 napi_value GetNapiInt32(const napi_env &env, int32_t number)
129 {
130 napi_value value = nullptr;
131 CHKNRP(env, napi_create_int32(env, number, &value), "napi_create_int32");
132 return value;
133 }
134
GetStringValue(const napi_env & env,const napi_value & value,string & result)135 bool GetStringValue(const napi_env &env, const napi_value &value, string &result)
136 {
137 CALL_LOG_ENTER;
138 CHKNCF(env, IsMatchType(env, value, napi_string), "Wrong argument type. String or function expected");
139 char buf[STRING_LENGTH_MAX] = { 0 };
140 size_t copyLength = 0;
141 CHKNRF(env, napi_get_value_string_utf8(env, value, buf, STRING_LENGTH_MAX, ©Length),
142 "napi_get_value_string_utf8");
143 result = std::string(buf);
144 return true;
145 }
146
RegisterNapiCallback(const napi_env & env,const napi_value & value,napi_ref & callback)147 bool RegisterNapiCallback(const napi_env &env, const napi_value &value,
148 napi_ref &callback)
149 {
150 CHKNCF(env, IsMatchType(env, value, napi_function), "Wrong argument type, should be function");
151 CHKNRF(env, napi_create_reference(env, value, 1, &callback), "napi_create_reference");
152 return true;
153 }
154
CreateFailMessage(CallbackDataType type,int32_t code,string message,sptr<AsyncCallbackInfo> & asyncCallbackInfo)155 bool CreateFailMessage(CallbackDataType type, int32_t code, string message,
156 sptr<AsyncCallbackInfo> &asyncCallbackInfo)
157 {
158 CHKPF(asyncCallbackInfo);
159 asyncCallbackInfo->type = type;
160 asyncCallbackInfo->error.code = code;
161 asyncCallbackInfo->error.message = message;
162 return true;
163 }
164
165 std::map<int32_t, vector<string>> g_sensorAttributeList = {
166 { 0, { "x" } },
167 { SENSOR_TYPE_ID_ACCELEROMETER, { "x", "y", "z" } },
168 { SENSOR_TYPE_ID_GYROSCOPE, { "x", "y", "z" } },
169 { SENSOR_TYPE_ID_AMBIENT_LIGHT, { "intensity", "colorTemperature", "infraredLuminance" } },
170 { SENSOR_TYPE_ID_MAGNETIC_FIELD, { "x", "y", "z" } },
171 { SENSOR_TYPE_ID_BAROMETER, { "pressure" } },
172 { SENSOR_TYPE_ID_HALL, { "status" } },
173 { SENSOR_TYPE_ID_TEMPERATURE, { "temperature" } },
174 { SENSOR_TYPE_ID_PROXIMITY, { "distance" } },
175 { SENSOR_TYPE_ID_HUMIDITY, { "humidity" } },
176 { SENSOR_TYPE_ID_ORIENTATION, { "alpha", "beta", "gamma" } },
177 { SENSOR_TYPE_ID_GRAVITY, { "x", "y", "z" } },
178 { SENSOR_TYPE_ID_LINEAR_ACCELERATION, { "x", "y", "z" } },
179 { SENSOR_TYPE_ID_ROTATION_VECTOR, { "x", "y", "z", "w" } },
180 { SENSOR_TYPE_ID_AMBIENT_TEMPERATURE, { "temperature" } },
181 { SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } },
182 { SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } },
183 { SENSOR_TYPE_ID_SIGNIFICANT_MOTION, { "scalar" } },
184 { SENSOR_TYPE_ID_PEDOMETER_DETECTION, { "scalar" } },
185 { SENSOR_TYPE_ID_PEDOMETER, { "steps" } },
186 { SENSOR_TYPE_ID_HEART_RATE, { "heartRate" } },
187 { SENSOR_TYPE_ID_WEAR_DETECTION, { "value" } },
188 { SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } },
189 { SENSOR_TYPE_ID_COLOR, { "lightIntensity", "colorTemperature" } },
190 { SENSOR_TYPE_ID_SAR, { "absorptionRatio" } }
191 };
192
193 std::map<int32_t, ConvertDataFunc> g_convertfuncList = {
194 {FAIL, ConvertToFailData},
195 {ON_CALLBACK, ConvertToSensorData},
196 {ONCE_CALLBACK, ConvertToSensorData},
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_CALLBACK, ConvertToSensorData},
210 {SUBSCRIBE_COMPASS, ConvertToCompass},
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.sensorId, &value), "napi_create_double");
267 CHKNRF(env, napi_set_named_property(env, result, "sensorId", value), "napi_set_named_property");
268 value = nullptr;
269 CHKNRF(env, napi_create_double(env, sensorInfo.maxRange, &value), "napi_create_double");
270 CHKNRF(env, napi_set_named_property(env, result, "maxRange", value), "napi_set_named_property");
271 value = nullptr;
272 CHKNRF(env, napi_create_double(env, sensorInfo.precision, &value), "napi_create_double");
273 CHKNRF(env, napi_set_named_property(env, result, "precision", value), "napi_set_named_property");
274 value = nullptr;
275 CHKNRF(env, napi_create_double(env, sensorInfo.power, &value), "napi_create_double");
276 CHKNRF(env, napi_set_named_property(env, result, "power", value), "napi_set_named_property");
277 value = nullptr;
278 CHKNRF(env, napi_create_int64(env, sensorInfo.minSamplePeriod, &value), "napi_create_int64");
279 CHKNRF(env, napi_set_named_property(env, result, "minSamplePeriod", value), "napi_set_named_property");
280 value = nullptr;
281 CHKNRF(env, napi_create_int64(env, sensorInfo.maxSamplePeriod, &value), "napi_create_int64");
282 CHKNRF(env, napi_set_named_property(env, result, "maxSamplePeriod", value), "napi_set_named_property");
283 return true;
284 }
285
ConvertToSingleSensor(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])286 bool ConvertToSingleSensor(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
287 {
288 CALL_LOG_ENTER;
289 CHKPF(asyncCallbackInfo);
290 return ConvertToSensorInfo(env, asyncCallbackInfo->sensorInfos[0], result[1]);
291 }
292
ConvertToSensorInfos(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])293 bool ConvertToSensorInfos(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
294 {
295 CALL_LOG_ENTER;
296 CHKPF(asyncCallbackInfo);
297 CHKNRF(env, napi_create_array(env, &result[1]), "napi_create_array");
298 auto sensorInfos = asyncCallbackInfo->sensorInfos;
299 for (uint32_t i = 0; i < sensorInfos.size(); ++i) {
300 napi_value value = nullptr;
301 CHKNCF(env, ConvertToSensorInfo(env, sensorInfos[i], value), "Convert sensor info fail");
302 CHKNRF(env, napi_set_element(env, result[1], i, value), "napi_set_element");
303 }
304 return true;
305 }
306
ConvertToFailData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])307 bool ConvertToFailData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
308 {
309 CALL_LOG_ENTER;
310 CHKPF(asyncCallbackInfo);
311 int32_t code = asyncCallbackInfo->error.code;
312 auto msg = GetNapiError(code);
313 if (!msg) {
314 SEN_HILOGE("ErrCode:%{public}d is invalid", code);
315 return false;
316 }
317 result[0] = CreateBusinessError(env, code, msg.value());
318 return (result[0] != nullptr);
319 }
320
ConvertToSensorData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])321 bool ConvertToSensorData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
322 {
323 CHKPF(asyncCallbackInfo);
324 int32_t sensorTypeId = asyncCallbackInfo->data.sensorData.sensorTypeId;
325 std::lock_guard<std::mutex> sensorAttrListLock(g_sensorAttrListMutex);
326 CHKNCF(env, (g_sensorAttributeList.find(sensorTypeId) != g_sensorAttributeList.end()), "Invalid sensor type");
327 if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && asyncCallbackInfo->type == SUBSCRIBE_CALLBACK) {
328 return ConvertToBodyData(env, asyncCallbackInfo, result);
329 }
330 size_t size = g_sensorAttributeList[sensorTypeId].size();
331 uint32_t dataLength = asyncCallbackInfo->data.sensorData.dataLength / sizeof(float);
332 CHKNCF(env, (size <= dataLength), "Data length mismatch");
333
334 CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
335 napi_value message = nullptr;
336 auto sensorAttributes = g_sensorAttributeList[sensorTypeId];
337 for (uint32_t i = 0; i < size; ++i) {
338 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.sensorData.data[i], &message),
339 "napi_create_double");
340 CHKNRF(env, napi_set_named_property(env, result[1], sensorAttributes[i].c_str(), message),
341 "napi_set_named_property");
342 message = nullptr;
343 }
344 CHKNRF(env, napi_create_int64(env, asyncCallbackInfo->data.sensorData.timestamp, &message),
345 "napi_create_int64");
346 CHKNRF(env, napi_set_named_property(env, result[1], "timestamp", message), "napi_set_named_property");
347 message = nullptr;
348 CHKNRF(env, napi_create_int32(env, asyncCallbackInfo->data.sensorData.sensorAccuracy, &message),
349 "napi_create_int32");
350 CHKNRF(env, napi_set_named_property(env, result[1], "accuracy", message), "napi_set_named_property");
351 return true;
352 }
353
ConvertToGeomagneticData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])354 bool ConvertToGeomagneticData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
355 {
356 CALL_LOG_ENTER;
357 return getJsonObject(env, asyncCallbackInfo, result[1]);
358 }
359
ConvertToBodyData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])360 bool ConvertToBodyData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
361 {
362 CALL_LOG_ENTER;
363 CHKPF(asyncCallbackInfo);
364 CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
365 napi_value status = nullptr;
366 CHKNRF(env, napi_get_boolean(env, asyncCallbackInfo->data.sensorData.data[0], &status),
367 "napi_get_boolean");
368 CHKNRF(env, napi_set_named_property(env, result[1], "value", status), "napi_set_named_property");
369 return true;
370 }
371
ConvertToCompass(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])372 bool ConvertToCompass(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
373 {
374 CALL_LOG_ENTER;
375 CHKPF(asyncCallbackInfo);
376 CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
377 napi_value message = nullptr;
378 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.sensorData.data[0], &message),
379 "napi_create_double");
380 CHKNRF(env, napi_set_named_property(env, result[1], "direction", message), "napi_set_named_property");
381 return true;
382 }
383
ConvertToNumber(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])384 bool ConvertToNumber(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
385 {
386 CALL_LOG_ENTER;
387 CHKPF(asyncCallbackInfo);
388 napi_status status =
389 napi_create_double(env, static_cast<double>(asyncCallbackInfo->data.reserveData.reserve[0]), &result[1]);
390 CHKNRF(env, status, "napi_create_double");
391 return true;
392 }
393
ConvertToArray(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])394 bool ConvertToArray(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
395 {
396 CALL_LOG_ENTER;
397 CHKPF(asyncCallbackInfo);
398 bool ret = CreateNapiArray(env, asyncCallbackInfo->data.reserveData.reserve,
399 asyncCallbackInfo->data.reserveData.length, result[1]);
400 CHKNCF(env, ret, "Create napi array fail");
401 return true;
402 }
403
ConvertToRotationMatrix(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])404 bool ConvertToRotationMatrix(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
405 {
406 CALL_LOG_ENTER;
407 CHKPF(asyncCallbackInfo);
408 napi_value rotation = nullptr;
409 bool ret = CreateNapiArray(env, asyncCallbackInfo->data.rationMatrixData.rotationMatrix,
410 THREE_DIMENSIONAL_MATRIX_LENGTH, rotation);
411 CHKNCF(env, ret, "Create napi array rotation fail");
412 napi_value inclination = nullptr;
413 ret = CreateNapiArray(env, asyncCallbackInfo->data.rationMatrixData.inclinationMatrix,
414 THREE_DIMENSIONAL_MATRIX_LENGTH, inclination);
415 CHKNCF(env, ret, "Create napi array inclination fail");
416 CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
417 CHKNRF(env, napi_set_named_property(env, result[1], "rotation", rotation),
418 "napi_set_named_property");
419 CHKNRF(env, napi_set_named_property(env, result[1], "inclination", inclination),
420 "napi_set_named_property");
421 return true;
422 }
423
CreateNapiArray(const napi_env & env,float data[],int32_t dataLength,napi_value & result)424 bool CreateNapiArray(const napi_env &env, float data[], int32_t dataLength, napi_value &result)
425 {
426 CHKNRF(env, napi_create_array(env, &result), "napi_create_array");
427 for (int32_t i = 0; i < dataLength; ++i) {
428 napi_value message = nullptr;
429 CHKNRF(env, napi_create_double(env, data[i], &message), "napi_create_double");
430 CHKNRF(env, napi_set_element(env, result, i, message), "napi_set_element");
431 }
432 return true;
433 }
434
ReleaseCallback(sptr<AsyncCallbackInfo> asyncCallbackInfo)435 void ReleaseCallback(sptr<AsyncCallbackInfo> asyncCallbackInfo)
436 {
437 CHKPV(asyncCallbackInfo);
438 if (asyncCallbackInfo->type == ONCE_CALLBACK) {
439 napi_env env = asyncCallbackInfo->env;
440 CHKPV(env);
441 napi_ref callback = asyncCallbackInfo->callback[0];
442 if (callback != nullptr) {
443 napi_delete_reference(env, callback);
444 }
445 }
446 }
447
EmitAsyncCallbackWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)448 void EmitAsyncCallbackWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)
449 {
450 CALL_LOG_ENTER;
451 CHKPV(asyncCallbackInfo);
452 napi_value resourceName = nullptr;
453 napi_env env = asyncCallbackInfo->env;
454 napi_status ret = napi_create_string_latin1(env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName);
455 CHKCV((ret == napi_ok), "napi_create_string_latin1 fail");
456 asyncCallbackInfo->IncStrongRef(nullptr);
457 napi_status status = napi_create_async_work(env, nullptr, resourceName,
458 [](napi_env env, void *data) {},
459 [](napi_env env, napi_status status, void *data) {
460 CALL_LOG_ENTER;
461 sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(data));
462 /**
463 * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
464 * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
465 * asynchronous task is created, and subtract 1 from the reference count after the naked
466 * pointer is converted to a pointer when the asynchronous task is executed, the reference
467 * count of the smart pointer is guaranteed to be 1.
468 */
469 asyncCallbackInfo->DecStrongRef(nullptr);
470 napi_value callback = nullptr;
471 napi_value callResult = nullptr;
472 napi_value result[2] = {0};
473 if (asyncCallbackInfo->type == SUBSCRIBE_FAIL) {
474 CHKCV((napi_get_reference_value(env, asyncCallbackInfo->callback[1], &callback) == napi_ok),
475 "napi_get_reference_value fail");
476 CHKCV((napi_create_string_utf8(env, asyncCallbackInfo->error.message.c_str(),
477 NAPI_AUTO_LENGTH, &result[0]) == napi_ok), "napi_create_string_utf8 fail");
478 CHKCV((napi_create_int32(env, asyncCallbackInfo->error.code, &result[1]) == napi_ok),
479 "napi_create_int32 fail");
480 CHKCV((napi_call_function(env, nullptr, callback, 2, result, &callResult) == napi_ok),
481 "napi_call_function fail");
482 return;
483 }
484 CHKCV((napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback) == napi_ok),
485 "napi_get_reference_value fail");
486 CHKCV((g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end()),
487 "Callback type invalid in async work");
488 bool ret = g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
489 CHKCV(ret, "Create napi data fail in async work");
490 CHKCV((napi_call_function(env, nullptr, callback, 2, result, &callResult) == napi_ok),
491 "napi_call_function fail");
492 },
493 asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork);
494 if (status != napi_ok
495 || napi_queue_async_work_with_qos(
496 asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) {
497 SEN_HILOGE("Create async work fail");
498 asyncCallbackInfo->DecStrongRef(nullptr);
499 }
500 }
501
DeleteWork(uv_work_t * work)502 void DeleteWork(uv_work_t *work)
503 {
504 CHKPV(work);
505 delete work;
506 work = nullptr;
507 }
508
EmitUvEventLoop(sptr<AsyncCallbackInfo> asyncCallbackInfo)509 void EmitUvEventLoop(sptr<AsyncCallbackInfo> asyncCallbackInfo)
510 {
511 CHKPV(asyncCallbackInfo);
512 uv_loop_s *loop(nullptr);
513 CHKCV((napi_get_uv_event_loop(asyncCallbackInfo->env, &loop) == napi_ok), "napi_get_uv_event_loop fail");
514 CHKPV(loop);
515 uv_work_t *work = new(std::nothrow) uv_work_t;
516 CHKPV(work);
517 asyncCallbackInfo->IncStrongRef(nullptr);
518 work->data = asyncCallbackInfo.GetRefPtr();
519 int32_t ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) { }, [] (uv_work_t *work, int status) {
520 CHKPV(work);
521 sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(work->data));
522 DeleteWork(work);
523 /**
524 * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
525 * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
526 * asynchronous task is created, and subtract 1 from the reference count after the naked
527 * pointer is converted to a pointer when the asynchronous task is executed, the reference
528 * count of the smart pointer is guaranteed to be 1.
529 */
530 asyncCallbackInfo->DecStrongRef(nullptr);
531 napi_handle_scope scope = nullptr;
532 napi_open_handle_scope(asyncCallbackInfo->env, &scope);
533 if (scope == nullptr) {
534 SEN_HILOGE("napi_handle_scope is nullptr");
535 ReleaseCallback(asyncCallbackInfo);
536 return;
537 }
538 napi_env env = asyncCallbackInfo->env;
539 napi_value callback = nullptr;
540 if (napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback) != napi_ok) {
541 SEN_HILOGE("napi_get_reference_value fail");
542 napi_throw_error(env, nullptr, "napi_get_reference_value fail");
543 ReleaseCallback(asyncCallbackInfo);
544 napi_close_handle_scope(asyncCallbackInfo->env, scope);
545 return;
546 }
547 napi_value callResult = nullptr;
548 napi_value result[2] = {0};
549 if (!(g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end())) {
550 SEN_HILOGE("asyncCallbackInfo type is invalid");
551 napi_throw_error(env, nullptr, "asyncCallbackInfo type is invalid");
552 ReleaseCallback(asyncCallbackInfo);
553 napi_close_handle_scope(asyncCallbackInfo->env, scope);
554 return;
555 }
556 g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
557 if (napi_call_function(env, nullptr, callback, 1, &result[1], &callResult) != napi_ok) {
558 SEN_HILOGE("napi_call_function callback fail");
559 napi_throw_error(env, nullptr, "napi_call_function callback fail");
560 ReleaseCallback(asyncCallbackInfo);
561 napi_close_handle_scope(asyncCallbackInfo->env, scope);
562 return;
563 }
564 ReleaseCallback(asyncCallbackInfo);
565 napi_close_handle_scope(asyncCallbackInfo->env, scope);
566 }, uv_qos_default);
567 if (ret != 0) {
568 SEN_HILOGE("uv_queue_work_with_qos fail");
569 asyncCallbackInfo->DecStrongRef(nullptr);
570 DeleteWork(work);
571 }
572 }
573
EmitPromiseWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)574 void EmitPromiseWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)
575 {
576 CALL_LOG_ENTER;
577 CHKPV(asyncCallbackInfo);
578 napi_value resourceName = nullptr;
579 napi_env env = asyncCallbackInfo->env;
580 napi_status ret = napi_create_string_latin1(env, "Promise", NAPI_AUTO_LENGTH, &resourceName);
581 CHKCV((ret == napi_ok), "napi_create_string_latin1 fail");
582 asyncCallbackInfo->IncStrongRef(nullptr);
583 napi_status status = napi_create_async_work(env, nullptr, resourceName,
584 [](napi_env env, void *data) {},
585 [](napi_env env, napi_status status, void *data) {
586 CALL_LOG_ENTER;
587 sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(data));
588 /**
589 * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
590 * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
591 * asynchronous task is created, and subtract 1 from the reference count after the naked
592 * pointer is converted to a pointer when the asynchronous task is executed, the reference
593 * count of the smart pointer is guaranteed to be 1.
594 */
595 asyncCallbackInfo->DecStrongRef(nullptr);
596 napi_value result[2] = {0};
597 CHKCV((g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end()),
598 "Callback type invalid in promise");
599 bool ret = g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
600 CHKCV(ret, "Callback type invalid in promise");
601 if (asyncCallbackInfo->type == FAIL) {
602 CHKCV((napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]) == napi_ok),
603 "napi_reject_deferred fail");
604 } else {
605 CHKCV((napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[1]) == napi_ok),
606 "napi_resolve_deferred fail");
607 }
608 },
609 asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork);
610 if (status != napi_ok
611 || napi_queue_async_work_with_qos(
612 asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) {
613 SEN_HILOGE("Create async work fail");
614 asyncCallbackInfo->DecStrongRef(nullptr);
615 }
616 }
617
GetSelfTargetVersion(uint32_t & targetVersion)618 bool GetSelfTargetVersion(uint32_t &targetVersion)
619 {
620 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
621 if (samgr == nullptr) {
622 SEN_HILOGE("Samgr error");
623 return false;
624 }
625 auto bundleObj = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
626 if (bundleObj == nullptr) {
627 SEN_HILOGE("BundleObj error");
628 return false;
629 }
630 auto bundleMgrProxy = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
631 if (bundleMgrProxy == nullptr) {
632 SEN_HILOGE("BundleMgrProxy error");
633 return false;
634 }
635 AppExecFwk::BundleInfo bundleInfo;
636 ErrCode ret = bundleMgrProxy->GetBundleInfoForSelf(OHOS::AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo);
637 if (ret != ERR_OK) {
638 SEN_HILOGE("GetBundleInfoForSelf error");
639 return false;
640 }
641 targetVersion = bundleInfo.targetVersion;
642 return true;
643 }
644 } // namespace Sensors
645 } // namespace OHOS