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 (uint32_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 { SENSOR_TYPE_ID_FUSION_PRESSURE, { "fusionPressure" } },
192 };
193
194 std::map<int32_t, ConvertDataFunc> g_convertfuncList = {
195 {FAIL, ConvertToFailData},
196 {ON_CALLBACK, ConvertToSensorData},
197 {ONCE_CALLBACK, ConvertToSensorData},
198 {GET_GEOMAGNETIC_FIELD, ConvertToGeomagneticData},
199 {GET_ALTITUDE, ConvertToNumber},
200 {GET_GEOMAGNETIC_DIP, ConvertToNumber},
201 {GET_ANGLE_MODIFY, ConvertToArray},
202 {CREATE_ROTATION_MATRIX, ConvertToArray},
203 {TRANSFORM_COORDINATE_SYSTEM, ConvertToArray},
204 {CREATE_QUATERNION, ConvertToArray},
205 {GET_DIRECTION, ConvertToArray},
206 {ROTATION_INCLINATION_MATRIX, ConvertToRotationMatrix},
207 {GET_SENSOR_LIST, ConvertToSensorInfos},
208 {GET_SINGLE_SENSOR, ConvertToSingleSensor},
209 {GET_BODY_STATE, ConvertToBodyData},
210 {SUBSCRIBE_CALLBACK, ConvertToSensorData},
211 {SUBSCRIBE_COMPASS, ConvertToCompass},
212 };
213
getJsonObject(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value & result)214 bool getJsonObject(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value &result)
215 {
216 CHKPF(asyncCallbackInfo);
217 CHKNRF(env, napi_create_object(env, &result), "napi_create_object");
218 napi_value value = nullptr;
219 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.x, &value), "napi_create_double");
220 CHKNRF(env, napi_set_named_property(env, result, "x", value), "napi_set_named_property");
221 value = nullptr;
222 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.y, &value), "napi_create_double");
223 CHKNRF(env, napi_set_named_property(env, result, "y", value), "napi_set_named_property");
224 value = nullptr;
225 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.z, &value), "napi_create_double");
226 CHKNRF(env, napi_set_named_property(env, result, "z", value), "napi_set_named_property");
227 value = nullptr;
228 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.geomagneticDip, &value),
229 "napi_create_double");
230 CHKNRF(env, napi_set_named_property(env, result, "geomagneticDip", value), "napi_set_named_property");
231 value = nullptr;
232 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.deflectionAngle, &value),
233 "napi_create_double");
234 CHKNRF(env, napi_set_named_property(env, result, "deflectionAngle", value), "napi_set_named_property");
235 value = nullptr;
236 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.levelIntensity, &value),
237 "napi_create_double");
238 CHKNRF(env, napi_set_named_property(env, result, "levelIntensity", value), "napi_set_named_property");
239 value = nullptr;
240 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.geomagneticData.totalIntensity, &value),
241 "napi_create_double");
242 CHKNRF(env, napi_set_named_property(env, result, "totalIntensity", value), "napi_set_named_property");
243 return true;
244 }
245
ConvertToSensorInfo(const napi_env & env,const SensorInfo & sensorInfo,napi_value & result)246 bool ConvertToSensorInfo(const napi_env &env, const SensorInfo &sensorInfo, napi_value &result)
247 {
248 CALL_LOG_ENTER;
249 CHKNRF(env, napi_create_object(env, &result), "napi_create_object");
250 napi_value value = nullptr;
251 CHKNRF(env, napi_create_string_latin1(env, sensorInfo.sensorName, NAPI_AUTO_LENGTH, &value),
252 "napi_create_string_latin1");
253 CHKNRF(env, napi_set_named_property(env, result, "sensorName", value), "napi_set_named_property");
254 value = nullptr;
255 CHKNRF(env, napi_create_string_latin1(env, sensorInfo.vendorName, NAPI_AUTO_LENGTH, &value),
256 "napi_create_string_latin1");
257 CHKNRF(env, napi_set_named_property(env, result, "vendorName", value), "napi_set_named_property");
258 value = nullptr;
259 CHKNRF(env, napi_create_string_latin1(env, sensorInfo.firmwareVersion, NAPI_AUTO_LENGTH, &value),
260 "napi_create_string_latin1");
261 CHKNRF(env, napi_set_named_property(env, result, "firmwareVersion", value), "napi_set_named_property");
262 value = nullptr;
263 CHKNRF(env, napi_create_string_latin1(env, sensorInfo.hardwareVersion, NAPI_AUTO_LENGTH, &value),
264 "napi_create_string_latin1");
265 CHKNRF(env, napi_set_named_property(env, result, "hardwareVersion", value), "napi_set_named_property");
266 value = nullptr;
267 CHKNRF(env, napi_create_double(env, sensorInfo.sensorId, &value), "napi_create_double");
268 CHKNRF(env, napi_set_named_property(env, result, "sensorId", value), "napi_set_named_property");
269 value = nullptr;
270 CHKNRF(env, napi_create_double(env, sensorInfo.maxRange, &value), "napi_create_double");
271 CHKNRF(env, napi_set_named_property(env, result, "maxRange", value), "napi_set_named_property");
272 value = nullptr;
273 CHKNRF(env, napi_create_double(env, sensorInfo.precision, &value), "napi_create_double");
274 CHKNRF(env, napi_set_named_property(env, result, "precision", value), "napi_set_named_property");
275 value = nullptr;
276 CHKNRF(env, napi_create_double(env, sensorInfo.power, &value), "napi_create_double");
277 CHKNRF(env, napi_set_named_property(env, result, "power", value), "napi_set_named_property");
278 value = nullptr;
279 CHKNRF(env, napi_create_int64(env, sensorInfo.minSamplePeriod, &value), "napi_create_int64");
280 CHKNRF(env, napi_set_named_property(env, result, "minSamplePeriod", value), "napi_set_named_property");
281 value = nullptr;
282 CHKNRF(env, napi_create_int64(env, sensorInfo.maxSamplePeriod, &value), "napi_create_int64");
283 CHKNRF(env, napi_set_named_property(env, result, "maxSamplePeriod", value), "napi_set_named_property");
284 return true;
285 }
286
ConvertToSingleSensor(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])287 bool ConvertToSingleSensor(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
288 {
289 CALL_LOG_ENTER;
290 CHKPF(asyncCallbackInfo);
291 return ConvertToSensorInfo(env, asyncCallbackInfo->sensorInfos[0], result[1]);
292 }
293
ConvertToSensorInfos(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])294 bool ConvertToSensorInfos(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
295 {
296 CALL_LOG_ENTER;
297 CHKPF(asyncCallbackInfo);
298 CHKNRF(env, napi_create_array(env, &result[1]), "napi_create_array");
299 auto sensorInfos = asyncCallbackInfo->sensorInfos;
300 for (uint32_t i = 0; i < sensorInfos.size(); ++i) {
301 napi_value value = nullptr;
302 CHKNCF(env, ConvertToSensorInfo(env, sensorInfos[i], value), "Convert sensor info fail");
303 CHKNRF(env, napi_set_element(env, result[1], i, value), "napi_set_element");
304 }
305 return true;
306 }
307
ConvertToFailData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])308 bool ConvertToFailData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
309 {
310 CALL_LOG_ENTER;
311 CHKPF(asyncCallbackInfo);
312 int32_t code = asyncCallbackInfo->error.code;
313 auto msg = GetNapiError(code);
314 if (!msg) {
315 SEN_HILOGE("ErrCode:%{public}d is invalid", code);
316 return false;
317 }
318 result[0] = CreateBusinessError(env, code, msg.value());
319 return (result[0] != nullptr);
320 }
321
ConvertToSensorData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])322 bool ConvertToSensorData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
323 {
324 CHKPF(asyncCallbackInfo);
325 int32_t sensorTypeId = asyncCallbackInfo->data.sensorData.sensorTypeId;
326 std::lock_guard<std::mutex> sensorAttrListLock(g_sensorAttrListMutex);
327 CHKNCF(env, (g_sensorAttributeList.find(sensorTypeId) != g_sensorAttributeList.end()), "Invalid sensor type");
328 if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && asyncCallbackInfo->type == SUBSCRIBE_CALLBACK) {
329 return ConvertToBodyData(env, asyncCallbackInfo, result);
330 }
331 size_t size = g_sensorAttributeList[sensorTypeId].size();
332 uint32_t dataLength = asyncCallbackInfo->data.sensorData.dataLength / sizeof(float);
333 CHKNCF(env, (size <= dataLength), "Data length mismatch");
334
335 CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
336 napi_value message = nullptr;
337 auto sensorAttributes = g_sensorAttributeList[sensorTypeId];
338 for (uint32_t i = 0; i < size; ++i) {
339 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.sensorData.data[i], &message),
340 "napi_create_double");
341 CHKNRF(env, napi_set_named_property(env, result[1], sensorAttributes[i].c_str(), message),
342 "napi_set_named_property");
343 message = nullptr;
344 }
345 CHKNRF(env, napi_create_int64(env, asyncCallbackInfo->data.sensorData.timestamp, &message),
346 "napi_create_int64");
347 CHKNRF(env, napi_set_named_property(env, result[1], "timestamp", message), "napi_set_named_property");
348 message = nullptr;
349 CHKNRF(env, napi_create_int32(env, asyncCallbackInfo->data.sensorData.sensorAccuracy, &message),
350 "napi_create_int32");
351 CHKNRF(env, napi_set_named_property(env, result[1], "accuracy", message), "napi_set_named_property");
352 return true;
353 }
354
ConvertToGeomagneticData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])355 bool ConvertToGeomagneticData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
356 {
357 CALL_LOG_ENTER;
358 return getJsonObject(env, asyncCallbackInfo, result[1]);
359 }
360
ConvertToBodyData(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])361 bool ConvertToBodyData(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
362 {
363 CALL_LOG_ENTER;
364 CHKPF(asyncCallbackInfo);
365 CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
366 napi_value status = nullptr;
367 CHKNRF(env, napi_get_boolean(env, asyncCallbackInfo->data.sensorData.data[0], &status),
368 "napi_get_boolean");
369 CHKNRF(env, napi_set_named_property(env, result[1], "value", status), "napi_set_named_property");
370 return true;
371 }
372
ConvertToCompass(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])373 bool ConvertToCompass(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
374 {
375 CALL_LOG_ENTER;
376 CHKPF(asyncCallbackInfo);
377 CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
378 napi_value message = nullptr;
379 CHKNRF(env, napi_create_double(env, asyncCallbackInfo->data.sensorData.data[0], &message),
380 "napi_create_double");
381 CHKNRF(env, napi_set_named_property(env, result[1], "direction", message), "napi_set_named_property");
382 return true;
383 }
384
ConvertToNumber(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])385 bool ConvertToNumber(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
386 {
387 CALL_LOG_ENTER;
388 CHKPF(asyncCallbackInfo);
389 napi_status status =
390 napi_create_double(env, static_cast<double>(asyncCallbackInfo->data.reserveData.reserve[0]), &result[1]);
391 CHKNRF(env, status, "napi_create_double");
392 return true;
393 }
394
ConvertToArray(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])395 bool ConvertToArray(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
396 {
397 CALL_LOG_ENTER;
398 CHKPF(asyncCallbackInfo);
399 bool ret = CreateNapiArray(env, asyncCallbackInfo->data.reserveData.reserve,
400 asyncCallbackInfo->data.reserveData.length, result[1]);
401 CHKNCF(env, ret, "Create napi array fail");
402 return true;
403 }
404
ConvertToRotationMatrix(const napi_env & env,sptr<AsyncCallbackInfo> asyncCallbackInfo,napi_value result[2])405 bool ConvertToRotationMatrix(const napi_env &env, sptr<AsyncCallbackInfo> asyncCallbackInfo, napi_value result[2])
406 {
407 CALL_LOG_ENTER;
408 CHKPF(asyncCallbackInfo);
409 napi_value rotation = nullptr;
410 bool ret = CreateNapiArray(env, asyncCallbackInfo->data.rationMatrixData.rotationMatrix,
411 THREE_DIMENSIONAL_MATRIX_LENGTH, rotation);
412 CHKNCF(env, ret, "Create napi array rotation fail");
413 napi_value inclination = nullptr;
414 ret = CreateNapiArray(env, asyncCallbackInfo->data.rationMatrixData.inclinationMatrix,
415 THREE_DIMENSIONAL_MATRIX_LENGTH, inclination);
416 CHKNCF(env, ret, "Create napi array inclination fail");
417 CHKNRF(env, napi_create_object(env, &result[1]), "napi_create_object");
418 CHKNRF(env, napi_set_named_property(env, result[1], "rotation", rotation),
419 "napi_set_named_property");
420 CHKNRF(env, napi_set_named_property(env, result[1], "inclination", inclination),
421 "napi_set_named_property");
422 return true;
423 }
424
CreateNapiArray(const napi_env & env,float data[],int32_t dataLength,napi_value & result)425 bool CreateNapiArray(const napi_env &env, float data[], int32_t dataLength, napi_value &result)
426 {
427 CHKNRF(env, napi_create_array(env, &result), "napi_create_array");
428 for (int32_t i = 0; i < dataLength; ++i) {
429 napi_value message = nullptr;
430 CHKNRF(env, napi_create_double(env, data[i], &message), "napi_create_double");
431 CHKNRF(env, napi_set_element(env, result, i, message), "napi_set_element");
432 }
433 return true;
434 }
435
ReleaseCallback(sptr<AsyncCallbackInfo> asyncCallbackInfo)436 void ReleaseCallback(sptr<AsyncCallbackInfo> asyncCallbackInfo)
437 {
438 CHKPV(asyncCallbackInfo);
439 if (asyncCallbackInfo->type == ONCE_CALLBACK) {
440 napi_env env = asyncCallbackInfo->env;
441 CHKPV(env);
442 napi_ref callback = asyncCallbackInfo->callback[0];
443 if (callback != nullptr) {
444 napi_delete_reference(env, callback);
445 }
446 }
447 }
448
EmitAsyncCallbackWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)449 void EmitAsyncCallbackWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)
450 {
451 CALL_LOG_ENTER;
452 CHKPV(asyncCallbackInfo);
453 napi_value resourceName = nullptr;
454 napi_env env = asyncCallbackInfo->env;
455 napi_status ret = napi_create_string_latin1(env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName);
456 CHKCV((ret == napi_ok), "napi_create_string_latin1 fail");
457 asyncCallbackInfo->IncStrongRef(nullptr);
458 napi_status status = napi_create_async_work(env, nullptr, resourceName,
459 [](napi_env env, void *data) {},
460 [](napi_env env, napi_status status, void *data) {
461 CALL_LOG_ENTER;
462 sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(data));
463 /**
464 * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
465 * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
466 * asynchronous task is created, and subtract 1 from the reference count after the naked
467 * pointer is converted to a pointer when the asynchronous task is executed, the reference
468 * count of the smart pointer is guaranteed to be 1.
469 */
470 asyncCallbackInfo->DecStrongRef(nullptr);
471 napi_value callback = nullptr;
472 napi_value callResult = nullptr;
473 napi_value result[2] = {0};
474 if (asyncCallbackInfo->type == SUBSCRIBE_FAIL) {
475 CHKCV((napi_get_reference_value(env, asyncCallbackInfo->callback[1], &callback) == napi_ok),
476 "napi_get_reference_value fail");
477 CHKCV((napi_create_string_utf8(env, asyncCallbackInfo->error.message.c_str(),
478 NAPI_AUTO_LENGTH, &result[0]) == napi_ok), "napi_create_string_utf8 fail");
479 CHKCV((napi_create_int32(env, asyncCallbackInfo->error.code, &result[1]) == napi_ok),
480 "napi_create_int32 fail");
481 CHKCV((napi_call_function(env, nullptr, callback, 2, result, &callResult) == napi_ok),
482 "napi_call_function fail");
483 return;
484 }
485 CHKCV((napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback) == napi_ok),
486 "napi_get_reference_value fail");
487 CHKCV((g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end()),
488 "Callback type invalid in async work");
489 bool ret = g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
490 CHKCV(ret, "Create napi data fail in async work");
491 CHKCV((napi_call_function(env, nullptr, callback, 2, result, &callResult) == napi_ok),
492 "napi_call_function fail");
493 },
494 asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork);
495 if (status != napi_ok
496 || napi_queue_async_work_with_qos(
497 asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) {
498 SEN_HILOGE("Create async work fail");
499 asyncCallbackInfo->DecStrongRef(nullptr);
500 }
501 }
502
DeleteWork(uv_work_t * work)503 void DeleteWork(uv_work_t *work)
504 {
505 CHKPV(work);
506 delete work;
507 work = nullptr;
508 }
509
EmitUvEventLoop(sptr<AsyncCallbackInfo> asyncCallbackInfo)510 void EmitUvEventLoop(sptr<AsyncCallbackInfo> asyncCallbackInfo)
511 {
512 CHKPV(asyncCallbackInfo);
513 uv_loop_s *loop(nullptr);
514 CHKCV((napi_get_uv_event_loop(asyncCallbackInfo->env, &loop) == napi_ok), "napi_get_uv_event_loop fail");
515 CHKPV(loop);
516 uv_work_t *work = new(std::nothrow) uv_work_t;
517 CHKPV(work);
518 asyncCallbackInfo->IncStrongRef(nullptr);
519 work->data = asyncCallbackInfo.GetRefPtr();
520 int32_t ret = uv_queue_work_with_qos(loop, work, [] (uv_work_t *work) { }, [] (uv_work_t *work, int status) {
521 CHKPV(work);
522 sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(work->data));
523 DeleteWork(work);
524 /**
525 * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
526 * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
527 * asynchronous task is created, and subtract 1 from the reference count after the naked
528 * pointer is converted to a pointer when the asynchronous task is executed, the reference
529 * count of the smart pointer is guaranteed to be 1.
530 */
531 asyncCallbackInfo->DecStrongRef(nullptr);
532 napi_handle_scope scope = nullptr;
533 napi_open_handle_scope(asyncCallbackInfo->env, &scope);
534 if (scope == nullptr) {
535 SEN_HILOGE("napi_handle_scope is nullptr");
536 ReleaseCallback(asyncCallbackInfo);
537 return;
538 }
539 napi_env env = asyncCallbackInfo->env;
540 napi_value callback = nullptr;
541 if (napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback) != napi_ok) {
542 SEN_HILOGE("napi_get_reference_value fail");
543 napi_throw_error(env, nullptr, "napi_get_reference_value fail");
544 ReleaseCallback(asyncCallbackInfo);
545 napi_close_handle_scope(asyncCallbackInfo->env, scope);
546 return;
547 }
548 napi_value callResult = nullptr;
549 napi_value result[2] = {0};
550 if (!(g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end())) {
551 SEN_HILOGE("asyncCallbackInfo type is invalid");
552 napi_throw_error(env, nullptr, "asyncCallbackInfo type is invalid");
553 ReleaseCallback(asyncCallbackInfo);
554 napi_close_handle_scope(asyncCallbackInfo->env, scope);
555 return;
556 }
557 g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
558 if (napi_call_function(env, nullptr, callback, 1, &result[1], &callResult) != napi_ok) {
559 SEN_HILOGE("napi_call_function callback fail");
560 napi_throw_error(env, nullptr, "napi_call_function callback fail");
561 ReleaseCallback(asyncCallbackInfo);
562 napi_close_handle_scope(asyncCallbackInfo->env, scope);
563 return;
564 }
565 ReleaseCallback(asyncCallbackInfo);
566 napi_close_handle_scope(asyncCallbackInfo->env, scope);
567 }, uv_qos_default);
568 if (ret != 0) {
569 SEN_HILOGE("uv_queue_work_with_qos fail");
570 asyncCallbackInfo->DecStrongRef(nullptr);
571 DeleteWork(work);
572 }
573 }
574
EmitPromiseWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)575 void EmitPromiseWork(sptr<AsyncCallbackInfo> asyncCallbackInfo)
576 {
577 CALL_LOG_ENTER;
578 CHKPV(asyncCallbackInfo);
579 napi_value resourceName = nullptr;
580 napi_env env = asyncCallbackInfo->env;
581 napi_status ret = napi_create_string_latin1(env, "Promise", NAPI_AUTO_LENGTH, &resourceName);
582 CHKCV((ret == napi_ok), "napi_create_string_latin1 fail");
583 asyncCallbackInfo->IncStrongRef(nullptr);
584 napi_status status = napi_create_async_work(env, nullptr, resourceName,
585 [](napi_env env, void *data) {},
586 [](napi_env env, napi_status status, void *data) {
587 CALL_LOG_ENTER;
588 sptr<AsyncCallbackInfo> asyncCallbackInfo(static_cast<AsyncCallbackInfo *>(data));
589 /**
590 * After the asynchronous task is created, the asyncCallbackInfo reference count is reduced
591 * to 0 destruction, so you need to add 1 to the asyncCallbackInfo reference count when the
592 * asynchronous task is created, and subtract 1 from the reference count after the naked
593 * pointer is converted to a pointer when the asynchronous task is executed, the reference
594 * count of the smart pointer is guaranteed to be 1.
595 */
596 asyncCallbackInfo->DecStrongRef(nullptr);
597 napi_value result[2] = {0};
598 CHKCV((g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end()),
599 "Callback type invalid in promise");
600 bool ret = g_convertfuncList[asyncCallbackInfo->type](env, asyncCallbackInfo, result);
601 CHKCV(ret, "Callback type invalid in promise");
602 if (asyncCallbackInfo->type == FAIL) {
603 CHKCV((napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]) == napi_ok),
604 "napi_reject_deferred fail");
605 } else {
606 CHKCV((napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[1]) == napi_ok),
607 "napi_resolve_deferred fail");
608 }
609 },
610 asyncCallbackInfo.GetRefPtr(), &asyncCallbackInfo->asyncWork);
611 if (status != napi_ok
612 || napi_queue_async_work_with_qos(
613 asyncCallbackInfo->env, asyncCallbackInfo->asyncWork, napi_qos_default) != napi_ok) {
614 SEN_HILOGE("Create async work fail");
615 asyncCallbackInfo->DecStrongRef(nullptr);
616 }
617 }
618
GetSelfTargetVersion(uint32_t & targetVersion)619 bool GetSelfTargetVersion(uint32_t &targetVersion)
620 {
621 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
622 if (samgr == nullptr) {
623 SEN_HILOGE("Samgr error");
624 return false;
625 }
626 auto bundleObj = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
627 if (bundleObj == nullptr) {
628 SEN_HILOGE("BundleObj error");
629 return false;
630 }
631 auto bundleMgrProxy = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
632 if (bundleMgrProxy == nullptr) {
633 SEN_HILOGE("BundleMgrProxy error");
634 return false;
635 }
636 AppExecFwk::BundleInfo bundleInfo;
637 ErrCode ret = bundleMgrProxy->GetBundleInfoForSelf(OHOS::AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo);
638 if (ret != ERR_OK) {
639 SEN_HILOGE("GetBundleInfoForSelf error");
640 return false;
641 }
642 targetVersion = bundleInfo.targetVersion;
643 return true;
644 }
645 } // namespace Sensors
646 } // namespace OHOS