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 #include "location_napi_event.h"
16
17 #include "callback_manager.h"
18 #include "common_utils.h"
19 #include "location_log.h"
20 #include "location_napi_errcode.h"
21 #include "country_code_callback_napi.h"
22 #include "locator.h"
23 #include "geofence_sdk.h"
24 #include "geofence_napi.h"
25 #include "napi_util.h"
26 #ifdef SUPPORT_JSSTACK
27 #include "xpower_event_js.h"
28 #endif
29 #include "want_agent_helper.h"
30
31 namespace OHOS {
32 namespace Location {
33 CallbackManager<LocationSwitchCallbackNapi> g_switchCallbacks;
34 CallbackManager<LocatorCallbackNapi> g_locationCallbacks;
35 CallbackManager<GnssStatusCallbackNapi> g_gnssStatusInfoCallbacks;
36 CallbackManager<NmeaMessageCallbackNapi> g_nmeaCallbacks;
37 CallbackManager<CachedLocationsCallbackNapi> g_cachedLocationCallbacks;
38 CallbackManager<CountryCodeCallbackNapi> g_countryCodeCallbacks;
39 CallbackManager<LocatingRequiredDataCallbackNapi> g_locatingRequiredDataCallbacks;
40 CallbackManager<LocationErrorCallbackNapi> g_locationErrorCallbackHosts;
41
42 std::unique_ptr<CachedGnssLocationsRequest> g_cachedRequest = std::make_unique<CachedGnssLocationsRequest>();
43 auto g_locatorProxy = Locator::GetInstance();
44 auto g_geofenceProxy = GeofenceManager::GetInstance();
45
46 std::mutex g_FuncMapMutex;
47 std::map<std::string, bool(*)(const napi_env &)> g_offAllFuncMap;
48 std::map<std::string, bool(*)(const napi_env &, const napi_value &)> g_offFuncMap;
49 std::map<std::string, bool(*)(const napi_env &, const size_t, const napi_value *)> g_onFuncMap;
50
51 static constexpr int LASTLOCATION_CACHED_TIME = 10 * 60;
52
53 const int MIN_TIMEOUTMS_FOR_LOCATIONONCE = 1000;
54
InitOnFuncMap()55 void InitOnFuncMap()
56 {
57 std::unique_lock<std::mutex> lock(g_FuncMapMutex);
58 if (g_onFuncMap.size() != 0) {
59 return;
60 }
61 #ifdef ENABLE_NAPI_MANAGER
62 g_onFuncMap.insert(std::make_pair("locationEnabledChange", &OnLocationServiceStateCallback));
63 g_onFuncMap.insert(std::make_pair("cachedGnssLocationsChange", &OnCachedGnssLocationsReportingCallback));
64 g_onFuncMap.insert(std::make_pair("satelliteStatusChange", &OnGnssStatusChangeCallback));
65 g_onFuncMap.insert(std::make_pair("gnssFenceStatusChange", &OnFenceStatusChangeCallback));
66 g_onFuncMap.insert(std::make_pair("nmeaMessage", &OnNmeaMessageChangeCallback));
67 g_onFuncMap.insert(std::make_pair("locatingRequiredDataChange", &OnLocatingRequiredDataChangeCallback));
68 g_onFuncMap.insert(std::make_pair("locationError", &OnLocationErrorCallback));
69 #else
70 g_onFuncMap.insert(std::make_pair("locationServiceState", &OnLocationServiceStateCallback));
71 g_onFuncMap.insert(std::make_pair("cachedGnssLocationsReporting", &OnCachedGnssLocationsReportingCallback));
72 g_onFuncMap.insert(std::make_pair("gnssStatusChange", &OnGnssStatusChangeCallback));
73 g_onFuncMap.insert(std::make_pair("fenceStatusChange", &OnFenceStatusChangeCallback));
74 g_onFuncMap.insert(std::make_pair("nmeaMessageChange", &OnNmeaMessageChangeCallback));
75 #endif
76 g_onFuncMap.insert(std::make_pair("locationChange", &OnLocationChangeCallback));
77 g_onFuncMap.insert(std::make_pair("countryCodeChange", &OnCountryCodeChangeCallback));
78 }
79
InitOffFuncMap()80 void InitOffFuncMap()
81 {
82 std::unique_lock<std::mutex> lock(g_FuncMapMutex);
83 if (g_offAllFuncMap.size() != 0 || g_offFuncMap.size() != 0) {
84 return;
85 }
86 #ifdef ENABLE_NAPI_MANAGER
87 g_offAllFuncMap.insert(std::make_pair("locationEnabledChange", &OffAllLocationServiceStateCallback));
88 g_offAllFuncMap.insert(std::make_pair("cachedGnssLocationsChange", &OffAllCachedGnssLocationsReportingCallback));
89 g_offAllFuncMap.insert(std::make_pair("satelliteStatusChange", &OffAllGnssStatusChangeCallback));
90 g_offAllFuncMap.insert(std::make_pair("nmeaMessage", &OffAllNmeaMessageChangeCallback));
91 g_offAllFuncMap.insert(std::make_pair("locatingRequiredDataChange", &OffAllLocatingRequiredDataChangeCallback));
92 #else
93 g_offAllFuncMap.insert(std::make_pair("locationServiceState", &OffAllLocationServiceStateCallback));
94 g_offAllFuncMap.insert(std::make_pair("cachedGnssLocationsReporting", &OffAllCachedGnssLocationsReportingCallback));
95 g_offAllFuncMap.insert(std::make_pair("gnssStatusChange", &OffAllGnssStatusChangeCallback));
96 g_offAllFuncMap.insert(std::make_pair("nmeaMessageChange", &OffAllNmeaMessageChangeCallback));
97 #endif
98 g_offAllFuncMap.insert(std::make_pair("locationChange", &OffAllLocationChangeCallback));
99 g_offAllFuncMap.insert(std::make_pair("countryCodeChange", &OffAllCountryCodeChangeCallback));
100
101 #ifdef ENABLE_NAPI_MANAGER
102 g_offFuncMap.insert(std::make_pair("locationEnabledChange", &OffLocationServiceStateCallback));
103 g_offFuncMap.insert(std::make_pair("cachedGnssLocationsChange", &OffCachedGnssLocationsReportingCallback));
104 g_offFuncMap.insert(std::make_pair("satelliteStatusChange", &OffGnssStatusChangeCallback));
105 g_offFuncMap.insert(std::make_pair("nmeaMessage", &OffNmeaMessageChangeCallback));
106 g_offFuncMap.insert(std::make_pair("locatingRequiredDataChange", &OffLocatingRequiredDataChangeCallback));
107 g_offFuncMap.insert(std::make_pair("locationError", &OffLocationErrorCallback));
108 #else
109 g_offFuncMap.insert(std::make_pair("locationServiceState", &OffLocationServiceStateCallback));
110 g_offFuncMap.insert(std::make_pair("cachedGnssLocationsReporting", &OffCachedGnssLocationsReportingCallback));
111 g_offFuncMap.insert(std::make_pair("gnssStatusChange", &OffGnssStatusChangeCallback));
112 g_offFuncMap.insert(std::make_pair("nmeaMessageChange", &OffNmeaMessageChangeCallback));
113 #endif
114 g_offFuncMap.insert(std::make_pair("locationChange", &OffLocationChangeCallback));
115 g_offFuncMap.insert(std::make_pair("countryCodeChange", &OffCountryCodeChangeCallback));
116 }
117
SubscribeLocationServiceState(const napi_env & env,const napi_ref & handlerRef,sptr<LocationSwitchCallbackNapi> & switchCallbackHost)118 void SubscribeLocationServiceState(const napi_env& env,
119 const napi_ref& handlerRef, sptr<LocationSwitchCallbackNapi>& switchCallbackHost)
120 {
121 switchCallbackHost->SetEnv(env);
122 switchCallbackHost->SetHandleCb(handlerRef);
123 g_locatorProxy->RegisterSwitchCallback(switchCallbackHost->AsObject(), DEFAULT_UID);
124 }
125
126 #ifdef ENABLE_NAPI_MANAGER
SubscribeLocationServiceStateV9(const napi_env & env,const napi_ref & handlerRef,sptr<LocationSwitchCallbackNapi> & switchCallbackHost)127 LocationErrCode SubscribeLocationServiceStateV9(const napi_env& env,
128 const napi_ref& handlerRef, sptr<LocationSwitchCallbackNapi>& switchCallbackHost)
129 {
130 switchCallbackHost->SetEnv(env);
131 switchCallbackHost->SetHandleCb(handlerRef);
132 return g_locatorProxy->RegisterSwitchCallbackV9(switchCallbackHost->AsObject());
133 }
134 #endif
135
SubscribeGnssStatus(const napi_env & env,const napi_ref & handlerRef,sptr<GnssStatusCallbackNapi> & gnssStatusCallbackHost)136 void SubscribeGnssStatus(const napi_env& env, const napi_ref& handlerRef,
137 sptr<GnssStatusCallbackNapi>& gnssStatusCallbackHost)
138 {
139 gnssStatusCallbackHost->SetEnv(env);
140 gnssStatusCallbackHost->SetHandleCb(handlerRef);
141 g_locatorProxy->RegisterGnssStatusCallback(gnssStatusCallbackHost->AsObject(), DEFAULT_UID);
142 }
143
144 #ifdef ENABLE_NAPI_MANAGER
SubscribeGnssStatusV9(const napi_env & env,const napi_ref & handlerRef,sptr<GnssStatusCallbackNapi> & gnssStatusCallbackHost)145 LocationErrCode SubscribeGnssStatusV9(const napi_env& env, const napi_ref& handlerRef,
146 sptr<GnssStatusCallbackNapi>& gnssStatusCallbackHost)
147 {
148 LocationErrCode errorCode = CheckLocationSwitchEnable();
149 if (errorCode != ERRCODE_SUCCESS) {
150 return errorCode;
151 }
152 gnssStatusCallbackHost->SetEnv(env);
153 gnssStatusCallbackHost->SetHandleCb(handlerRef);
154 return g_locatorProxy->RegisterGnssStatusCallbackV9(gnssStatusCallbackHost->AsObject());
155 }
156 #endif
157
SubscribeNmeaMessage(const napi_env & env,const napi_ref & handlerRef,sptr<NmeaMessageCallbackNapi> & nmeaMessageCallbackHost)158 void SubscribeNmeaMessage(const napi_env& env, const napi_ref& handlerRef,
159 sptr<NmeaMessageCallbackNapi>& nmeaMessageCallbackHost)
160 {
161 nmeaMessageCallbackHost->SetEnv(env);
162 nmeaMessageCallbackHost->SetHandleCb(handlerRef);
163 g_locatorProxy->RegisterNmeaMessageCallback(nmeaMessageCallbackHost->AsObject(), DEFAULT_UID);
164 }
165
166 #ifdef ENABLE_NAPI_MANAGER
SubscribeNmeaMessageV9(const napi_env & env,const napi_ref & handlerRef,sptr<NmeaMessageCallbackNapi> & nmeaMessageCallbackHost)167 LocationErrCode SubscribeNmeaMessageV9(const napi_env& env, const napi_ref& handlerRef,
168 sptr<NmeaMessageCallbackNapi>& nmeaMessageCallbackHost)
169 {
170 LocationErrCode errorCode = CheckLocationSwitchEnable();
171 if (errorCode != ERRCODE_SUCCESS) {
172 return errorCode;
173 }
174 nmeaMessageCallbackHost->SetEnv(env);
175 nmeaMessageCallbackHost->SetHandleCb(handlerRef);
176 return g_locatorProxy->RegisterNmeaMessageCallbackV9(nmeaMessageCallbackHost->AsObject());
177 }
178 #endif
179
UnSubscribeLocationServiceState(sptr<LocationSwitchCallbackNapi> & switchCallbackHost)180 void UnSubscribeLocationServiceState(sptr<LocationSwitchCallbackNapi>& switchCallbackHost)
181 {
182 LBSLOGD(LOCATION_NAPI, "UnSubscribeLocationServiceState");
183 g_locatorProxy->UnregisterSwitchCallback(switchCallbackHost->AsObject());
184 }
185
186 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeLocationServiceStateV9(sptr<LocationSwitchCallbackNapi> & switchCallbackHost)187 LocationErrCode UnSubscribeLocationServiceStateV9(sptr<LocationSwitchCallbackNapi>& switchCallbackHost)
188 {
189 LBSLOGD(LOCATION_NAPI, "UnSubscribeLocationServiceStateV9");
190 return g_locatorProxy->UnregisterSwitchCallbackV9(switchCallbackHost->AsObject());
191 }
192 #endif
193
UnSubscribeGnssStatus(sptr<GnssStatusCallbackNapi> & gnssStatusCallbackHost)194 void UnSubscribeGnssStatus(sptr<GnssStatusCallbackNapi>& gnssStatusCallbackHost)
195 {
196 LBSLOGD(LOCATION_NAPI, "UnSubscribeGnssStatus");
197 g_locatorProxy->UnregisterGnssStatusCallback(gnssStatusCallbackHost->AsObject());
198 }
199
200 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeGnssStatusV9(sptr<GnssStatusCallbackNapi> & gnssStatusCallbackHost)201 LocationErrCode UnSubscribeGnssStatusV9(sptr<GnssStatusCallbackNapi>& gnssStatusCallbackHost)
202 {
203 LBSLOGD(LOCATION_NAPI, "UnSubscribeGnssStatusV9");
204 return g_locatorProxy->UnregisterGnssStatusCallbackV9(gnssStatusCallbackHost->AsObject());
205 }
206 #endif
207
UnSubscribeNmeaMessage(sptr<NmeaMessageCallbackNapi> & nmeaMessageCallbackHost)208 void UnSubscribeNmeaMessage(sptr<NmeaMessageCallbackNapi>& nmeaMessageCallbackHost)
209 {
210 LBSLOGD(LOCATION_NAPI, "UnSubscribeNmeaMessage");
211 g_locatorProxy->UnregisterNmeaMessageCallback(nmeaMessageCallbackHost->AsObject());
212 }
213
214 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeNmeaMessageV9(sptr<NmeaMessageCallbackNapi> & nmeaMessageCallbackHost)215 LocationErrCode UnSubscribeNmeaMessageV9(sptr<NmeaMessageCallbackNapi>& nmeaMessageCallbackHost)
216 {
217 LBSLOGD(LOCATION_NAPI, "UnSubscribeNmeaMessageV9");
218 return g_locatorProxy->UnregisterNmeaMessageCallbackV9(nmeaMessageCallbackHost->AsObject());
219 }
220 #endif
221
SubscribeLocationChange(const napi_env & env,const napi_value & object,const napi_ref & handlerRef,sptr<LocatorCallbackNapi> & locatorCallbackHost)222 void SubscribeLocationChange(const napi_env& env, const napi_value& object,
223 const napi_ref& handlerRef, sptr<LocatorCallbackNapi>& locatorCallbackHost)
224 {
225 auto locatorCallback = sptr<ILocatorCallback>(locatorCallbackHost);
226 locatorCallbackHost->SetFixNumber(0);
227 locatorCallbackHost->SetEnv(env);
228 locatorCallbackHost->SetHandleCb(handlerRef);
229 auto requestConfig = std::make_unique<RequestConfig>();
230 JsObjToLocationRequest(env, object, requestConfig);
231 g_locatorProxy->StartLocating(requestConfig, locatorCallback);
232 }
233
234 #ifdef ENABLE_NAPI_MANAGER
SubscribeLocationChangeV9(const napi_env & env,const napi_value & object,const napi_ref & handlerRef,sptr<LocatorCallbackNapi> & locatorCallbackHost)235 LocationErrCode SubscribeLocationChangeV9(const napi_env& env, const napi_value& object,
236 const napi_ref& handlerRef, sptr<LocatorCallbackNapi>& locatorCallbackHost)
237 {
238 LocationErrCode errorCode = CheckLocationSwitchEnable();
239 if (errorCode != ERRCODE_SUCCESS) {
240 return errorCode;
241 }
242 auto locatorCallback = sptr<ILocatorCallback>(locatorCallbackHost);
243 locatorCallbackHost->SetFixNumber(0);
244 locatorCallbackHost->SetEnv(env);
245 locatorCallbackHost->SetHandleCb(handlerRef);
246 auto requestConfig = std::make_unique<RequestConfig>();
247 JsObjToLocationRequest(env, object, requestConfig);
248 if (!IsRequestConfigValid(requestConfig)) {
249 return ERRCODE_INVALID_PARAM;
250 }
251 return g_locatorProxy->StartLocatingV9(requestConfig, locatorCallback);
252 }
253 #endif
254
SubscribeCountryCodeChange(const napi_env & env,const napi_ref & handlerRef,sptr<CountryCodeCallbackNapi> & callbackHost)255 void SubscribeCountryCodeChange(const napi_env& env,
256 const napi_ref& handlerRef, sptr<CountryCodeCallbackNapi>& callbackHost)
257 {
258 auto callbackPtr = sptr<ICountryCodeCallback>(callbackHost);
259 callbackHost->SetEnv(env);
260 callbackHost->SetCallback(handlerRef);
261 g_locatorProxy->RegisterCountryCodeCallback(callbackPtr->AsObject(), DEFAULT_UID);
262 }
263
264 #ifdef ENABLE_NAPI_MANAGER
SubscribeCountryCodeChangeV9(const napi_env & env,const napi_ref & handlerRef,sptr<CountryCodeCallbackNapi> & callbackHost)265 LocationErrCode SubscribeCountryCodeChangeV9(const napi_env& env,
266 const napi_ref& handlerRef, sptr<CountryCodeCallbackNapi>& callbackHost)
267 {
268 auto callbackPtr = sptr<ICountryCodeCallback>(callbackHost);
269 callbackHost->SetEnv(env);
270 callbackHost->SetCallback(handlerRef);
271 return g_locatorProxy->RegisterCountryCodeCallbackV9(callbackPtr->AsObject());
272 }
273 #endif
274
275 #ifdef ENABLE_NAPI_MANAGER
SubscribeLocatingRequiredDataChange(const napi_env & env,const napi_value & object,const napi_ref & handlerRef,sptr<LocatingRequiredDataCallbackNapi> & locatingCallbackHost)276 LocationErrCode SubscribeLocatingRequiredDataChange(const napi_env& env, const napi_value& object,
277 const napi_ref& handlerRef, sptr<LocatingRequiredDataCallbackNapi>& locatingCallbackHost)
278 {
279 auto callbackPtr = sptr<ILocatingRequiredDataCallback>(locatingCallbackHost);
280 locatingCallbackHost->SetEnv(env);
281 locatingCallbackHost->SetHandleCb(handlerRef);
282 std::unique_ptr<LocatingRequiredDataConfig> dataConfig = std::make_unique<LocatingRequiredDataConfig>();
283 JsObjToLocatingRequiredDataConfig(env, object, dataConfig);
284 return g_locatorProxy->RegisterLocatingRequiredDataCallback(dataConfig, callbackPtr);
285 }
286
SubscribeLocationError(const napi_env & env,const napi_ref & handlerRef,sptr<LocationErrorCallbackNapi> & locationErrorCallbackHost)287 LocationErrCode SubscribeLocationError(const napi_env& env,
288 const napi_ref& handlerRef, sptr<LocationErrorCallbackNapi>& locationErrorCallbackHost)
289 {
290 locationErrorCallbackHost->SetEnv(env);
291 locationErrorCallbackHost->SetHandleCb(handlerRef);
292 auto locationErrorCallback = sptr<ILocatorCallback>(locationErrorCallbackHost);
293 return g_locatorProxy->SubscribeLocationError(locationErrorCallback);
294 }
295 #endif
296
UnsubscribeCountryCodeChange(sptr<CountryCodeCallbackNapi> & callbackHost)297 void UnsubscribeCountryCodeChange(sptr<CountryCodeCallbackNapi>& callbackHost)
298 {
299 LBSLOGD(LOCATION_NAPI, "UnsubscribeCountryCodeChange");
300 g_locatorProxy->UnregisterCountryCodeCallback(callbackHost->AsObject());
301 }
302
303 #ifdef ENABLE_NAPI_MANAGER
UnsubscribeCountryCodeChangeV9(sptr<CountryCodeCallbackNapi> & callbackHost)304 LocationErrCode UnsubscribeCountryCodeChangeV9(sptr<CountryCodeCallbackNapi>& callbackHost)
305 {
306 LBSLOGD(LOCATION_NAPI, "UnsubscribeCountryCodeChangeV9");
307 return g_locatorProxy->UnregisterCountryCodeCallbackV9(callbackHost->AsObject());
308 }
309 #endif
310
SubscribeCacheLocationChange(const napi_env & env,const napi_value & object,const napi_ref & handlerRef,sptr<CachedLocationsCallbackNapi> & cachedCallbackHost)311 void SubscribeCacheLocationChange(const napi_env& env, const napi_value& object,
312 const napi_ref& handlerRef, sptr<CachedLocationsCallbackNapi>& cachedCallbackHost)
313 {
314 auto cachedCallback = sptr<ICachedLocationsCallback>(cachedCallbackHost);
315 cachedCallbackHost->SetEnv(env);
316 cachedCallbackHost->SetHandleCb(handlerRef);
317 JsObjToCachedLocationRequest(env, object, g_cachedRequest);
318 g_locatorProxy->RegisterCachedLocationCallback(g_cachedRequest, cachedCallback);
319 }
320
321 #ifdef ENABLE_NAPI_MANAGER
SubscribeCacheLocationChangeV9(const napi_env & env,const napi_value & object,const napi_ref & handlerRef,sptr<CachedLocationsCallbackNapi> & cachedCallbackHost)322 LocationErrCode SubscribeCacheLocationChangeV9(const napi_env& env, const napi_value& object,
323 const napi_ref& handlerRef, sptr<CachedLocationsCallbackNapi>& cachedCallbackHost)
324 {
325 LocationErrCode errorCode = CheckLocationSwitchEnable();
326 if (errorCode != ERRCODE_SUCCESS) {
327 return errorCode;
328 }
329 auto cachedCallback = sptr<ICachedLocationsCallback>(cachedCallbackHost);
330 cachedCallbackHost->SetEnv(env);
331 cachedCallbackHost->SetHandleCb(handlerRef);
332 JsObjToCachedLocationRequest(env, object, g_cachedRequest);
333 g_locatorProxy->RegisterCachedLocationCallbackV9(g_cachedRequest, cachedCallback);
334 return ERRCODE_NOT_SUPPORTED;
335 }
336 #endif
337
SubscribeFenceStatusChange(const napi_env & env,const napi_value & object,const napi_value & handler)338 void SubscribeFenceStatusChange(const napi_env& env, const napi_value& object, const napi_value& handler)
339 {
340 AbilityRuntime::WantAgent::WantAgent *wantAgent = nullptr;
341 napi_unwrap(env, handler, (void **)&wantAgent);
342 if (wantAgent == nullptr) {
343 LBSLOGE(LOCATION_NAPI, "wantAgent is nullptr");
344 return;
345 }
346 std::shared_ptr<GeofenceRequest> fenceRequest = std::make_shared<GeofenceRequest>();
347 fenceRequest->SetWantAgent(*wantAgent);
348 JsObjToGeoFenceRequest(env, object, fenceRequest);
349 g_geofenceProxy->AddFenceV9(fenceRequest);
350 }
351
352 #ifdef ENABLE_NAPI_MANAGER
SubscribeFenceStatusChangeV9(const napi_env & env,const napi_value & object,const napi_value & handler)353 LocationErrCode SubscribeFenceStatusChangeV9(const napi_env& env, const napi_value& object, const napi_value& handler)
354 {
355 LocationErrCode errorCode = CheckLocationSwitchEnable();
356 if (errorCode != ERRCODE_SUCCESS) {
357 return errorCode;
358 }
359 AbilityRuntime::WantAgent::WantAgent *wantAgent = nullptr;
360 napi_unwrap(env, handler, (void **)&wantAgent);
361 if (wantAgent == nullptr) {
362 LBSLOGE(LOCATION_NAPI, "wantAgent is nullptr");
363 return ERRCODE_INVALID_PARAM;
364 }
365 std::shared_ptr<GeofenceRequest> fenceRequest = std::make_shared<GeofenceRequest>();
366 fenceRequest->SetWantAgent(*wantAgent);
367 JsObjToGeoFenceRequest(env, object, fenceRequest);
368 LocationErrCode errCode = g_geofenceProxy->AddFenceV9(fenceRequest);
369 return errCode;
370 }
371 #endif
372
UnSubscribeFenceStatusChange(const napi_env & env,const napi_value & object,const napi_value & handler)373 void UnSubscribeFenceStatusChange(const napi_env& env, const napi_value& object, const napi_value& handler)
374 {
375 AbilityRuntime::WantAgent::WantAgent *wantAgent = nullptr;
376 napi_unwrap(env, handler, (void **)&wantAgent);
377 if (wantAgent == nullptr) {
378 LBSLOGE(LOCATION_NAPI, "wantAgent is nullptr");
379 return;
380 }
381 std::shared_ptr<GeofenceRequest> fenceRequest = std::make_shared<GeofenceRequest>();
382 fenceRequest->SetWantAgent(*wantAgent);
383 JsObjToGeoFenceRequest(env, object, fenceRequest);
384 g_geofenceProxy->RemoveFenceV9(fenceRequest);
385 }
386
387 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeFenceStatusChangeV9(const napi_env & env,const napi_value & object,const napi_value & handler)388 LocationErrCode UnSubscribeFenceStatusChangeV9(const napi_env& env, const napi_value& object, const napi_value& handler)
389 {
390 AbilityRuntime::WantAgent::WantAgent *wantAgent = nullptr;
391 napi_unwrap(env, handler, (void **)&wantAgent);
392 if (wantAgent == nullptr) {
393 LBSLOGE(LOCATION_NAPI, "wantAgent is nullptr");
394 return ERRCODE_INVALID_PARAM;
395 }
396 std::shared_ptr<GeofenceRequest> fenceRequest = std::make_shared<GeofenceRequest>();
397 fenceRequest->SetWantAgent(*wantAgent);
398 JsObjToGeoFenceRequest(env, object, fenceRequest);
399 return g_geofenceProxy->RemoveFenceV9(fenceRequest);
400 }
401 #endif
402
403 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeLocatingRequiredDataChange(sptr<LocatingRequiredDataCallbackNapi> & callbackHost)404 LocationErrCode UnSubscribeLocatingRequiredDataChange(sptr<LocatingRequiredDataCallbackNapi>& callbackHost)
405 {
406 LBSLOGD(LOCATION_NAPI, "%{public}s start", __func__);
407 auto callbackPtr = sptr<ILocatingRequiredDataCallback>(callbackHost);
408 return g_locatorProxy->UnRegisterLocatingRequiredDataCallback(callbackPtr);
409 }
410 #endif
411
GenerateExecuteContext(SingleLocationAsyncContext * context)412 void GenerateExecuteContext(SingleLocationAsyncContext* context)
413 {
414 if (context == nullptr) {
415 return;
416 }
417 auto callbackHost = context->callbackHost_;
418 if (g_locatorProxy->IsLocationEnabled() && callbackHost != nullptr) {
419 auto callbackPtr = sptr<ILocatorCallback>(callbackHost);
420 #ifdef ENABLE_NAPI_MANAGER
421 LocationErrCode errorCode = g_locatorProxy->StartLocatingV9(context->request_, callbackPtr);
422 context->errCode = errorCode;
423 if (errorCode != ERRCODE_SUCCESS) {
424 callbackHost->SetCount(0);
425 }
426 #else
427 g_locatorProxy->StartLocating(context->request_, callbackPtr);
428 #endif
429 if (context->timeout_ > DEFAULT_TIMEOUT_30S) {
430 callbackHost->Wait(DEFAULT_TIMEOUT_30S);
431 if (callbackHost->GetSingleLocation() == nullptr) {
432 callbackHost->Wait(context->timeout_ - DEFAULT_TIMEOUT_30S);
433 }
434 } else {
435 callbackHost->Wait(context->timeout_);
436 }
437 g_locatorProxy->StopLocating(callbackPtr);
438 if (callbackHost->GetCount() != 0 && callbackHost->GetSingleLocation() == nullptr) {
439 std::unique_ptr<Location> location = nullptr;
440 #ifdef ENABLE_NAPI_MANAGER
441 g_locatorProxy->GetCachedLocationV9(location);
442 #else
443 location = g_locatorProxy->GetCachedLocation();
444 #endif
445 int64_t curTime = CommonUtils::GetCurrentTimeStamp();
446 if (location != nullptr &&
447 (curTime - location->GetTimeStamp() / MILLI_PER_SEC) <= LASTLOCATION_CACHED_TIME) {
448 callbackHost->SetSingleLocation(location);
449 } else {
450 context->errCode = ERRCODE_LOCATING_FAIL;
451 }
452 }
453 callbackHost->SetCount(1);
454 #ifndef ENABLE_NAPI_MANAGER
455 } else {
456 context->errCode = LOCATION_SWITCH_ERROR;
457 #endif
458 }
459 }
460
GenerateCompleteContext(SingleLocationAsyncContext * context)461 void GenerateCompleteContext(SingleLocationAsyncContext* context)
462 {
463 if (context == nullptr) {
464 return;
465 }
466 NAPI_CALL_RETURN_VOID(context->env, napi_create_object(context->env, &context->result[PARAM1]));
467 auto callbackHost = context->callbackHost_;
468 if (callbackHost != nullptr && callbackHost->GetSingleLocation() != nullptr) {
469 std::unique_ptr<Location> location = std::make_unique<Location>(*callbackHost->GetSingleLocation());
470 LocationToJs(context->env, location, context->result[PARAM1]);
471 } else {
472 LBSLOGE(LOCATOR_STANDARD, "m_singleLocation is nullptr!");
473 }
474 if (context->callbackHost_) {
475 context->callbackHost_ = nullptr;
476 }
477 }
478
CreateSingleLocationAsyncContext(const napi_env & env,std::unique_ptr<RequestConfig> & config,sptr<LocatorCallbackNapi> callback)479 SingleLocationAsyncContext* CreateSingleLocationAsyncContext(const napi_env& env,
480 std::unique_ptr<RequestConfig>& config, sptr<LocatorCallbackNapi> callback)
481 {
482 auto asyncContext = new (std::nothrow) SingleLocationAsyncContext(env);
483 NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
484 NAPI_CALL(env, napi_create_string_latin1(env, "GetCurrentLocation",
485 NAPI_AUTO_LENGTH, &asyncContext->resourceName));
486 asyncContext->timeout_ = config->GetTimeOut();
487 asyncContext->callbackHost_ = callback;
488 asyncContext->request_ = std::move(config);
489 asyncContext->executeFunc = [&](void* data) -> void {
490 if (data == nullptr) {
491 LBSLOGE(LOCATOR_STANDARD, "data is nullptr!");
492 return;
493 }
494 auto context = static_cast<SingleLocationAsyncContext*>(data);
495 GenerateExecuteContext(context);
496 };
497 asyncContext->completeFunc = [&](void* data) -> void {
498 if (data == nullptr) {
499 LBSLOGE(LOCATOR_STANDARD, "data is nullptr!");
500 return;
501 }
502 auto context = static_cast<SingleLocationAsyncContext*>(data);
503 GenerateCompleteContext(context);
504 LBSLOGD(LOCATOR_STANDARD, "Push single location to client");
505 };
506 return asyncContext;
507 }
508
GetObjectArgsNum(const napi_env & env,const size_t argc,const napi_value * argv)509 int GetObjectArgsNum(const napi_env& env, const size_t argc, const napi_value* argv)
510 {
511 napi_valuetype valueType = napi_undefined;
512 int objectArgsNum = PARAM0;
513 if (argc == PARAM0) {
514 objectArgsNum = PARAM0;
515 } else if (argc == PARAM1) {
516 NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM0], &valueType), objectArgsNum);
517 if (valueType == napi_object) {
518 objectArgsNum = PARAM1;
519 } else if (valueType == napi_function) {
520 objectArgsNum = PARAM0;
521 }
522 } else if (argc == PARAM2) {
523 objectArgsNum = PARAM1;
524 } else {
525 LBSLOGD(LOCATION_NAPI, "argc of GetCurrentLocation is wrong.");
526 }
527 return objectArgsNum;
528 }
529
CreateRequestConfig(const napi_env & env,const napi_value * argv,const size_t & objectArgsNum)530 std::unique_ptr<RequestConfig> CreateRequestConfig(const napi_env& env,
531 const napi_value* argv, const size_t& objectArgsNum)
532 {
533 auto requestConfig = std::make_unique<RequestConfig>();
534 if (objectArgsNum > 0) {
535 JsObjToCurrentLocationRequest(env, argv[objectArgsNum - 1], requestConfig);
536 } else {
537 requestConfig->SetPriority(PRIORITY_FAST_FIRST_FIX);
538 }
539 requestConfig->SetFixNumber(1);
540 return requestConfig;
541 }
542
CreateSingleLocationCallbackHost()543 sptr<LocatorCallbackNapi> CreateSingleLocationCallbackHost()
544 {
545 auto callbackHost =
546 sptr<LocatorCallbackNapi>(new (std::nothrow) LocatorCallbackNapi());
547 if (callbackHost) {
548 callbackHost->SetFixNumber(1);
549 }
550 return callbackHost;
551 }
552
RequestLocationOnce(const napi_env & env,const size_t argc,const napi_value * argv)553 napi_value RequestLocationOnce(const napi_env& env, const size_t argc, const napi_value* argv)
554 {
555 size_t objectArgsNum = 0;
556
557 objectArgsNum = static_cast<size_t>(GetObjectArgsNum(env, argc, argv));
558 auto requestConfig = CreateRequestConfig(env, argv, objectArgsNum);
559 NAPI_ASSERT(env, requestConfig != nullptr, "requestConfig is null.");
560 auto singleLocatorCallbackHost = CreateSingleLocationCallbackHost();
561 NAPI_ASSERT(env, singleLocatorCallbackHost != nullptr, "callbackHost is null.");
562
563 auto asyncContext = CreateSingleLocationAsyncContext(env, requestConfig, singleLocatorCallbackHost);
564 NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
565 return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
566 }
567
568 #ifdef ENABLE_NAPI_MANAGER
RequestLocationOnceV9(const napi_env & env,const size_t argc,const napi_value * argv)569 napi_value RequestLocationOnceV9(const napi_env& env, const size_t argc, const napi_value* argv)
570 {
571 size_t objectArgsNum = 0;
572 objectArgsNum = static_cast<size_t>(GetObjectArgsNum(env, argc, argv));
573 auto requestConfig = CreateRequestConfig(env, argv, objectArgsNum);
574 if (!IsRequestConfigValid(requestConfig)) {
575 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
576 return UndefinedNapiValue(env);
577 }
578 auto singleLocatorCallbackHost = CreateSingleLocationCallbackHost();
579 if (singleLocatorCallbackHost == nullptr) {
580 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
581 return UndefinedNapiValue(env);
582 }
583 singleLocatorCallbackHost->SetLocationPriority(GetCurrentLocationType(requestConfig));
584 LocationErrCode errorCode = CheckLocationSwitchEnable();
585 if (errorCode != ERRCODE_SUCCESS) {
586 HandleSyncErrCode(env, errorCode);
587 return UndefinedNapiValue(env);
588 }
589
590 auto asyncContext = CreateSingleLocationAsyncContext(env, requestConfig, singleLocatorCallbackHost);
591 if (asyncContext == nullptr) {
592 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
593 return UndefinedNapiValue(env);
594 }
595 return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
596 }
597 #endif
598
UnSubscribeLocationChange(sptr<ILocatorCallback> & callback)599 void UnSubscribeLocationChange(sptr<ILocatorCallback>& callback)
600 {
601 LBSLOGD(LOCATION_NAPI, "UnSubscribeLocationChange");
602 g_locatorProxy->StopLocating(callback);
603 }
604
605 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeLocationChangeV9(sptr<ILocatorCallback> & callback)606 LocationErrCode UnSubscribeLocationChangeV9(sptr<ILocatorCallback>& callback)
607 {
608 LBSLOGD(LOCATION_NAPI, "UnSubscribeLocationChangeV9");
609 return g_locatorProxy->StopLocatingV9(callback);
610 }
611 #endif
612
UnSubscribeCacheLocationChange(sptr<ICachedLocationsCallback> & callback)613 void UnSubscribeCacheLocationChange(sptr<ICachedLocationsCallback>& callback)
614 {
615 LBSLOGD(LOCATION_NAPI, "UnSubscribeCacheLocationChange");
616 g_locatorProxy->UnregisterCachedLocationCallback(callback);
617 }
618
619 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeCacheLocationChangeV9(sptr<ICachedLocationsCallback> & callback)620 LocationErrCode UnSubscribeCacheLocationChangeV9(sptr<ICachedLocationsCallback>& callback)
621 {
622 LBSLOGD(LOCATION_NAPI, "UnSubscribeCacheLocationChangeV9");
623 g_locatorProxy->UnregisterCachedLocationCallbackV9(callback);
624 return ERRCODE_NOT_SUPPORTED;
625 }
626
UnSubscribeLocationError(sptr<ILocatorCallback> & callback)627 LocationErrCode UnSubscribeLocationError(sptr<ILocatorCallback>& callback)
628 {
629 LBSLOGD(LOCATION_NAPI, "UnSubscribeLocationError");
630 return g_locatorProxy->UnSubscribeLocationError(callback);
631 }
632 #endif
633
IsCallbackEquals(const napi_env & env,const napi_value & handler,const napi_ref & savedCallback)634 bool IsCallbackEquals(const napi_env& env, const napi_value& handler, const napi_ref& savedCallback)
635 {
636 napi_value handlerTemp = nullptr;
637 if (savedCallback == nullptr || handler == nullptr) {
638 return false;
639 }
640 NAPI_CALL_BASE(env, napi_get_reference_value(env, savedCallback, &handlerTemp), false);
641 bool isEqual = false;
642 NAPI_CALL_BASE(env, napi_strict_equals(env, handlerTemp, handler, &isEqual), false);
643 return isEqual;
644 }
645
OnLocationServiceStateCallback(const napi_env & env,const size_t argc,const napi_value * argv)646 bool OnLocationServiceStateCallback(const napi_env& env, const size_t argc, const napi_value* argv)
647 {
648 #ifdef ENABLE_NAPI_MANAGER
649 if (argc != PARAM2) {
650 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
651 return false;
652 }
653 if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
654 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
655 return false;
656 }
657 #else
658 NAPI_ASSERT_BASE(env, argc == PARAM2, "number of parameters is wrong", INPUT_PARAMS_ERROR);
659 NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
660 "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
661 #endif
662 if (g_switchCallbacks.IsCallbackInMap(env, argv[PARAM1])) {
663 LBSLOGE(LOCATION_NAPI, "This request already exists");
664 return false;
665 }
666 auto switchCallbackHost =
667 sptr<LocationSwitchCallbackNapi>(new (std::nothrow) LocationSwitchCallbackNapi());
668 if (switchCallbackHost != nullptr) {
669 napi_ref handlerRef = nullptr;
670 NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], 1, &handlerRef), false);
671 #ifdef ENABLE_NAPI_MANAGER
672 LocationErrCode errorCode = SubscribeLocationServiceStateV9(env, handlerRef, switchCallbackHost);
673 if (errorCode != ERRCODE_SUCCESS) {
674 HandleSyncErrCode(env, errorCode);
675 return false;
676 }
677 #else
678 SubscribeLocationServiceState(env, handlerRef, switchCallbackHost);
679 #endif
680 g_switchCallbacks.AddCallback(env, handlerRef, switchCallbackHost);
681 }
682 return true;
683 }
684
OnCachedGnssLocationsReportingCallback(const napi_env & env,const size_t argc,const napi_value * argv)685 bool OnCachedGnssLocationsReportingCallback(const napi_env& env, const size_t argc, const napi_value* argv)
686 {
687 #ifdef ENABLE_NAPI_MANAGER
688 if (argc != PARAM3) {
689 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
690 return false;
691 }
692 napi_valuetype valueType;
693 NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM1], &valueType), false);
694 if (valueType != napi_object || !CheckIfParamIsFunctionType(env, argv[PARAM2])) {
695 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
696 return UndefinedNapiValue(env);
697 }
698 #else
699 NAPI_ASSERT_BASE(env, argc == PARAM3, "number of parameters is wrong", INPUT_PARAMS_ERROR);
700 NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM2]),
701 "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
702 #endif
703 #ifndef ENABLE_NAPI_MANAGER
704 if (!g_locatorProxy->IsLocationEnabled()) {
705 LBSLOGE(LOCATION_NAPI, "location switch is off, just return.");
706 return false;
707 }
708 #endif
709 // the third params should be handler
710 if (g_cachedLocationCallbacks.IsCallbackInMap(env, argv[PARAM2])) {
711 LBSLOGE(LOCATION_NAPI, "This request already exists");
712 return false;
713 }
714 auto cachedCallbackHost =
715 sptr<CachedLocationsCallbackNapi>(new (std::nothrow) CachedLocationsCallbackNapi());
716 if (cachedCallbackHost != nullptr) {
717 napi_ref handlerRef = nullptr;
718 NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM2], PARAM1, &handlerRef), false);
719 #ifdef ENABLE_NAPI_MANAGER
720 LocationErrCode errorCode = SubscribeCacheLocationChangeV9(env, argv[PARAM1], handlerRef, cachedCallbackHost);
721 if (errorCode != ERRCODE_SUCCESS) {
722 HandleSyncErrCode(env, errorCode);
723 return false;
724 }
725 #else
726 SubscribeCacheLocationChange(env, argv[PARAM1], handlerRef, cachedCallbackHost);
727 #endif
728 g_cachedLocationCallbacks.AddCallback(env, handlerRef, cachedCallbackHost);
729 }
730 return true;
731 }
732
OnGnssStatusChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)733 bool OnGnssStatusChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
734 {
735 #ifdef ENABLE_NAPI_MANAGER
736 if (argc != PARAM2) {
737 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
738 return false;
739 }
740 if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
741 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
742 return UndefinedNapiValue(env);
743 }
744 #else
745 NAPI_ASSERT_BASE(env, argc == PARAM2, "number of parameters is wrong", INPUT_PARAMS_ERROR);
746 NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
747 "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
748 #endif
749 if (g_gnssStatusInfoCallbacks.IsCallbackInMap(env, argv[PARAM1])) {
750 LBSLOGE(LOCATION_NAPI, "This request already exists");
751 return false;
752 }
753 auto gnssCallbackHost =
754 sptr<GnssStatusCallbackNapi>(new (std::nothrow) GnssStatusCallbackNapi());
755 if (gnssCallbackHost != nullptr) {
756 napi_ref handlerRef = nullptr;
757 NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], PARAM1, &handlerRef), false);
758 #ifdef ENABLE_NAPI_MANAGER
759 LocationErrCode errorCode = SubscribeGnssStatusV9(env, handlerRef, gnssCallbackHost);
760 if (errorCode != ERRCODE_SUCCESS) {
761 HandleSyncErrCode(env, errorCode);
762 return false;
763 }
764 #else
765 SubscribeGnssStatus(env, handlerRef, gnssCallbackHost);
766 #endif
767 g_gnssStatusInfoCallbacks.AddCallback(env, handlerRef, gnssCallbackHost);
768 }
769 return true;
770 }
771
OnLocationChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)772 bool OnLocationChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
773 {
774 #ifdef SUPPORT_JSSTACK
775 HiviewDFX::ReportXPowerJsStackSysEvent(env, "GNSS_STATE");
776 #endif
777 #ifdef ENABLE_NAPI_MANAGER
778 if (argc != PARAM3) {
779 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
780 return false;
781 }
782 napi_valuetype valueType;
783 NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM1], &valueType), false);
784 if (valueType != napi_object || !CheckIfParamIsFunctionType(env, argv[PARAM2])) {
785 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
786 return false;
787 }
788 #else
789 NAPI_ASSERT_BASE(env, argc == PARAM3, "number of parameters is wrong", INPUT_PARAMS_ERROR);
790 NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM2]),
791 "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
792 if (!g_locatorProxy->IsLocationEnabled()) {
793 LBSLOGE(LOCATION_NAPI, "location switch is off, just return.");
794 return false;
795 }
796 #endif
797 // the third params should be handler
798 if (g_locationCallbacks.IsCallbackInMap(env, argv[PARAM2])) {
799 LBSLOGE(LOCATION_NAPI, "This request already exists");
800 return false;
801 }
802 auto locatorCallbackHost =
803 sptr<LocatorCallbackNapi>(new (std::nothrow) LocatorCallbackNapi());
804 if (locatorCallbackHost != nullptr) {
805 napi_ref handlerRef = nullptr;
806 NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM2], 1, &handlerRef), false);
807 // argv[1]:request params, argv[2]:handler
808 #ifdef ENABLE_NAPI_MANAGER
809 LocationErrCode errorCode = SubscribeLocationChangeV9(env, argv[PARAM1], handlerRef, locatorCallbackHost);
810 if (errorCode != ERRCODE_SUCCESS) {
811 HandleSyncErrCode(env, errorCode);
812 return false;
813 }
814 #else
815 SubscribeLocationChange(env, argv[PARAM1], handlerRef, locatorCallbackHost);
816 #endif
817 g_locationCallbacks.AddCallback(env, handlerRef, locatorCallbackHost);
818 }
819 return true;
820 }
821
OnNmeaMessageChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)822 bool OnNmeaMessageChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
823 {
824 #ifdef ENABLE_NAPI_MANAGER
825 if (argc != PARAM2) {
826 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
827 return false;
828 }
829 if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
830 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
831 return false;
832 }
833 #else
834 NAPI_ASSERT_BASE(env, argc == PARAM2, "number of parameters is wrong", INPUT_PARAMS_ERROR);
835 NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
836 "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
837 #endif
838 if (g_nmeaCallbacks.IsCallbackInMap(env, argv[PARAM1])) {
839 LBSLOGE(LOCATION_NAPI, "This request already exists");
840 return false;
841 }
842 auto nmeaCallbackHost =
843 sptr<NmeaMessageCallbackNapi>(new (std::nothrow) NmeaMessageCallbackNapi());
844 if (nmeaCallbackHost != nullptr) {
845 napi_ref handlerRef = nullptr;
846 NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], PARAM1, &handlerRef), false);
847 #ifdef ENABLE_NAPI_MANAGER
848 LocationErrCode errorCode = SubscribeNmeaMessageV9(env, handlerRef, nmeaCallbackHost);
849 if (errorCode != ERRCODE_SUCCESS) {
850 HandleSyncErrCode(env, errorCode);
851 return false;
852 }
853 #else
854 SubscribeNmeaMessage(env, handlerRef, nmeaCallbackHost);
855 #endif
856 g_nmeaCallbacks.AddCallback(env, handlerRef, nmeaCallbackHost);
857 }
858 return true;
859 }
860
OnCountryCodeChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)861 bool OnCountryCodeChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
862 {
863 #ifdef ENABLE_NAPI_MANAGER
864 if (argc != PARAM2) {
865 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
866 return false;
867 }
868 if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
869 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
870 return false;
871 }
872 #else
873 NAPI_ASSERT_BASE(env, argc == PARAM2, "number of parameters is wrong", INPUT_PARAMS_ERROR);
874 NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
875 "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
876 #endif
877 if (g_countryCodeCallbacks.IsCallbackInMap(env, argv[PARAM1])) {
878 LBSLOGE(LOCATION_NAPI, "This request already exists");
879 return false;
880 }
881 auto callbackHost =
882 sptr<CountryCodeCallbackNapi>(new (std::nothrow) CountryCodeCallbackNapi());
883 if (callbackHost) {
884 napi_ref handlerRef = nullptr;
885 NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], 1, &handlerRef), false);
886 #ifdef ENABLE_NAPI_MANAGER
887 LocationErrCode errorCode = SubscribeCountryCodeChangeV9(env, handlerRef, callbackHost);
888 if (errorCode != ERRCODE_SUCCESS) {
889 HandleSyncErrCode(env, errorCode);
890 return false;
891 }
892 #else
893 SubscribeCountryCodeChange(env, handlerRef, callbackHost);
894 #endif
895 g_countryCodeCallbacks.AddCallback(env, handlerRef, callbackHost);
896 }
897 return true;
898 }
899
OnFenceStatusChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)900 bool OnFenceStatusChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
901 {
902 #ifdef ENABLE_NAPI_MANAGER
903 if (argc != PARAM3) {
904 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
905 return false;
906 }
907 #else
908 NAPI_ASSERT_BASE(env, argc == PARAM3, "number of parameters is wrong", INPUT_PARAMS_ERROR);
909 if (!g_locatorProxy->IsLocationEnabled()) {
910 LBSLOGE(LOCATION_NAPI, "location switch is off, just return.");
911 return false;
912 }
913 #endif
914 // the third params should be handler
915 #ifdef ENABLE_NAPI_MANAGER
916 LocationErrCode errorCode = SubscribeFenceStatusChangeV9(env, argv[PARAM1], argv[PARAM2]);
917 if (errorCode != ERRCODE_SUCCESS) {
918 HandleSyncErrCode(env, errorCode);
919 return false;
920 }
921 #else
922 SubscribeFenceStatusChange(env, argv[PARAM1], argv[PARAM2]);
923 #endif
924 return true;
925 }
926
927 #ifdef ENABLE_NAPI_MANAGER
OnLocatingRequiredDataChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)928 bool OnLocatingRequiredDataChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
929 {
930 if (argc != PARAM3) {
931 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
932 return false;
933 }
934 if (!CheckIfParamIsFunctionType(env, argv[PARAM2])) {
935 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
936 return false;
937 }
938 if (g_locatingRequiredDataCallbacks.IsCallbackInMap(env, argv[PARAM2])) {
939 LBSLOGE(LOCATION_NAPI, "%{public}s, This request already exists", __func__);
940 return false;
941 }
942 auto locatingCallbackHost =
943 sptr<LocatingRequiredDataCallbackNapi>(new (std::nothrow) LocatingRequiredDataCallbackNapi());
944 if (locatingCallbackHost != nullptr) {
945 napi_ref handlerRef = nullptr;
946 NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM2], 1, &handlerRef), false);
947
948 LocationErrCode errorCode =
949 SubscribeLocatingRequiredDataChange(env, argv[PARAM1], handlerRef, locatingCallbackHost);
950 if (errorCode != ERRCODE_SUCCESS) {
951 HandleSyncErrCode(env, errorCode);
952 return false;
953 }
954 g_locatingRequiredDataCallbacks.AddCallback(env, handlerRef, locatingCallbackHost);
955 }
956 return true;
957 }
958 #endif
959
On(napi_env env,napi_callback_info cbinfo)960 napi_value On(napi_env env, napi_callback_info cbinfo)
961 {
962 InitOnFuncMap();
963 size_t argc = MAXIMUM_JS_PARAMS;
964 napi_value argv[MAXIMUM_JS_PARAMS] = {0};
965 napi_value thisVar = nullptr;
966 LBSLOGD(LOCATION_NAPI, "On function entry");
967 NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
968 napi_valuetype eventName = napi_undefined;
969 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &eventName));
970 #ifdef ENABLE_NAPI_MANAGER
971 if (eventName != napi_string) {
972 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
973 return UndefinedNapiValue(env);
974 }
975 #else
976 NAPI_ASSERT(env, eventName == napi_string, "type mismatch for parameter 1");
977 #endif
978 NAPI_ASSERT(env, g_locatorProxy != nullptr, "locator instance is null.");
979
980 char type[64] = {0}; // max length
981 size_t typeLen = 0;
982 NAPI_CALL(env, napi_get_value_string_utf8(env, argv[PARAM0], type, sizeof(type), &typeLen));
983 std::string event = type;
984 LBSLOGD(LOCATION_NAPI, "Subscribe event: %{public}s", event.c_str());
985 std::unique_lock<std::mutex> lock(g_FuncMapMutex);
986 auto onCallbackFunc = g_onFuncMap.find(event);
987 if (onCallbackFunc != g_onFuncMap.end() && onCallbackFunc->second != nullptr) {
988 auto memberFunc = onCallbackFunc->second;
989 (*memberFunc)(env, argc, argv);
990 }
991 return UndefinedNapiValue(env);
992 }
993
OffAllLocationServiceStateCallback(const napi_env & env)994 bool OffAllLocationServiceStateCallback(const napi_env& env)
995 {
996 std::map<napi_env, std::map<napi_ref, sptr<LocationSwitchCallbackNapi>>> callbackMap =
997 g_switchCallbacks.GetCallbackMap();
998 auto iter = callbackMap.find(env);
999 if (iter == callbackMap.end()) {
1000 return false;
1001 }
1002 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1003 auto callbackHost = innerIter->second;
1004 if (callbackHost == nullptr) {
1005 continue;
1006 }
1007 #ifdef ENABLE_NAPI_MANAGER
1008 LocationErrCode errorCode = UnSubscribeLocationServiceStateV9(callbackHost);
1009 if (errorCode != ERRCODE_SUCCESS) {
1010 HandleSyncErrCode(env, errorCode);
1011 return false;
1012 }
1013 #else
1014 UnSubscribeLocationServiceState(callbackHost);
1015 #endif
1016 callbackHost->DeleteHandler();
1017 callbackHost = nullptr;
1018 }
1019 g_switchCallbacks.DeleteCallbackByEnv(env);
1020 return true;
1021 }
1022
OffAllLocationChangeCallback(const napi_env & env)1023 bool OffAllLocationChangeCallback(const napi_env& env)
1024 {
1025 std::map<napi_env, std::map<napi_ref, sptr<LocatorCallbackNapi>>> callbackMap =
1026 g_locationCallbacks.GetCallbackMap();
1027 auto iter = callbackMap.find(env);
1028 if (iter == callbackMap.end()) {
1029 return false;
1030 }
1031 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1032 auto callbackHost = innerIter->second;
1033 if (callbackHost == nullptr) {
1034 continue;
1035 }
1036 auto locatorCallback = sptr<ILocatorCallback>(callbackHost);
1037 #ifdef ENABLE_NAPI_MANAGER
1038 LocationErrCode errorCode = UnSubscribeLocationChangeV9(locatorCallback);
1039 if (errorCode != ERRCODE_SUCCESS) {
1040 HandleSyncErrCode(env, errorCode);
1041 return false;
1042 }
1043 #else
1044 UnSubscribeLocationChange(locatorCallback);
1045 #endif
1046 callbackHost->DeleteAllCallbacks();
1047 callbackHost = nullptr;
1048 }
1049 g_locationCallbacks.DeleteCallbackByEnv(env);
1050 return true;
1051 }
1052
OffAllGnssStatusChangeCallback(const napi_env & env)1053 bool OffAllGnssStatusChangeCallback(const napi_env& env)
1054 {
1055 std::map<napi_env, std::map<napi_ref, sptr<GnssStatusCallbackNapi>>> callbackMap =
1056 g_gnssStatusInfoCallbacks.GetCallbackMap();
1057 auto iter = callbackMap.find(env);
1058 if (iter == callbackMap.end()) {
1059 return false;
1060 }
1061 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1062 auto callbackHost = innerIter->second;
1063 if (callbackHost == nullptr) {
1064 continue;
1065 }
1066 #ifdef ENABLE_NAPI_MANAGER
1067 LocationErrCode errorCode = UnSubscribeGnssStatusV9(callbackHost);
1068 if (errorCode != ERRCODE_SUCCESS) {
1069 HandleSyncErrCode(env, errorCode);
1070 return false;
1071 }
1072 #else
1073 UnSubscribeGnssStatus(callbackHost);
1074 #endif
1075 callbackHost->DeleteHandler();
1076 callbackHost = nullptr;
1077 }
1078 g_gnssStatusInfoCallbacks.DeleteCallbackByEnv(env);
1079 return true;
1080 }
1081
OffAllNmeaMessageChangeCallback(const napi_env & env)1082 bool OffAllNmeaMessageChangeCallback(const napi_env& env)
1083 {
1084 std::map<napi_env, std::map<napi_ref, sptr<NmeaMessageCallbackNapi>>> callbackMap =
1085 g_nmeaCallbacks.GetCallbackMap();
1086 auto iter = callbackMap.find(env);
1087 if (iter == callbackMap.end()) {
1088 return false;
1089 }
1090 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1091 auto callbackHost = innerIter->second;
1092 if (callbackHost == nullptr) {
1093 continue;
1094 }
1095 #ifdef ENABLE_NAPI_MANAGER
1096 LocationErrCode errorCode = UnSubscribeNmeaMessageV9(callbackHost);
1097 if (errorCode != ERRCODE_SUCCESS) {
1098 HandleSyncErrCode(env, errorCode);
1099 return false;
1100 }
1101 #else
1102 UnSubscribeNmeaMessage(callbackHost);
1103 #endif
1104 callbackHost->DeleteHandler();
1105 callbackHost = nullptr;
1106 }
1107 g_nmeaCallbacks.DeleteCallbackByEnv(env);
1108 return true;
1109 }
1110
OffAllCachedGnssLocationsReportingCallback(const napi_env & env)1111 bool OffAllCachedGnssLocationsReportingCallback(const napi_env& env)
1112 {
1113 std::map<napi_env, std::map<napi_ref, sptr<CachedLocationsCallbackNapi>>> callbackMap =
1114 g_cachedLocationCallbacks.GetCallbackMap();
1115 auto iter = callbackMap.find(env);
1116 if (iter == callbackMap.end()) {
1117 #ifdef ENABLE_NAPI_MANAGER
1118 HandleSyncErrCode(env, ERRCODE_NOT_SUPPORTED);
1119 #endif
1120 return false;
1121 }
1122 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1123 auto callbackHost = innerIter->second;
1124 if (callbackHost == nullptr) {
1125 continue;
1126 }
1127 auto cachedCallback = sptr<ICachedLocationsCallback>(callbackHost);
1128 #ifdef ENABLE_NAPI_MANAGER
1129 LocationErrCode errorCode = UnSubscribeCacheLocationChangeV9(cachedCallback);
1130 if (errorCode != ERRCODE_SUCCESS) {
1131 HandleSyncErrCode(env, errorCode);
1132 return false;
1133 }
1134 #else
1135 UnSubscribeCacheLocationChange(cachedCallback);
1136 #endif
1137 callbackHost->DeleteHandler();
1138 callbackHost = nullptr;
1139 }
1140 g_cachedLocationCallbacks.DeleteCallbackByEnv(env);
1141 return true;
1142 }
1143
OffAllCountryCodeChangeCallback(const napi_env & env)1144 bool OffAllCountryCodeChangeCallback(const napi_env& env)
1145 {
1146 std::map<napi_env, std::map<napi_ref, sptr<CountryCodeCallbackNapi>>> callbackMap =
1147 g_countryCodeCallbacks.GetCallbackMap();
1148 auto iter = callbackMap.find(env);
1149 if (iter == callbackMap.end()) {
1150 return false;
1151 }
1152 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1153 auto callbackHost = innerIter->second;
1154 if (callbackHost == nullptr) {
1155 continue;
1156 }
1157 #ifdef ENABLE_NAPI_MANAGER
1158 LocationErrCode errorCode = UnsubscribeCountryCodeChangeV9(callbackHost);
1159 if (errorCode != ERRCODE_SUCCESS) {
1160 HandleSyncErrCode(env, errorCode);
1161 return false;
1162 }
1163 #else
1164 UnsubscribeCountryCodeChange(callbackHost);
1165 #endif
1166 callbackHost->DeleteHandler();
1167 callbackHost = nullptr;
1168 }
1169 g_countryCodeCallbacks.DeleteCallbackByEnv(env);
1170 return true;
1171 }
1172
1173 #ifdef ENABLE_NAPI_MANAGER
OffAllLocatingRequiredDataChangeCallback(const napi_env & env)1174 bool OffAllLocatingRequiredDataChangeCallback(const napi_env& env)
1175 {
1176 std::map<napi_env, std::map<napi_ref, sptr<LocatingRequiredDataCallbackNapi>>> callbackMap =
1177 g_locatingRequiredDataCallbacks.GetCallbackMap();
1178 auto iter = callbackMap.find(env);
1179 if (iter == callbackMap.end()) {
1180 return false;
1181 }
1182 for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1183 auto callbackHost = innerIter->second;
1184 if (callbackHost == nullptr) {
1185 continue;
1186 }
1187 LocationErrCode errorCode = UnSubscribeLocatingRequiredDataChange(callbackHost);
1188 if (errorCode != ERRCODE_SUCCESS) {
1189 HandleSyncErrCode(env, errorCode);
1190 return false;
1191 }
1192 callbackHost->DeleteHandler();
1193 callbackHost = nullptr;
1194 }
1195 g_locatingRequiredDataCallbacks.DeleteCallbackByEnv(env);
1196 return true;
1197 }
1198 #endif
1199
OffLocationServiceStateCallback(const napi_env & env,const napi_value & handler)1200 bool OffLocationServiceStateCallback(const napi_env& env, const napi_value& handler)
1201 {
1202 auto switchCallbackHost = g_switchCallbacks.GetCallbackPtr(env, handler);
1203 if (switchCallbackHost) {
1204 #ifdef ENABLE_NAPI_MANAGER
1205 LocationErrCode errorCode = UnSubscribeLocationServiceStateV9(switchCallbackHost);
1206 if (errorCode != ERRCODE_SUCCESS) {
1207 HandleSyncErrCode(env, errorCode);
1208 return false;
1209 }
1210 #else
1211 UnSubscribeLocationServiceState(switchCallbackHost);
1212 #endif
1213 g_switchCallbacks.DeleteCallback(env, handler);
1214 switchCallbackHost->DeleteHandler();
1215 switchCallbackHost = nullptr;
1216 return true;
1217 }
1218 return false;
1219 }
1220
OffLocationChangeCallback(const napi_env & env,const napi_value & handler)1221 bool OffLocationChangeCallback(const napi_env& env, const napi_value& handler)
1222 {
1223 auto locatorCallbackHost = g_locationCallbacks.GetCallbackPtr(env, handler);
1224 if (locatorCallbackHost) {
1225 auto locatorCallback = sptr<ILocatorCallback>(locatorCallbackHost);
1226 #ifdef ENABLE_NAPI_MANAGER
1227 LocationErrCode errorCode = UnSubscribeLocationChangeV9(locatorCallback);
1228 if (errorCode != ERRCODE_SUCCESS) {
1229 HandleSyncErrCode(env, errorCode);
1230 return false;
1231 }
1232 #else
1233 UnSubscribeLocationChange(locatorCallback);
1234 #endif
1235 g_locationCallbacks.DeleteCallback(env, handler);
1236 locatorCallbackHost->DeleteAllCallbacks();
1237 locatorCallbackHost = nullptr;
1238 return true;
1239 }
1240 return false;
1241 }
1242
OffGnssStatusChangeCallback(const napi_env & env,const napi_value & handler)1243 bool OffGnssStatusChangeCallback(const napi_env& env, const napi_value& handler)
1244 {
1245 auto gnssCallbackHost = g_gnssStatusInfoCallbacks.GetCallbackPtr(env, handler);
1246 if (gnssCallbackHost) {
1247 #ifdef ENABLE_NAPI_MANAGER
1248 LocationErrCode errorCode = UnSubscribeGnssStatusV9(gnssCallbackHost);
1249 if (errorCode != ERRCODE_SUCCESS) {
1250 HandleSyncErrCode(env, errorCode);
1251 return false;
1252 }
1253 #else
1254 UnSubscribeGnssStatus(gnssCallbackHost);
1255 #endif
1256 g_gnssStatusInfoCallbacks.DeleteCallback(env, handler);
1257 gnssCallbackHost->DeleteHandler();
1258 gnssCallbackHost = nullptr;
1259 return true;
1260 }
1261 return false;
1262 }
1263
OffNmeaMessageChangeCallback(const napi_env & env,const napi_value & handler)1264 bool OffNmeaMessageChangeCallback(const napi_env& env, const napi_value& handler)
1265 {
1266 auto nmeaCallbackHost = g_nmeaCallbacks.GetCallbackPtr(env, handler);
1267 if (nmeaCallbackHost) {
1268 #ifdef ENABLE_NAPI_MANAGER
1269 LocationErrCode ret = UnSubscribeNmeaMessageV9(nmeaCallbackHost);
1270 if (ret != ERRCODE_SUCCESS) {
1271 HandleSyncErrCode(env, ret);
1272 return false;
1273 }
1274 #else
1275 UnSubscribeNmeaMessage(nmeaCallbackHost);
1276 #endif
1277 g_nmeaCallbacks.DeleteCallback(env, handler);
1278 nmeaCallbackHost->DeleteHandler();
1279 nmeaCallbackHost = nullptr;
1280 return true;
1281 }
1282 return false;
1283 }
1284
OffCachedGnssLocationsReportingCallback(const napi_env & env,const napi_value & handler)1285 bool OffCachedGnssLocationsReportingCallback(const napi_env& env, const napi_value& handler)
1286 {
1287 auto cachedCallbackHost = g_cachedLocationCallbacks.GetCallbackPtr(env, handler);
1288 if (cachedCallbackHost) {
1289 auto cachedCallback = sptr<ICachedLocationsCallback>(cachedCallbackHost);
1290 #ifdef ENABLE_NAPI_MANAGER
1291 LocationErrCode errorCode = UnSubscribeCacheLocationChangeV9(cachedCallback);
1292 if (errorCode != ERRCODE_SUCCESS) {
1293 HandleSyncErrCode(env, errorCode);
1294 return false;
1295 }
1296 #else
1297 UnSubscribeCacheLocationChange(cachedCallback);
1298 #endif
1299 g_cachedLocationCallbacks.DeleteCallback(env, handler);
1300 cachedCallbackHost->DeleteHandler();
1301 cachedCallbackHost = nullptr;
1302 return true;
1303 } else {
1304 LBSLOGI(LOCATION_NAPI, "%{public}s, the callback is not in the map", __func__);
1305 #ifdef ENABLE_NAPI_MANAGER
1306 HandleSyncErrCode(env, ERRCODE_NOT_SUPPORTED);
1307 #endif
1308 }
1309 return false;
1310 }
1311
OffCountryCodeChangeCallback(const napi_env & env,const napi_value & handler)1312 bool OffCountryCodeChangeCallback(const napi_env& env, const napi_value& handler)
1313 {
1314 auto callbackHost = g_countryCodeCallbacks.GetCallbackPtr(env, handler);
1315 if (callbackHost) {
1316 #ifdef ENABLE_NAPI_MANAGER
1317 LocationErrCode errorCode = UnsubscribeCountryCodeChangeV9(callbackHost);
1318 if (errorCode != ERRCODE_SUCCESS) {
1319 HandleSyncErrCode(env, errorCode);
1320 return false;
1321 }
1322 #else
1323 UnsubscribeCountryCodeChange(callbackHost);
1324 #endif
1325 g_countryCodeCallbacks.DeleteCallback(env, handler);
1326 callbackHost->DeleteHandler();
1327 callbackHost = nullptr;
1328 return true;
1329 }
1330 return false;
1331 }
1332
1333 #ifdef ENABLE_NAPI_MANAGER
OffLocatingRequiredDataChangeCallback(const napi_env & env,const napi_value & handler)1334 bool OffLocatingRequiredDataChangeCallback(const napi_env& env, const napi_value& handler)
1335 {
1336 auto callbackHost = g_locatingRequiredDataCallbacks.GetCallbackPtr(env, handler);
1337 if (callbackHost) {
1338 LocationErrCode errorCode = UnSubscribeLocatingRequiredDataChange(callbackHost);
1339 if (errorCode != ERRCODE_SUCCESS) {
1340 HandleSyncErrCode(env, errorCode);
1341 return false;
1342 }
1343 g_locatingRequiredDataCallbacks.DeleteCallback(env, handler);
1344 callbackHost->DeleteHandler();
1345 callbackHost = nullptr;
1346 return true;
1347 }
1348 return false;
1349 }
1350 #endif
1351
VerifyOffFuncParam(napi_env env,napi_callback_info cbinfo,size_t & argc)1352 bool VerifyOffFuncParam(napi_env env, napi_callback_info cbinfo, size_t& argc)
1353 {
1354 napi_value argv[MAXIMUM_JS_PARAMS] = {0};
1355 napi_valuetype valueType[PARAM3] = {napi_undefined};
1356 napi_value thisVar = nullptr;
1357 NAPI_CALL_BASE(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr), false);
1358 NAPI_ASSERT_BASE(env, g_locatorProxy != nullptr, "locator instance is null.", false);
1359 argc = (argc > PARAM3) ? PARAM3 : argc;
1360 if (argc > 0) {
1361 for (int i = (int)(argc - 1); i >= 0; i--) {
1362 NAPI_CALL_BASE(env, napi_typeof(env, argv[i], &valueType[i]), false);
1363 /* If the type of the last input parameter is incorrect, ignore it. */
1364 if (valueType[i] != napi_function && valueType[i] != napi_object && valueType[i] != napi_string &&
1365 i == (int)(argc - 1)) {
1366 argc--;
1367 }
1368 }
1369 }
1370 if (argc == PARAM3 && valueType[argc - 1] != napi_object) {
1371 argc--;
1372 }
1373 if (argc == PARAM2 && valueType[argc - 1] != napi_function) {
1374 argc--;
1375 }
1376 if (argc < PARAM1 || valueType[PARAM0] != napi_string ||
1377 (argc == PARAM2 && valueType[PARAM1] != napi_function) ||
1378 (argc == PARAM3 && valueType[PARAM1] != napi_object && valueType[PARAM2] != napi_object)) {
1379 #ifdef ENABLE_NAPI_MANAGER
1380 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1381 #else
1382 NAPI_ASSERT_BASE(env, false, "ERRCODE_INVALID_PARAM", false);
1383 #endif
1384 return false;
1385 }
1386 return true;
1387 }
1388
Off(napi_env env,napi_callback_info cbinfo)1389 napi_value Off(napi_env env, napi_callback_info cbinfo)
1390 {
1391 LBSLOGD(LOCATION_NAPI, "Off function entry");
1392 InitOffFuncMap();
1393
1394 size_t argc = MAXIMUM_JS_PARAMS;
1395 napi_value argv[MAXIMUM_JS_PARAMS] = {0};
1396 napi_value thisVar = nullptr;
1397 NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
1398
1399 if (!VerifyOffFuncParam(env, cbinfo, argc)) {
1400 LBSLOGE(LOCATION_NAPI, "VerifyOffFuncParam fail");
1401 return UndefinedNapiValue(env);
1402 }
1403
1404 char type[64] = {0};
1405 size_t typeLen = 0;
1406 NAPI_CALL(env, napi_get_value_string_utf8(env, argv[PARAM0], type, sizeof(type), &typeLen));
1407 std::string event = type;
1408 LBSLOGD(LOCATION_NAPI, "Unsubscribe event: %{public}s", event.c_str());
1409 if (argc == PARAM1) {
1410 std::unique_lock<std::mutex> lock(g_FuncMapMutex);
1411 auto offAllCallbackFunc = g_offAllFuncMap.find(event);
1412 if (offAllCallbackFunc != g_offAllFuncMap.end() && offAllCallbackFunc->second != nullptr) {
1413 auto memberFunc = offAllCallbackFunc->second;
1414 (*memberFunc)(env);
1415 }
1416 } else if (argc == PARAM2) {
1417 std::unique_lock<std::mutex> lock(g_FuncMapMutex);
1418 auto offCallbackFunc = g_offFuncMap.find(event);
1419 if (offCallbackFunc != g_offFuncMap.end() && offCallbackFunc->second != nullptr) {
1420 auto singleMemberFunc = offCallbackFunc->second;
1421 (*singleMemberFunc)(env, argv[PARAM1]);
1422 }
1423 #ifdef ENABLE_NAPI_MANAGER
1424 } else if (argc == PARAM3 && event == "gnssFenceStatusChange") {
1425 LocationErrCode errorCode = UnSubscribeFenceStatusChangeV9(env, argv[PARAM1], argv[PARAM2]);
1426 if (errorCode != ERRCODE_SUCCESS) {
1427 HandleSyncErrCode(env, errorCode);
1428 }
1429 } else {
1430 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1431 #else
1432 } else if (argc == PARAM3 && event == "fenceStatusChange") {
1433 UnSubscribeFenceStatusChange(env, argv[PARAM1], argv[PARAM2]);
1434 #endif
1435 }
1436 return UndefinedNapiValue(env);
1437 }
1438
GetCurrentLocation(napi_env env,napi_callback_info cbinfo)1439 napi_value GetCurrentLocation(napi_env env, napi_callback_info cbinfo)
1440 {
1441 size_t argc = MAXIMUM_JS_PARAMS;
1442 napi_value argv[MAXIMUM_JS_PARAMS] = {0};
1443 napi_valuetype valueType[MAXIMUM_JS_PARAMS] = {napi_undefined};
1444 napi_value thisVar = nullptr;
1445 NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
1446 NAPI_ASSERT(env, g_locatorProxy != nullptr, "locator instance is null.");
1447 LBSLOGD(LOCATION_NAPI, "GetCurrentLocation enter");
1448 #ifdef SUPPORT_JSSTACK
1449 HiviewDFX::ReportXPowerJsStackSysEvent(env, "GNSS_STATE");
1450 #endif
1451 argc = (argc > PARAM2) ? PARAM2 : argc;
1452 if (argc > 0) {
1453 for (int i = (int)(argc - 1); i >= 0; i--) {
1454 NAPI_CALL(env, napi_typeof(env, argv[i], &valueType[i]));
1455 /* If the type of the last input parameter is incorrect, ignore it. */
1456 if (valueType[i] != napi_function && valueType[i] != napi_object &&
1457 i == (int)(argc - 1)) {
1458 argc--;
1459 }
1460 }
1461 }
1462 if (argc == PARAM2) {
1463 if (valueType[PARAM1] != napi_function) {
1464 argc--;
1465 }
1466 #ifdef ENABLE_NAPI_MANAGER
1467 else if (valueType[PARAM0] != napi_object) {
1468 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1469 return UndefinedNapiValue(env);
1470 }
1471 #else
1472 else {
1473 NAPI_ASSERT(env, valueType[PARAM0] == napi_object, "type mismatch for parameter 1");
1474 }
1475 #endif
1476 }
1477 if (argc == PARAM1) {
1478 if (valueType[PARAM0] != napi_function && valueType[PARAM0] != napi_object) {
1479 argc--;
1480 }
1481 }
1482 #ifdef ENABLE_NAPI_MANAGER
1483 return RequestLocationOnceV9(env, argc, argv);
1484 #else
1485 return RequestLocationOnce(env, argc, argv);
1486 #endif
1487 }
1488
1489 #ifdef ENABLE_NAPI_MANAGER
CheckLocationSwitchEnable()1490 LocationErrCode CheckLocationSwitchEnable()
1491 {
1492 bool isEnabled = false;
1493 LocationErrCode errorCode = g_locatorProxy->IsLocationEnabledV9(isEnabled);
1494 if (errorCode != ERRCODE_SUCCESS) {
1495 return errorCode;
1496 }
1497 if (!isEnabled) {
1498 return ERRCODE_SWITCH_OFF;
1499 }
1500 return ERRCODE_SUCCESS;
1501 }
1502 #endif
1503
IsRequestConfigValid(std::unique_ptr<RequestConfig> & config)1504 bool IsRequestConfigValid(std::unique_ptr<RequestConfig>& config)
1505 {
1506 if (config == nullptr) {
1507 return false;
1508 }
1509 if ((config->GetScenario() > SCENE_NO_POWER || config->GetScenario() < SCENE_UNSET) &&
1510 (config->GetScenario() > LOCATION_SCENE_RIDE ||
1511 config->GetScenario() < LOCATION_SCENE_NAVIGATION) &&
1512 (config->GetScenario() > LOCATION_SCENE_NO_POWER_CONSUMPTION ||
1513 config->GetScenario() < LOCATION_SCENE_HIGH_POWER_CONSUMPTION)) {
1514 return false;
1515 }
1516 if ((config->GetPriority() > PRIORITY_FAST_FIRST_FIX || config->GetPriority() < PRIORITY_UNSET) &&
1517 (config->GetPriority() > LOCATION_PRIORITY_LOCATING_SPEED ||
1518 config->GetPriority() < LOCATION_PRIORITY_ACCURACY)) {
1519 return false;
1520 }
1521 if (config->GetTimeOut() < MIN_TIMEOUTMS_FOR_LOCATIONONCE) {
1522 return false;
1523 }
1524 if (config->GetTimeInterval() < 0) {
1525 return false;
1526 }
1527 if (config->GetDistanceInterval() < 0) {
1528 return false;
1529 }
1530 if (config->GetMaxAccuracy() < 0) {
1531 return false;
1532 }
1533 return true;
1534 }
1535
1536 #ifdef ENABLE_NAPI_MANAGER
OnLocationErrorCallback(const napi_env & env,const size_t argc,const napi_value * argv)1537 bool OnLocationErrorCallback(const napi_env& env, const size_t argc, const napi_value* argv)
1538 {
1539 if (argc != PARAM2) {
1540 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1541 LBSLOGE(LOCATION_NAPI, "ERRCODE_INVALID_PARAM");
1542 return false;
1543 }
1544 if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
1545 HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1546 LBSLOGE(LOCATION_NAPI, "ERRCODE_INVALID_PARAM");
1547 return false;
1548 }
1549 // the third params should be handler
1550 if (g_locationErrorCallbackHosts.IsCallbackInMap(env, argv[PARAM1])) {
1551 LBSLOGE(LOCATION_NAPI, "This request already exists");
1552 return false;
1553 }
1554 auto locationErrorCallbackHost =
1555 sptr<LocationErrorCallbackNapi>(new (std::nothrow) LocationErrorCallbackNapi());
1556 if (locationErrorCallbackHost != nullptr) {
1557 napi_ref handlerRef = nullptr;
1558 NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], 1, &handlerRef), false);
1559 // argv[1]:request params, argv[2]:handler
1560 LocationErrCode errorCode = SubscribeLocationError(env, handlerRef, locationErrorCallbackHost);
1561 if (errorCode != ERRCODE_SUCCESS) {
1562 HandleSyncErrCode(env, errorCode);
1563 return false;
1564 }
1565 g_locationErrorCallbackHosts.AddCallback(env, handlerRef, locationErrorCallbackHost);
1566 }
1567 return true;
1568 }
1569
OffLocationErrorCallback(const napi_env & env,const napi_value & handler)1570 bool OffLocationErrorCallback(const napi_env& env, const napi_value& handler)
1571 {
1572 auto locationErrorCallbackHost = g_locationErrorCallbackHosts.GetCallbackPtr(env, handler);
1573 if (locationErrorCallbackHost) {
1574 auto locatorCallback = sptr<ILocatorCallback>(locationErrorCallbackHost);
1575 LocationErrCode errorCode = UnSubscribeLocationError(locatorCallback);
1576 if (errorCode != ERRCODE_SUCCESS) {
1577 HandleSyncErrCode(env, errorCode);
1578 return false;
1579 }
1580 g_locationErrorCallbackHosts.DeleteCallback(env, handler);
1581 locationErrorCallbackHost = nullptr;
1582 return true;
1583 }
1584 return false;
1585 }
1586 #endif
1587
GetCurrentLocationType(std::unique_ptr<RequestConfig> & config)1588 int GetCurrentLocationType(std::unique_ptr<RequestConfig>& config)
1589 {
1590 if (config->GetPriority() == LOCATION_PRIORITY_ACCURACY ||
1591 (config->GetScenario() == SCENE_UNSET && config->GetPriority() == PRIORITY_ACCURACY) ||
1592 config->GetScenario() == SCENE_NAVIGATION ||
1593 config->GetScenario() == SCENE_TRAJECTORY_TRACKING ||
1594 config->GetScenario() == SCENE_CAR_HAILING) {
1595 return LOCATION_PRIORITY_ACCURACY;
1596 } else {
1597 return LOCATION_PRIORITY_LOCATING_SPEED;
1598 }
1599 }
1600 } // namespace Location
1601 } // namespace OHOS
1602