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