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