• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "location_napi_adapter.h"
17 #include "location_log.h"
18 #include "location_napi_errcode.h"
19 #include "constant_definition.h"
20 #include "geofence_sdk.h"
21 #include "geofence_napi.h"
22 #include "geofence_async_context.h"
23 #include "beacon_fence_request.h"
24 #include "beacon_fence_napi.h"
25 
26 namespace OHOS {
27 namespace Location {
28 auto g_locatorClient = Locator::GetInstance();
29 auto g_geofenceClient = GeofenceManager::GetInstance();
30 std::map<int, sptr<LocationGnssGeofenceCallbackNapi>> g_gnssGeofenceCallbackHostMap;
31 std::map<std::shared_ptr<BeaconFence>, sptr<LocationGnssGeofenceCallbackNapi>> g_beaconFenceRequestMap;
32 std::mutex g_gnssGeofenceCallbackHostMutex;
33 std::mutex g_beaconFenceRequestMutex;
34 
GetLastLocation(napi_env env,napi_callback_info info)35 napi_value GetLastLocation(napi_env env, napi_callback_info info)
36 {
37     size_t argc = MAXIMUM_JS_PARAMS;
38     napi_value argv[MAXIMUM_JS_PARAMS];
39     napi_value thisVar = nullptr;
40     void* data = nullptr;
41 
42     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
43     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
44 
45 #ifdef ENABLE_NAPI_MANAGER
46     return HandleGetCachedLocation(env);
47 #else
48     auto asyncContext = new (std::nothrow) LocationAsyncContext(env);
49     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
50     if (napi_create_string_latin1(env, "getLastLocation",
51         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
52         GET_AND_THROW_LAST_ERROR(env);
53         delete asyncContext;
54         return nullptr;
55     }
56     asyncContext->executeFunc = [&](void* data) -> void {
57         auto context = static_cast<LocationAsyncContext*>(data);
58         context->loc = g_locatorClient->IsLocationEnabled() ? g_locatorClient->GetCachedLocation() : nullptr;
59         if (context->loc != nullptr) {
60             context->errCode = SUCCESS;
61         } else {
62             context->errCode = LAST_KNOWN_LOCATION_ERROR;
63         }
64     };
65 
66     asyncContext->completeFunc = [&](void* data) -> void {
67         auto context = static_cast<LocationAsyncContext*>(data);
68         NAPI_CALL_RETURN_VOID(context->env, napi_create_object(context->env, &context->result[PARAM1]));
69         if (context->loc != nullptr) {
70             LocationToJs(context->env, context->loc, context->result[PARAM1]);
71         } else {
72             LBSLOGE(LOCATOR_STANDARD, "loc is nullptr!");
73         }
74         LBSLOGI(LOCATOR_STANDARD, "Push last location result to client");
75     };
76 
77     size_t objectArgsNum = 0;
78     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
79 #endif
80 }
81 
82 #ifdef ENABLE_NAPI_MANAGER
HandleGetCachedLocation(napi_env env)83 napi_value HandleGetCachedLocation(napi_env env)
84 {
85     napi_value res;
86     NAPI_CALL(env, napi_create_object(env, &res));
87     std::unique_ptr<Location> loc;
88     LocationErrCode errorCode = g_locatorClient->GetCachedLocationV9(loc);
89     if (loc != nullptr && errorCode == ERRCODE_SUCCESS) {
90         LocationToJs(env, loc, res);
91         return res;
92     }
93     if (errorCode != ERRCODE_SUCCESS) {
94         HandleSyncErrCode(env, errorCode);
95     }
96     return UndefinedNapiValue(env);
97 }
98 #endif
99 
IsLocationEnabled(napi_env env,napi_callback_info info)100 napi_value IsLocationEnabled(napi_env env, napi_callback_info info)
101 {
102     size_t argc = MAXIMUM_JS_PARAMS;
103     napi_value argv[MAXIMUM_JS_PARAMS];
104     napi_value thisVar = nullptr;
105     void* data = nullptr;
106     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
107     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
108 #ifdef ENABLE_NAPI_MANAGER
109     napi_value res;
110     bool isEnabled = false;
111     LocationErrCode errorCode = g_locatorClient->IsLocationEnabledV9(isEnabled);
112     if (errorCode != ERRCODE_SUCCESS) {
113         HandleSyncErrCode(env, errorCode);
114         return UndefinedNapiValue(env);
115     }
116     NAPI_CALL(env, napi_get_boolean(env, isEnabled, &res));
117     return res;
118 #else
119     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
120     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
121     if (napi_create_string_latin1(env, "isLocationEnabled", NAPI_AUTO_LENGTH,
122         &asyncContext->resourceName) != napi_ok) {
123         LBSLOGE(LOCATOR_STANDARD, "copy string failed");
124     }
125     asyncContext->executeFunc = [&](void* data) -> void {
126         auto context = static_cast<SwitchAsyncContext*>(data);
127         context->enable = g_locatorClient->IsLocationEnabled();
128         context->errCode = SUCCESS;
129     };
130     asyncContext->completeFunc = [&](void* data) -> void {
131         auto context = static_cast<SwitchAsyncContext*>(data);
132         NAPI_CALL_RETURN_VOID(context->env, napi_get_boolean(context->env, context->enable, &context->result[PARAM1]));
133         LBSLOGI(LOCATOR_STANDARD, "Push IsLocationEnabled result to client");
134     };
135 
136     size_t objectArgsNum = 0;
137     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
138 #endif
139 }
140 
141 #ifdef ENABLE_NAPI_MANAGER
IsLocationEnabledByUserId(napi_env env,napi_callback_info info)142 napi_value IsLocationEnabledByUserId(napi_env env, napi_callback_info info)
143 {
144     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
145     size_t argc = MAXIMUM_JS_PARAMS;
146     napi_value argv[MAXIMUM_JS_PARAMS];
147     napi_value thisVar = nullptr;
148     void* data = nullptr;
149     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
150     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
151 
152     napi_value res;
153     bool isEnabled = false;
154     int userId;
155     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &userId));
156     LocationErrCode errorCode = g_locatorClient->IsLocationEnabledForUser(isEnabled, userId);
157     if (errorCode != ERRCODE_SUCCESS) {
158         ThrowBusinessError(env, errorCode);
159     }
160     NAPI_CALL(env, napi_get_boolean(env, isEnabled, &res));
161     return res;
162 }
163 
EnableLocationByUserId(napi_env env,napi_callback_info info)164 napi_value EnableLocationByUserId(napi_env env, napi_callback_info info)
165 {
166     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
167     size_t argc = MAXIMUM_JS_PARAMS;
168     napi_value argv[MAXIMUM_JS_PARAMS];
169     napi_value thisVar = nullptr;
170     void* data = nullptr;
171     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
172     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
173     int userId;
174     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &userId));
175     LocationErrCode errorCode = g_locatorClient->EnableAbilityForUser(true, userId);
176     if (errorCode != ERRCODE_SUCCESS) {
177         ThrowBusinessError(env, errorCode);
178     }
179     return UndefinedNapiValue(env);
180 }
181 
DisableLocationByUserId(napi_env env,napi_callback_info info)182 napi_value DisableLocationByUserId(napi_env env, napi_callback_info info)
183 {
184     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
185     size_t argc = MAXIMUM_JS_PARAMS;
186     napi_value argv[MAXIMUM_JS_PARAMS];
187     napi_value thisVar = nullptr;
188     void* data = nullptr;
189     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
190     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
191     int userId;
192     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &userId));
193     LocationErrCode errorCode = g_locatorClient->EnableAbilityForUser(false, userId);
194     if (errorCode != ERRCODE_SUCCESS) {
195         ThrowBusinessError(env, errorCode);
196     }
197     return UndefinedNapiValue(env);
198 }
199 #endif
200 
201 #ifdef ENABLE_NAPI_MANAGER
GetCurrentWifiBssidForLocating(napi_env env,napi_callback_info info)202 napi_value GetCurrentWifiBssidForLocating(napi_env env, napi_callback_info info)
203 {
204     size_t argc = MAXIMUM_JS_PARAMS;
205     napi_value argv[MAXIMUM_JS_PARAMS];
206     napi_value thisVar = nullptr;
207     void* data = nullptr;
208     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
209     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
210     napi_value res;
211     std::string bssid;
212     LocationErrCode errorCode = g_locatorClient->GetCurrentWifiBssidForLocating(bssid);
213     if (errorCode != ERRCODE_SUCCESS) {
214         ThrowBusinessError(env, errorCode);
215         return UndefinedNapiValue(env);
216     }
217     NAPI_CALL(env, napi_create_string_utf8(env, bssid.c_str(), NAPI_AUTO_LENGTH, &res));
218     return res;
219 }
220 
GetDistanceBetweenLocations(napi_env env,napi_callback_info info)221 napi_value GetDistanceBetweenLocations(napi_env env, napi_callback_info info)
222 {
223     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
224     size_t argc = MAXIMUM_JS_PARAMS;
225     napi_value argv[MAXIMUM_JS_PARAMS];
226     napi_value thisVar = nullptr;
227     void* data = nullptr;
228     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
229     if (g_locatorClient == nullptr) {
230         HandleSyncErrCode(env, ERRCODE_SERVICE_UNAVAILABLE);
231         return UndefinedNapiValue(env);
232     }
233     // 2 arguement is necessary
234     if (argc != PARAM2) {
235         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
236         return UndefinedNapiValue(env);
237     }
238     napi_valuetype valueType;
239     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
240     napi_valuetype valueType1;
241     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType1));
242     if (valueType != napi_object || valueType1 != napi_object) {
243         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
244         return UndefinedNapiValue(env);
245     }
246     Location location1;
247     Location location2;
248     if (!JsObjToLocation(env, argv[0], location1) || !JsObjToLocation(env, argv[1], location2)) {
249         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
250         return UndefinedNapiValue(env);
251     }
252     if (!location1.isValidLatitude(location1.GetLatitude()) || !location1.isValidLongitude(location1.GetLongitude()) ||
253         !location1.isValidLatitude(location2.GetLatitude()) || !location1.isValidLongitude(location2.GetLongitude())) {
254         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
255         return UndefinedNapiValue(env);
256     }
257     napi_value res;
258     double distance;
259     LocationErrCode errorCode = g_locatorClient->GetDistanceBetweenLocations(location1, location2, distance);
260     if (errorCode != ERRCODE_SUCCESS) {
261         HandleSyncErrCode(env, errorCode);
262         return UndefinedNapiValue(env);
263     }
264     NAPI_CALL(env, napi_create_double(env, distance, &res));
265     return res;
266 }
267 #endif
268 
269 #ifdef ENABLE_NAPI_MANAGER
IsPoiServiceSupported(napi_env env,napi_callback_info info)270 napi_value IsPoiServiceSupported(napi_env env, napi_callback_info info)
271 {
272     size_t argc = MAXIMUM_JS_PARAMS;
273     napi_value argv[MAXIMUM_JS_PARAMS];
274     napi_value thisVar = nullptr;
275     void* data = nullptr;
276     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
277     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
278     napi_value res;
279     bool poiServiceSupportState = g_locatorClient->IsPoiServiceSupported();
280     NAPI_CALL(env, napi_get_boolean(env, poiServiceSupportState, &res));
281     return res;
282 }
283 #endif
284 
EnableLocation(napi_env env,napi_callback_info info)285 napi_value EnableLocation(napi_env env, napi_callback_info info)
286 {
287     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
288     size_t argc = MAXIMUM_JS_PARAMS;
289     napi_value argv[MAXIMUM_JS_PARAMS];
290     napi_value thisVar = nullptr;
291     void* data = nullptr;
292     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
293     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
294 #ifdef ENABLE_NAPI_MANAGER
295     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsFunctionType(env, argv[PARAM0]))) {
296         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
297         return UndefinedNapiValue(env);
298     }
299 #endif
300     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
301     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
302     if (napi_create_string_latin1(env, "enableLocation",
303         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
304         GET_AND_THROW_LAST_ERROR(env);
305         delete asyncContext;
306         return nullptr;
307     }
308     asyncContext->executeFunc = [&](void* data) -> void {
309         auto context = static_cast<SwitchAsyncContext*>(data);
310 #ifdef ENABLE_NAPI_MANAGER
311         context->errCode = g_locatorClient->EnableAbilityV9(true);
312 #else
313         g_locatorClient->EnableAbility(true);
314         context->errCode = SUCCESS;
315 #endif
316     };
317 
318     asyncContext->completeFunc = [&](void* data) -> void {
319         auto context = static_cast<SwitchAsyncContext*>(data);
320 #ifdef ENABLE_NAPI_MANAGER
321         NAPI_CALL_RETURN_VOID(context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
322 #else
323         NAPI_CALL_RETURN_VOID(context->env,
324             napi_get_boolean(context->env, context->errCode == SUCCESS, &context->result[PARAM1]));
325 #endif
326         LBSLOGI(LOCATOR_STANDARD, "Push EnableLocation result to client");
327     };
328 
329     size_t objectArgsNum = 0;
330     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
331 }
332 
DisableLocation(napi_env env,napi_callback_info info)333 napi_value DisableLocation(napi_env env, napi_callback_info info)
334 {
335     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
336     size_t argc = MAXIMUM_JS_PARAMS;
337     napi_value argv[MAXIMUM_JS_PARAMS];
338     napi_value thisVar = nullptr;
339     void* data = nullptr;
340     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
341     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
342 
343 #ifdef ENABLE_NAPI_MANAGER
344     LocationErrCode errorCode = g_locatorClient->EnableAbilityV9(false);
345     if (errorCode != ERRCODE_SUCCESS) {
346         HandleSyncErrCode(env, errorCode);
347     }
348     return UndefinedNapiValue(env);
349 #else
350     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
351     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
352     NAPI_CALL(env, napi_create_string_latin1(env, "disableLocation", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
353     asyncContext->executeFunc = [&](void* data) -> void {
354         auto context = static_cast<SwitchAsyncContext*>(data);
355         g_locatorClient->EnableAbility(false);
356         context->errCode = SUCCESS;
357     };
358     asyncContext->completeFunc = [&](void* data) -> void {
359         auto context = static_cast<SwitchAsyncContext*>(data);
360         NAPI_CALL_RETURN_VOID(context->env,
361             napi_get_boolean(context->env, context->errCode == SUCCESS, &context->result[PARAM1]));
362         LBSLOGI(LOCATOR_STANDARD, "Push DisableLocation result to client");
363     };
364     size_t objectArgsNum = 0;
365     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
366 #endif
367 }
368 
RequestEnableLocation(napi_env env,napi_callback_info info)369 napi_value RequestEnableLocation(napi_env env, napi_callback_info info)
370 {
371     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
372     size_t argc = MAXIMUM_JS_PARAMS;
373     napi_value argv[MAXIMUM_JS_PARAMS];
374     napi_value thisVar = nullptr;
375     void* data = nullptr;
376     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
377     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
378 
379     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
380     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
381     if (napi_create_string_latin1(env, "enableLocation",
382         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
383         GET_AND_THROW_LAST_ERROR(env);
384         delete asyncContext;
385         return nullptr;
386     }
387     asyncContext->executeFunc = [&](void* data) -> void {
388         auto context = static_cast<SwitchAsyncContext*>(data);
389         if (!g_locatorClient->IsLocationEnabled()) {
390             g_locatorClient->ShowNotification();
391         }
392         g_locatorClient->EnableAbility(true);
393         context->errCode = SUCCESS;
394     };
395 
396     asyncContext->completeFunc = [&](void* data) -> void {
397         auto context = static_cast<SwitchAsyncContext*>(data);
398         NAPI_CALL_RETURN_VOID(context->env,
399             napi_get_boolean(context->env, context->errCode == SUCCESS, &context->result[PARAM1]));
400         LBSLOGI(LOCATOR_STANDARD, "Push RequestEnableLocation result to client");
401     };
402 
403     size_t objectArgsNum = 0;
404     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
405 }
406 
IsGeoServiceAvailable(napi_env env,napi_callback_info info)407 napi_value IsGeoServiceAvailable(napi_env env, napi_callback_info info)
408 {
409     size_t argc = MAXIMUM_JS_PARAMS;
410     napi_value argv[MAXIMUM_JS_PARAMS];
411     napi_value thisVar = nullptr;
412     void* data = nullptr;
413     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
414     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
415 #ifdef ENABLE_NAPI_MANAGER
416     napi_value res;
417     bool isAvailable = false;
418     LocationErrCode errorCode = g_locatorClient->IsGeoServiceAvailableV9(isAvailable);
419     if (errorCode != ERRCODE_SUCCESS) {
420         HandleSyncErrCode(env, errorCode);
421         return UndefinedNapiValue(env);
422     }
423     NAPI_CALL(env, napi_get_boolean(env, isAvailable, &res));
424     return res;
425 #else
426     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
427     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
428     NAPI_CALL(env,
429         napi_create_string_latin1(env, "isGeoServiceAvailable", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
430     asyncContext->executeFunc = [&](void* data) -> void {
431         auto context = static_cast<SwitchAsyncContext*>(data);
432         bool isAvailable = g_locatorClient->IsGeoServiceAvailable();
433         context->enable = isAvailable;
434         context->errCode = SUCCESS;
435     };
436     asyncContext->completeFunc = [&](void* data) -> void {
437         auto context = static_cast<SwitchAsyncContext*>(data);
438         NAPI_CALL_RETURN_VOID(context->env, napi_get_boolean(context->env, context->enable, &context->result[PARAM1]));
439         LBSLOGI(LOCATOR_STANDARD, "Push isGeoServiceAvailable result to client");
440     };
441     size_t objectArgsNum = 0;
442     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
443 #endif
444 }
445 
446 #ifdef ENABLE_NAPI_MANAGER
SetLocationSwitchIgnored(napi_env env,napi_callback_info info)447 napi_value SetLocationSwitchIgnored(napi_env env, napi_callback_info info)
448 {
449     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
450     size_t argc = MAXIMUM_JS_PARAMS;
451     napi_value argv[MAXIMUM_JS_PARAMS];
452     napi_value thisVar = nullptr;
453     void* data = nullptr;
454     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
455     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
456     bool isIgnored;
457     NAPI_CALL(env, napi_get_value_bool(env, argv[0], &isIgnored));
458     LocationErrCode errorCode = g_locatorClient->SetLocationSwitchIgnored(isIgnored);
459     if (errorCode != ERRCODE_SUCCESS) {
460         ThrowBusinessError(env, errorCode);
461     }
462     return UndefinedNapiValue(env);
463 }
464 #endif
465 
CreateReverseGeocodeAsyncContext(ReverseGeoCodeAsyncContext * asyncContext)466 void CreateReverseGeocodeAsyncContext(ReverseGeoCodeAsyncContext* asyncContext)
467 {
468     asyncContext->executeFunc = [&](void* data) -> void {
469         auto context = static_cast<ReverseGeoCodeAsyncContext*>(data);
470 #ifdef ENABLE_NAPI_MANAGER
471         if (context->errCode != ERRCODE_SUCCESS) {
472 #else
473         if (context->errCode != SUCCESS) {
474 #endif
475             return;
476         }
477 #ifdef ENABLE_NAPI_MANAGER
478         bool isAvailable = false;
479         LocationErrCode errorCode = g_locatorClient->IsGeoServiceAvailableV9(isAvailable);
480         if (errorCode != ERRCODE_SUCCESS) {
481             context->errCode = errorCode;
482             return;
483         }
484         if (!isAvailable) {
485             context->errCode = ERRCODE_REVERSE_GEOCODING_FAIL;
486             return;
487         }
488         errorCode = g_locatorClient->GetAddressByCoordinateV9(context->reverseGeoCodeRequest, context->replyList);
489         if (context->replyList.empty() || errorCode != ERRCODE_SUCCESS) {
490             context->errCode = errorCode;
491         }
492 #else
493         if (!g_locatorClient->IsGeoServiceAvailable()) {
494             context->errCode = REVERSE_GEOCODE_ERROR;
495             return;
496         }
497         g_locatorClient->GetAddressByCoordinate(context->reverseGeoCodeRequest, context->replyList);
498         if (context->replyList.empty()) {
499             context->errCode = REVERSE_GEOCODE_ERROR;
500         }
501 #endif
502     };
503     asyncContext->completeFunc = [&](void* data) -> void {
504         auto context = static_cast<ReverseGeoCodeAsyncContext*>(data);
505         NAPI_CALL_RETURN_VOID(context->env,
506             napi_create_array_with_length(context->env, context->replyList.size(), &context->result[PARAM1]));
507         GeoAddressesToJsObj(context->env, context->replyList, context->result[PARAM1]);
508     };
509 }
510 
511 void CreateGeocodeAsyncContext(GeoCodeAsyncContext* asyncContext)
512 {
513     asyncContext->executeFunc = [&](void* data) -> void {
514         auto context = static_cast<GeoCodeAsyncContext*>(data);
515         if (context->errCode != SUCCESS) {
516             return;
517         }
518 #ifdef ENABLE_NAPI_MANAGER
519         bool isAvailable = false;
520         LocationErrCode errorCode = g_locatorClient->IsGeoServiceAvailableV9(isAvailable);
521         if (errorCode != ERRCODE_SUCCESS) {
522             context->errCode = errorCode;
523             return;
524         }
525         if (!isAvailable) {
526             context->errCode = ERRCODE_GEOCODING_FAIL;
527             return;
528         }
529         errorCode = g_locatorClient->GetAddressByLocationNameV9(context->geoCodeRequest, context->replyList);
530         if (context->replyList.empty() || errorCode != ERRCODE_SUCCESS) {
531             context->errCode = errorCode;
532         }
533 #else
534         if (!g_locatorClient->IsGeoServiceAvailable()) {
535             context->errCode = GEOCODE_ERROR;
536             return;
537         }
538         g_locatorClient->GetAddressByLocationName(context->geoCodeRequest, context->replyList);
539         if (context->replyList.empty()) {
540             context->errCode = GEOCODE_ERROR;
541         }
542 #endif
543     };
544     asyncContext->completeFunc = [&](void* data) -> void {
545         auto context = static_cast<GeoCodeAsyncContext*>(data);
546         NAPI_CALL_RETURN_VOID(context->env,
547             napi_create_array_with_length(context->env, context->replyList.size(), &context->result[PARAM1]));
548         GeoAddressesToJsObj(context->env, context->replyList, context->result[PARAM1]);
549         LBSLOGI(LOCATOR_STANDARD, "Push GetAddressesFromLocationName result to client");
550     };
551 }
552 
553 napi_value GetAddressesFromLocation(napi_env env, napi_callback_info info)
554 {
555     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
556     size_t argc = MAXIMUM_JS_PARAMS;
557     napi_value argv[MAXIMUM_JS_PARAMS];
558     napi_value thisVar = nullptr;
559     void* data = nullptr;
560     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
561     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
562 #ifdef ENABLE_NAPI_MANAGER
563     if (argc < PARAM1 || argc > PARAM2 || (argc == PARAM2 && !CheckIfParamIsFunctionType(env, argv[1]))) {
564         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
565         return UndefinedNapiValue(env);
566     }
567 #else
568     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
569 #endif
570 
571     napi_valuetype valueType;
572     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
573 #ifdef ENABLE_NAPI_MANAGER
574     if (valueType != napi_object) {
575         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
576         return UndefinedNapiValue(env);
577     }
578 #else
579     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type, object is expected for parameter 1.");
580 #endif
581     auto asyncContext = new ReverseGeoCodeAsyncContext(env);
582     if (napi_create_string_latin1(env, "getAddressesFromLocation",
583         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
584         GET_AND_THROW_LAST_ERROR(env);
585         delete asyncContext;
586         return nullptr;
587     }
588     int ret = JsObjToReverseGeoCodeRequest(env, argv[0], asyncContext->reverseGeoCodeRequest);
589 #ifdef ENABLE_NAPI_MANAGER
590     asyncContext->errCode = (ret == SUCCESS) ? ERRCODE_SUCCESS : ERRCODE_INVALID_PARAM;
591 #else
592     asyncContext->errCode = (ret == SUCCESS) ? SUCCESS : INPUT_PARAMS_ERROR;
593 #endif
594 #ifdef ENABLE_NAPI_MANAGER
595     if (asyncContext->errCode != SUCCESS) {
596         int code = asyncContext->errCode;
597         delete asyncContext;
598         asyncContext = nullptr;
599         HandleSyncErrCode(env, code);
600         return UndefinedNapiValue(env);
601     }
602 #endif
603     CreateReverseGeocodeAsyncContext(asyncContext);
604 
605     size_t objectArgsNum = 1;
606     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
607 }
608 
609 napi_value GetAddressesFromLocationName(napi_env env, napi_callback_info info)
610 {
611     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
612     size_t argc = MAXIMUM_JS_PARAMS;
613     napi_value argv[MAXIMUM_JS_PARAMS];
614     napi_value thisVar = nullptr;
615     void* data = nullptr;
616     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
617     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
618 #ifdef ENABLE_NAPI_MANAGER
619     if (argc < PARAM1 || argc > PARAM2 || (argc == PARAM2 && !CheckIfParamIsFunctionType(env, argv[1]))) {
620         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
621         return UndefinedNapiValue(env);
622     }
623 #else
624     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
625 #endif
626 
627     napi_valuetype valueType;
628     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
629 #ifdef ENABLE_NAPI_MANAGER
630     if (valueType != napi_object) {
631         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
632         return UndefinedNapiValue(env);
633     }
634 #else
635     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type, object is expected for parameter 1.");
636 #endif
637     auto asyncContext = new (std::nothrow) GeoCodeAsyncContext(env);
638     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
639     if (napi_create_string_latin1(env, "GetAddressesFromLocationName",
640         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
641         GET_AND_THROW_LAST_ERROR(env);
642         delete asyncContext;
643         return nullptr;
644     }
645     asyncContext->errCode = JsObjToGeoCodeRequest(env, argv[0], asyncContext->geoCodeRequest);
646 #ifdef ENABLE_NAPI_MANAGER
647     if (asyncContext->errCode == INPUT_PARAMS_ERROR) {
648         delete asyncContext;
649         asyncContext = nullptr;
650         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
651         return UndefinedNapiValue(env);
652     }
653 #endif
654     CreateGeocodeAsyncContext(asyncContext);
655     size_t objectArgsNum = 1;
656     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
657 }
658 
659 #ifdef ENABLE_NAPI_MANAGER
660 napi_value IsLocationPrivacyConfirmed(napi_env env, napi_callback_info info)
661 {
662     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
663     size_t argc = MAXIMUM_JS_PARAMS;
664     napi_value argv[MAXIMUM_JS_PARAMS];
665     napi_value thisVar = nullptr;
666     void* data = nullptr;
667     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
668     if (g_locatorClient == nullptr) {
669         HandleSyncErrCode(env, ERRCODE_SERVICE_UNAVAILABLE);
670         return UndefinedNapiValue(env);
671     }
672     // 1 arguement is necessary
673     if (argc != PARAM1) {
674         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
675         return UndefinedNapiValue(env);
676     }
677     napi_valuetype valueType;
678     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
679     if (valueType != napi_number) {
680         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
681         return UndefinedNapiValue(env);
682     }
683     int type;
684     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &type));
685     napi_value res;
686     bool isEnabled = false;
687     LocationErrCode errorCode = g_locatorClient->IsLocationPrivacyConfirmedV9(type, isEnabled);
688     if (errorCode != ERRCODE_SUCCESS) {
689         HandleSyncErrCode(env, errorCode);
690         return UndefinedNapiValue(env);
691     }
692     NAPI_CALL(env, napi_get_boolean(env, isEnabled, &res));
693     return res;
694 }
695 
696 napi_value SetLocationPrivacyConfirmStatus(napi_env env, napi_callback_info info)
697 {
698     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
699     size_t argc = MAXIMUM_JS_PARAMS;
700     napi_value argv[MAXIMUM_JS_PARAMS];
701     napi_value thisVar = nullptr;
702     void* data = nullptr;
703     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
704     if (g_locatorClient == nullptr) {
705         HandleSyncErrCode(env, ERRCODE_SERVICE_UNAVAILABLE);
706         return UndefinedNapiValue(env);
707     }
708     // 2 arguement is necessary
709     if (argc != PARAM2) {
710         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
711         return UndefinedNapiValue(env);
712     }
713     napi_valuetype valueType1;
714     napi_valuetype valueType2;
715     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType1));
716     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType2));
717     if (valueType1 != napi_number || valueType2 != napi_boolean) {
718         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
719         return UndefinedNapiValue(env);
720     }
721     int type;
722     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &type));
723     bool isConfirmed;
724     NAPI_CALL(env, napi_get_value_bool(env, argv[1], &isConfirmed));
725     LocationErrCode errorCode = g_locatorClient->SetLocationPrivacyConfirmStatusV9(type, isConfirmed);
726     if (errorCode != ERRCODE_SUCCESS) {
727         HandleSyncErrCode(env, errorCode);
728     }
729     return UndefinedNapiValue(env);
730 }
731 #endif
732 
733 napi_value GetCachedGnssLocationsSize(napi_env env, napi_callback_info info)
734 {
735     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
736     size_t argc = MAXIMUM_JS_PARAMS;
737     napi_value argv[MAXIMUM_JS_PARAMS];
738     napi_value thisVar = nullptr;
739     void* data = nullptr;
740     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
741     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
742 #ifdef ENABLE_NAPI_MANAGER
743     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsFunctionType(env, argv[PARAM0]))) {
744         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
745         return UndefinedNapiValue(env);
746     }
747 #endif
748     auto asyncContext = new (std::nothrow) CachedAsyncContext(env);
749     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
750     if (napi_create_string_latin1(env, "GetCachedGnssLocationsSize",
751         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
752         GET_AND_THROW_LAST_ERROR(env);
753         delete asyncContext;
754         return nullptr;
755     }
756     asyncContext->executeFunc = [&](void* data) -> void {
757         auto context = static_cast<CachedAsyncContext*>(data);
758 #ifdef ENABLE_NAPI_MANAGER
759         LocationErrCode errorCode = CheckLocationSwitchState();
760         if (errorCode != ERRCODE_SUCCESS) {
761             context->errCode = errorCode;
762             return;
763         }
764 #endif
765 
766 #ifdef ENABLE_NAPI_MANAGER
767         int size = -1;
768         g_locatorClient->GetCachedGnssLocationsSizeV9(size);
769         context->errCode = ERRCODE_NOT_SUPPORTED;
770         context->locationSize = size;
771 #else
772         context->locationSize = g_locatorClient->GetCachedGnssLocationsSize();
773         context->errCode = (context->locationSize >= 0) ? SUCCESS : NOT_SUPPORTED;
774 #endif
775     };
776     asyncContext->completeFunc = [&](void* data) -> void {
777         auto context = static_cast<CachedAsyncContext*>(data);
778         NAPI_CALL_RETURN_VOID(context->env,
779             napi_create_int32(context->env, context->locationSize, &context->result[PARAM1]));
780         LBSLOGI(LOCATOR_STANDARD, "Push GetCachedGnssLocationsSize result to client");
781     };
782 
783     size_t objectArgsNum = 0;
784     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
785 }
786 
787 napi_value FlushCachedGnssLocations(napi_env env, napi_callback_info info)
788 {
789     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
790     size_t argc = MAXIMUM_JS_PARAMS;
791     napi_value argv[MAXIMUM_JS_PARAMS];
792     napi_value thisVar = nullptr;
793     void* data = nullptr;
794     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
795     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
796 #ifdef ENABLE_NAPI_MANAGER
797     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsFunctionType(env, argv[PARAM0]))) {
798         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
799         return UndefinedNapiValue(env);
800     }
801 #endif
802     auto asyncContext = new CachedAsyncContext(env);
803     if (napi_create_string_latin1(env, "FlushCachedGnssLocations",
804         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
805         GET_AND_THROW_LAST_ERROR(env);
806         delete asyncContext;
807         return nullptr;
808     }
809     asyncContext->executeFunc = [&](void* data) -> void {
810         auto context = static_cast<CachedAsyncContext*>(data);
811 #ifdef ENABLE_NAPI_MANAGER
812         LocationErrCode errorCode = CheckLocationSwitchState();
813         if (errorCode != ERRCODE_SUCCESS) {
814             context->errCode = errorCode;
815             return;
816         }
817         g_locatorClient->FlushCachedGnssLocationsV9();
818         context->errCode = ERRCODE_NOT_SUPPORTED;
819 #else
820         if (g_locatorClient->IsLocationEnabled()) {
821             g_locatorClient->FlushCachedGnssLocations();
822         }
823         context->errCode = NOT_SUPPORTED;
824 #endif
825     };
826 
827     asyncContext->completeFunc = [&](void* data) -> void {
828         auto context = static_cast<CachedAsyncContext*>(data);
829 #ifdef ENABLE_NAPI_MANAGER
830         NAPI_CALL_RETURN_VOID(context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
831 #else
832         NAPI_CALL_RETURN_VOID(context->env,
833             napi_get_boolean(context->env, context->errCode == SUCCESS, &context->result[PARAM1]));
834 #endif
835         LBSLOGI(LOCATOR_STANDARD, "Push FlushCachedGnssLocations result to client");
836     };
837 
838     size_t objectArgsNum = 0;
839     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
840 }
841 
842 void CreateCommandAsyncContext(CommandAsyncContext* asyncContext)
843 {
844     asyncContext->executeFunc = [&](void* data) -> void {
845         auto context = static_cast<CommandAsyncContext*>(data);
846 #ifdef ENABLE_NAPI_MANAGER
847         if (context->command != nullptr) {
848             context->errCode = g_locatorClient->SendCommandV9(context->command);
849         }
850 #else
851         if (context->command != nullptr) {
852             g_locatorClient->SendCommand(context->command);
853         }
854         context->errCode = NOT_SUPPORTED;
855 #endif
856     };
857     asyncContext->completeFunc = [&](void* data) -> void {
858         auto context = static_cast<CommandAsyncContext*>(data);
859 #ifdef ENABLE_NAPI_MANAGER
860         NAPI_CALL_RETURN_VOID(context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
861 #else
862         NAPI_CALL_RETURN_VOID(context->env, napi_get_boolean(context->env,
863             context->enable, &context->result[PARAM1]));
864 #endif
865         LBSLOGI(LOCATOR_STANDARD, "Push SendCommand result to client");
866     };
867 }
868 
869 napi_value SendCommand(napi_env env, napi_callback_info info)
870 {
871     size_t argc = MAXIMUM_JS_PARAMS;
872     napi_value argv[MAXIMUM_JS_PARAMS];
873     napi_value thisVar = nullptr;
874     void* data = nullptr;
875     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
876     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
877 #ifdef ENABLE_NAPI_MANAGER
878     if (argc < PARAM1 || argc > PARAM2 || (argc == PARAM2 && !CheckIfParamIsFunctionType(env, argv[1]))) {
879         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
880         return UndefinedNapiValue(env);
881     }
882 #else
883     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
884 #endif
885 
886     napi_valuetype valueType;
887     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
888 #ifdef ENABLE_NAPI_MANAGER
889     if (valueType != napi_object) {
890         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
891         return UndefinedNapiValue(env);
892     }
893 #else
894     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type, object is expected for parameter 1.");
895 #endif
896 
897 #ifdef ENABLE_NAPI_MANAGER
898     if (argc == PARAM2 && !CheckIfParamIsFunctionType(env, argv[PARAM1])) {
899         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
900         return UndefinedNapiValue(env);
901     }
902 #endif
903     auto asyncContext = new CommandAsyncContext(env);
904     asyncContext->command = std::make_unique<LocationCommand>();
905     if (napi_create_string_latin1(env, "SendCommand",
906         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
907         GET_AND_THROW_LAST_ERROR(env);
908         delete asyncContext;
909         return nullptr;
910     }
911     int errCode = JsObjToCommand(env, argv[0], asyncContext->command);
912 #ifdef ENABLE_NAPI_MANAGER
913     if (errCode == INPUT_PARAMS_ERROR) {
914         delete asyncContext;
915         asyncContext = nullptr;
916         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
917         return UndefinedNapiValue(env);
918     }
919 #else
920     NAPI_ASSERT(env, errCode != INPUT_PARAMS_ERROR, "The input params should be checked first.");
921 #endif
922     CreateCommandAsyncContext(asyncContext);
923     size_t objectArgsNum = 1;
924     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
925 }
926 
927 #ifdef ENABLE_NAPI_MANAGER
928 napi_value GetIsoCountryCode(napi_env env, napi_callback_info info)
929 {
930     LBSLOGD(LOCATOR_STANDARD, "%{public}s called.", __func__);
931     size_t argc = MAXIMUM_JS_PARAMS;
932     napi_value argv[MAXIMUM_JS_PARAMS];
933     napi_value thisVar = nullptr;
934     void *data = nullptr;
935     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
936     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
937     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsFunctionType(env, argv[PARAM0]))) {
938         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
939         return UndefinedNapiValue(env);
940     }
941     CountryCodeContext *asyncContext = new (std::nothrow) CountryCodeContext(env);
942     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
943     if (napi_create_string_latin1(env, "CountryCodeContext", NAPI_AUTO_LENGTH,
944         &asyncContext->resourceName) != napi_ok) {
945         LBSLOGE(LOCATOR_STANDARD, "copy string failed");
946     }
947     asyncContext->executeFunc = [&](void *data) -> void {
948         if (data == nullptr) {
949             LBSLOGE(LOCATOR_STANDARD, "GetIsoCountryCode data == nullptr");
950             return;
951         }
952         CountryCodeContext *context = static_cast<CountryCodeContext*>(data);
953         std::shared_ptr<CountryCode> country = std::make_shared<CountryCode>();
954         LocationErrCode errorCode = g_locatorClient->GetIsoCountryCodeV9(country);
955         context->errCode = errorCode;
956         if (errorCode == ERRCODE_SUCCESS) {
957             context->country = country;
958         }
959     };
960     asyncContext->completeFunc = [&](void *data) -> void {
961         if (data == nullptr) {
962             LBSLOGE(LOCATOR_STANDARD, "GetIsoCountryCode data == nullptr");
963             return;
964         }
965         CountryCodeContext *context = static_cast<CountryCodeContext *>(data);
966         NAPI_CALL_RETURN_VOID(context->env, napi_create_object(context->env, &context->result[PARAM1]));
967         if (context->country) {
968             CountryCodeToJs(context->env, context->country, context->result[PARAM1]);
969         } else {
970             LBSLOGE(LOCATOR_STANDARD, "country is nullptr!");
971         }
972         LBSLOGI(LOCATOR_STANDARD, "Push GetIsoCountryCode result to client, time = %{public}s",
973             std::to_string(CommonUtils::GetCurrentTimeMilSec()).c_str());
974     };
975 
976     size_t objectArgsNum = 0;
977     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
978 }
979 
980 int ParseLocationMockParams(napi_env env, LocationMockAsyncContext *asyncContext, napi_value object)
981 {
982     CHK_ERROR_CODE("timeInterval", JsObjectToInt(env, object, "timeInterval", asyncContext->timeInterval), true);
983     bool result = false;
984     napi_value value = nullptr;
985     NAPI_CALL_BASE(env, napi_has_named_property(env, object, "locations", &result), false);
986     if (result) {
987         NAPI_CALL_BASE(env, napi_get_named_property(env, object, "locations", &value), false);
988         bool isArray = false;
989         NAPI_CALL_BASE(env, napi_is_array(env, value, &isArray), false);
990         if (!isArray) {
991             LBSLOGE(LOCATOR_STANDARD, "not an array!");
992             return INPUT_PARAMS_ERROR;
993         }
994         GetLocationArray(env, asyncContext, value);
995     }
996     return SUCCESS;
997 }
998 
999 napi_value EnableLocationMock(napi_env env, napi_callback_info info)
1000 {
1001     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
1002     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
1003     LocationErrCode errorCode = CheckLocationSwitchState();
1004     if (errorCode != ERRCODE_SUCCESS) {
1005         HandleSyncErrCode(env, errorCode);
1006         return UndefinedNapiValue(env);
1007     }
1008     errorCode = g_locatorClient->EnableLocationMockV9();
1009     if (errorCode != ERRCODE_SUCCESS) {
1010         HandleSyncErrCode(env, errorCode);
1011     }
1012     return UndefinedNapiValue(env);
1013 }
1014 
1015 napi_value DisableLocationMock(napi_env env, napi_callback_info info)
1016 {
1017     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
1018     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
1019     LocationErrCode errorCode = CheckLocationSwitchState();
1020     if (errorCode != ERRCODE_SUCCESS) {
1021         HandleSyncErrCode(env, errorCode);
1022         return UndefinedNapiValue(env);
1023     }
1024     errorCode = g_locatorClient->DisableLocationMockV9();
1025     if (errorCode != ERRCODE_SUCCESS) {
1026         HandleSyncErrCode(env, errorCode);
1027     }
1028     return UndefinedNapiValue(env);
1029 }
1030 
1031 napi_value SetMockedLocations(napi_env env, napi_callback_info info)
1032 {
1033     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
1034     size_t argc = MAXIMUM_JS_PARAMS;
1035     napi_value argv[MAXIMUM_JS_PARAMS];
1036     napi_value thisVar = nullptr;
1037     void *data = nullptr;
1038     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1039     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
1040     if (argc != PARAM1) {
1041         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1042         return UndefinedNapiValue(env);
1043     }
1044     napi_valuetype valueType;
1045     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
1046     if (valueType != napi_object) {
1047         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1048         return UndefinedNapiValue(env);
1049     }
1050 
1051     LocationMockAsyncContext *asyncContext = new (std::nothrow) LocationMockAsyncContext(env);
1052     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
1053     if (napi_create_string_latin1(env, "SetMockedLocations",
1054         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
1055         GET_AND_THROW_LAST_ERROR(env);
1056         delete asyncContext;
1057         return nullptr;
1058     }
1059     asyncContext->errCode = ParseLocationMockParams(env, asyncContext, argv[0]);
1060     if (asyncContext->errCode == INPUT_PARAMS_ERROR) {
1061         delete asyncContext;
1062         asyncContext = nullptr;
1063         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1064         return UndefinedNapiValue(env);
1065     }
1066     LocationErrCode errorCode = CheckLocationSwitchState();
1067     if (errorCode != ERRCODE_SUCCESS) {
1068         delete asyncContext;
1069         asyncContext = nullptr;
1070         HandleSyncErrCode(env, errorCode);
1071         return UndefinedNapiValue(env);
1072     }
1073     errorCode = g_locatorClient->SetMockedLocationsV9(asyncContext->timeInterval, asyncContext->LocationNapi);
1074     if (errorCode != ERRCODE_SUCCESS) {
1075         HandleSyncErrCode(env, errorCode);
1076     }
1077     delete asyncContext;
1078     asyncContext = nullptr;
1079     return UndefinedNapiValue(env);
1080 }
1081 
1082 napi_value EnableReverseGeocodingMock(napi_env env, napi_callback_info info)
1083 {
1084     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
1085     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
1086     LocationErrCode errorCode = g_locatorClient->EnableReverseGeocodingMockV9();
1087     if (errorCode != ERRCODE_SUCCESS) {
1088         HandleSyncErrCode(env, errorCode);
1089     }
1090     return UndefinedNapiValue(env);
1091 }
1092 
1093 napi_value DisableReverseGeocodingMock(napi_env env, napi_callback_info info)
1094 {
1095     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
1096     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
1097     LocationErrCode errorCode = g_locatorClient->DisableReverseGeocodingMockV9();
1098     if (errorCode != ERRCODE_SUCCESS) {
1099         HandleSyncErrCode(env, errorCode);
1100     }
1101     return UndefinedNapiValue(env);
1102 }
1103 
1104 napi_value SetReverseGeocodingMockInfo(napi_env env, napi_callback_info info)
1105 {
1106     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
1107     size_t argc = MAXIMUM_JS_PARAMS;
1108     napi_value argv[MAXIMUM_JS_PARAMS];
1109     napi_value thisVar = nullptr;
1110     void *data = nullptr;
1111     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1112     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
1113     if (argc != PARAM1) {
1114         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1115         return UndefinedNapiValue(env);
1116     }
1117 
1118     bool isArray = false;
1119     NAPI_CALL(env, napi_is_array(env, argv[0], &isArray));
1120     if (!isArray) {
1121         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1122         return UndefinedNapiValue(env);
1123     }
1124     std::vector<std::shared_ptr<GeocodingMockInfo>> mockInfo;
1125     JsObjToRevGeocodeMock(env, argv[0], mockInfo);
1126     LocationErrCode errorCode = g_locatorClient->SetReverseGeocodingMockInfoV9(mockInfo);
1127     if (errorCode != ERRCODE_SUCCESS) {
1128         HandleSyncErrCode(env, errorCode);
1129     }
1130     return UndefinedNapiValue(env);
1131 }
1132 #endif
1133 
1134 #ifdef ENABLE_NAPI_MANAGER
1135 LocationErrCode CheckLocationSwitchState()
1136 {
1137     bool isEnabled = false;
1138     LocationErrCode errorCode = g_locatorClient->IsLocationEnabledV9(isEnabled);
1139     if (errorCode != ERRCODE_SUCCESS) {
1140         return errorCode;
1141     }
1142     if (!isEnabled) {
1143         return ERRCODE_SWITCH_OFF;
1144     }
1145     return ERRCODE_SUCCESS;
1146 }
1147 
1148 sptr<LocatingRequiredDataCallbackNapi> CreateSingleCallbackHost()
1149 {
1150     auto callbackHost =
1151         sptr<LocatingRequiredDataCallbackNapi>(new (std::nothrow) LocatingRequiredDataCallbackNapi());
1152     if (callbackHost) {
1153         callbackHost->SetFixNumber(1);
1154     }
1155     return callbackHost;
1156 }
1157 
1158 SingleScanAsyncContext* CreateSingleScanAsyncContext(const napi_env& env,
1159     std::unique_ptr<LocatingRequiredDataConfig>& config, sptr<LocatingRequiredDataCallbackNapi> callback)
1160 {
1161     auto asyncContext = new (std::nothrow) SingleScanAsyncContext(env);
1162     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
1163     if (napi_create_string_latin1(env, "getLocatingRequiredDataOnce",
1164         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
1165         GET_AND_THROW_LAST_ERROR(env);
1166         delete asyncContext;
1167         return nullptr;
1168     }
1169     asyncContext->timeout_ = config->GetScanTimeoutMs();
1170     asyncContext->callbackHost_ = callback;
1171     asyncContext->executeFunc = [&](void* data) -> void {
1172         if (data == nullptr) {
1173             LBSLOGE(LOCATOR_STANDARD, "data is nullptr!");
1174             return;
1175         }
1176         auto context = static_cast<SingleScanAsyncContext*>(data);
1177         auto callbackHost = context->callbackHost_;
1178         if (callbackHost != nullptr) {
1179             callbackHost->Wait(context->timeout_);
1180             auto callbackPtr = sptr<ILocatingRequiredDataCallback>(callbackHost);
1181             g_locatorClient->UnRegisterLocatingRequiredDataCallback(callbackPtr);
1182             if (callbackHost->GetCount() != 0) {
1183                 context->errCode = ERRCODE_SCAN_FAIL;
1184             }
1185             callbackHost->SetCount(1);
1186         }
1187     };
1188     asyncContext->completeFunc = [&](void* data) -> void {
1189         if (data == nullptr) {
1190             LBSLOGE(LOCATOR_STANDARD, "data is nullptr!");
1191             return;
1192         }
1193         auto context = static_cast<SingleScanAsyncContext*>(data);
1194 
1195         auto callbackHost = context->callbackHost_;
1196         if (callbackHost != nullptr) {
1197             std::vector<std::shared_ptr<LocatingRequiredData>> res = callbackHost->GetSingleResult();
1198             napi_create_array_with_length(context->env, res.size(), &context->result[PARAM1]);
1199             LocatingRequiredDataToJsObj(context->env, res, context->result[PARAM1]);
1200             callbackHost->ClearSingleResult();
1201         } else {
1202             LBSLOGE(LOCATOR_STANDARD, "m_singleLocation is nullptr!");
1203         }
1204         if (context->callbackHost_) {
1205             context->callbackHost_ = nullptr;
1206         }
1207         LBSLOGI(LOCATOR_STANDARD, "Push scan info to client");
1208     };
1209     return asyncContext;
1210 }
1211 
1212 napi_value GetLocatingRequiredData(napi_env env, napi_callback_info info)
1213 {
1214     LBSLOGD(LOCATOR_STANDARD, "%{public}s called.", __func__);
1215     size_t argc = MAXIMUM_JS_PARAMS;
1216     napi_value argv[MAXIMUM_JS_PARAMS];
1217     napi_value thisVar = nullptr;
1218     void* data = nullptr;
1219     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1220     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
1221     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsObjectType(env, argv[PARAM0]))) {
1222         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1223         return UndefinedNapiValue(env);
1224     }
1225     if (argc == PARAM1) {
1226         napi_valuetype valueType;
1227         NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
1228         if (valueType != napi_object) {
1229             HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1230             return UndefinedNapiValue(env);
1231         }
1232     }
1233 
1234     auto singleCallbackHost = CreateSingleCallbackHost();
1235     if (singleCallbackHost == nullptr) {
1236         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1237         return UndefinedNapiValue(env);
1238     }
1239     std::unique_ptr<LocatingRequiredDataConfig> requestConfig = std::make_unique<LocatingRequiredDataConfig>();
1240     JsObjToLocatingRequiredDataConfig(env, argv[0], requestConfig);
1241     requestConfig->SetFixNumber(1);
1242     auto callbackPtr = sptr<ILocatingRequiredDataCallback>(singleCallbackHost);
1243     LocationErrCode errorCode = g_locatorClient->RegisterLocatingRequiredDataCallback(requestConfig, callbackPtr);
1244     if (errorCode != ERRCODE_SUCCESS) {
1245         HandleSyncErrCode(env, errorCode);
1246         return UndefinedNapiValue(env);
1247     }
1248 
1249     auto asyncContext = CreateSingleScanAsyncContext(env, requestConfig, singleCallbackHost);
1250     if (asyncContext == nullptr) {
1251         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1252         return UndefinedNapiValue(env);
1253     }
1254     return DoAsyncWork(env, asyncContext, argc, argv, 1);
1255 }
1256 
1257 napi_value AddGnssGeofence(napi_env env, napi_callback_info info)
1258 {
1259     LBSLOGD(LOCATOR_STANDARD, "%{public}s called.", __func__);
1260     size_t argc = MAXIMUM_JS_PARAMS;
1261     napi_value argv[MAXIMUM_JS_PARAMS];
1262     napi_value thisVar = nullptr;
1263     void* data = nullptr;
1264     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1265     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator ext SA failed");
1266     if (argc > PARAM1) {
1267         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1268         return UndefinedNapiValue(env);
1269     }
1270     std::shared_ptr<GeofenceRequest> gnssGeofenceRequest = std::make_shared<GeofenceRequest>();
1271     bool isValidParameter = ParseGnssGeofenceRequest(env, argv[0], gnssGeofenceRequest);
1272     if (!isValidParameter) {
1273         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1274         return UndefinedNapiValue(env);
1275     }
1276     auto locationGnssGeofenceCallbackHost =
1277         sptr<LocationGnssGeofenceCallbackNapi>(new LocationGnssGeofenceCallbackNapi());
1278     JsObjToGeofenceTransitionCallback(env, argv[0], locationGnssGeofenceCallbackHost);
1279     auto callbackPtr = sptr<IGnssGeofenceCallback>(locationGnssGeofenceCallbackHost);
1280     gnssGeofenceRequest->SetGeofenceTransitionCallback(callbackPtr->AsObject());
1281     auto asyncContext = CreateAsyncContextForAddGnssGeofence(
1282         env, gnssGeofenceRequest, locationGnssGeofenceCallbackHost);
1283     if (asyncContext == nullptr) {
1284         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1285         return UndefinedNapiValue(env);
1286     }
1287     return DoAsyncWork(env, asyncContext, argc, argv, 1);
1288 }
1289 
1290 GnssGeofenceAsyncContext* CreateAsyncContextForAddGnssGeofence(const napi_env& env,
1291     std::shared_ptr<GeofenceRequest>& request, sptr<LocationGnssGeofenceCallbackNapi> callback)
1292 {
1293     auto asyncContext = new GnssGeofenceAsyncContext(env);
1294     if (napi_create_string_latin1(env, "addGnssGeofence",
1295         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
1296         GET_AND_THROW_LAST_ERROR(env);
1297         delete asyncContext;
1298         return nullptr;
1299     }
1300     asyncContext->callbackHost_ = callback;
1301     asyncContext->request_ = request;
1302     asyncContext->executeFunc = [&](void* data) -> void {
1303         if (data == nullptr) {
1304             return;
1305         }
1306         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1307         auto callbackHost = context->callbackHost_;
1308         auto gnssGeofenceRequest = context->request_;
1309         if (callbackHost != nullptr && gnssGeofenceRequest != nullptr) {
1310             auto errCode = g_geofenceClient->AddGnssGeofence(gnssGeofenceRequest);
1311             if (errCode != ERRCODE_SUCCESS) {
1312                 context->errCode = errCode;
1313                 callbackHost->SetCount(0);
1314             }
1315             callbackHost->Wait(DEFAULT_CALLBACK_WAIT_TIME);
1316             if (callbackHost->GetCount() != 0) {
1317                 context->errCode = ERRCODE_SERVICE_UNAVAILABLE;
1318             }
1319             callbackHost->SetCount(1);
1320         }
1321     };
1322     asyncContext->completeFunc = [&](void* data) -> void {
1323         if (data == nullptr) {
1324             return;
1325         }
1326         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1327         auto callbackHost = context->callbackHost_;
1328         if (callbackHost != nullptr && context->errCode == ERRCODE_SUCCESS &&
1329             callbackHost->GetGeofenceOperationType() == GnssGeofenceOperateType::GNSS_GEOFENCE_OPT_TYPE_ADD) {
1330             LocationErrCode errCode = callbackHost->DealGeofenceOperationResult();
1331             if (errCode == ERRCODE_SUCCESS) {
1332                 int fenceId = callbackHost->GetFenceId();
1333                 napi_create_object(context->env, &context->result[PARAM1]);
1334                 napi_create_int64(context->env, fenceId, &context->result[PARAM1]);
1335                 AddCallbackToGnssGeofenceCallbackHostMap(fenceId, callbackHost);
1336             } else {
1337                 context->errCode = errCode;
1338             }
1339         }
1340     };
1341     return asyncContext;
1342 }
1343 
1344 napi_value RemoveGnssGeofence(napi_env env, napi_callback_info info)
1345 {
1346     LBSLOGD(LOCATOR_STANDARD, "%{public}s called.", __func__);
1347     size_t argc = MAXIMUM_JS_PARAMS;
1348     napi_value argv[MAXIMUM_JS_PARAMS];
1349     napi_value thisVar = nullptr;
1350     void* data = nullptr;
1351     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1352     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
1353     if (argc > PARAM1) {
1354         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1355         return UndefinedNapiValue(env);
1356     }
1357     int fenceId = -1;
1358     napi_valuetype valueType1;
1359     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType1));
1360     if (valueType1 != napi_number) {
1361         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1362         return UndefinedNapiValue(env);
1363     }
1364     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &fenceId));
1365     auto asyncContext = CreateAsyncContextForRemoveGnssGeofence(env, fenceId);
1366     if (asyncContext == nullptr) {
1367         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1368         return UndefinedNapiValue(env);
1369     }
1370     size_t objectArgsNum = 1;
1371     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
1372 }
1373 
1374 GnssGeofenceAsyncContext* CreateAsyncContextForRemoveGnssGeofence(const napi_env& env, int fenceId)
1375 {
1376     auto asyncContext = new (std::nothrow) GnssGeofenceAsyncContext(env);
1377     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
1378     asyncContext->fenceId_ = fenceId;
1379     asyncContext->callbackHost_ = FindCallbackInGnssGeofenceCallbackHostMap(fenceId);
1380     if (napi_create_string_latin1(env, "removeGnssGeofence",
1381         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
1382         GET_AND_THROW_LAST_ERROR(env);
1383         delete asyncContext;
1384         return nullptr;
1385     }
1386     asyncContext->executeFunc = [&](void* data) -> void {
1387         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1388         std::shared_ptr<GeofenceRequest> request = std::make_shared<GeofenceRequest>();
1389         request->SetFenceId(context->fenceId_);
1390         context->errCode = g_geofenceClient->RemoveGnssGeofence(request);
1391         auto callbackHost = context->callbackHost_;
1392         if (callbackHost != nullptr) {
1393             if (context->errCode != ERRCODE_SUCCESS) {
1394                 callbackHost->SetCount(0);
1395             }
1396             callbackHost->Wait(DEFAULT_CALLBACK_WAIT_TIME);
1397             if (callbackHost->GetCount() != 0) {
1398                 context->errCode = ERRCODE_SERVICE_UNAVAILABLE;
1399             }
1400             callbackHost->SetCount(1);
1401         } else {
1402             context->errCode = ERRCODE_GEOFENCE_INCORRECT_ID;
1403         }
1404     };
1405 
1406     asyncContext->completeFunc = [&](void* data) -> void {
1407         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1408         auto callbackHost = context->callbackHost_;
1409         if (callbackHost != nullptr && context->errCode == ERRCODE_SUCCESS &&
1410             callbackHost->GetGeofenceOperationType() ==
1411             GnssGeofenceOperateType::GNSS_GEOFENCE_OPT_TYPE_DELETE) {
1412             LocationErrCode errCode = callbackHost->DealGeofenceOperationResult();
1413             if (errCode == ERRCODE_SUCCESS) {
1414                 NAPI_CALL_RETURN_VOID(
1415                     context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
1416                 RemoveCallbackToGnssGeofenceCallbackHostMap(context->fenceId_);
1417             } else {
1418                 context->errCode = errCode;
1419             }
1420         }
1421         LBSLOGD(LOCATOR_STANDARD, "Push RemoveGnssGeofence result to client");
1422     };
1423     return asyncContext;
1424 }
1425 
1426 napi_value AddBeaconFence(napi_env env, napi_callback_info info)
1427 {
1428     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
1429     size_t argc = MAXIMUM_JS_PARAMS;
1430     napi_value argv[MAXIMUM_JS_PARAMS];
1431     napi_value thisVar = nullptr;
1432     void* data = nullptr;
1433     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1434     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator ext SA failed");
1435     if (argc > PARAM1) {
1436         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1437         return UndefinedNapiValue(env);
1438     }
1439     std::shared_ptr<BeaconFenceRequest> beaconFenceRequest = std::make_shared<BeaconFenceRequest>();
1440     bool isValidParameter = ParseBeaconFenceRequest(env, argv[0], beaconFenceRequest);
1441     if (!isValidParameter) {
1442         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1443         return UndefinedNapiValue(env);
1444     }
1445     auto asyncContext = new GnssGeofenceAsyncContext(env);
1446     if (napi_create_string_latin1(env, "addBeaconFence",
1447         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
1448         GET_AND_THROW_LAST_ERROR(env);
1449         delete asyncContext;
1450         return nullptr;
1451     }
1452     asyncContext->beaconRequest_ = beaconFenceRequest;
1453     auto beaconFenceCallbackHost =
1454         sptr<LocationGnssGeofenceCallbackNapi>(new LocationGnssGeofenceCallbackNapi());
1455     JsObjToBeaconFenceTransitionCallback(env, argv[0], beaconFenceCallbackHost);
1456     auto callbackPtr = sptr<IGnssGeofenceCallback>(beaconFenceCallbackHost);
1457     beaconFenceRequest->SetBeaconFenceTransitionCallback(callbackPtr->AsObject());
1458     asyncContext->callbackHost_ = beaconFenceCallbackHost;
1459     CreateAsyncContextForAddBeaconFence(asyncContext);
1460     if (asyncContext == nullptr) {
1461         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1462         return UndefinedNapiValue(env);
1463     }
1464     return DoAsyncWork(env, asyncContext, argc, argv, 1);
1465 }
1466 
1467 void CreateAsyncContextForAddBeaconFence(GnssGeofenceAsyncContext* asyncContext)
1468 {
1469     asyncContext->executeFunc = [&](void* data) -> void {
1470         if (data == nullptr) {
1471             return;
1472         }
1473         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1474         auto callbackHost = context->callbackHost_;
1475         auto beaconFenceRequest = context->beaconRequest_;
1476         if (beaconFenceRequest == nullptr) {
1477             return;
1478         }
1479         context->errCode = g_locatorClient->AddBeaconFence(beaconFenceRequest);
1480         if (callbackHost != nullptr) {
1481             if (context->errCode != ERRCODE_SUCCESS) {
1482                 callbackHost->SetCount(0);
1483             }
1484             callbackHost->Wait(DEFAULT_CALLBACK_WAIT_TIME);
1485             if (callbackHost->GetCount() != 0) {
1486                 context->errCode = ERRCODE_SERVICE_UNAVAILABLE;
1487             }
1488             callbackHost->SetCount(1);
1489         }
1490     };
1491     asyncContext->completeFunc = [&](void* data) -> void {
1492         if (data == nullptr) {
1493             return;
1494         }
1495         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1496         auto callbackHost = context->callbackHost_;
1497         auto beaconFenceRequest = context->beaconRequest_;
1498         if (callbackHost != nullptr && context->errCode == ERRCODE_SUCCESS &&
1499             callbackHost->GetGeofenceOperationType() == GnssGeofenceOperateType::GNSS_GEOFENCE_OPT_TYPE_ADD) {
1500             LocationErrCode errCode = callbackHost->DealGeofenceOperationResult();
1501             if (errCode == ERRCODE_SUCCESS) {
1502                 int fenceId = callbackHost->GetFenceId();
1503                 napi_create_object(context->env, &context->result[PARAM1]);
1504                 napi_create_int64(context->env, fenceId, &context->result[PARAM1]);
1505                 AddBeaconFenceRequest(beaconFenceRequest, callbackHost);
1506             } else {
1507                 context->errCode = errCode;
1508             }
1509         }
1510     };
1511 }
1512 
1513 napi_value RemoveBeaconFence(napi_env env, napi_callback_info info)
1514 {
1515     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
1516     size_t argc = MAXIMUM_JS_PARAMS;
1517     napi_value argv[MAXIMUM_JS_PARAMS];
1518     napi_value thisVar = nullptr;
1519     void* data = nullptr;
1520     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1521     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
1522     if (argc > PARAM1) {
1523         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1524         return UndefinedNapiValue(env);
1525     }
1526     auto asyncContext = new (std::nothrow) GnssGeofenceAsyncContext(env);
1527     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
1528     if (napi_create_string_latin1(env, "removeBeaconFence",
1529         NAPI_AUTO_LENGTH, &asyncContext->resourceName) != napi_ok) {
1530         GET_AND_THROW_LAST_ERROR(env);
1531         delete asyncContext;
1532         return nullptr;
1533     }
1534 
1535     napi_valuetype valueType;
1536     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
1537     if (valueType == napi_undefined) {
1538         std::unique_lock<std::mutex> lock(g_beaconFenceRequestMutex);
1539         if (g_beaconFenceRequestMap.size() == 0) {
1540             HandleSyncErrCode(env, ERRCODE_BEACONFENCE_INCORRECT_ID);
1541             delete asyncContext;
1542             return UndefinedNapiValue(env);
1543         }
1544         asyncContext->clearBeaconFence_ = true;
1545     } else {
1546         std::shared_ptr<BeaconFence> beaconFence = std::make_shared<BeaconFence>();
1547         bool isValidParameter = JsObjToBeaconFence(env, argv[0], beaconFence);
1548         if (!isValidParameter) {
1549             HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1550             delete asyncContext;
1551             return UndefinedNapiValue(env);
1552         }
1553         asyncContext->beaconFence_ = beaconFence;
1554         asyncContext->callbackHost_ = FindRequestByBeaconFence(beaconFence);
1555     }
1556     CreateAsyncContextForRemoveBeaconFence(asyncContext);
1557     if (asyncContext == nullptr) {
1558         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1559         return UndefinedNapiValue(env);
1560     }
1561     size_t objectArgsNum = 1;
1562     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
1563 }
1564 
1565 void CreateAsyncContextForRemoveBeaconFence(GnssGeofenceAsyncContext* asyncContext)
1566 {
1567     asyncContext->executeFunc = [&](void* data) -> void {
1568         if (data == nullptr) {
1569             return;
1570         }
1571         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1572         if (context->clearBeaconFence_) {
1573             std::unique_lock<std::mutex> lock(g_beaconFenceRequestMutex);
1574             for (auto it = g_beaconFenceRequestMap.begin(); it != g_beaconFenceRequestMap.end(); ++it) {
1575                 std::shared_ptr<BeaconFence> beaconFence = it->first;
1576                 context->callbackHost_ = it->second;
1577                 context->errCode = g_locatorClient->RemoveBeaconFence(beaconFence);
1578             }
1579         } else {
1580             context->errCode = g_locatorClient->RemoveBeaconFence(context->beaconFence_);
1581         }
1582     };
1583 
1584     asyncContext->completeFunc = [&](void* data) -> void {
1585         if (data == nullptr) {
1586             return;
1587         }
1588         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1589         auto callbackHost = context->callbackHost_;
1590         if (callbackHost == nullptr && context->errCode == ERRCODE_SUCCESS) {
1591             NAPI_CALL_RETURN_VOID(
1592                 context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
1593         }
1594         if (callbackHost != nullptr && context->errCode == ERRCODE_SUCCESS &&
1595             callbackHost->GetGeofenceOperationType() ==
1596             GnssGeofenceOperateType::GNSS_GEOFENCE_OPT_TYPE_DELETE) {
1597             context->errCode = callbackHost->DealGeofenceOperationResult();
1598             if (context->errCode != ERRCODE_SUCCESS) {
1599                 return;
1600             }
1601             if (context->clearBeaconFence_) {
1602                 ClearBeaconFenceRequest();
1603             } else {
1604                 RemoveBeaconFenceRequest(context->beaconFence_);
1605             }
1606             NAPI_CALL_RETURN_VOID(
1607                 context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
1608         }
1609         LBSLOGI(LOCATOR_STANDARD, "Push RemoveBeaconFence result to client");
1610     };
1611 }
1612 
1613 napi_value IsBeaconFenceSupported(napi_env env, napi_callback_info info)
1614 {
1615     size_t argc = MAXIMUM_JS_PARAMS;
1616     napi_value argv[MAXIMUM_JS_PARAMS];
1617     napi_value thisVar = nullptr;
1618     void* data = nullptr;
1619     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1620     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
1621     napi_value res;
1622     bool beaconFenceSupportedState = g_locatorClient->IsBeaconFenceSupported();
1623     NAPI_CALL(env, napi_get_boolean(env, beaconFenceSupportedState, &res));
1624     return res;
1625 }
1626 
1627 napi_value GetGeofenceSupportedCoordTypes(napi_env env, napi_callback_info info)
1628 {
1629     size_t argc = MAXIMUM_JS_PARAMS;
1630     napi_value argv[MAXIMUM_JS_PARAMS];
1631     napi_value thisVar = nullptr;
1632     void* data = nullptr;
1633     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1634     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
1635     std::vector<CoordinateSystemType> coordinateSystemTypes;
1636     LocationErrCode errorCode =
1637         g_geofenceClient->GetGeofenceSupportedCoordTypes(coordinateSystemTypes);
1638     if (errorCode != ERRCODE_SUCCESS) {
1639         HandleSyncErrCode(env, errorCode);
1640         return UndefinedNapiValue(env);
1641     }
1642     napi_value res;
1643     NAPI_CALL(env,
1644         napi_create_array_with_length(env, coordinateSystemTypes.size(), &res));
1645     uint32_t idx = 0;
1646     for (auto iter = coordinateSystemTypes.begin(); iter != coordinateSystemTypes.end(); ++iter) {
1647         auto coordType = *iter;
1648         napi_value eachObj;
1649         NAPI_CALL(env, napi_create_int32(env, static_cast<int>(coordType), &eachObj));
1650         NAPI_CALL(env, napi_set_element(env, res, idx++, eachObj));
1651     }
1652     return res;
1653 }
1654 
1655 void AddCallbackToGnssGeofenceCallbackHostMap(int fenceId, sptr<LocationGnssGeofenceCallbackNapi> callbackHost)
1656 {
1657     std::unique_lock<std::mutex> lock(g_gnssGeofenceCallbackHostMutex);
1658     g_gnssGeofenceCallbackHostMap.insert(std::make_pair(fenceId, callbackHost));
1659 }
1660 
1661 void RemoveCallbackToGnssGeofenceCallbackHostMap(int fenceId)
1662 {
1663     std::unique_lock<std::mutex> lock(g_gnssGeofenceCallbackHostMutex);
1664     auto iterForDelete = g_gnssGeofenceCallbackHostMap.find(fenceId);
1665     if (iterForDelete != g_gnssGeofenceCallbackHostMap.end()) {
1666         g_gnssGeofenceCallbackHostMap.erase(iterForDelete);
1667     }
1668 }
1669 
1670 sptr<LocationGnssGeofenceCallbackNapi> FindCallbackInGnssGeofenceCallbackHostMap(int fenceId)
1671 {
1672     std::unique_lock<std::mutex> lock(g_gnssGeofenceCallbackHostMutex);
1673     auto iter = g_gnssGeofenceCallbackHostMap.find(fenceId);
1674     if (iter != g_gnssGeofenceCallbackHostMap.end()) {
1675         return iter->second;
1676     }
1677     return nullptr;
1678 }
1679 
1680 void AddBeaconFenceRequest(std::shared_ptr<BeaconFenceRequest>& request,
1681     sptr<LocationGnssGeofenceCallbackNapi> callbackHost)
1682 {
1683     std::unique_lock<std::mutex> lock(g_beaconFenceRequestMutex);
1684     std::shared_ptr<BeaconFence> beaconFence = request->GetBeaconFence();
1685     g_beaconFenceRequestMap.insert(std::make_pair(beaconFence, callbackHost));
1686 }
1687 
1688 void RemoveBeaconFenceRequest(std::shared_ptr<BeaconFence>& beaconFence)
1689 {
1690     std::unique_lock<std::mutex> lock(g_beaconFenceRequestMutex);
1691     std::shared_ptr<BeaconFence> beaconFenceDelete;
1692     for (auto it = g_beaconFenceRequestMap.begin(); it != g_beaconFenceRequestMap.end(); ++it) {
1693         if (CompareBeaconFence(beaconFence, it->first)) {
1694             beaconFenceDelete = it->first;
1695         }
1696     }
1697     auto iterForDelete = g_beaconFenceRequestMap.find(beaconFenceDelete);
1698     if (iterForDelete != g_beaconFenceRequestMap.end()) {
1699         g_beaconFenceRequestMap.erase(iterForDelete);
1700     }
1701 }
1702 
1703 void ClearBeaconFenceRequest()
1704 {
1705     std::unique_lock<std::mutex> lock(g_beaconFenceRequestMutex);
1706     g_beaconFenceRequestMap.clear();
1707 }
1708 
1709 sptr<LocationGnssGeofenceCallbackNapi> FindRequestByBeaconFence(std::shared_ptr<BeaconFence>& beaconFence)
1710 {
1711     std::unique_lock<std::mutex> lock(g_beaconFenceRequestMutex);
1712     for (auto it = g_beaconFenceRequestMap.begin(); it != g_beaconFenceRequestMap.end(); ++it) {
1713         if (CompareBeaconFence(beaconFence, it->first)) {
1714             return it->second;
1715         }
1716     }
1717     LBSLOGE(BEACON_FENCE_MANAGER, "%{public}s, can not find beaconfence", __func__);
1718     return nullptr;
1719 }
1720 
1721 bool CompareBeaconFence(
1722     std::shared_ptr<BeaconFence> beaconFence1, std::shared_ptr<BeaconFence> beaconFence2)
1723 {
1724     if (beaconFence1->GetIdentifier().compare(beaconFence2->GetIdentifier()) != 0) {
1725         LBSLOGE(BEACON_FENCE_MANAGER, "%{public}s, compare Identifier fail", __func__);
1726         return false;
1727     }
1728     if (static_cast<int>(beaconFence1->GetBeaconFenceInfoType()) !=
1729         static_cast<int>(beaconFence2->GetBeaconFenceInfoType())) {
1730             LBSLOGE(BEACON_FENCE_MANAGER, "%{public}s, compare BeaconFenceInfoType fail", __func__);
1731         return false;
1732     }
1733     if (beaconFence1->GetBeaconManufactureData().manufactureId !=
1734         beaconFence2->GetBeaconManufactureData().manufactureId) {
1735             LBSLOGE(BEACON_FENCE_MANAGER, "%{public}s, compare manufactureId fail", __func__);
1736         return false;
1737     }
1738     if (beaconFence1->GetBeaconManufactureData().manufactureData !=
1739         beaconFence2->GetBeaconManufactureData().manufactureData) {
1740             LBSLOGE(BEACON_FENCE_MANAGER, "%{public}s, compare manufactureData fail", __func__);
1741         return false;
1742     }
1743     if (beaconFence1->GetBeaconManufactureData().manufactureDataMask !=
1744         beaconFence2->GetBeaconManufactureData().manufactureDataMask) {
1745             LBSLOGE(BEACON_FENCE_MANAGER, "%{public}s, compare manufactureDataMask fail", __func__);
1746         return false;
1747     }
1748     LBSLOGD(BEACON_FENCE_MANAGER, "%{public}s res:true", __func__);
1749     return true;
1750 }
1751 #endif
1752 } // namespace Location
1753 } // namespace OHOS
1754