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