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