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