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