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