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