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, ¶mType), "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, ©Length),
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