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