• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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