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