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