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