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