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