• 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 
24 namespace OHOS {
25 namespace Location {
26 auto g_locatorClient = Locator::GetInstance();
27 auto g_geofenceClient = GeofenceManager::GetInstance();
28 std::map<int, sptr<LocationGnssGeofenceCallbackNapi>> g_gnssGeofenceCallbackHostMap;
29 std::mutex g_gnssGeofenceCallbackHostMutex;
30 
GetLastLocation(napi_env env,napi_callback_info info)31 napi_value GetLastLocation(napi_env env, napi_callback_info info)
32 {
33     size_t argc = MAXIMUM_JS_PARAMS;
34     napi_value argv[MAXIMUM_JS_PARAMS];
35     napi_value thisVar = nullptr;
36     void* data = nullptr;
37 
38     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
39     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
40 
41 #ifdef ENABLE_NAPI_MANAGER
42     return HandleGetCachedLocation(env);
43 #else
44     auto asyncContext = new (std::nothrow) LocationAsyncContext(env);
45     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
46     NAPI_CALL(env, napi_create_string_latin1(env, "getLastLocation", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
47     asyncContext->executeFunc = [&](void* data) -> void {
48         auto context = static_cast<LocationAsyncContext*>(data);
49         context->loc = g_locatorClient->IsLocationEnabled() ? g_locatorClient->GetCachedLocation() : nullptr;
50         if (context->loc != nullptr) {
51             context->errCode = SUCCESS;
52         } else {
53             context->errCode = LAST_KNOWN_LOCATION_ERROR;
54         }
55     };
56 
57     asyncContext->completeFunc = [&](void* data) -> void {
58         auto context = static_cast<LocationAsyncContext*>(data);
59         NAPI_CALL_RETURN_VOID(context->env, napi_create_object(context->env, &context->result[PARAM1]));
60         if (context->loc != nullptr) {
61             LocationToJs(context->env, context->loc, context->result[PARAM1]);
62         } else {
63             LBSLOGE(LOCATOR_STANDARD, "loc is nullptr!");
64         }
65         LBSLOGI(LOCATOR_STANDARD, "Push last location result to client");
66     };
67 
68     size_t objectArgsNum = 0;
69     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
70 #endif
71 }
72 
73 #ifdef ENABLE_NAPI_MANAGER
HandleGetCachedLocation(napi_env env)74 napi_value HandleGetCachedLocation(napi_env env)
75 {
76     napi_value res;
77     NAPI_CALL(env, napi_create_object(env, &res));
78     LocationErrCode errorCode = CheckLocationSwitchState();
79     if (errorCode != ERRCODE_SUCCESS) {
80         HandleSyncErrCode(env, errorCode);
81         return UndefinedNapiValue(env);
82     }
83     std::unique_ptr<Location> loc;
84     errorCode = g_locatorClient->GetCachedLocationV9(loc);
85     if (loc != nullptr) {
86         LocationToJs(env, loc, res);
87         return res;
88     } else {
89         HandleSyncErrCode(env, errorCode);
90     }
91     return UndefinedNapiValue(env);
92 }
93 #endif
94 
IsLocationEnabled(napi_env env,napi_callback_info info)95 napi_value IsLocationEnabled(napi_env env, napi_callback_info info)
96 {
97     size_t argc = MAXIMUM_JS_PARAMS;
98     napi_value argv[MAXIMUM_JS_PARAMS];
99     napi_value thisVar = nullptr;
100     void* data = nullptr;
101     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
102     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
103 #ifdef ENABLE_NAPI_MANAGER
104     napi_value res;
105     bool isEnabled = false;
106     LocationErrCode errorCode = g_locatorClient->IsLocationEnabledV9(isEnabled);
107     if (errorCode != ERRCODE_SUCCESS) {
108         HandleSyncErrCode(env, errorCode);
109         return UndefinedNapiValue(env);
110     }
111     NAPI_CALL(env, napi_get_boolean(env, isEnabled, &res));
112     return res;
113 #else
114     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
115     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
116     if (napi_create_string_latin1(env, "isLocationEnabled", NAPI_AUTO_LENGTH,
117         &asyncContext->resourceName) != napi_ok) {
118         LBSLOGE(LOCATOR_STANDARD, "copy string failed");
119     }
120     asyncContext->executeFunc = [&](void* data) -> void {
121         auto context = static_cast<SwitchAsyncContext*>(data);
122         context->enable = g_locatorClient->IsLocationEnabled();
123         context->errCode = SUCCESS;
124     };
125     asyncContext->completeFunc = [&](void* data) -> void {
126         auto context = static_cast<SwitchAsyncContext*>(data);
127         NAPI_CALL_RETURN_VOID(context->env, napi_get_boolean(context->env, context->enable, &context->result[PARAM1]));
128         LBSLOGI(LOCATOR_STANDARD, "Push IsLocationEnabled result to client");
129     };
130 
131     size_t objectArgsNum = 0;
132     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
133 #endif
134 }
135 
EnableLocation(napi_env env,napi_callback_info info)136 napi_value EnableLocation(napi_env env, napi_callback_info info)
137 {
138     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
139     size_t argc = MAXIMUM_JS_PARAMS;
140     napi_value argv[MAXIMUM_JS_PARAMS];
141     napi_value thisVar = nullptr;
142     void* data = nullptr;
143     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
144     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
145 #ifdef ENABLE_NAPI_MANAGER
146     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsFunctionType(env, argv[PARAM0]))) {
147         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
148         return UndefinedNapiValue(env);
149     }
150 #endif
151     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
152     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
153     NAPI_CALL(env, napi_create_string_latin1(env, "enableLocation", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
154 
155     asyncContext->executeFunc = [&](void* data) -> void {
156         auto context = static_cast<SwitchAsyncContext*>(data);
157 #ifdef ENABLE_NAPI_MANAGER
158         context->errCode = g_locatorClient->EnableAbilityV9(true);
159 #else
160         g_locatorClient->EnableAbility(true);
161         context->errCode = SUCCESS;
162 #endif
163     };
164 
165     asyncContext->completeFunc = [&](void* data) -> void {
166         auto context = static_cast<SwitchAsyncContext*>(data);
167 #ifdef ENABLE_NAPI_MANAGER
168         NAPI_CALL_RETURN_VOID(context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
169 #else
170         NAPI_CALL_RETURN_VOID(context->env,
171             napi_get_boolean(context->env, context->errCode == SUCCESS, &context->result[PARAM1]));
172 #endif
173         LBSLOGI(LOCATOR_STANDARD, "Push EnableLocation result to client");
174     };
175 
176     size_t objectArgsNum = 0;
177     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
178 }
179 
DisableLocation(napi_env env,napi_callback_info info)180 napi_value DisableLocation(napi_env env, napi_callback_info info)
181 {
182     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
183     size_t argc = MAXIMUM_JS_PARAMS;
184     napi_value argv[MAXIMUM_JS_PARAMS];
185     napi_value thisVar = nullptr;
186     void* data = nullptr;
187     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
188     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
189 
190 #ifdef ENABLE_NAPI_MANAGER
191     LocationErrCode errorCode = g_locatorClient->EnableAbilityV9(false);
192     if (errorCode != ERRCODE_SUCCESS) {
193         HandleSyncErrCode(env, errorCode);
194     }
195     return UndefinedNapiValue(env);
196 #else
197     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
198     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
199     NAPI_CALL(env, napi_create_string_latin1(env, "disableLocation", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
200     asyncContext->executeFunc = [&](void* data) -> void {
201         auto context = static_cast<SwitchAsyncContext*>(data);
202         g_locatorClient->EnableAbility(false);
203         context->errCode = SUCCESS;
204     };
205     asyncContext->completeFunc = [&](void* data) -> void {
206         auto context = static_cast<SwitchAsyncContext*>(data);
207         NAPI_CALL_RETURN_VOID(context->env,
208             napi_get_boolean(context->env, context->errCode == SUCCESS, &context->result[PARAM1]));
209         LBSLOGI(LOCATOR_STANDARD, "Push DisableLocation result to client");
210     };
211     size_t objectArgsNum = 0;
212     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
213 #endif
214 }
215 
RequestEnableLocation(napi_env env,napi_callback_info info)216 napi_value RequestEnableLocation(napi_env env, napi_callback_info info)
217 {
218     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
219     size_t argc = MAXIMUM_JS_PARAMS;
220     napi_value argv[MAXIMUM_JS_PARAMS];
221     napi_value thisVar = nullptr;
222     void* data = nullptr;
223     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
224     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
225 
226     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
227     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
228     NAPI_CALL(env, napi_create_string_latin1(env, "enableLocation", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
229 
230     asyncContext->executeFunc = [&](void* data) -> void {
231         auto context = static_cast<SwitchAsyncContext*>(data);
232         if (!g_locatorClient->IsLocationEnabled()) {
233             g_locatorClient->ShowNotification();
234         }
235         g_locatorClient->EnableAbility(true);
236         context->errCode = SUCCESS;
237     };
238 
239     asyncContext->completeFunc = [&](void* data) -> void {
240         auto context = static_cast<SwitchAsyncContext*>(data);
241         NAPI_CALL_RETURN_VOID(context->env,
242             napi_get_boolean(context->env, context->errCode == SUCCESS, &context->result[PARAM1]));
243         LBSLOGI(LOCATOR_STANDARD, "Push RequestEnableLocation result to client");
244     };
245 
246     size_t objectArgsNum = 0;
247     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
248 }
249 
IsGeoServiceAvailable(napi_env env,napi_callback_info info)250 napi_value IsGeoServiceAvailable(napi_env env, napi_callback_info info)
251 {
252     size_t argc = MAXIMUM_JS_PARAMS;
253     napi_value argv[MAXIMUM_JS_PARAMS];
254     napi_value thisVar = nullptr;
255     void* data = nullptr;
256     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
257     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
258 #ifdef ENABLE_NAPI_MANAGER
259     napi_value res;
260     bool isAvailable = false;
261     LocationErrCode errorCode = g_locatorClient->IsGeoServiceAvailableV9(isAvailable);
262     if (errorCode != ERRCODE_SUCCESS) {
263         HandleSyncErrCode(env, errorCode);
264         return UndefinedNapiValue(env);
265     }
266     NAPI_CALL(env, napi_get_boolean(env, isAvailable, &res));
267     return res;
268 #else
269     auto asyncContext = new (std::nothrow) SwitchAsyncContext(env);
270     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
271     NAPI_CALL(env,
272         napi_create_string_latin1(env, "isGeoServiceAvailable", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
273     asyncContext->executeFunc = [&](void* data) -> void {
274         auto context = static_cast<SwitchAsyncContext*>(data);
275         bool isAvailable = g_locatorClient->IsGeoServiceAvailable();
276         context->enable = isAvailable;
277         context->errCode = SUCCESS;
278     };
279     asyncContext->completeFunc = [&](void* data) -> void {
280         auto context = static_cast<SwitchAsyncContext*>(data);
281         NAPI_CALL_RETURN_VOID(context->env, napi_get_boolean(context->env, context->enable, &context->result[PARAM1]));
282         LBSLOGI(LOCATOR_STANDARD, "Push isGeoServiceAvailable result to client");
283     };
284     size_t objectArgsNum = 0;
285     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
286 #endif
287 }
288 
CreateReverseGeocodeAsyncContext(ReverseGeoCodeAsyncContext * asyncContext)289 void CreateReverseGeocodeAsyncContext(ReverseGeoCodeAsyncContext* asyncContext)
290 {
291     asyncContext->executeFunc = [&](void* data) -> void {
292         auto context = static_cast<ReverseGeoCodeAsyncContext*>(data);
293 #ifdef ENABLE_NAPI_MANAGER
294         if (context->errCode != ERRCODE_SUCCESS) {
295 #else
296         if (context->errCode != SUCCESS) {
297 #endif
298             return;
299         }
300 #ifdef ENABLE_NAPI_MANAGER
301         bool isAvailable = false;
302         LocationErrCode errorCode = g_locatorClient->IsGeoServiceAvailableV9(isAvailable);
303         if (errorCode != ERRCODE_SUCCESS) {
304             context->errCode = errorCode;
305             return;
306         }
307         if (!isAvailable) {
308             context->errCode = ERRCODE_REVERSE_GEOCODING_FAIL;
309             return;
310         }
311         errorCode = g_locatorClient->GetAddressByCoordinateV9(context->reverseGeoCodeRequest, context->replyList);
312         if (context->replyList.empty() || errorCode != ERRCODE_SUCCESS) {
313             context->errCode = errorCode;
314         }
315 #else
316         if (!g_locatorClient->IsGeoServiceAvailable()) {
317             context->errCode = REVERSE_GEOCODE_ERROR;
318             return;
319         }
320         g_locatorClient->GetAddressByCoordinate(context->reverseGeoCodeRequest, context->replyList);
321         if (context->replyList.empty()) {
322             context->errCode = REVERSE_GEOCODE_ERROR;
323         }
324 #endif
325     };
326     asyncContext->completeFunc = [&](void* data) -> void {
327         auto context = static_cast<ReverseGeoCodeAsyncContext*>(data);
328         NAPI_CALL_RETURN_VOID(context->env,
329             napi_create_array_with_length(context->env, context->replyList.size(), &context->result[PARAM1]));
330         GeoAddressesToJsObj(context->env, context->replyList, context->result[PARAM1]);
331     };
332 }
333 
334 void CreateGeocodeAsyncContext(GeoCodeAsyncContext* asyncContext)
335 {
336     asyncContext->executeFunc = [&](void* data) -> void {
337         auto context = static_cast<GeoCodeAsyncContext*>(data);
338         if (context->errCode != SUCCESS) {
339             return;
340         }
341 #ifdef ENABLE_NAPI_MANAGER
342         bool isAvailable = false;
343         LocationErrCode errorCode = g_locatorClient->IsGeoServiceAvailableV9(isAvailable);
344         if (errorCode != ERRCODE_SUCCESS) {
345             context->errCode = errorCode;
346             return;
347         }
348         if (!isAvailable) {
349             context->errCode = ERRCODE_GEOCODING_FAIL;
350             return;
351         }
352         errorCode = g_locatorClient->GetAddressByLocationNameV9(context->geoCodeRequest, context->replyList);
353         if (context->replyList.empty() || errorCode != ERRCODE_SUCCESS) {
354             context->errCode = errorCode;
355         }
356 #else
357         if (!g_locatorClient->IsGeoServiceAvailable()) {
358             context->errCode = GEOCODE_ERROR;
359             return;
360         }
361         g_locatorClient->GetAddressByLocationName(context->geoCodeRequest, context->replyList);
362         if (context->replyList.empty()) {
363             context->errCode = GEOCODE_ERROR;
364         }
365 #endif
366     };
367     asyncContext->completeFunc = [&](void* data) -> void {
368         auto context = static_cast<GeoCodeAsyncContext*>(data);
369         NAPI_CALL_RETURN_VOID(context->env,
370             napi_create_array_with_length(context->env, context->replyList.size(), &context->result[PARAM1]));
371         GeoAddressesToJsObj(context->env, context->replyList, context->result[PARAM1]);
372         LBSLOGI(LOCATOR_STANDARD, "Push GetAddressesFromLocationName result to client");
373     };
374 }
375 
376 napi_value GetAddressesFromLocation(napi_env env, napi_callback_info info)
377 {
378     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
379     size_t argc = MAXIMUM_JS_PARAMS;
380     napi_value argv[MAXIMUM_JS_PARAMS];
381     napi_value thisVar = nullptr;
382     void* data = nullptr;
383     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
384     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
385 #ifdef ENABLE_NAPI_MANAGER
386     if (argc < PARAM1 || argc > PARAM2 || (argc == PARAM2 && !CheckIfParamIsFunctionType(env, argv[1]))) {
387         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
388         return UndefinedNapiValue(env);
389     }
390 #else
391     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
392 #endif
393 
394     napi_valuetype valueType;
395     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
396 #ifdef ENABLE_NAPI_MANAGER
397     if (valueType != napi_object) {
398         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
399         return UndefinedNapiValue(env);
400     }
401 #else
402     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type, object is expected for parameter 1.");
403 #endif
404     auto asyncContext = new (std::nothrow) ReverseGeoCodeAsyncContext(env);
405     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
406     NAPI_CALL(env, napi_create_string_latin1(env, "getAddressesFromLocation",
407         NAPI_AUTO_LENGTH, &asyncContext->resourceName));
408     bool ret = JsObjToReverseGeoCodeRequest(env, argv[0], asyncContext->reverseGeoCodeRequest);
409 #ifdef ENABLE_NAPI_MANAGER
410     asyncContext->errCode = ret ? ERRCODE_SUCCESS : ERRCODE_INVALID_PARAM;
411 #else
412     asyncContext->errCode = ret ? SUCCESS : INPUT_PARAMS_ERROR;
413 #endif
414 #ifdef ENABLE_NAPI_MANAGER
415     if (asyncContext->errCode != SUCCESS) {
416         int code = asyncContext->errCode;
417         delete asyncContext;
418         asyncContext = nullptr;
419         HandleSyncErrCode(env, code);
420         return UndefinedNapiValue(env);
421     }
422 #endif
423     CreateReverseGeocodeAsyncContext(asyncContext);
424 
425     size_t objectArgsNum = 1;
426     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
427 }
428 
429 napi_value GetAddressesFromLocationName(napi_env env, napi_callback_info info)
430 {
431     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
432     size_t argc = MAXIMUM_JS_PARAMS;
433     napi_value argv[MAXIMUM_JS_PARAMS];
434     napi_value thisVar = nullptr;
435     void* data = nullptr;
436     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
437     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
438 #ifdef ENABLE_NAPI_MANAGER
439     if (argc < PARAM1 || argc > PARAM2 || (argc == PARAM2 && !CheckIfParamIsFunctionType(env, argv[1]))) {
440         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
441         return UndefinedNapiValue(env);
442     }
443 #else
444     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
445 #endif
446 
447     napi_valuetype valueType;
448     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
449 #ifdef ENABLE_NAPI_MANAGER
450     if (valueType != napi_object) {
451         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
452         return UndefinedNapiValue(env);
453     }
454 #else
455     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type, object is expected for parameter 1.");
456 #endif
457     auto asyncContext = new (std::nothrow) GeoCodeAsyncContext(env);
458     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
459     NAPI_CALL(env,
460         napi_create_string_latin1(env, "GetAddressesFromLocationName", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
461     asyncContext->errCode = JsObjToGeoCodeRequest(env, argv[0], asyncContext->geoCodeRequest);
462 #ifdef ENABLE_NAPI_MANAGER
463     if (asyncContext->errCode == INPUT_PARAMS_ERROR) {
464         delete asyncContext;
465         asyncContext = nullptr;
466         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
467         return UndefinedNapiValue(env);
468     }
469 #endif
470     CreateGeocodeAsyncContext(asyncContext);
471     size_t objectArgsNum = 1;
472     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
473 }
474 
475 #ifdef ENABLE_NAPI_MANAGER
476 napi_value IsLocationPrivacyConfirmed(napi_env env, napi_callback_info info)
477 {
478     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
479     size_t argc = MAXIMUM_JS_PARAMS;
480     napi_value argv[MAXIMUM_JS_PARAMS];
481     napi_value thisVar = nullptr;
482     void* data = nullptr;
483     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
484     if (g_locatorClient == nullptr) {
485         HandleSyncErrCode(env, ERRCODE_SERVICE_UNAVAILABLE);
486         return UndefinedNapiValue(env);
487     }
488     // 1 arguement is necessary
489     if (argc != PARAM1) {
490         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
491         return UndefinedNapiValue(env);
492     }
493     napi_valuetype valueType;
494     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
495     if (valueType != napi_number) {
496         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
497         return UndefinedNapiValue(env);
498     }
499     int type;
500     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &type));
501     napi_value res;
502     bool isEnabled = false;
503     LocationErrCode errorCode = g_locatorClient->IsLocationPrivacyConfirmedV9(type, isEnabled);
504     if (errorCode != ERRCODE_SUCCESS) {
505         HandleSyncErrCode(env, errorCode);
506         return UndefinedNapiValue(env);
507     }
508     NAPI_CALL(env, napi_get_boolean(env, isEnabled, &res));
509     return res;
510 }
511 
512 napi_value SetLocationPrivacyConfirmStatus(napi_env env, napi_callback_info info)
513 {
514     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
515     size_t argc = MAXIMUM_JS_PARAMS;
516     napi_value argv[MAXIMUM_JS_PARAMS];
517     napi_value thisVar = nullptr;
518     void* data = nullptr;
519     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
520     if (g_locatorClient == nullptr) {
521         HandleSyncErrCode(env, ERRCODE_SERVICE_UNAVAILABLE);
522         return UndefinedNapiValue(env);
523     }
524     // 2 arguement is necessary
525     if (argc != PARAM2) {
526         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
527         return UndefinedNapiValue(env);
528     }
529     napi_valuetype valueType1;
530     napi_valuetype valueType2;
531     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType1));
532     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType2));
533     if (valueType1 != napi_number || valueType2 != napi_boolean) {
534         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
535         return UndefinedNapiValue(env);
536     }
537     int type;
538     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &type));
539     bool isConfirmed;
540     NAPI_CALL(env, napi_get_value_bool(env, argv[1], &isConfirmed));
541     LocationErrCode errorCode = g_locatorClient->SetLocationPrivacyConfirmStatusV9(type, isConfirmed);
542     if (errorCode != ERRCODE_SUCCESS) {
543         HandleSyncErrCode(env, errorCode);
544     }
545     return UndefinedNapiValue(env);
546 }
547 #endif
548 
549 napi_value GetCachedGnssLocationsSize(napi_env env, napi_callback_info info)
550 {
551     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
552     size_t argc = MAXIMUM_JS_PARAMS;
553     napi_value argv[MAXIMUM_JS_PARAMS];
554     napi_value thisVar = nullptr;
555     void* data = nullptr;
556     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
557     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
558 #ifdef ENABLE_NAPI_MANAGER
559     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsFunctionType(env, argv[PARAM0]))) {
560         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
561         return UndefinedNapiValue(env);
562     }
563 #endif
564     auto asyncContext = new (std::nothrow) CachedAsyncContext(env);
565     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
566     NAPI_CALL(env,
567         napi_create_string_latin1(env, "GetCachedGnssLocationsSize", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
568 
569     asyncContext->executeFunc = [&](void* data) -> void {
570         auto context = static_cast<CachedAsyncContext*>(data);
571 #ifdef ENABLE_NAPI_MANAGER
572         LocationErrCode errorCode = CheckLocationSwitchState();
573         if (errorCode != ERRCODE_SUCCESS) {
574             context->errCode = errorCode;
575             return;
576         }
577 #endif
578 
579 #ifdef ENABLE_NAPI_MANAGER
580         int size = -1;
581         g_locatorClient->GetCachedGnssLocationsSizeV9(size);
582         context->errCode = ERRCODE_NOT_SUPPORTED;
583         context->locationSize = size;
584 #else
585         context->locationSize = g_locatorClient->GetCachedGnssLocationsSize();
586         context->errCode = (context->locationSize >= 0) ? SUCCESS : NOT_SUPPORTED;
587 #endif
588     };
589     asyncContext->completeFunc = [&](void* data) -> void {
590         auto context = static_cast<CachedAsyncContext*>(data);
591         NAPI_CALL_RETURN_VOID(context->env,
592             napi_create_int32(context->env, context->locationSize, &context->result[PARAM1]));
593         LBSLOGI(LOCATOR_STANDARD, "Push GetCachedGnssLocationsSize result to client");
594     };
595 
596     size_t objectArgsNum = 0;
597     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
598 }
599 
600 napi_value FlushCachedGnssLocations(napi_env env, napi_callback_info info)
601 {
602     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
603     size_t argc = MAXIMUM_JS_PARAMS;
604     napi_value argv[MAXIMUM_JS_PARAMS];
605     napi_value thisVar = nullptr;
606     void* data = nullptr;
607     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
608     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
609 #ifdef ENABLE_NAPI_MANAGER
610     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsFunctionType(env, argv[PARAM0]))) {
611         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
612         return UndefinedNapiValue(env);
613     }
614 #endif
615     auto asyncContext = new (std::nothrow) CachedAsyncContext(env);
616     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
617     NAPI_CALL(env,
618         napi_create_string_latin1(env, "FlushCachedGnssLocations", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
619 
620     asyncContext->executeFunc = [&](void* data) -> void {
621         auto context = static_cast<CachedAsyncContext*>(data);
622 #ifdef ENABLE_NAPI_MANAGER
623         LocationErrCode errorCode = CheckLocationSwitchState();
624         if (errorCode != ERRCODE_SUCCESS) {
625             context->errCode = errorCode;
626             return;
627         }
628         g_locatorClient->FlushCachedGnssLocationsV9();
629         context->errCode = ERRCODE_NOT_SUPPORTED;
630 #else
631         if (g_locatorClient->IsLocationEnabled()) {
632             g_locatorClient->FlushCachedGnssLocations();
633         }
634         context->errCode = NOT_SUPPORTED;
635 #endif
636     };
637 
638     asyncContext->completeFunc = [&](void* data) -> void {
639         auto context = static_cast<CachedAsyncContext*>(data);
640 #ifdef ENABLE_NAPI_MANAGER
641         NAPI_CALL_RETURN_VOID(context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
642 #else
643         NAPI_CALL_RETURN_VOID(context->env,
644             napi_get_boolean(context->env, context->errCode == SUCCESS, &context->result[PARAM1]));
645 #endif
646         LBSLOGI(LOCATOR_STANDARD, "Push FlushCachedGnssLocations result to client");
647     };
648 
649     size_t objectArgsNum = 0;
650     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
651 }
652 
653 void CreateCommandAsyncContext(CommandAsyncContext* asyncContext)
654 {
655     asyncContext->executeFunc = [&](void* data) -> void {
656         auto context = static_cast<CommandAsyncContext*>(data);
657 #ifdef ENABLE_NAPI_MANAGER
658         if (context->command != nullptr) {
659             context->errCode = g_locatorClient->SendCommandV9(context->command);
660         }
661 #else
662         if (context->command != nullptr) {
663             g_locatorClient->SendCommand(context->command);
664         }
665         context->errCode = NOT_SUPPORTED;
666 #endif
667     };
668     asyncContext->completeFunc = [&](void* data) -> void {
669         auto context = static_cast<CommandAsyncContext*>(data);
670 #ifdef ENABLE_NAPI_MANAGER
671         NAPI_CALL_RETURN_VOID(context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
672 #else
673         NAPI_CALL_RETURN_VOID(context->env, napi_get_boolean(context->env,
674             context->enable, &context->result[PARAM1]));
675 #endif
676         LBSLOGI(LOCATOR_STANDARD, "Push SendCommand result to client");
677     };
678 }
679 
680 napi_value SendCommand(napi_env env, napi_callback_info info)
681 {
682     size_t argc = MAXIMUM_JS_PARAMS;
683     napi_value argv[MAXIMUM_JS_PARAMS];
684     napi_value thisVar = nullptr;
685     void* data = nullptr;
686     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
687     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
688 #ifdef ENABLE_NAPI_MANAGER
689     if (argc < PARAM1 || argc > PARAM2 || (argc == PARAM2 && !CheckIfParamIsFunctionType(env, argv[1]))) {
690         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
691         return UndefinedNapiValue(env);
692     }
693 #else
694     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
695 #endif
696 
697     napi_valuetype valueType;
698     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
699 #ifdef ENABLE_NAPI_MANAGER
700     if (valueType != napi_object) {
701         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
702         return UndefinedNapiValue(env);
703     }
704 #else
705     NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type, object is expected for parameter 1.");
706 #endif
707 
708 #ifdef ENABLE_NAPI_MANAGER
709     if (argc == PARAM2 && !CheckIfParamIsFunctionType(env, argv[PARAM1])) {
710         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
711         return UndefinedNapiValue(env);
712     }
713 #endif
714     auto asyncContext = new (std::nothrow) CommandAsyncContext(env);
715     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
716     asyncContext->command = std::make_unique<LocationCommand>();
717     NAPI_CALL(env, napi_create_string_latin1(env, "SendCommand", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
718 
719     int errCode = JsObjToCommand(env, argv[0], asyncContext->command);
720 #ifdef ENABLE_NAPI_MANAGER
721     if (errCode == INPUT_PARAMS_ERROR) {
722         delete asyncContext;
723         asyncContext = nullptr;
724         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
725         return UndefinedNapiValue(env);
726     }
727 #else
728     NAPI_ASSERT(env, errCode != INPUT_PARAMS_ERROR, "The input params should be checked first.");
729 #endif
730     CreateCommandAsyncContext(asyncContext);
731     size_t objectArgsNum = 1;
732     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
733 }
734 
735 #ifdef ENABLE_NAPI_MANAGER
736 napi_value GetIsoCountryCode(napi_env env, napi_callback_info info)
737 {
738     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
739     size_t argc = MAXIMUM_JS_PARAMS;
740     napi_value argv[MAXIMUM_JS_PARAMS];
741     napi_value thisVar = nullptr;
742     void *data = nullptr;
743     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
744     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
745     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsFunctionType(env, argv[PARAM0]))) {
746         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
747         return UndefinedNapiValue(env);
748     }
749     CountryCodeContext *asyncContext = new (std::nothrow) CountryCodeContext(env);
750     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
751     if (napi_create_string_latin1(env, "CountryCodeContext", NAPI_AUTO_LENGTH,
752         &asyncContext->resourceName) != napi_ok) {
753         LBSLOGE(LOCATOR_STANDARD, "copy string failed");
754     }
755     asyncContext->executeFunc = [&](void *data) -> void {
756         if (data == nullptr) {
757             LBSLOGE(LOCATOR_STANDARD, "GetIsoCountryCode data == nullptr");
758             return;
759         }
760         CountryCodeContext *context = static_cast<CountryCodeContext*>(data);
761         std::shared_ptr<CountryCode> country = std::make_shared<CountryCode>();
762         LocationErrCode errorCode = g_locatorClient->GetIsoCountryCodeV9(country);
763         context->errCode = errorCode;
764         if (errorCode == ERRCODE_SUCCESS) {
765             context->country = country;
766         }
767     };
768     asyncContext->completeFunc = [&](void *data) -> void {
769         if (data == nullptr) {
770             LBSLOGE(LOCATOR_STANDARD, "GetIsoCountryCode data == nullptr");
771             return;
772         }
773         CountryCodeContext *context = static_cast<CountryCodeContext *>(data);
774         NAPI_CALL_RETURN_VOID(context->env, napi_create_object(context->env, &context->result[PARAM1]));
775         if (context->country) {
776             CountryCodeToJs(context->env, context->country, context->result[PARAM1]);
777         } else {
778             LBSLOGE(LOCATOR_STANDARD, "country is nullptr!");
779         }
780         LBSLOGI(LOCATOR_STANDARD, "Push GetIsoCountryCode result to client");
781     };
782 
783     size_t objectArgsNum = 0;
784     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
785 }
786 
787 int ParseLocationMockParams(napi_env env, LocationMockAsyncContext *asyncContext, napi_value object)
788 {
789     CHK_ERROR_CODE("timeInterval", JsObjectToInt(env, object, "timeInterval", asyncContext->timeInterval), true);
790     bool result = false;
791     napi_value value = nullptr;
792     NAPI_CALL_BASE(env, napi_has_named_property(env, object, "locations", &result), false);
793     if (result) {
794         NAPI_CALL_BASE(env, napi_get_named_property(env, object, "locations", &value), false);
795         bool isArray = false;
796         NAPI_CALL_BASE(env, napi_is_array(env, value, &isArray), false);
797         if (!isArray) {
798             LBSLOGE(LOCATOR_STANDARD, "not an array!");
799             return INPUT_PARAMS_ERROR;
800         }
801         GetLocationArray(env, asyncContext, value);
802     }
803     return SUCCESS;
804 }
805 
806 napi_value EnableLocationMock(napi_env env, napi_callback_info info)
807 {
808     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
809     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
810     LocationErrCode errorCode = CheckLocationSwitchState();
811     if (errorCode != ERRCODE_SUCCESS) {
812         HandleSyncErrCode(env, errorCode);
813         return UndefinedNapiValue(env);
814     }
815     errorCode = g_locatorClient->EnableLocationMockV9();
816     if (errorCode != ERRCODE_SUCCESS) {
817         HandleSyncErrCode(env, errorCode);
818     }
819     return UndefinedNapiValue(env);
820 }
821 
822 napi_value DisableLocationMock(napi_env env, napi_callback_info info)
823 {
824     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
825     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
826     LocationErrCode errorCode = CheckLocationSwitchState();
827     if (errorCode != ERRCODE_SUCCESS) {
828         HandleSyncErrCode(env, errorCode);
829         return UndefinedNapiValue(env);
830     }
831     errorCode = g_locatorClient->DisableLocationMockV9();
832     if (errorCode != ERRCODE_SUCCESS) {
833         HandleSyncErrCode(env, errorCode);
834     }
835     return UndefinedNapiValue(env);
836 }
837 
838 napi_value SetMockedLocations(napi_env env, napi_callback_info info)
839 {
840     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
841     size_t argc = MAXIMUM_JS_PARAMS;
842     napi_value argv[MAXIMUM_JS_PARAMS];
843     napi_value thisVar = nullptr;
844     void *data = nullptr;
845     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
846     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
847     if (argc != PARAM1) {
848         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
849         return UndefinedNapiValue(env);
850     }
851     napi_valuetype valueType;
852     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
853     if (valueType != napi_object) {
854         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
855         return UndefinedNapiValue(env);
856     }
857 
858     LocationMockAsyncContext *asyncContext = new (std::nothrow) LocationMockAsyncContext(env);
859     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
860     NAPI_CALL(env, napi_create_string_latin1(env,
861         "SetMockedLocations", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
862     asyncContext->errCode = ParseLocationMockParams(env, asyncContext, argv[0]);
863     if (asyncContext->errCode == INPUT_PARAMS_ERROR) {
864         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
865         return UndefinedNapiValue(env);
866     }
867     LocationErrCode errorCode = CheckLocationSwitchState();
868     if (errorCode != ERRCODE_SUCCESS) {
869         HandleSyncErrCode(env, errorCode);
870         return UndefinedNapiValue(env);
871     }
872     errorCode = g_locatorClient->SetMockedLocationsV9(asyncContext->timeInterval, asyncContext->LocationNapi);
873     if (errorCode != ERRCODE_SUCCESS) {
874         HandleSyncErrCode(env, errorCode);
875     }
876     return UndefinedNapiValue(env);
877 }
878 
879 napi_value EnableReverseGeocodingMock(napi_env env, napi_callback_info info)
880 {
881     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
882     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
883     LocationErrCode errorCode = g_locatorClient->EnableReverseGeocodingMockV9();
884     if (errorCode != ERRCODE_SUCCESS) {
885         HandleSyncErrCode(env, errorCode);
886     }
887     return UndefinedNapiValue(env);
888 }
889 
890 napi_value DisableReverseGeocodingMock(napi_env env, napi_callback_info info)
891 {
892     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
893     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
894     LocationErrCode errorCode = g_locatorClient->DisableReverseGeocodingMockV9();
895     if (errorCode != ERRCODE_SUCCESS) {
896         HandleSyncErrCode(env, errorCode);
897     }
898     return UndefinedNapiValue(env);
899 }
900 
901 napi_value SetReverseGeocodingMockInfo(napi_env env, napi_callback_info info)
902 {
903     LBSLOGI(LOCATOR_STANDARD, "%{public}s called.", __func__);
904     size_t argc = MAXIMUM_JS_PARAMS;
905     napi_value argv[MAXIMUM_JS_PARAMS];
906     napi_value thisVar = nullptr;
907     void *data = nullptr;
908     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
909     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
910     if (argc != PARAM1) {
911         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
912         return UndefinedNapiValue(env);
913     }
914 
915     bool isArray = false;
916     NAPI_CALL(env, napi_is_array(env, argv[0], &isArray));
917     if (!isArray) {
918         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
919         return UndefinedNapiValue(env);
920     }
921     std::vector<std::shared_ptr<GeocodingMockInfo>> mockInfo;
922     JsObjToRevGeocodeMock(env, argv[0], mockInfo);
923     LocationErrCode errorCode = g_locatorClient->SetReverseGeocodingMockInfoV9(mockInfo);
924     if (errorCode != ERRCODE_SUCCESS) {
925         HandleSyncErrCode(env, errorCode);
926     }
927     return UndefinedNapiValue(env);
928 }
929 #endif
930 
931 #ifdef ENABLE_NAPI_MANAGER
932 LocationErrCode CheckLocationSwitchState()
933 {
934     bool isEnabled = false;
935     LocationErrCode errorCode = g_locatorClient->IsLocationEnabledV9(isEnabled);
936     if (errorCode != ERRCODE_SUCCESS) {
937         return errorCode;
938     }
939     if (!isEnabled) {
940         return ERRCODE_SWITCH_OFF;
941     }
942     return ERRCODE_SUCCESS;
943 }
944 
945 sptr<LocatingRequiredDataCallbackNapi> CreateSingleCallbackHost()
946 {
947     auto callbackHost =
948         sptr<LocatingRequiredDataCallbackNapi>(new (std::nothrow) LocatingRequiredDataCallbackNapi());
949     if (callbackHost) {
950         callbackHost->SetFixNumber(1);
951     }
952     return callbackHost;
953 }
954 
955 SingleScanAsyncContext* CreateSingleScanAsyncContext(const napi_env& env,
956     std::unique_ptr<LocatingRequiredDataConfig>& config, sptr<LocatingRequiredDataCallbackNapi> callback)
957 {
958     auto asyncContext = new (std::nothrow) SingleScanAsyncContext(env);
959     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
960     NAPI_CALL(env, napi_create_string_latin1(env, "getLocatingRequiredDataOnce",
961         NAPI_AUTO_LENGTH, &asyncContext->resourceName));
962     asyncContext->timeout_ = config->GetScanTimeoutMs();
963     asyncContext->callbackHost_ = callback;
964     asyncContext->executeFunc = [&](void* data) -> void {
965         if (data == nullptr) {
966             LBSLOGE(LOCATOR_STANDARD, "data is nullptr!");
967             return;
968         }
969         auto context = static_cast<SingleScanAsyncContext*>(data);
970         auto callbackHost = context->callbackHost_;
971         if (callbackHost != nullptr) {
972             callbackHost->Wait(context->timeout_);
973             auto callbackPtr = sptr<ILocatingRequiredDataCallback>(callbackHost);
974             g_locatorClient->UnRegisterLocatingRequiredDataCallback(callbackPtr);
975             if (callbackHost->GetCount() != 0) {
976                 context->errCode = ERRCODE_SCAN_FAIL;
977             }
978             callbackHost->SetCount(1);
979         }
980     };
981     asyncContext->completeFunc = [&](void* data) -> void {
982         if (data == nullptr) {
983             LBSLOGE(LOCATOR_STANDARD, "data is nullptr!");
984             return;
985         }
986         auto context = static_cast<SingleScanAsyncContext*>(data);
987 
988         auto callbackHost = context->callbackHost_;
989         if (callbackHost != nullptr) {
990             std::vector<std::shared_ptr<LocatingRequiredData>> res = callbackHost->GetSingleResult();
991             napi_create_array_with_length(context->env, res.size(), &context->result[PARAM1]);
992             LocatingRequiredDataToJsObj(context->env, res, context->result[PARAM1]);
993             callbackHost->ClearSingleResult();
994         } else {
995             LBSLOGE(LOCATOR_STANDARD, "m_singleLocation is nullptr!");
996         }
997         if (context->callbackHost_) {
998             context->callbackHost_ = nullptr;
999         }
1000         LBSLOGI(LOCATOR_STANDARD, "Push scan info to client");
1001     };
1002     return asyncContext;
1003 }
1004 
1005 napi_value GetLocatingRequiredData(napi_env env, napi_callback_info info)
1006 {
1007     LBSLOGD(LOCATOR_STANDARD, "%{public}s called.", __func__);
1008     size_t argc = MAXIMUM_JS_PARAMS;
1009     napi_value argv[MAXIMUM_JS_PARAMS];
1010     napi_value thisVar = nullptr;
1011     void* data = nullptr;
1012     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1013     NAPI_ASSERT(env, g_locatorClient != nullptr, "locator instance is null.");
1014     if (argc > PARAM1 || (argc == PARAM1 && !CheckIfParamIsObjectType(env, argv[PARAM0]))) {
1015         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1016         return UndefinedNapiValue(env);
1017     }
1018     if (argc == PARAM1) {
1019         napi_valuetype valueType;
1020         NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
1021         if (valueType != napi_object) {
1022             HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1023             return UndefinedNapiValue(env);
1024         }
1025     }
1026 
1027     auto singleCallbackHost = CreateSingleCallbackHost();
1028     if (singleCallbackHost == nullptr) {
1029         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1030         return UndefinedNapiValue(env);
1031     }
1032     std::unique_ptr<LocatingRequiredDataConfig> requestConfig = std::make_unique<LocatingRequiredDataConfig>();
1033     JsObjToLocatingRequiredDataConfig(env, argv[0], requestConfig);
1034     requestConfig->SetFixNumber(1);
1035     auto callbackPtr = sptr<ILocatingRequiredDataCallback>(singleCallbackHost);
1036     LocationErrCode errorCode = g_locatorClient->RegisterLocatingRequiredDataCallback(requestConfig, callbackPtr);
1037     if (errorCode != ERRCODE_SUCCESS) {
1038         HandleSyncErrCode(env, errorCode);
1039         return UndefinedNapiValue(env);
1040     }
1041 
1042     auto asyncContext = CreateSingleScanAsyncContext(env, requestConfig, singleCallbackHost);
1043     if (asyncContext == nullptr) {
1044         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1045         return UndefinedNapiValue(env);
1046     }
1047     return DoAsyncWork(env, asyncContext, argc, argv, 1);
1048 }
1049 
1050 napi_value AddGnssGeofence(napi_env env, napi_callback_info info)
1051 {
1052     LBSLOGD(LOCATOR_STANDARD, "%{public}s called.", __func__);
1053     size_t argc = MAXIMUM_JS_PARAMS;
1054     napi_value argv[MAXIMUM_JS_PARAMS];
1055     napi_value thisVar = nullptr;
1056     void* data = nullptr;
1057     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1058     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator ext SA failed");
1059     if (argc > PARAM1) {
1060         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1061         return UndefinedNapiValue(env);
1062     }
1063     std::shared_ptr<GeofenceRequest> gnssGeofenceRequest = std::make_shared<GeofenceRequest>();
1064     bool isValidParameter = ParseGnssGeofenceRequest(env, argv[0], gnssGeofenceRequest);
1065     if (!isValidParameter) {
1066         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1067         return UndefinedNapiValue(env);
1068     }
1069     auto locationGnssGeofenceCallbackHost =
1070         sptr<LocationGnssGeofenceCallbackNapi>(new (std::nothrow) LocationGnssGeofenceCallbackNapi());
1071     JsObjToGeofenceTransitionCallback(env, argv[0], locationGnssGeofenceCallbackHost);
1072     auto callbackPtr = sptr<IGnssGeofenceCallback>(locationGnssGeofenceCallbackHost);
1073     gnssGeofenceRequest->SetGeofenceTransitionCallback(callbackPtr->AsObject());
1074     auto asyncContext = CreateAsyncContextForAddGnssGeofence(
1075         env, gnssGeofenceRequest, locationGnssGeofenceCallbackHost);
1076     if (asyncContext == nullptr) {
1077         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1078         return UndefinedNapiValue(env);
1079     }
1080     return DoAsyncWork(env, asyncContext, argc, argv, 1);
1081 }
1082 
1083 GnssGeofenceAsyncContext* CreateAsyncContextForAddGnssGeofence(const napi_env& env,
1084     std::shared_ptr<GeofenceRequest>& request, sptr<LocationGnssGeofenceCallbackNapi> callback)
1085 {
1086     auto asyncContext = new (std::nothrow) GnssGeofenceAsyncContext(env);
1087     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
1088     NAPI_CALL(env, napi_create_string_latin1(env, "addGnssGeofence", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
1089     asyncContext->callbackHost_ = callback;
1090     asyncContext->request_ = request;
1091     asyncContext->executeFunc = [&](void* data) -> void {
1092         if (data == nullptr) {
1093             return;
1094         }
1095         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1096         auto callbackHost = context->callbackHost_;
1097         auto gnssGeofenceRequest = context->request_;
1098         if (callbackHost != nullptr && gnssGeofenceRequest != nullptr) {
1099             auto errCode = g_geofenceClient->AddGnssGeofence(gnssGeofenceRequest);
1100             if (errCode != ERRCODE_SUCCESS) {
1101                 context->errCode = errCode;
1102                 callbackHost->SetCount(0);
1103             }
1104             callbackHost->Wait(DEFAULT_CALLBACK_WAIT_TIME);
1105             if (callbackHost->GetCount() != 0) {
1106                 context->errCode = ERRCODE_SERVICE_UNAVAILABLE;
1107             }
1108             callbackHost->SetCount(1);
1109         }
1110     };
1111     asyncContext->completeFunc = [&](void* data) -> void {
1112         if (data == nullptr) {
1113             return;
1114         }
1115         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1116         auto callbackHost = context->callbackHost_;
1117         if (callbackHost != nullptr && context->errCode == ERRCODE_SUCCESS &&
1118             callbackHost->GetGeofenceOperationType() == GnssGeofenceOperateType::GNSS_GEOFENCE_OPT_TYPE_ADD) {
1119             LocationErrCode errCode = callbackHost->DealGeofenceOperationResult();
1120             if (errCode == ERRCODE_SUCCESS) {
1121                 int fenceId = callbackHost->GetFenceId();
1122                 napi_create_object(context->env, &context->result[PARAM1]);
1123                 napi_create_int64(context->env, fenceId, &context->result[PARAM1]);
1124                 AddCallbackToGnssGeofenceCallbackHostMap(fenceId, callbackHost);
1125             } else {
1126                 context->errCode = errCode;
1127             }
1128         }
1129     };
1130     return asyncContext;
1131 }
1132 
1133 napi_value RemoveGnssGeofence(napi_env env, napi_callback_info info)
1134 {
1135     LBSLOGD(LOCATOR_STANDARD, "%{public}s called.", __func__);
1136     size_t argc = MAXIMUM_JS_PARAMS;
1137     napi_value argv[MAXIMUM_JS_PARAMS];
1138     napi_value thisVar = nullptr;
1139     void* data = nullptr;
1140     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1141     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
1142     if (argc > PARAM1) {
1143         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1144         return UndefinedNapiValue(env);
1145     }
1146     int fenceId = -1;
1147     napi_valuetype valueType1;
1148     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType1));
1149     if (valueType1 != napi_number) {
1150         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1151         return UndefinedNapiValue(env);
1152     }
1153     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &fenceId));
1154     auto asyncContext = CreateAsyncContextForRemoveGnssGeofence(env, fenceId);
1155     if (asyncContext == nullptr) {
1156         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1157         return UndefinedNapiValue(env);
1158     }
1159     size_t objectArgsNum = 1;
1160     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
1161 }
1162 
1163 GnssGeofenceAsyncContext* CreateAsyncContextForRemoveGnssGeofence(const napi_env& env, int fenceId)
1164 {
1165     auto asyncContext = new (std::nothrow) GnssGeofenceAsyncContext(env);
1166     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
1167     asyncContext->fenceId_ = fenceId;
1168     asyncContext->callbackHost_ = FindCallbackInGnssGeofenceCallbackHostMap(fenceId);
1169     NAPI_CALL(env, napi_create_string_latin1(env,
1170         "removeGnssGeofence", NAPI_AUTO_LENGTH, &asyncContext->resourceName));
1171 
1172     asyncContext->executeFunc = [&](void* data) -> void {
1173         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1174         std::shared_ptr<GeofenceRequest> request = std::make_shared<GeofenceRequest>();
1175         request->SetFenceId(context->fenceId_);
1176         context->errCode = g_geofenceClient->RemoveGnssGeofence(request);
1177         auto callbackHost = context->callbackHost_;
1178         if (callbackHost != nullptr) {
1179             if (context->errCode != ERRCODE_SUCCESS) {
1180                 callbackHost->SetCount(0);
1181             }
1182             callbackHost->Wait(DEFAULT_CALLBACK_WAIT_TIME);
1183             if (callbackHost->GetCount() != 0) {
1184                 context->errCode = ERRCODE_SERVICE_UNAVAILABLE;
1185             }
1186             callbackHost->SetCount(1);
1187         } else {
1188             context->errCode = ERRCODE_GEOFENCE_INCORRECT_ID;
1189         }
1190     };
1191 
1192     asyncContext->completeFunc = [&](void* data) -> void {
1193         auto context = static_cast<GnssGeofenceAsyncContext*>(data);
1194         auto callbackHost = context->callbackHost_;
1195         if (callbackHost != nullptr && context->errCode == ERRCODE_SUCCESS &&
1196             callbackHost->GetGeofenceOperationType() ==
1197             GnssGeofenceOperateType::GNSS_GEOFENCE_OPT_TYPE_DELETE) {
1198             LocationErrCode errCode = callbackHost->DealGeofenceOperationResult();
1199             if (errCode == ERRCODE_SUCCESS) {
1200                 NAPI_CALL_RETURN_VOID(
1201                     context->env, napi_get_undefined(context->env, &context->result[PARAM1]));
1202                 RemoveCallbackToGnssGeofenceCallbackHostMap(context->fenceId_);
1203             } else {
1204                 context->errCode = errCode;
1205             }
1206         }
1207         LBSLOGD(LOCATOR_STANDARD, "Push RemoveGnssGeofence result to client");
1208     };
1209     return asyncContext;
1210 }
1211 
1212 napi_value GetGeofenceSupportedCoordTypes(napi_env env, napi_callback_info info)
1213 {
1214     size_t argc = MAXIMUM_JS_PARAMS;
1215     napi_value argv[MAXIMUM_JS_PARAMS];
1216     napi_value thisVar = nullptr;
1217     void* data = nullptr;
1218     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
1219     NAPI_ASSERT(env, g_locatorClient != nullptr, "get locator SA failed");
1220     std::vector<CoordinateSystemType> coordinateSystemTypes;
1221     LocationErrCode errorCode =
1222         g_geofenceClient->GetGeofenceSupportedCoordTypes(coordinateSystemTypes);
1223     if (errorCode != ERRCODE_SUCCESS) {
1224         HandleSyncErrCode(env, errorCode);
1225         return UndefinedNapiValue(env);
1226     }
1227     napi_value res;
1228     NAPI_CALL(env,
1229         napi_create_array_with_length(env, coordinateSystemTypes.size(), &res));
1230     uint32_t idx = 0;
1231     for (auto iter = coordinateSystemTypes.begin(); iter != coordinateSystemTypes.end(); ++iter) {
1232         auto coordType = *iter;
1233         napi_value eachObj;
1234         NAPI_CALL(env, napi_create_int32(env, static_cast<int>(coordType), &eachObj));
1235         NAPI_CALL(env, napi_set_element(env, res, idx++, eachObj));
1236     }
1237     return res;
1238 }
1239 
1240 void AddCallbackToGnssGeofenceCallbackHostMap(int fenceId, sptr<LocationGnssGeofenceCallbackNapi> callbackHost)
1241 {
1242     std::unique_lock<std::mutex> lock(g_gnssGeofenceCallbackHostMutex);
1243     g_gnssGeofenceCallbackHostMap.insert(std::make_pair(fenceId, callbackHost));
1244 }
1245 
1246 void RemoveCallbackToGnssGeofenceCallbackHostMap(int fenceId)
1247 {
1248     std::unique_lock<std::mutex> lock(g_gnssGeofenceCallbackHostMutex);
1249     auto iterForDelete = g_gnssGeofenceCallbackHostMap.find(fenceId);
1250     if (iterForDelete != g_gnssGeofenceCallbackHostMap.end()) {
1251         g_gnssGeofenceCallbackHostMap.erase(iterForDelete);
1252     }
1253 }
1254 
1255 sptr<LocationGnssGeofenceCallbackNapi> FindCallbackInGnssGeofenceCallbackHostMap(int fenceId)
1256 {
1257     std::unique_lock<std::mutex> lock(g_gnssGeofenceCallbackHostMutex);
1258     auto iter = g_gnssGeofenceCallbackHostMap.find(fenceId);
1259     if (iter != g_gnssGeofenceCallbackHostMap.end()) {
1260         return iter->second;
1261     }
1262     return nullptr;
1263 }
1264 #endif
1265 } // namespace Location
1266 } // namespace OHOS
1267