1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi_util.h"
17
18 #include "securec.h"
19 #include "string_ex.h"
20
21 #include "country_code.h"
22 #include "common_utils.h"
23 #include "geo_address.h"
24 #include "location_log.h"
25 #include "locator_proxy.h"
26 #include "request_config.h"
27
28 namespace OHOS {
29 namespace Location {
30 static constexpr int MAX_BUF_LEN = 100;
31 static constexpr int MAX_CALLBACK_NUM = 3;
32 static constexpr int MAX_ARGU_NUM = 10;
33
UndefinedNapiValue(const napi_env & env)34 napi_value UndefinedNapiValue(const napi_env& env)
35 {
36 napi_value result;
37 NAPI_CALL(env, napi_get_undefined(env, &result));
38 return result;
39 }
40
SatelliteStatusToJs(const napi_env & env,const std::shared_ptr<SatelliteStatus> & statusInfo,napi_value & result)41 void SatelliteStatusToJs(const napi_env& env,
42 const std::shared_ptr<SatelliteStatus>& statusInfo, napi_value& result)
43 {
44 napi_value satelliteIdsArray;
45 napi_value cn0Array;
46 napi_value altitudesArray;
47 napi_value azimuthsArray;
48 napi_value carrierFrequenciesArray;
49 SetValueDouble(env, "satellitesNumber", statusInfo->GetSatellitesNumber(), result);
50 if (statusInfo->GetSatellitesNumber() > 0) {
51 NAPI_CALL_RETURN_VOID(env,
52 napi_create_array_with_length(env, statusInfo->GetSatellitesNumber(), &satelliteIdsArray));
53 NAPI_CALL_RETURN_VOID(env,
54 napi_create_array_with_length(env, statusInfo->GetSatellitesNumber(), &cn0Array));
55 NAPI_CALL_RETURN_VOID(env,
56 napi_create_array_with_length(env, statusInfo->GetSatellitesNumber(), &altitudesArray));
57 NAPI_CALL_RETURN_VOID(env,
58 napi_create_array_with_length(env, statusInfo->GetSatellitesNumber(), &azimuthsArray));
59 NAPI_CALL_RETURN_VOID(env,
60 napi_create_array_with_length(env, statusInfo->GetSatellitesNumber(), &carrierFrequenciesArray));
61 uint32_t idx1 = 0;
62 for (int index = 0; index < statusInfo->GetSatellitesNumber(); index++) {
63 napi_value value = nullptr;
64 NAPI_CALL_RETURN_VOID(env, napi_create_double(env, statusInfo->GetSatelliteIds()[index], &value));
65 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, satelliteIdsArray, idx1, value));
66 NAPI_CALL_RETURN_VOID(env,
67 napi_create_double(env, statusInfo->GetCarrierToNoiseDensitys()[index], &value));
68 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, cn0Array, idx1, value));
69 NAPI_CALL_RETURN_VOID(env, napi_create_double(env, statusInfo->GetAltitudes()[index], &value));
70 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, altitudesArray, idx1, value));
71 NAPI_CALL_RETURN_VOID(env, napi_create_double(env, statusInfo->GetAzimuths()[index], &value));
72 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, azimuthsArray, idx1, value));
73 NAPI_CALL_RETURN_VOID(env, napi_create_double(env, statusInfo->GetCarrierFrequencies()[index], &value));
74 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, carrierFrequenciesArray, idx1, value));
75 idx1++;
76 }
77 SetValueStringArray(env, "satelliteIds", satelliteIdsArray, result);
78 SetValueStringArray(env, "carrierToNoiseDensitys", cn0Array, result);
79 SetValueStringArray(env, "altitudes", altitudesArray, result);
80 SetValueStringArray(env, "azimuths", azimuthsArray, result);
81 SetValueStringArray(env, "carrierFrequencies", carrierFrequenciesArray, result);
82 }
83 }
84
LocationsToJs(const napi_env & env,const std::vector<std::shared_ptr<Location>> & locations,napi_value & result)85 void LocationsToJs(const napi_env& env, const std::vector<std::shared_ptr<Location>>& locations, napi_value& result)
86 {
87 if (locations.size() > 0) {
88 for (unsigned int index = 0; index < locations.size(); index++) {
89 napi_value value;
90 SetValueDouble(env, "latitude", locations[index]->GetLatitude(), value);
91 SetValueDouble(env, "longitude", locations[index]->GetLongitude(), value);
92 SetValueDouble(env, "altitude", locations[index]->GetAltitude(), value);
93 SetValueDouble(env, "accuracy", locations[index]->GetAccuracy(), value);
94 SetValueDouble(env, "speed", locations[index]->GetSpeed(), value);
95 SetValueInt64(env, "timeStamp", locations[index]->GetTimeStamp(), value);
96 SetValueDouble(env, "direction", locations[index]->GetDirection(), value);
97 SetValueInt64(env, "timeSinceBoot", locations[index]->GetTimeSinceBoot(), value);
98 SetValueUtf8String(env, "additions", locations[index]->GetAdditions().c_str(), value);
99 SetValueInt64(env, "additionSize", locations[index]->GetAdditionSize(), value);
100 SetValueBool(env, "isFromMock", locations[index]->GetIsFromMock(), value);
101 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index, value));
102 }
103 }
104 }
105
LocationToJs(const napi_env & env,const std::unique_ptr<Location> & locationInfo,napi_value & result)106 void LocationToJs(const napi_env& env, const std::unique_ptr<Location>& locationInfo, napi_value& result)
107 {
108 SetValueDouble(env, "latitude", locationInfo->GetLatitude(), result);
109 SetValueDouble(env, "longitude", locationInfo->GetLongitude(), result);
110 SetValueDouble(env, "altitude", locationInfo->GetAltitude(), result);
111 SetValueDouble(env, "accuracy", locationInfo->GetAccuracy(), result);
112 SetValueDouble(env, "speed", locationInfo->GetSpeed(), result);
113 SetValueInt64(env, "timeStamp", locationInfo->GetTimeStamp(), result);
114 SetValueDouble(env, "direction", locationInfo->GetDirection(), result);
115 SetValueInt64(env, "timeSinceBoot", locationInfo->GetTimeSinceBoot(), result);
116 SetValueUtf8String(env, "additions", locationInfo->GetAdditions().c_str(), result);
117 SetValueInt64(env, "additionSize", locationInfo->GetAdditionSize(), result);
118 SetValueBool(env, "isFromMock", locationInfo->GetIsFromMock(), result);
119 }
120
CountryCodeToJs(const napi_env & env,const std::shared_ptr<CountryCode> & country,napi_value & result)121 void CountryCodeToJs(const napi_env& env, const std::shared_ptr<CountryCode>& country, napi_value& result)
122 {
123 SetValueUtf8String(env, "country", country->GetCountryCodeStr().c_str(), result);
124 SetValueInt64(env, "type", country->GetCountryCodeType(), result);
125 }
126
SystemLocationToJs(const napi_env & env,const std::unique_ptr<Location> & locationInfo,napi_value & result)127 void SystemLocationToJs(const napi_env& env, const std::unique_ptr<Location>& locationInfo, napi_value& result)
128 {
129 SetValueDouble(env, "longitude", locationInfo->GetLongitude(), result);
130 SetValueDouble(env, "latitude", locationInfo->GetLatitude(), result);
131 SetValueDouble(env, "altitude", locationInfo->GetAltitude(), result);
132 SetValueDouble(env, "accuracy", locationInfo->GetAccuracy(), result);
133 SetValueInt64(env, "time", locationInfo->GetTimeStamp(), result);
134 }
135
GeoAddressesToJsObj(const napi_env & env,std::list<std::shared_ptr<GeoAddress>> & replyList,napi_value & arrayResult)136 bool GeoAddressesToJsObj(const napi_env& env,
137 std::list<std::shared_ptr<GeoAddress>>& replyList, napi_value& arrayResult)
138 {
139 uint32_t idx = 0;
140 for (auto iter = replyList.begin(); iter != replyList.end(); ++iter) {
141 auto geoAddress = *iter;
142 napi_value eachObj;
143 NAPI_CALL_BASE(env, napi_create_object(env, &eachObj), false);
144 SetValueDouble(env, "latitude", geoAddress->GetLatitude(), eachObj);
145 SetValueDouble(env, "longitude", geoAddress->GetLongitude(), eachObj);
146 SetValueUtf8String(env, "locale", geoAddress->m_localeLanguage.c_str(), eachObj);
147 SetValueUtf8String(env, "placeName", geoAddress->m_placeName.c_str(), eachObj);
148 SetValueUtf8String(env, "countryCode", geoAddress->m_countryCode.c_str(), eachObj);
149 SetValueUtf8String(env, "countryName", geoAddress->m_countryName.c_str(), eachObj);
150 SetValueUtf8String(env, "administrativeArea", geoAddress->m_administrativeArea.c_str(), eachObj);
151 SetValueUtf8String(env, "subAdministrativeArea", geoAddress->m_subAdministrativeArea.c_str(), eachObj);
152 SetValueUtf8String(env, "locality", geoAddress->m_locality.c_str(), eachObj);
153 SetValueUtf8String(env, "subLocality", geoAddress->m_subLocality.c_str(), eachObj);
154 SetValueUtf8String(env, "roadName", geoAddress->m_roadName.c_str(), eachObj);
155 SetValueUtf8String(env, "subRoadName", geoAddress->m_subRoadName.c_str(), eachObj);
156 SetValueUtf8String(env, "premises", geoAddress->m_premises.c_str(), eachObj);
157 SetValueUtf8String(env, "postalCode", geoAddress->m_postalCode.c_str(), eachObj);
158 SetValueUtf8String(env, "phoneNumber", geoAddress->m_phoneNumber.c_str(), eachObj);
159 SetValueUtf8String(env, "addressUrl", geoAddress->m_addressUrl.c_str(), eachObj);
160 napi_value descriptionArray;
161 if (geoAddress->m_descriptionsSize > 0) {
162 NAPI_CALL_BASE(env,
163 napi_create_array_with_length(env, geoAddress->m_descriptionsSize, &descriptionArray), false);
164 uint32_t idx1 = 0;
165 for (int index = 0; index < geoAddress->m_descriptionsSize; index++) {
166 napi_value value;
167 NAPI_CALL_BASE(env, napi_create_string_utf8(env, geoAddress->GetDescriptions(index).c_str(),
168 NAPI_AUTO_LENGTH, &value), false);
169 NAPI_CALL_BASE(env, napi_set_element(env, descriptionArray, idx1++, value), false);
170 }
171 SetValueStringArray(env, "descriptions", descriptionArray, eachObj);
172 }
173 SetValueInt32(env, "descriptionsSize", geoAddress->m_descriptionsSize, eachObj);
174 SetValueBool(env, "isFromMock", geoAddress->m_isFromMock, eachObj);
175 NAPI_CALL_BASE(env, napi_set_element(env, arrayResult, idx++, eachObj), false);
176 }
177 return true;
178 }
179
JsObjToCachedLocationRequest(const napi_env & env,const napi_value & object,std::unique_ptr<CachedGnssLocationsRequest> & request)180 void JsObjToCachedLocationRequest(const napi_env& env, const napi_value& object,
181 std::unique_ptr<CachedGnssLocationsRequest>& request)
182 {
183 JsObjectToInt(env, object, "reportingPeriodSec", request->reportingPeriodSec);
184 JsObjectToBool(env, object, "wakeUpCacheQueueFull", request->wakeUpCacheQueueFull);
185 }
186
JsObjToGeoFenceRequest(const napi_env & env,const napi_value & object,const std::unique_ptr<GeofenceRequest> & request)187 void JsObjToGeoFenceRequest(const napi_env& env, const napi_value& object,
188 const std::unique_ptr<GeofenceRequest>& request)
189 {
190 int value = 0;
191 double doubleValue = 0.0;
192 if (JsObjectToInt(env, object, "scenario", value) == SUCCESS) {
193 request->scenario = value;
194 }
195 if (JsObjectToDouble(env, object, "latitude", doubleValue) == SUCCESS) {
196 request->geofence.latitude = doubleValue;
197 }
198 if (JsObjectToDouble(env, object, "longitude", doubleValue) == SUCCESS) {
199 request->geofence.longitude = doubleValue;
200 }
201 if (JsObjectToDouble(env, object, "radius", doubleValue) == SUCCESS) {
202 request->geofence.radius = doubleValue;
203 }
204 if (JsObjectToDouble(env, object, "expiration", doubleValue) == SUCCESS) {
205 request->geofence.expiration = doubleValue;
206 }
207 }
208
JsObjToLocationRequest(const napi_env & env,const napi_value & object,std::unique_ptr<RequestConfig> & requestConfig)209 void JsObjToLocationRequest(const napi_env& env, const napi_value& object,
210 std::unique_ptr<RequestConfig>& requestConfig)
211 {
212 int value = 0;
213 double valueDouble = 0.0;
214 if (JsObjectToInt(env, object, "priority", value) == SUCCESS) {
215 requestConfig->SetPriority(value);
216 }
217 if (JsObjectToInt(env, object, "scenario", value) == SUCCESS) {
218 requestConfig->SetScenario(value);
219 }
220 if (JsObjectToInt(env, object, "timeInterval", value) == SUCCESS) {
221 requestConfig->SetTimeInterval(value);
222 }
223 if (JsObjectToDouble(env, object, "maxAccuracy", valueDouble) == SUCCESS) {
224 requestConfig->SetMaxAccuracy(valueDouble);
225 }
226 if (JsObjectToInt(env, object, "distanceInterval", value) == SUCCESS) {
227 requestConfig->SetDistanceInterval(value);
228 }
229 }
230
JsObjToCurrentLocationRequest(const napi_env & env,const napi_value & object,std::unique_ptr<RequestConfig> & requestConfig)231 void JsObjToCurrentLocationRequest(const napi_env& env, const napi_value& object,
232 std::unique_ptr<RequestConfig>& requestConfig)
233 {
234 int value = 0;
235 double valueDouble = 0.0;
236 if (JsObjectToInt(env, object, "priority", value) == SUCCESS) {
237 requestConfig->SetPriority(value);
238 }
239 if (JsObjectToInt(env, object, "scenario", value) == SUCCESS) {
240 requestConfig->SetScenario(value);
241 }
242 if (JsObjectToDouble(env, object, "maxAccuracy", valueDouble) == SUCCESS) {
243 requestConfig->SetMaxAccuracy(valueDouble);
244 }
245 if (JsObjectToInt(env, object, "timeoutMs", value) == SUCCESS) {
246 requestConfig->SetTimeOut(value);
247 }
248 }
249
JsObjToCommand(const napi_env & env,const napi_value & object,std::unique_ptr<LocationCommand> & commandConfig)250 int JsObjToCommand(const napi_env& env, const napi_value& object,
251 std::unique_ptr<LocationCommand>& commandConfig)
252 {
253 if (commandConfig == nullptr) {
254 return COMMON_ERROR;
255 }
256 CHK_ERROR_CODE("scenario", JsObjectToInt(env, object, "scenario", commandConfig->scenario), true);
257 CHK_ERROR_CODE("command", JsObjectToString(env, object, "command", MAX_BUF_LEN, commandConfig->command), true);
258 return SUCCESS;
259 }
260
JsObjToGeoCodeRequest(const napi_env & env,const napi_value & object,MessageParcel & dataParcel)261 int JsObjToGeoCodeRequest(const napi_env& env, const napi_value& object, MessageParcel& dataParcel)
262 {
263 std::string description = "";
264 int maxItems = 0;
265 double minLatitude = 0.0;
266 double minLongitude = 0.0;
267 double maxLatitude = 0.0;
268 double maxLongitude = 0.0;
269 std::string locale = "";
270 int bufLen = MAX_BUF_LEN;
271 CHK_ERROR_CODE("locale", JsObjectToString(env, object, "locale", bufLen, locale), false);
272 CHK_ERROR_CODE("description", JsObjectToString(env, object, "description", bufLen, description), true);
273 if (description == "") {
274 LBSLOGE(LOCATOR_STANDARD, "The required description field should not be empty.");
275 return INPUT_PARAMS_ERROR;
276 }
277 CHK_ERROR_CODE("maxItems", JsObjectToInt(env, object, "maxItems", maxItems), false);
278 CHK_ERROR_CODE("minLatitude", JsObjectToDouble(env, object, "minLatitude", minLatitude), false);
279 CHK_ERROR_CODE("minLongitude", JsObjectToDouble(env, object, "minLongitude", minLongitude), false);
280 CHK_ERROR_CODE("maxLatitude", JsObjectToDouble(env, object, "maxLatitude", maxLatitude), false);
281 CHK_ERROR_CODE("maxLongitude", JsObjectToDouble(env, object, "maxLongitude", maxLongitude), false);
282 if (minLatitude < MIN_LATITUDE || minLatitude > MAX_LATITUDE) {
283 return INPUT_PARAMS_ERROR;
284 }
285 if (minLongitude < MIN_LONGITUDE || minLongitude > MAX_LONGITUDE) {
286 return INPUT_PARAMS_ERROR;
287 }
288 if (maxLatitude < MIN_LATITUDE || maxLatitude > MAX_LATITUDE) {
289 return INPUT_PARAMS_ERROR;
290 }
291 if (maxLongitude < MIN_LONGITUDE || maxLongitude > MAX_LONGITUDE) {
292 return INPUT_PARAMS_ERROR;
293 }
294 if (!dataParcel.WriteInterfaceToken(LocatorProxy::GetDescriptor())) {
295 LBSLOGE(LOCATOR_STANDARD, "write interfaceToken fail!");
296 return COMMON_ERROR;
297 }
298 std::string str = "";
299 dataParcel.WriteString16(Str8ToStr16(description));
300 dataParcel.WriteDouble(minLatitude); // latitude
301 dataParcel.WriteDouble(minLongitude); // longitude
302 dataParcel.WriteDouble(maxLatitude); // latitude
303 dataParcel.WriteDouble(maxLongitude); // longitude
304 dataParcel.WriteInt32(maxItems); // maxItems
305 dataParcel.WriteInt32(1); // locale object size = 1
306 dataParcel.WriteString16(Str8ToStr16(locale)); // locale.getLanguage()
307 dataParcel.WriteString16(Str8ToStr16(str)); // locale.getCountry()
308 dataParcel.WriteString16(Str8ToStr16(str)); // locale.getVariant()
309 dataParcel.WriteString16(Str8ToStr16(str)); // ""
310 return SUCCESS;
311 }
312
JsObjToReverseGeoCodeRequest(const napi_env & env,const napi_value & object,MessageParcel & dataParcel)313 bool JsObjToReverseGeoCodeRequest(const napi_env& env, const napi_value& object, MessageParcel& dataParcel)
314 {
315 double latitude = 0;
316 double longitude = 0;
317 int maxItems = 0;
318 std::string locale = "";
319
320 CHK_ERROR_CODE("latitude", JsObjectToDouble(env, object, "latitude", latitude), true);
321 CHK_ERROR_CODE("longitude", JsObjectToDouble(env, object, "longitude", longitude), true);
322 CHK_ERROR_CODE("maxItems", JsObjectToInt(env, object, "maxItems", maxItems), false);
323 CHK_ERROR_CODE("locale", JsObjectToString(env, object, "locale", MAX_BUF_LEN, locale), false); // max bufLen
324
325 if (latitude < MIN_LATITUDE || latitude > MAX_LATITUDE) {
326 return false;
327 }
328 if (longitude < MIN_LONGITUDE || longitude > MAX_LONGITUDE) {
329 return false;
330 }
331 std::string str = "";
332 if (!dataParcel.WriteInterfaceToken(LocatorProxy::GetDescriptor())) {
333 return false;
334 }
335 dataParcel.WriteDouble(latitude); // latitude
336 dataParcel.WriteDouble(longitude); // longitude
337 dataParcel.WriteInt32(maxItems); // maxItems
338 dataParcel.WriteInt32(1); // locale object size = 1
339 dataParcel.WriteString16(Str8ToStr16(locale)); // locale.getLanguage()
340 dataParcel.WriteString16(Str8ToStr16(str)); // locale.getCountry()
341 dataParcel.WriteString16(Str8ToStr16(str)); // locale.getVariant()
342 dataParcel.WriteString16(Str8ToStr16(str)); // ""
343 return true;
344 }
345
GetLocationInfo(const napi_env & env,const napi_value & object,const char * fieldStr,std::shared_ptr<ReverseGeocodeRequest> & request)346 bool GetLocationInfo(const napi_env& env, const napi_value& object,
347 const char* fieldStr, std::shared_ptr<ReverseGeocodeRequest>& request)
348 {
349 bool result = false;
350 napi_value value = nullptr;
351
352 if (object == nullptr) {
353 LBSLOGE(LOCATOR_STANDARD, "object is nullptr.");
354 return false;
355 }
356
357 NAPI_CALL_BASE(env, napi_has_named_property(env, object, fieldStr, &result), false);
358 if (result) {
359 NAPI_CALL_BASE(env, napi_get_named_property(env, object, fieldStr, &value), false);
360 JsObjectToString(env, value, "locale", MAX_BUF_LEN, request->locale);
361 JsObjectToInt(env, value, "maxItems", request->maxItems);
362 JsObjectToDouble(env, value, "latitude", request->latitude);
363 JsObjectToDouble(env, value, "longitude", request->longitude);
364 return true;
365 }
366 return false;
367 }
368
GetNapiValueByKey(napi_env env,const std::string & keyChar,napi_value object)369 napi_value GetNapiValueByKey(napi_env env, const std::string& keyChar, napi_value object)
370 {
371 if (object == nullptr) {
372 LBSLOGE(LOCATOR_STANDARD, "GetNapiValueByKey object is nullptr.");
373 return nullptr;
374 }
375 bool result = false;
376 NAPI_CALL(env, napi_has_named_property(env, object, keyChar.c_str(), &result));
377 if (result) {
378 napi_value value = nullptr;
379 NAPI_CALL(env, napi_get_named_property(env, object, keyChar.c_str(), &value));
380 return value;
381 }
382 return nullptr;
383 }
384
GetStringArrayFromJsObj(napi_env env,napi_value value,std::vector<std::string> & outArray)385 bool GetStringArrayFromJsObj(napi_env env, napi_value value, std::vector<std::string>& outArray)
386 {
387 uint32_t arrayLength = 0;
388 NAPI_CALL_BASE(env, napi_get_array_length(env, value, &arrayLength), false);
389 if (arrayLength == 0) {
390 LBSLOGE(LOCATOR_STANDARD, "The array is empty.");
391 return false;
392 }
393 for (size_t i = 0; i < arrayLength; i++) {
394 napi_value napiElement = nullptr;
395 NAPI_CALL_BASE(env, napi_get_element(env, value, i, &napiElement), false);
396 napi_valuetype napiValueType = napi_undefined;
397 NAPI_CALL_BASE(env, napi_typeof(env, napiElement, &napiValueType), false);
398 if (napiValueType != napi_string) {
399 LBSLOGE(LOCATOR_STANDARD, "wrong argument type.");
400 return false;
401 }
402 char type[64] = {0}; // max length
403 size_t typeLen = 0;
404 NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, napiElement, type, sizeof(type), &typeLen), false);
405 std::string event = type;
406 outArray.push_back(event);
407 }
408 return true;
409 }
410
GetStringArrayValueByKey(napi_env env,napi_value jsObject,const std::string & key,std::vector<std::string> & outArray)411 bool GetStringArrayValueByKey(
412 napi_env env, napi_value jsObject, const std::string& key, std::vector<std::string>& outArray)
413 {
414 napi_value array = GetNapiValueByKey(env, key, jsObject);
415 if (array == nullptr) {
416 return false;
417 }
418 bool isArray = false;
419 NAPI_CALL_BASE(env, napi_is_array(env, array, &isArray), false);
420 if (!isArray) {
421 LBSLOGE(LOCATOR_STANDARD, "not an array!");
422 return false;
423 }
424 return GetStringArrayFromJsObj(env, array, outArray);
425 }
426
GetGeoAddressInfo(const napi_env & env,const napi_value & object,const std::string & fieldStr,std::shared_ptr<GeoAddress> address)427 bool GetGeoAddressInfo(const napi_env& env, const napi_value& object,
428 const std::string& fieldStr, std::shared_ptr<GeoAddress> address)
429 {
430 napi_value value = GetNapiValueByKey(env, fieldStr, object);
431 if (value == nullptr) {
432 LBSLOGE(LOCATOR_STANDARD, "GetNapiValueByKey is nullptr.");
433 return false;
434 }
435 double latitude = 0.0;
436 double longitude = 0.0;
437 JsObjectToDouble(env, value, "latitude", latitude);
438 if (CommonUtils::DoubleEqual(latitude, 0.0)) {
439 address->m_hasLatitude = false;
440 } else {
441 address->m_hasLatitude = true;
442 address->m_latitude = latitude;
443 }
444 JsObjectToDouble(env, value, "longitude", longitude);
445 if (CommonUtils::DoubleEqual(longitude, 0.0)) {
446 address->m_hasLongitude = false;
447 } else {
448 address->m_hasLongitude = true;
449 address->m_longitude = longitude;
450 }
451 int bufLen = MAX_BUF_LEN;
452 JsObjectToString(env, value, "locale", bufLen, address->m_localeLanguage);
453 JsObjectToString(env, value, "placeName", bufLen, address->m_placeName);
454 JsObjectToString(env, value, "countryCode", bufLen, address->m_countryCode);
455 JsObjectToString(env, value, "countryName", bufLen, address->m_countryName);
456 JsObjectToString(env, value, "administrativeArea", bufLen, address->m_administrativeArea);
457 JsObjectToString(env, value, "subAdministrativeArea", bufLen, address->m_subAdministrativeArea);
458 JsObjectToString(env, value, "locality", bufLen, address->m_locality);
459 JsObjectToString(env, value, "subLocality", bufLen, address->m_subLocality);
460 JsObjectToString(env, value, "roadName", bufLen, address->m_roadName);
461 JsObjectToString(env, value, "subRoadName", bufLen, address->m_subRoadName);
462 JsObjectToString(env, value, "premises", bufLen, address->m_premises);
463 JsObjectToString(env, value, "postalCode", bufLen, address->m_postalCode);
464 JsObjectToString(env, value, "phoneNumber", bufLen, address->m_phoneNumber);
465 JsObjectToString(env, value, "addressUrl", bufLen, address->m_addressUrl);
466 JsObjectToInt(env, value, "descriptionsSize", address->m_descriptionsSize);
467 JsObjectToBool(env, value, "isFromMock", address->m_isFromMock);
468 std::vector<std::string> descriptions;
469 GetStringArrayValueByKey(env, value, "descriptions", descriptions);
470 size_t size = static_cast<size_t>(address->m_descriptionsSize) > descriptions.size() ?
471 descriptions.size() : static_cast<size_t>(address->m_descriptionsSize);
472 for (size_t i = 0; i < size; i++) {
473 address->m_descriptions.insert(std::make_pair(i, descriptions[i]));
474 }
475 return true;
476 }
477
JsObjToRevGeocodeMock(const napi_env & env,const napi_value & object,std::vector<std::shared_ptr<GeocodingMockInfo>> & mockInfo)478 bool JsObjToRevGeocodeMock(const napi_env& env, const napi_value& object,
479 std::vector<std::shared_ptr<GeocodingMockInfo>>& mockInfo)
480 {
481 bool isArray = false;
482 NAPI_CALL_BASE(env, napi_is_array(env, object, &isArray), false);
483 if (!isArray) {
484 LBSLOGE(LOCATOR_STANDARD, "JsObjToRevGeocodeMock:not an array!");
485 return false;
486 }
487 uint32_t arrayLength = 0;
488 NAPI_CALL_BASE(env, napi_get_array_length(env, object, &arrayLength), false);
489 if (arrayLength == 0) {
490 LBSLOGE(LOCATOR_STANDARD, "JsObjToRevGeocodeMock:The array is empty.");
491 return false;
492 }
493 for (size_t i = 0; i < arrayLength; i++) {
494 napi_value napiElement = nullptr;
495 NAPI_CALL_BASE(env, napi_get_element(env, object, i, &napiElement), false);
496 std::shared_ptr<GeocodingMockInfo> info = std::make_shared<GeocodingMockInfo>();
497 std::shared_ptr<ReverseGeocodeRequest> request = std::make_shared<ReverseGeocodeRequest>();
498 std::shared_ptr<GeoAddress> geoAddress = std::make_shared<GeoAddress>();
499 GetLocationInfo(env, napiElement, "location", request);
500 GetGeoAddressInfo(env, napiElement, "geoAddress", geoAddress);
501 info->SetLocation(request);
502 info->SetGeoAddressInfo(geoAddress);
503 mockInfo.push_back(info);
504 }
505 return true;
506 }
507
GetLocationArray(const napi_env & env,LocationMockAsyncContext * asyncContext,const napi_value & object)508 void GetLocationArray(const napi_env& env, LocationMockAsyncContext *asyncContext, const napi_value& object)
509 {
510 uint32_t arrayLength = 0;
511 NAPI_CALL_RETURN_VOID(env, napi_get_array_length(env, object, &arrayLength));
512 if (arrayLength == 0) {
513 LBSLOGE(LOCATOR_STANDARD, "The array is empty.");
514 return;
515 }
516 for (uint32_t i = 0; i < arrayLength; i++) {
517 napi_value elementValue = nullptr;
518 std::shared_ptr<Location> locationAdapter = std::make_shared<Location>();
519 NAPI_CALL_RETURN_VOID(env, napi_get_element(env, object, i, &elementValue));
520 double latitude = 0.0;
521 JsObjectToDouble(env, elementValue, "latitude", latitude);
522 locationAdapter->SetLatitude(latitude);
523 double longitude = 0.0;
524 JsObjectToDouble(env, elementValue, "longitude", longitude);
525 locationAdapter->SetLongitude(longitude);
526 double altitude = 0.0;
527 JsObjectToDouble(env, elementValue, "altitude", altitude);
528 locationAdapter->SetAltitude(altitude);
529 int32_t accuracy = 0;
530 JsObjectToInt(env, elementValue, "accuracy", accuracy);
531 locationAdapter->SetAccuracy(static_cast<float>(accuracy));
532 int32_t speed = 0;
533 JsObjectToInt(env, elementValue, "speed", speed);
534 locationAdapter->SetSpeed(static_cast<float>(speed));
535 double direction = 0.0;
536 JsObjectToDouble(env, elementValue, "direction", direction);
537 locationAdapter->SetDirection(direction);
538 int64_t timeStamp = 0;
539 JsObjectToInt64(env, elementValue, "timeStamp", timeStamp);
540 locationAdapter->SetTimeStamp(timeStamp);
541 int64_t timeSinceBoot = 0;
542 JsObjectToInt64(env, elementValue, "timeSinceBoot", timeSinceBoot);
543 locationAdapter->SetTimeSinceBoot(timeSinceBoot);
544 std::string additions = " ";
545 int buffLen = 100;
546 JsObjectToString(env, elementValue, "additions", buffLen, additions);
547 locationAdapter->SetAdditions(additions);
548 int32_t additionSize = 0;
549 JsObjectToInt(env, elementValue, "additionSize", additionSize);
550 locationAdapter->SetAdditionSize(static_cast<int64_t>(additionSize));
551 bool isFromMock = false;
552 JsObjectToBool(env, elementValue, "isFromMock", isFromMock);
553 locationAdapter->SetIsFromMock(isFromMock);
554 asyncContext->LocationNapi.push_back(locationAdapter);
555 }
556 }
557
JsObjectToString(const napi_env & env,const napi_value & object,const char * fieldStr,const int bufLen,std::string & fieldRef)558 int JsObjectToString(const napi_env& env, const napi_value& object,
559 const char* fieldStr, const int bufLen, std::string& fieldRef)
560 {
561 bool hasProperty = false;
562 NAPI_CALL_BASE(env, napi_has_named_property(env, object, fieldStr, &hasProperty), COMMON_ERROR);
563 if (hasProperty) {
564 napi_value field;
565 napi_valuetype valueType;
566
567 NAPI_CALL_BASE(env, napi_get_named_property(env, object, fieldStr, &field), COMMON_ERROR);
568 NAPI_CALL_BASE(env, napi_typeof(env, field, &valueType), COMMON_ERROR);
569 NAPI_ASSERT_BASE(env, valueType == napi_string, "Wrong argument type.", INPUT_PARAMS_ERROR);
570 if (bufLen <= 0) {
571 LBSLOGE(LOCATOR_STANDARD, "The length of buf should be greater than 0.");
572 return COMMON_ERROR;
573 }
574 int32_t actBuflen = bufLen + 1;
575 std::unique_ptr<char[]> buf = std::make_unique<char[]>(actBuflen);
576 (void)memset_s(buf.get(), actBuflen, 0, actBuflen);
577 size_t result = 0;
578 NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, field, buf.get(), actBuflen, &result), COMMON_ERROR);
579 fieldRef = buf.get();
580 return SUCCESS;
581 }
582 LBSLOGD(LOCATOR_STANDARD, "Js obj to str no property: %{public}s", fieldStr);
583 return PARAM_IS_EMPTY;
584 }
585
JsObjectToDouble(const napi_env & env,const napi_value & object,const char * fieldStr,double & fieldRef)586 int JsObjectToDouble(const napi_env& env, const napi_value& object, const char* fieldStr, double& fieldRef)
587 {
588 bool hasProperty = false;
589 NAPI_CALL_BASE(env, napi_has_named_property(env, object, fieldStr, &hasProperty), COMMON_ERROR);
590 if (hasProperty) {
591 napi_value field;
592 napi_valuetype valueType;
593
594 NAPI_CALL_BASE(env, napi_get_named_property(env, object, fieldStr, &field), COMMON_ERROR);
595 NAPI_CALL_BASE(env, napi_typeof(env, field, &valueType), COMMON_ERROR);
596 NAPI_ASSERT_BASE(env, valueType == napi_number, "Wrong argument type.", INPUT_PARAMS_ERROR);
597 NAPI_CALL_BASE(env, napi_get_value_double(env, field, &fieldRef), COMMON_ERROR);
598 return SUCCESS;
599 }
600 LBSLOGD(LOCATOR_STANDARD, "Js to int no property: %{public}s", fieldStr);
601 return PARAM_IS_EMPTY;
602 }
603
JsObjectToInt(const napi_env & env,const napi_value & object,const char * fieldStr,int & fieldRef)604 int JsObjectToInt(const napi_env& env, const napi_value& object, const char* fieldStr, int& fieldRef)
605 {
606 bool hasProperty = false;
607 NAPI_CALL_BASE(env, napi_has_named_property(env, object, fieldStr, &hasProperty), COMMON_ERROR);
608 if (hasProperty) {
609 napi_value field;
610 napi_valuetype valueType;
611
612 NAPI_CALL_BASE(env, napi_get_named_property(env, object, fieldStr, &field), COMMON_ERROR);
613 NAPI_CALL_BASE(env, napi_typeof(env, field, &valueType), COMMON_ERROR);
614 NAPI_ASSERT_BASE(env, valueType == napi_number, "Wrong argument type.", INPUT_PARAMS_ERROR);
615 NAPI_CALL_BASE(env, napi_get_value_int32(env, field, &fieldRef), COMMON_ERROR);
616 return SUCCESS;
617 }
618 LBSLOGD(LOCATOR_STANDARD, "Js to int no property: %{public}s", fieldStr);
619 return PARAM_IS_EMPTY;
620 }
621
JsObjectToInt64(const napi_env & env,const napi_value & object,const char * fieldStr,int64_t & fieldRef)622 int JsObjectToInt64(const napi_env& env, const napi_value& object, const char* fieldStr, int64_t& fieldRef)
623 {
624 bool hasProperty = false;
625 NAPI_CALL_BASE(env, napi_has_named_property(env, object, fieldStr, &hasProperty), COMMON_ERROR);
626 if (hasProperty) {
627 napi_value field;
628 napi_valuetype valueType;
629
630 NAPI_CALL_BASE(env, napi_get_named_property(env, object, fieldStr, &field), COMMON_ERROR);
631 NAPI_CALL_BASE(env, napi_typeof(env, field, &valueType), COMMON_ERROR);
632 NAPI_ASSERT_BASE(env, valueType == napi_number, "Wrong argument type.", INPUT_PARAMS_ERROR);
633 NAPI_CALL_BASE(env, napi_get_value_int64(env, field, &fieldRef), COMMON_ERROR);
634 return SUCCESS;
635 }
636 LBSLOGD(LOCATOR_STANDARD, "Js to int no property: %{public}s", fieldStr);
637 return PARAM_IS_EMPTY;
638 }
639
JsObjectToBool(const napi_env & env,const napi_value & object,const char * fieldStr,bool & fieldRef)640 int JsObjectToBool(const napi_env& env, const napi_value& object, const char* fieldStr, bool& fieldRef)
641 {
642 bool hasProperty = false;
643 NAPI_CALL_BASE(env, napi_has_named_property(env, object, fieldStr, &hasProperty), COMMON_ERROR);
644 if (hasProperty) {
645 napi_value field;
646 napi_valuetype valueType;
647
648 NAPI_CALL_BASE(env, napi_get_named_property(env, object, fieldStr, &field), COMMON_ERROR);
649 NAPI_CALL_BASE(env, napi_typeof(env, field, &valueType), COMMON_ERROR);
650 NAPI_ASSERT_BASE(env, valueType == napi_boolean, "Wrong argument type.", INPUT_PARAMS_ERROR);
651 NAPI_CALL_BASE(env, napi_get_value_bool(env, field, &fieldRef), COMMON_ERROR);
652 return SUCCESS;
653 }
654 LBSLOGD(LOCATOR_STANDARD, "Js to bool no property: %{public}s", fieldStr);
655 return PARAM_IS_EMPTY;
656 }
657
SetValueUtf8String(const napi_env & env,const char * fieldStr,const char * str,napi_value & result)658 napi_status SetValueUtf8String(const napi_env& env, const char* fieldStr, const char* str, napi_value& result)
659 {
660 napi_value value = nullptr;
661 NAPI_CALL_BASE(env, napi_create_string_utf8(env, str, NAPI_AUTO_LENGTH, &value), napi_generic_failure);
662 NAPI_CALL_BASE(env, napi_set_named_property(env, result, fieldStr, value), napi_generic_failure);
663 return napi_ok;
664 }
665
SetValueStringArray(const napi_env & env,const char * fieldStr,napi_value & value,napi_value & result)666 napi_status SetValueStringArray(const napi_env& env, const char* fieldStr, napi_value& value, napi_value& result)
667 {
668 NAPI_CALL_BASE(env, napi_set_named_property(env, result, fieldStr, value), napi_generic_failure);
669 return napi_ok;
670 }
671
SetValueInt32(const napi_env & env,const char * fieldStr,const int intValue,napi_value & result)672 napi_status SetValueInt32(const napi_env& env, const char* fieldStr, const int intValue, napi_value& result)
673 {
674 napi_value value = nullptr;
675 NAPI_CALL_BASE(env, napi_create_int32(env, intValue, &value), napi_generic_failure);
676 NAPI_CALL_BASE(env, napi_set_named_property(env, result, fieldStr, value), napi_generic_failure);
677 return napi_ok;
678 }
679
SetValueInt64(const napi_env & env,const char * fieldStr,const int64_t intValue,napi_value & result)680 napi_status SetValueInt64(const napi_env& env, const char* fieldStr, const int64_t intValue, napi_value& result)
681 {
682 napi_value value = nullptr;
683 NAPI_CALL_BASE(env, napi_create_int64(env, intValue, &value), napi_generic_failure);
684 NAPI_CALL_BASE(env, napi_set_named_property(env, result, fieldStr, value), napi_generic_failure);
685 return napi_ok;
686 }
687
SetValueDouble(const napi_env & env,const char * fieldStr,const double doubleValue,napi_value & result)688 napi_status SetValueDouble(const napi_env& env, const char* fieldStr, const double doubleValue, napi_value& result)
689 {
690 napi_value value = nullptr;
691 NAPI_CALL_BASE(env, napi_create_double(env, doubleValue, &value), napi_generic_failure);
692 NAPI_CALL_BASE(env, napi_set_named_property(env, result, fieldStr, value), napi_generic_failure);
693 return napi_ok;
694 }
695
SetValueBool(const napi_env & env,const char * fieldStr,const bool boolvalue,napi_value & result)696 napi_status SetValueBool(const napi_env& env, const char* fieldStr, const bool boolvalue, napi_value& result)
697 {
698 napi_value value = nullptr;
699 NAPI_CALL_BASE(env, napi_get_boolean(env, boolvalue, &value), napi_generic_failure);
700 NAPI_CALL_BASE(env, napi_set_named_property(env, result, fieldStr, value), napi_generic_failure);
701 return napi_ok;
702 }
703
InitAsyncCallBackEnv(const napi_env & env,AsyncContext * asyncContext,const size_t argc,const napi_value * argv,const size_t objectArgsNum)704 static bool InitAsyncCallBackEnv(const napi_env& env, AsyncContext* asyncContext,
705 const size_t argc, const napi_value* argv, const size_t objectArgsNum)
706 {
707 if (asyncContext == nullptr || argv == nullptr) {
708 return false;
709 }
710 size_t startLoop = objectArgsNum;
711 size_t endLoop = argc;
712 if (startLoop > MAX_ARGU_NUM || endLoop > MAX_ARGU_NUM) {
713 return false;
714 }
715 for (size_t i = startLoop; i < endLoop; ++i) {
716 napi_valuetype valuetype;
717 NAPI_CALL_BASE(env, napi_typeof(env, argv[i], &valuetype), false);
718 NAPI_ASSERT_BASE(env, valuetype == napi_function, "Wrong argument type.", false);
719 size_t index = i - startLoop;
720 if (index >= MAX_CALLBACK_NUM) {
721 break;
722 }
723 NAPI_CALL_BASE(env, napi_create_reference(env, argv[i], 1, &asyncContext->callback[index]), false);
724 }
725 return true;
726 }
727
InitAsyncPromiseEnv(const napi_env & env,AsyncContext * asyncContext,napi_value & promise)728 static bool InitAsyncPromiseEnv(const napi_env& env, AsyncContext *asyncContext, napi_value& promise)
729 {
730 napi_deferred deferred;
731 if (asyncContext == nullptr) {
732 return false;
733 }
734 NAPI_CALL_BASE(env, napi_create_promise(env, &deferred, &promise), false);
735 asyncContext->deferred = deferred;
736 return true;
737 }
738
CreateFailCallBackParams(AsyncContext & context,const std::string & msg,int32_t errorCode)739 void CreateFailCallBackParams(AsyncContext& context, const std::string& msg, int32_t errorCode)
740 {
741 SetValueUtf8String(context.env, "data", msg.c_str(), context.result[PARAM0]);
742 SetValueInt32(context.env, "code", errorCode, context.result[PARAM1]);
743 }
744
GetErrorMsgByCode(int code)745 std::string GetErrorMsgByCode(int code)
746 {
747 static std::map<int, std::string> errorCodeMap = {
748 {SUCCESS, "SUCCESS"},
749 {NOT_SUPPORTED, "NOT_SUPPORTED"},
750 {INPUT_PARAMS_ERROR, "INPUT_PARAMS_ERROR"},
751 {REVERSE_GEOCODE_ERROR, "REVERSE_GEOCODE_ERROR"},
752 {GEOCODE_ERROR, "GEOCODE_ERROR"},
753 {LOCATOR_ERROR, "LOCATOR_ERROR"},
754 {LOCATION_SWITCH_ERROR, "LOCATION_SWITCH_ERROR"},
755 {LAST_KNOWN_LOCATION_ERROR, "LAST_KNOWN_LOCATION_ERROR"},
756 {LOCATION_REQUEST_TIMEOUT_ERROR, "LOCATION_REQUEST_TIMEOUT_ERROR"},
757 {QUERY_COUNTRY_CODE_ERROR, "QUERY_COUNTRY_CODE_ERROR"},
758 {LocationErrCode::ERRCODE_SUCCESS, "SUCCESS."},
759 {LocationErrCode::ERRCODE_PERMISSION_DENIED, "Permission denied."},
760 {LocationErrCode::ERRCODE_SYSTEM_PERMISSION_DENIED, "System API is not allowed called by third HAP."},
761 {LocationErrCode::ERRCODE_INVALID_PARAM, "Parameter error."},
762 {LocationErrCode::ERRCODE_NOT_SUPPORTED, "Capability not supported."},
763 {LocationErrCode::ERRCODE_SERVICE_UNAVAILABLE, "Location service is unavailable."},
764 {LocationErrCode::ERRCODE_SWITCH_OFF, "The location switch is off."},
765 {LocationErrCode::ERRCODE_LOCATING_FAIL, "Failed to obtain the geographical location."},
766 {LocationErrCode::ERRCODE_REVERSE_GEOCODING_FAIL, "Reverse geocoding query failed."},
767 {LocationErrCode::ERRCODE_GEOCODING_FAIL, "Geocoding query failed."},
768 {LocationErrCode::ERRCODE_COUNTRYCODE_FAIL, "Failed to query the area information."},
769 {LocationErrCode::ERRCODE_GEOFENCE_FAIL, "Failed to operate the geofence."},
770 {LocationErrCode::ERRCODE_NO_RESPONSE, "No response to the request."},
771 };
772
773 auto iter = errorCodeMap.find(code);
774 if (iter != errorCodeMap.end()) {
775 std::string errMessage = "BussinessError ";
776 errMessage.append(std::to_string(code)).append(": ").append(iter->second);
777 return errMessage;
778 }
779 return "undefined error.";
780 }
781
GetErrorObject(napi_env env,const int32_t errCode,const std::string & errMsg)782 napi_value GetErrorObject(napi_env env, const int32_t errCode, const std::string& errMsg)
783 {
784 napi_value businessError = nullptr;
785 napi_value eCode = nullptr;
786 napi_value eMsg = nullptr;
787 NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
788 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), errMsg.length(), &eMsg));
789 NAPI_CALL(env, napi_create_object(env, &businessError));
790 NAPI_CALL(env, napi_set_named_property(env, businessError, "code", eCode));
791 NAPI_CALL(env, napi_set_named_property(env, businessError, "message", eMsg));
792 return businessError;
793 }
794
CreateResultObject(const napi_env & env,AsyncContext * context)795 void CreateResultObject(const napi_env& env, AsyncContext* context)
796 {
797 if (context == nullptr || env == nullptr) {
798 LBSLOGE(LOCATOR_STANDARD, "CreateResultObject input para error");
799 return;
800 }
801 if (context->errCode != SUCCESS) {
802 std::string errMsg = GetErrorMsgByCode(context->errCode);
803 context->result[PARAM0] = GetErrorObject(env, context->errCode, errMsg);
804 NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &context->result[PARAM1]));
805 } else {
806 NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &context->result[PARAM0]));
807 }
808 }
809
SendResultToJs(const napi_env & env,AsyncContext * context)810 void SendResultToJs(const napi_env& env, AsyncContext* context)
811 {
812 if (context == nullptr || env == nullptr) {
813 LBSLOGE(LOCATOR_STANDARD, "SendResultToJs input para error");
814 return;
815 }
816
817 bool isPromise = context->deferred != nullptr;
818 if (isPromise) {
819 if (context->errCode != SUCCESS) {
820 NAPI_CALL_RETURN_VOID(env,
821 napi_reject_deferred(env, context->deferred, context->result[PARAM0]));
822 } else {
823 NAPI_CALL_RETURN_VOID(env,
824 napi_resolve_deferred(env, context->deferred, context->result[PARAM1]));
825 }
826 } else {
827 napi_value undefine;
828 NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefine));
829 napi_value callback;
830 NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, context->callback[0], &callback));
831 NAPI_CALL_RETURN_VOID(env,
832 napi_call_function(env, nullptr, callback, RESULT_SIZE, context->result, &undefine));
833 }
834 }
835
MemoryReclamation(const napi_env & env,AsyncContext * context)836 void MemoryReclamation(const napi_env& env, AsyncContext* context)
837 {
838 if (context == nullptr || env == nullptr) {
839 LBSLOGE(LOCATOR_STANDARD, "MemoryReclamation input para error");
840 return;
841 }
842
843 if (context->callback[SUCCESS_CALLBACK] != nullptr) {
844 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, context->callback[SUCCESS_CALLBACK]));
845 }
846 if (context->callback[FAIL_CALLBACK] != nullptr) {
847 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, context->callback[FAIL_CALLBACK]));
848 }
849 if (context->callback[COMPLETE_CALLBACK] != nullptr) {
850 NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, context->callback[COMPLETE_CALLBACK]));
851 }
852 NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, context->work));
853 delete context;
854 }
855
CreateAsyncWork(const napi_env & env,AsyncContext * asyncContext)856 static napi_value CreateAsyncWork(const napi_env& env, AsyncContext* asyncContext)
857 {
858 if (asyncContext == nullptr) {
859 return UndefinedNapiValue(env);
860 }
861 NAPI_CALL(env, napi_create_async_work(
862 env, nullptr, asyncContext->resourceName,
863 [](napi_env env, void* data) {
864 if (data == nullptr) {
865 LBSLOGE(LOCATOR_STANDARD, "Async data parameter is null");
866 return;
867 }
868 AsyncContext* context = static_cast<AsyncContext *>(data);
869 context->executeFunc(context);
870 },
871 [](napi_env env, napi_status status, void* data) {
872 if (data == nullptr) {
873 LBSLOGE(LOCATOR_STANDARD, "Async data parameter is null");
874 return;
875 }
876 AsyncContext* context = static_cast<AsyncContext *>(data);
877 context->completeFunc(data);
878 CreateResultObject(env, context);
879 SendResultToJs(env, context);
880 MemoryReclamation(env, context);
881 }, static_cast<void*>(asyncContext), &asyncContext->work));
882 NAPI_CALL(env, napi_queue_async_work(env, asyncContext->work));
883 return UndefinedNapiValue(env);
884 }
885
DoAsyncWork(const napi_env & env,AsyncContext * asyncContext,const size_t argc,const napi_value * argv,const size_t objectArgsNum)886 napi_value DoAsyncWork(const napi_env& env, AsyncContext* asyncContext,
887 const size_t argc, const napi_value* argv, const size_t objectArgsNum)
888 {
889 if (asyncContext == nullptr || argv == nullptr) {
890 return UndefinedNapiValue(env);
891 }
892 if (argc > objectArgsNum) {
893 InitAsyncCallBackEnv(env, asyncContext, argc, argv, objectArgsNum);
894 return CreateAsyncWork(env, asyncContext);
895 } else {
896 napi_value promise;
897 InitAsyncPromiseEnv(env, asyncContext, promise);
898 CreateAsyncWork(env, asyncContext);
899 return promise;
900 }
901 }
902
DeleteQueueWork(AsyncContext * context)903 void DeleteQueueWork(AsyncContext* context)
904 {
905 uv_loop_s *loop = nullptr;
906 if (context->env == nullptr) {
907 LBSLOGE(CACHED_LOCATIONS_CALLBACK, "env is nullptr.");
908 delete context;
909 return;
910 }
911 NAPI_CALL_RETURN_VOID(context->env, napi_get_uv_event_loop(context->env, &loop));
912 if (loop == nullptr) {
913 LBSLOGE(CACHED_LOCATIONS_CALLBACK, "loop == nullptr.");
914 delete context;
915 return;
916 }
917 uv_work_t *work = new (std::nothrow) uv_work_t;
918 if (work == nullptr) {
919 LBSLOGE(CACHED_LOCATIONS_CALLBACK, "work == nullptr.");
920 delete context;
921 return;
922 }
923 work->data = context;
924 DeleteCallbackHandler(loop, work);
925 }
926
DeleteCallbackHandler(uv_loop_s * & loop,uv_work_t * & work)927 void DeleteCallbackHandler(uv_loop_s *&loop, uv_work_t *&work)
928 {
929 uv_queue_work(loop, work, [](uv_work_t *work) {},
930 [](uv_work_t *work, int status) {
931 AsyncContext *context = nullptr;
932 napi_handle_scope scope = nullptr;
933 if (work == nullptr) {
934 LBSLOGE(LOCATOR_CALLBACK, "work is nullptr");
935 return;
936 }
937 context = static_cast<AsyncContext *>(work->data);
938 if (context == nullptr || context->env == nullptr) {
939 LBSLOGE(LOCATOR_CALLBACK, "context is nullptr");
940 delete work;
941 return;
942 }
943 NAPI_CALL_RETURN_VOID(context->env, napi_open_handle_scope(context->env, &scope));
944 if (scope == nullptr) {
945 LBSLOGE(LOCATOR_CALLBACK, "scope is nullptr");
946 delete context;
947 delete work;
948 return;
949 }
950 if (context->callback[SUCCESS_CALLBACK] != nullptr) {
951 CHK_NAPI_ERR_CLOSE_SCOPE(context->env,
952 napi_delete_reference(context->env, context->callback[SUCCESS_CALLBACK]),
953 scope, context, work);
954 }
955 if (context->callback[FAIL_CALLBACK] != nullptr) {
956 CHK_NAPI_ERR_CLOSE_SCOPE(context->env,
957 napi_delete_reference(context->env, context->callback[FAIL_CALLBACK]),
958 scope, context, work);
959 }
960 if (context->callback[COMPLETE_CALLBACK] != nullptr) {
961 CHK_NAPI_ERR_CLOSE_SCOPE(context->env,
962 napi_delete_reference(context->env, context->callback[COMPLETE_CALLBACK]),
963 scope, context, work);
964 }
965 NAPI_CALL_RETURN_VOID(context->env, napi_close_handle_scope(context->env, scope));
966 delete context;
967 delete work;
968 });
969 }
970
CheckIfParamIsFunctionType(napi_env env,napi_value param)971 bool CheckIfParamIsFunctionType(napi_env env, napi_value param)
972 {
973 napi_valuetype valueType;
974 NAPI_CALL_BASE(env, napi_typeof(env, param, &valueType), false);
975 if (valueType != napi_function) {
976 return false;
977 }
978 return true;
979 }
980
SetEnumPropertyByInteger(napi_env env,napi_value dstObj,int32_t enumValue,const char * enumName)981 napi_value SetEnumPropertyByInteger(napi_env env, napi_value dstObj, int32_t enumValue, const char *enumName)
982 {
983 napi_value enumProp = nullptr;
984 NAPI_CALL(env, napi_create_int32(env, enumValue, &enumProp));
985 NAPI_CALL(env, napi_set_named_property(env, dstObj, enumName, enumProp));
986 return enumProp;
987 }
988 } // namespace Location
989 } // namespace OHOS
990