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