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