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