• 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     g_locatorProxy->RegisterCachedLocationCallbackV9(request, cachedCallback);
289     return ERRCODE_NOT_SUPPORTED;
290 }
291 #endif
292 
SubscribeFenceStatusChange(const napi_env & env,const napi_value & object,const napi_value & handler)293 void SubscribeFenceStatusChange(const napi_env& env, const napi_value& object, const napi_value& handler)
294 {
295     auto wantAgent = AbilityRuntime::WantAgent::WantAgent();
296     NAPI_CALL_RETURN_VOID(env, napi_unwrap(env, handler, (void **)&wantAgent));
297     auto request = std::make_unique<GeofenceRequest>();
298     JsObjToGeoFenceRequest(env, object, request);
299     auto state = new (std::nothrow) GeoFenceState(request->geofence, wantAgent);
300     if (state != nullptr) {
301         mFences.push_back(state);
302         g_locatorProxy->AddFence(request);
303     }
304 }
305 
306 #ifdef ENABLE_NAPI_MANAGER
SubscribeFenceStatusChangeV9(const napi_env & env,const napi_value & object,const napi_value & handler)307 LocationErrCode SubscribeFenceStatusChangeV9(const napi_env& env, const napi_value& object, const napi_value& handler)
308 {
309     LocationErrCode errorCode = CheckLocationSwitchEnable();
310     if (errorCode != ERRCODE_SUCCESS) {
311         return errorCode;
312     }
313     auto wantAgent = AbilityRuntime::WantAgent::WantAgent();
314     NAPI_CALL_BASE(env, napi_unwrap(env, handler, (void **)&wantAgent), ERRCODE_NOT_SUPPORTED);
315     auto request = std::make_unique<GeofenceRequest>();
316     JsObjToGeoFenceRequest(env, object, request);
317     auto state = new (std::nothrow) GeoFenceState(request->geofence, wantAgent);
318     if (state != nullptr) {
319         mFences.push_back(state);
320         g_locatorProxy->AddFenceV9(request);
321     }
322     return ERRCODE_NOT_SUPPORTED;
323 }
324 #endif
325 
UnSubscribeFenceStatusChange(const napi_env & env,const napi_value & object,const napi_value & handler)326 void UnSubscribeFenceStatusChange(const napi_env& env, const napi_value& object, const napi_value& handler)
327 {
328     auto wantAgent = AbilityRuntime::WantAgent::WantAgent();
329     NAPI_CALL_RETURN_VOID(env, napi_unwrap(env, handler, (void **)&wantAgent));
330     auto request = std::make_unique<GeofenceRequest>();
331     JsObjToGeoFenceRequest(env, object, request);
332     if (mFences.size() > 0) {
333         mFences.erase(mFences.begin());
334         g_locatorProxy->RemoveFence(request);
335     }
336 }
337 
338 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeFenceStatusChangeV9(const napi_env & env,const napi_value & object,const napi_value & handler)339 LocationErrCode UnSubscribeFenceStatusChangeV9(const napi_env& env, const napi_value& object, const napi_value& handler)
340 {
341     LocationErrCode errorCode = CheckLocationSwitchEnable();
342     if (errorCode != ERRCODE_SUCCESS) {
343         return errorCode;
344     }
345     auto wantAgent = AbilityRuntime::WantAgent::WantAgent();
346     NAPI_CALL_BASE(env, napi_unwrap(env, handler, (void **)&wantAgent), ERRCODE_NOT_SUPPORTED);
347     auto request = std::make_unique<GeofenceRequest>();
348     JsObjToGeoFenceRequest(env, object, request);
349     if (mFences.size() > 0) {
350         mFences.erase(mFences.begin());
351         g_locatorProxy->RemoveFenceV9(request);
352     }
353     return ERRCODE_NOT_SUPPORTED;
354 }
355 #endif
356 
CreateSingleLocationAsyncContext(const napi_env & env,std::unique_ptr<RequestConfig> & config,sptr<LocatorCallbackHost> callback)357 SingleLocationAsyncContext* CreateSingleLocationAsyncContext(const napi_env& env,
358     std::unique_ptr<RequestConfig>& config, sptr<LocatorCallbackHost> callback)
359 {
360     auto asyncContext = new (std::nothrow) SingleLocationAsyncContext(env);
361     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
362     NAPI_CALL(env, napi_create_string_latin1(env, "GetCurrentLocation",
363         NAPI_AUTO_LENGTH, &asyncContext->resourceName));
364     asyncContext->timeout_ = config->GetTimeOut();
365     asyncContext->callbackHost_ = callback;
366     asyncContext->executeFunc = [&](void* data) -> void {
367         if (data == nullptr) {
368             LBSLOGE(LOCATOR_STANDARD, "data is nullptr!");
369             return;
370         }
371         auto context = static_cast<SingleLocationAsyncContext*>(data);
372         auto callbackHost = context->callbackHost_;
373         if (g_locatorProxy->IsLocationEnabled() && callbackHost != nullptr) {
374             callbackHost->Wait(context->timeout_);
375             auto callbackPtr = sptr<ILocatorCallback>(callbackHost);
376             g_locatorProxy->StopLocating(callbackPtr);
377             if (callbackHost->GetCount() != 0) {
378                 context->errCode = ERRCODE_LOCATING_FAIL;
379             }
380             callbackHost->SetCount(1);
381 #ifndef ENABLE_NAPI_MANAGER
382         } else {
383             context->errCode = LOCATION_SWITCH_ERROR;
384 #endif
385         }
386     };
387     asyncContext->completeFunc = [&](void* data) -> void {
388         if (data == nullptr) {
389             LBSLOGE(LOCATOR_STANDARD, "data is nullptr!");
390             return;
391         }
392         auto context = static_cast<SingleLocationAsyncContext*>(data);
393         NAPI_CALL_RETURN_VOID(context->env, napi_create_object(context->env, &context->result[PARAM1]));
394         auto callbackHost = context->callbackHost_;
395         if (callbackHost != nullptr && callbackHost->GetSingleLocation() != nullptr) {
396             std::unique_ptr<Location> location = std::make_unique<Location>(*callbackHost->GetSingleLocation());
397             LocationToJs(context->env, location, context->result[PARAM1]);
398         } else {
399             LBSLOGE(LOCATOR_STANDARD, "m_singleLocation is nullptr!");
400         }
401         if (context->callbackHost_) {
402             context->callbackHost_ = nullptr;
403         }
404         LBSLOGI(LOCATOR_STANDARD, "Push single location to client");
405     };
406     return asyncContext;
407 }
408 
GetObjectArgsNum(const napi_env & env,const size_t argc,const napi_value * argv)409 int GetObjectArgsNum(const napi_env& env, const size_t argc, const napi_value* argv)
410 {
411     napi_valuetype valueType = napi_undefined;
412     int objectArgsNum = PARAM0;
413     if (argc == PARAM0) {
414         objectArgsNum = PARAM0;
415     } else if (argc == PARAM1) {
416         NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM0], &valueType), objectArgsNum);
417         if (valueType == napi_object) {
418             objectArgsNum = PARAM1;
419         } else if (valueType == napi_function) {
420             objectArgsNum = PARAM0;
421         }
422     } else if (argc == PARAM2) {
423         objectArgsNum = PARAM1;
424     } else {
425         LBSLOGI(LOCATION_NAPI, "argc of GetCurrentLocation is wrong.");
426     }
427     return objectArgsNum;
428 }
429 
CreateRequestConfig(const napi_env & env,const napi_value * argv,const size_t & objectArgsNum)430 std::unique_ptr<RequestConfig> CreateRequestConfig(const napi_env& env,
431     const napi_value* argv, const size_t& objectArgsNum)
432 {
433     auto requestConfig = std::make_unique<RequestConfig>();
434     if (objectArgsNum > 0) {
435         JsObjToCurrentLocationRequest(env, argv[objectArgsNum - 1], requestConfig);
436     } else {
437         requestConfig->SetPriority(PRIORITY_FAST_FIRST_FIX);
438     }
439     requestConfig->SetFixNumber(1);
440     return requestConfig;
441 }
442 
CreateSingleLocationCallbackHost()443 sptr<LocatorCallbackHost> CreateSingleLocationCallbackHost()
444 {
445     auto callbackHost =
446         sptr<LocatorCallbackHost>(new (std::nothrow) LocatorCallbackHost());
447     if (callbackHost) {
448         callbackHost->SetFixNumber(1);
449     }
450     return callbackHost;
451 }
452 
RequestLocationOnce(const napi_env & env,const size_t argc,const napi_value * argv)453 napi_value RequestLocationOnce(const napi_env& env, const size_t argc, const napi_value* argv)
454 {
455     size_t objectArgsNum = 0;
456 
457     objectArgsNum = static_cast<size_t>(GetObjectArgsNum(env, argc, argv));
458     auto requestConfig = CreateRequestConfig(env, argv, objectArgsNum);
459     NAPI_ASSERT(env, requestConfig != nullptr, "requestConfig is null.");
460     auto singleLocatorCallbackHost = CreateSingleLocationCallbackHost();
461     NAPI_ASSERT(env, singleLocatorCallbackHost != nullptr, "callbackHost is null.");
462 
463     if (g_locatorProxy->IsLocationEnabled()) {
464         auto callbackPtr = sptr<ILocatorCallback>(singleLocatorCallbackHost);
465         g_locatorProxy->StartLocating(requestConfig, callbackPtr);
466     }
467 
468     auto asyncContext = CreateSingleLocationAsyncContext(env, requestConfig, singleLocatorCallbackHost);
469     NAPI_ASSERT(env, asyncContext != nullptr, "asyncContext is null.");
470     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
471 }
472 
473 #ifdef ENABLE_NAPI_MANAGER
RequestLocationOnceV9(const napi_env & env,const size_t argc,const napi_value * argv)474 napi_value RequestLocationOnceV9(const napi_env& env, const size_t argc, const napi_value* argv)
475 {
476     size_t objectArgsNum = 0;
477     objectArgsNum = static_cast<size_t>(GetObjectArgsNum(env, argc, argv));
478     auto requestConfig = CreateRequestConfig(env, argv, objectArgsNum);
479     if (requestConfig == nullptr) {
480         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
481         return UndefinedNapiValue(env);
482     }
483     auto singleLocatorCallbackHost = CreateSingleLocationCallbackHost();
484     if (singleLocatorCallbackHost == nullptr) {
485         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
486         return UndefinedNapiValue(env);
487     }
488     LocationErrCode errorCode = CheckLocationSwitchEnable();
489     if (errorCode != ERRCODE_SUCCESS) {
490         HandleSyncErrCode(env, errorCode);
491         return UndefinedNapiValue(env);
492     }
493     auto callbackPtr = sptr<ILocatorCallback>(singleLocatorCallbackHost);
494     errorCode = g_locatorProxy->StartLocatingV9(requestConfig, callbackPtr);
495     if (errorCode != ERRCODE_SUCCESS) {
496         HandleSyncErrCode(env, errorCode);
497         return UndefinedNapiValue(env);
498     }
499 
500     auto asyncContext = CreateSingleLocationAsyncContext(env, requestConfig, singleLocatorCallbackHost);
501     if (asyncContext == nullptr) {
502         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
503         return UndefinedNapiValue(env);
504     }
505     return DoAsyncWork(env, asyncContext, argc, argv, objectArgsNum);
506 }
507 #endif
508 
UnSubscribeLocationChange(sptr<ILocatorCallback> & callback)509 void UnSubscribeLocationChange(sptr<ILocatorCallback>& callback)
510 {
511     LBSLOGI(LOCATION_NAPI, "UnSubscribeLocationChange");
512     g_locatorProxy->StopLocating(callback);
513 }
514 
515 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeLocationChangeV9(sptr<ILocatorCallback> & callback)516 LocationErrCode UnSubscribeLocationChangeV9(sptr<ILocatorCallback>& callback)
517 {
518     LBSLOGI(LOCATION_NAPI, "UnSubscribeLocationChangeV9");
519     return g_locatorProxy->StopLocatingV9(callback);
520 }
521 #endif
522 
UnSubscribeCacheLocationChange(sptr<ICachedLocationsCallback> & callback)523 void UnSubscribeCacheLocationChange(sptr<ICachedLocationsCallback>& callback)
524 {
525     LBSLOGI(LOCATION_NAPI, "UnSubscribeCacheLocationChange");
526     g_locatorProxy->UnregisterCachedLocationCallback(callback);
527 }
528 
529 #ifdef ENABLE_NAPI_MANAGER
UnSubscribeCacheLocationChangeV9(sptr<ICachedLocationsCallback> & callback)530 LocationErrCode UnSubscribeCacheLocationChangeV9(sptr<ICachedLocationsCallback>& callback)
531 {
532     LBSLOGI(LOCATION_NAPI, "UnSubscribeCacheLocationChangeV9");
533     g_locatorProxy->UnregisterCachedLocationCallbackV9(callback);
534     return ERRCODE_NOT_SUPPORTED;
535 }
536 #endif
537 
IsCallbackEquals(const napi_env & env,const napi_value & handler,const napi_ref & savedCallback)538 bool IsCallbackEquals(const napi_env& env, const napi_value& handler, const napi_ref& savedCallback)
539 {
540     napi_value handlerTemp = nullptr;
541     if (savedCallback == nullptr || handler == nullptr) {
542         return false;
543     }
544     NAPI_CALL_BASE(env, napi_get_reference_value(env, savedCallback, &handlerTemp), false);
545     bool isEqual = false;
546     NAPI_CALL_BASE(env, napi_strict_equals(env, handlerTemp, handler, &isEqual), false);
547     return isEqual;
548 }
549 
OnLocationServiceStateCallback(const napi_env & env,const size_t argc,const napi_value * argv)550 bool OnLocationServiceStateCallback(const napi_env& env, const size_t argc, const napi_value* argv)
551 {
552 #ifdef ENABLE_NAPI_MANAGER
553     if (argc != PARAM2) {
554         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
555         return false;
556     }
557     if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
558         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
559         return false;
560     }
561 #else
562     NAPI_ASSERT_BASE(env, argc == PARAM2, "number of parameters is wrong", INPUT_PARAMS_ERROR);
563     NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
564         "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
565 #endif
566     if (g_switchCallbacks.IsCallbackInMap(env, argv[PARAM1])) {
567         LBSLOGE(LOCATION_NAPI, "This request already exists");
568         return false;
569     }
570     auto switchCallbackHost =
571         sptr<LocationSwitchCallbackHost>(new (std::nothrow) LocationSwitchCallbackHost());
572     if (switchCallbackHost != nullptr) {
573         napi_ref handlerRef = nullptr;
574         NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], 1, &handlerRef), false);
575 #ifdef ENABLE_NAPI_MANAGER
576         LocationErrCode errorCode = SubscribeLocationServiceStateV9(env, handlerRef, switchCallbackHost);
577         if (errorCode != ERRCODE_SUCCESS) {
578             HandleSyncErrCode(env, errorCode);
579             return false;
580         }
581 #else
582         SubscribeLocationServiceState(env, handlerRef, switchCallbackHost);
583 #endif
584         g_switchCallbacks.AddCallback(env, handlerRef, switchCallbackHost);
585     }
586     return true;
587 }
588 
OnCachedGnssLocationsReportingCallback(const napi_env & env,const size_t argc,const napi_value * argv)589 bool OnCachedGnssLocationsReportingCallback(const napi_env& env, const size_t argc, const napi_value* argv)
590 {
591 #ifdef ENABLE_NAPI_MANAGER
592     if (argc != PARAM3) {
593         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
594         return false;
595     }
596     napi_valuetype valueType;
597     NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM1], &valueType), false);
598     if (valueType != napi_object || !CheckIfParamIsFunctionType(env, argv[PARAM2])) {
599         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
600         return UndefinedNapiValue(env);
601     }
602 #else
603     NAPI_ASSERT_BASE(env, argc == PARAM3, "number of parameters is wrong", INPUT_PARAMS_ERROR);
604     NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM2]),
605         "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
606 #endif
607 #ifndef ENABLE_NAPI_MANAGER
608     if (!g_locatorProxy->IsLocationEnabled()) {
609         LBSLOGE(LOCATION_NAPI, "location switch is off, just return.");
610         return false;
611     }
612 #endif
613     // the third params should be handler
614     if (g_cachedLocationCallbacks.IsCallbackInMap(env, argv[PARAM2])) {
615         LBSLOGE(LOCATION_NAPI, "This request already exists");
616         return false;
617     }
618     auto cachedCallbackHost =
619         sptr<CachedLocationsCallbackHost>(new (std::nothrow) CachedLocationsCallbackHost());
620     if (cachedCallbackHost != nullptr) {
621         napi_ref handlerRef = nullptr;
622         NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM2], PARAM1, &handlerRef), false);
623 #ifdef ENABLE_NAPI_MANAGER
624         LocationErrCode errorCode = SubscribeCacheLocationChangeV9(env, argv[PARAM1], handlerRef, cachedCallbackHost);
625         if (errorCode != ERRCODE_SUCCESS) {
626             HandleSyncErrCode(env, errorCode);
627             return false;
628         }
629 #else
630         SubscribeCacheLocationChange(env, argv[PARAM1], handlerRef, cachedCallbackHost);
631 #endif
632         g_cachedLocationCallbacks.AddCallback(env, handlerRef, cachedCallbackHost);
633     }
634     return true;
635 }
636 
OnGnssStatusChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)637 bool OnGnssStatusChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
638 {
639 #ifdef ENABLE_NAPI_MANAGER
640     if (argc != PARAM2) {
641         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
642         return false;
643     }
644     if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
645         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
646         return UndefinedNapiValue(env);
647     }
648 #else
649     NAPI_ASSERT_BASE(env, argc == PARAM2, "number of parameters is wrong", INPUT_PARAMS_ERROR);
650     NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
651         "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
652 #endif
653     if (g_gnssStatusInfoCallbacks.IsCallbackInMap(env, argv[PARAM1])) {
654         LBSLOGE(LOCATION_NAPI, "This request already exists");
655         return false;
656     }
657     auto gnssCallbackHost =
658         sptr<GnssStatusCallbackHost>(new (std::nothrow) GnssStatusCallbackHost());
659     if (gnssCallbackHost != nullptr) {
660         napi_ref handlerRef = nullptr;
661         NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], PARAM1, &handlerRef), false);
662 #ifdef ENABLE_NAPI_MANAGER
663         LocationErrCode errorCode = SubscribeGnssStatusV9(env, handlerRef, gnssCallbackHost);
664         if (errorCode != ERRCODE_SUCCESS) {
665             HandleSyncErrCode(env, errorCode);
666             return false;
667         }
668 #else
669         SubscribeGnssStatus(env, handlerRef, gnssCallbackHost);
670 #endif
671         g_gnssStatusInfoCallbacks.AddCallback(env, handlerRef, gnssCallbackHost);
672     }
673     return true;
674 }
675 
OnLocationChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)676 bool OnLocationChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
677 {
678 #ifdef ENABLE_NAPI_MANAGER
679     if (argc != PARAM3) {
680         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
681         return false;
682     }
683     napi_valuetype valueType;
684     NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM1], &valueType), false);
685     if (valueType != napi_object || !CheckIfParamIsFunctionType(env, argv[PARAM2])) {
686         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
687         return false;
688     }
689 #else
690     NAPI_ASSERT_BASE(env, argc == PARAM3, "number of parameters is wrong", INPUT_PARAMS_ERROR);
691     NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM2]),
692         "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
693     if (!g_locatorProxy->IsLocationEnabled()) {
694         LBSLOGE(LOCATION_NAPI, "location switch is off, just return.");
695         return false;
696     }
697 #endif
698     // the third params should be handler
699     if (g_locationCallbacks.IsCallbackInMap(env, argv[PARAM2])) {
700         LBSLOGE(LOCATION_NAPI, "This request already exists");
701         return false;
702     }
703     auto locatorCallbackHost =
704         sptr<LocatorCallbackHost>(new (std::nothrow) LocatorCallbackHost());
705     if (locatorCallbackHost != nullptr) {
706         napi_ref handlerRef = nullptr;
707         NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM2], 1, &handlerRef), false);
708         // argv[1]:request params, argv[2]:handler
709 #ifdef ENABLE_NAPI_MANAGER
710         LocationErrCode errorCode = SubscribeLocationChangeV9(env, argv[PARAM1], handlerRef, locatorCallbackHost);
711         if (errorCode != ERRCODE_SUCCESS) {
712             HandleSyncErrCode(env, errorCode);
713             return false;
714         }
715 #else
716         SubscribeLocationChange(env, argv[PARAM1], handlerRef, locatorCallbackHost);
717 #endif
718         g_locationCallbacks.AddCallback(env, handlerRef, locatorCallbackHost);
719     }
720     return true;
721 }
722 
OnNmeaMessageChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)723 bool OnNmeaMessageChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
724 {
725 #ifdef ENABLE_NAPI_MANAGER
726     if (argc != PARAM2) {
727         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
728         return false;
729     }
730     if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
731         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
732         return false;
733     }
734 #else
735     NAPI_ASSERT_BASE(env, argc == PARAM2, "number of parameters is wrong", INPUT_PARAMS_ERROR);
736     NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
737         "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
738 #endif
739     if (g_nmeaCallbacks.IsCallbackInMap(env, argv[PARAM1])) {
740         LBSLOGE(LOCATION_NAPI, "This request already exists");
741         return false;
742     }
743     auto nmeaCallbackHost =
744         sptr<NmeaMessageCallbackHost>(new (std::nothrow) NmeaMessageCallbackHost());
745     if (nmeaCallbackHost != nullptr) {
746         napi_ref handlerRef = nullptr;
747         NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], PARAM1, &handlerRef), false);
748 #ifdef ENABLE_NAPI_MANAGER
749         LocationErrCode errorCode = SubscribeNmeaMessageV9(env, handlerRef, nmeaCallbackHost);
750         if (errorCode != ERRCODE_SUCCESS) {
751             HandleSyncErrCode(env, errorCode);
752             return false;
753         }
754 #else
755         SubscribeNmeaMessage(env, handlerRef, nmeaCallbackHost);
756 #endif
757         g_nmeaCallbacks.AddCallback(env, handlerRef, nmeaCallbackHost);
758     }
759     return true;
760 }
761 
OnCountryCodeChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)762 bool OnCountryCodeChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
763 {
764 #ifdef ENABLE_NAPI_MANAGER
765     if (argc != PARAM2) {
766         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
767         return false;
768     }
769     if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
770         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
771         return false;
772     }
773 #else
774     NAPI_ASSERT_BASE(env, argc == PARAM2, "number of parameters is wrong", INPUT_PARAMS_ERROR);
775     NAPI_ASSERT_BASE(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
776         "callback should be function, mismatch for param.", INPUT_PARAMS_ERROR);
777 #endif
778     if (g_countryCodeCallbacks.IsCallbackInMap(env, argv[PARAM1])) {
779         LBSLOGE(LOCATION_NAPI, "This request already exists");
780         return false;
781     }
782     auto callbackHost =
783         sptr<CountryCodeCallbackHost>(new (std::nothrow) CountryCodeCallbackHost());
784     if (callbackHost) {
785         napi_ref handlerRef = nullptr;
786         NAPI_CALL_BASE(env, napi_create_reference(env, argv[PARAM1], 1, &handlerRef), false);
787 #ifdef ENABLE_NAPI_MANAGER
788         LocationErrCode errorCode = SubscribeCountryCodeChangeV9(env, handlerRef, callbackHost);
789         if (errorCode != ERRCODE_SUCCESS) {
790             HandleSyncErrCode(env, errorCode);
791             return false;
792         }
793 #else
794         SubscribeCountryCodeChange(env, handlerRef, callbackHost);
795 #endif
796         g_countryCodeCallbacks.AddCallback(env, handlerRef, callbackHost);
797     }
798     return true;
799 }
800 
OnFenceStatusChangeCallback(const napi_env & env,const size_t argc,const napi_value * argv)801 bool OnFenceStatusChangeCallback(const napi_env& env, const size_t argc, const napi_value* argv)
802 {
803 #ifdef ENABLE_NAPI_MANAGER
804     if (argc != PARAM3) {
805         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
806         return false;
807     }
808 #else
809     NAPI_ASSERT_BASE(env, argc == PARAM3, "number of parameters is wrong", INPUT_PARAMS_ERROR);
810     if (!g_locatorProxy->IsLocationEnabled()) {
811         LBSLOGE(LOCATION_NAPI, "location switch is off, just return.");
812         return false;
813     }
814 #endif
815     // the third params should be handler
816 #ifdef ENABLE_NAPI_MANAGER
817     LocationErrCode errorCode = SubscribeFenceStatusChangeV9(env, argv[PARAM1], argv[PARAM2]);
818     if (errorCode != ERRCODE_SUCCESS) {
819         HandleSyncErrCode(env, errorCode);
820         return false;
821     }
822 #else
823     SubscribeFenceStatusChange(env, argv[PARAM1], argv[PARAM2]);
824 #endif
825     return true;
826 }
827 
On(napi_env env,napi_callback_info cbinfo)828 napi_value On(napi_env env, napi_callback_info cbinfo)
829 {
830     InitOnFuncMap();
831     size_t argc = PARAM3;
832     napi_value argv[PARAM3] = {0};
833     napi_value thisVar = nullptr;
834     LBSLOGI(LOCATION_NAPI, "On function entry");
835     NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
836     napi_valuetype eventName = napi_undefined;
837     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &eventName));
838 #ifdef ENABLE_NAPI_MANAGER
839     if (eventName != napi_string) {
840         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
841         return UndefinedNapiValue(env);
842     }
843 #else
844     NAPI_ASSERT(env, eventName == napi_string, "type mismatch for parameter 1");
845 #endif
846 
847     NAPI_ASSERT(env, g_locatorProxy != nullptr, "locator instance is null.");
848 
849     char type[64] = {0}; // max length
850     size_t typeLen = 0;
851     NAPI_CALL(env, napi_get_value_string_utf8(env, argv[PARAM0], type, sizeof(type), &typeLen));
852     std::string event = type;
853     LBSLOGI(LOCATION_NAPI, "Subscribe event: %{public}s", event.c_str());
854     auto onCallbackFunc = g_onFuncMap.find(event);
855     if (onCallbackFunc != g_onFuncMap.end() && onCallbackFunc->second != nullptr) {
856         auto memberFunc = onCallbackFunc->second;
857         (*memberFunc)(env, argc, argv);
858     }
859     return UndefinedNapiValue(env);
860 }
861 
OffAllLocationServiceStateCallback(const napi_env & env)862 bool OffAllLocationServiceStateCallback(const napi_env& env)
863 {
864     std::map<napi_env, std::map<napi_ref, sptr<LocationSwitchCallbackHost>>> callbackMap =
865         g_switchCallbacks.GetCallbackMap();
866     auto iter = callbackMap.find(env);
867     if (iter == callbackMap.end()) {
868         return false;
869     }
870     for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
871         auto callbackHost = innerIter->second;
872         if (callbackHost == nullptr) {
873             continue;
874         }
875 #ifdef ENABLE_NAPI_MANAGER
876         LocationErrCode errorCode = UnSubscribeLocationServiceStateV9(callbackHost);
877         if (errorCode != ERRCODE_SUCCESS) {
878             HandleSyncErrCode(env, errorCode);
879             return false;
880         }
881 #else
882         UnSubscribeLocationServiceState(callbackHost);
883 #endif
884         callbackHost->DeleteHandler();
885         callbackHost = nullptr;
886     }
887     g_switchCallbacks.DeleteCallbackByEnv(env);
888     return true;
889 }
890 
OffAllLocationChangeCallback(const napi_env & env)891 bool OffAllLocationChangeCallback(const napi_env& env)
892 {
893 #ifdef ENABLE_NAPI_MANAGER
894     LocationErrCode errorCode = CheckLocationSwitchEnable();
895     if (errorCode != ERRCODE_SUCCESS) {
896         HandleSyncErrCode(env, errorCode);
897         return false;
898     }
899 #endif
900     std::map<napi_env, std::map<napi_ref, sptr<LocatorCallbackHost>>> callbackMap =
901         g_locationCallbacks.GetCallbackMap();
902     auto iter = callbackMap.find(env);
903     if (iter == callbackMap.end()) {
904         return false;
905     }
906     for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
907         auto callbackHost = innerIter->second;
908         if (callbackHost == nullptr) {
909             continue;
910         }
911         auto locatorCallback = sptr<ILocatorCallback>(callbackHost);
912 #ifdef ENABLE_NAPI_MANAGER
913         errorCode = UnSubscribeLocationChangeV9(locatorCallback);
914         if (errorCode != ERRCODE_SUCCESS) {
915             HandleSyncErrCode(env, errorCode);
916             return false;
917         }
918 #else
919         UnSubscribeLocationChange(locatorCallback);
920 #endif
921         callbackHost->DeleteAllCallbacks();
922         callbackHost = nullptr;
923     }
924     g_locationCallbacks.DeleteCallbackByEnv(env);
925     return true;
926 }
927 
OffAllGnssStatusChangeCallback(const napi_env & env)928 bool OffAllGnssStatusChangeCallback(const napi_env& env)
929 {
930 #ifdef ENABLE_NAPI_MANAGER
931     LocationErrCode errorCode = CheckLocationSwitchEnable();
932     if (errorCode != ERRCODE_SUCCESS) {
933         HandleSyncErrCode(env, errorCode);
934         return false;
935     }
936 #endif
937     std::map<napi_env, std::map<napi_ref, sptr<GnssStatusCallbackHost>>> callbackMap =
938         g_gnssStatusInfoCallbacks.GetCallbackMap();
939     auto iter = callbackMap.find(env);
940     if (iter == callbackMap.end()) {
941         return false;
942     }
943     for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
944         auto callbackHost = innerIter->second;
945         if (callbackHost == nullptr) {
946             continue;
947         }
948 #ifdef ENABLE_NAPI_MANAGER
949         errorCode = UnSubscribeGnssStatusV9(callbackHost);
950         if (errorCode != ERRCODE_SUCCESS) {
951             HandleSyncErrCode(env, errorCode);
952             return false;
953         }
954 #else
955         UnSubscribeGnssStatus(callbackHost);
956 #endif
957         callbackHost->DeleteHandler();
958         callbackHost = nullptr;
959     }
960     g_gnssStatusInfoCallbacks.DeleteCallbackByEnv(env);
961     return true;
962 }
963 
OffAllNmeaMessageChangeCallback(const napi_env & env)964 bool OffAllNmeaMessageChangeCallback(const napi_env& env)
965 {
966 #ifdef ENABLE_NAPI_MANAGER
967     LocationErrCode errorCode = CheckLocationSwitchEnable();
968     if (errorCode != ERRCODE_SUCCESS) {
969         HandleSyncErrCode(env, errorCode);
970         return false;
971     }
972 #endif
973     std::map<napi_env, std::map<napi_ref, sptr<NmeaMessageCallbackHost>>> callbackMap =
974         g_nmeaCallbacks.GetCallbackMap();
975     auto iter = callbackMap.find(env);
976     if (iter == callbackMap.end()) {
977         return false;
978     }
979     for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
980         auto callbackHost = innerIter->second;
981         if (callbackHost == nullptr) {
982             continue;
983         }
984 #ifdef ENABLE_NAPI_MANAGER
985         errorCode = UnSubscribeNmeaMessageV9(callbackHost);
986         if (errorCode != ERRCODE_SUCCESS) {
987             HandleSyncErrCode(env, errorCode);
988             return false;
989         }
990 #else
991         UnSubscribeNmeaMessage(callbackHost);
992 #endif
993         callbackHost->DeleteHandler();
994         callbackHost = nullptr;
995     }
996     g_nmeaCallbacks.DeleteCallbackByEnv(env);
997     return true;
998 }
999 
OffAllCachedGnssLocationsReportingCallback(const napi_env & env)1000 bool OffAllCachedGnssLocationsReportingCallback(const napi_env& env)
1001 {
1002 #ifdef ENABLE_NAPI_MANAGER
1003     LocationErrCode errorCode = CheckLocationSwitchEnable();
1004     if (errorCode != ERRCODE_SUCCESS) {
1005         HandleSyncErrCode(env, errorCode);
1006         return false;
1007     }
1008 #endif
1009     std::map<napi_env, std::map<napi_ref, sptr<CachedLocationsCallbackHost>>> callbackMap =
1010         g_cachedLocationCallbacks.GetCallbackMap();
1011     auto iter = callbackMap.find(env);
1012     if (iter == callbackMap.end()) {
1013 #ifdef ENABLE_NAPI_MANAGER
1014         HandleSyncErrCode(env, ERRCODE_NOT_SUPPORTED);
1015 #endif
1016         return false;
1017     }
1018     for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1019         auto callbackHost = innerIter->second;
1020         if (callbackHost == nullptr) {
1021             continue;
1022         }
1023         auto cachedCallback = sptr<ICachedLocationsCallback>(callbackHost);
1024 #ifdef ENABLE_NAPI_MANAGER
1025         errorCode = UnSubscribeCacheLocationChangeV9(cachedCallback);
1026         if (errorCode != ERRCODE_SUCCESS) {
1027             HandleSyncErrCode(env, errorCode);
1028             return false;
1029         }
1030 #else
1031         UnSubscribeCacheLocationChange(cachedCallback);
1032 #endif
1033         callbackHost->DeleteHandler();
1034         callbackHost = nullptr;
1035     }
1036     g_cachedLocationCallbacks.DeleteCallbackByEnv(env);
1037     return true;
1038 }
1039 
OffAllCountryCodeChangeCallback(const napi_env & env)1040 bool OffAllCountryCodeChangeCallback(const napi_env& env)
1041 {
1042     std::map<napi_env, std::map<napi_ref, sptr<CountryCodeCallbackHost>>> callbackMap =
1043         g_countryCodeCallbacks.GetCallbackMap();
1044     auto iter = callbackMap.find(env);
1045     if (iter == callbackMap.end()) {
1046         return false;
1047     }
1048     for (auto innerIter = iter->second.begin(); innerIter != iter->second.end(); innerIter++) {
1049         auto callbackHost = innerIter->second;
1050         if (callbackHost == nullptr) {
1051             continue;
1052         }
1053 #ifdef ENABLE_NAPI_MANAGER
1054         LocationErrCode errorCode = UnsubscribeCountryCodeChangeV9(callbackHost);
1055         if (errorCode != ERRCODE_SUCCESS) {
1056             HandleSyncErrCode(env, errorCode);
1057             return false;
1058         }
1059 #else
1060         UnsubscribeCountryCodeChange(callbackHost);
1061 #endif
1062         callbackHost->DeleteHandler();
1063         callbackHost = nullptr;
1064     }
1065     g_countryCodeCallbacks.DeleteCallbackByEnv(env);
1066     return true;
1067 }
1068 
OffLocationServiceStateCallback(const napi_env & env,const napi_value & handler)1069 bool OffLocationServiceStateCallback(const napi_env& env, const napi_value& handler)
1070 {
1071     auto switchCallbackHost = g_switchCallbacks.GetCallbackPtr(env, handler);
1072     if (switchCallbackHost) {
1073 #ifdef ENABLE_NAPI_MANAGER
1074         LocationErrCode errorCode = UnSubscribeLocationServiceStateV9(switchCallbackHost);
1075         if (errorCode != ERRCODE_SUCCESS) {
1076             HandleSyncErrCode(env, errorCode);
1077             return false;
1078         }
1079 #else
1080         UnSubscribeLocationServiceState(switchCallbackHost);
1081 #endif
1082         g_switchCallbacks.DeleteCallback(env, handler);
1083         switchCallbackHost->DeleteHandler();
1084         switchCallbackHost = nullptr;
1085         return true;
1086     }
1087     return false;
1088 }
1089 
OffLocationChangeCallback(const napi_env & env,const napi_value & handler)1090 bool OffLocationChangeCallback(const napi_env& env, const napi_value& handler)
1091 {
1092 #ifdef ENABLE_NAPI_MANAGER
1093     LocationErrCode errorCode = CheckLocationSwitchEnable();
1094     if (errorCode != ERRCODE_SUCCESS) {
1095         HandleSyncErrCode(env, errorCode);
1096         return false;
1097     }
1098 #endif
1099     auto locatorCallbackHost = g_locationCallbacks.GetCallbackPtr(env, handler);
1100     if (locatorCallbackHost) {
1101         auto locatorCallback = sptr<ILocatorCallback>(locatorCallbackHost);
1102 #ifdef ENABLE_NAPI_MANAGER
1103         errorCode = UnSubscribeLocationChangeV9(locatorCallback);
1104         if (errorCode != ERRCODE_SUCCESS) {
1105             HandleSyncErrCode(env, errorCode);
1106             return false;
1107         }
1108 #else
1109         UnSubscribeLocationChange(locatorCallback);
1110 #endif
1111         g_locationCallbacks.DeleteCallback(env, handler);
1112         locatorCallbackHost->DeleteAllCallbacks();
1113         locatorCallbackHost = nullptr;
1114         return true;
1115     }
1116     return false;
1117 }
1118 
OffGnssStatusChangeCallback(const napi_env & env,const napi_value & handler)1119 bool OffGnssStatusChangeCallback(const napi_env& env, const napi_value& handler)
1120 {
1121 #ifdef ENABLE_NAPI_MANAGER
1122     LocationErrCode errorCode = CheckLocationSwitchEnable();
1123     if (errorCode != ERRCODE_SUCCESS) {
1124         HandleSyncErrCode(env, errorCode);
1125         return false;
1126     }
1127 #endif
1128     auto gnssCallbackHost = g_gnssStatusInfoCallbacks.GetCallbackPtr(env, handler);
1129     if (gnssCallbackHost) {
1130 #ifdef ENABLE_NAPI_MANAGER
1131         errorCode = UnSubscribeGnssStatusV9(gnssCallbackHost);
1132         if (errorCode != ERRCODE_SUCCESS) {
1133             HandleSyncErrCode(env, errorCode);
1134             return false;
1135         }
1136 #else
1137         UnSubscribeGnssStatus(gnssCallbackHost);
1138 #endif
1139         g_gnssStatusInfoCallbacks.DeleteCallback(env, handler);
1140         gnssCallbackHost->DeleteHandler();
1141         gnssCallbackHost = nullptr;
1142         return true;
1143     }
1144     return false;
1145 }
1146 
OffNmeaMessageChangeCallback(const napi_env & env,const napi_value & handler)1147 bool OffNmeaMessageChangeCallback(const napi_env& env, const napi_value& handler)
1148 {
1149 #ifdef ENABLE_NAPI_MANAGER
1150     LocationErrCode errorCode = CheckLocationSwitchEnable();
1151     if (errorCode != ERRCODE_SUCCESS) {
1152         HandleSyncErrCode(env, errorCode);
1153         return false;
1154     }
1155 #endif
1156     auto nmeaCallbackHost = g_nmeaCallbacks.GetCallbackPtr(env, handler);
1157     if (nmeaCallbackHost) {
1158 #ifdef ENABLE_NAPI_MANAGER
1159         LocationErrCode ret = UnSubscribeNmeaMessageV9(nmeaCallbackHost);
1160         if (ret != ERRCODE_SUCCESS) {
1161             HandleSyncErrCode(env, ret);
1162             return false;
1163         }
1164 #else
1165         UnSubscribeNmeaMessage(nmeaCallbackHost);
1166 #endif
1167         g_nmeaCallbacks.DeleteCallback(env, handler);
1168         nmeaCallbackHost->DeleteHandler();
1169         nmeaCallbackHost = nullptr;
1170         return true;
1171     }
1172     return false;
1173 }
1174 
OffCachedGnssLocationsReportingCallback(const napi_env & env,const napi_value & handler)1175 bool OffCachedGnssLocationsReportingCallback(const napi_env& env, const napi_value& handler)
1176 {
1177 #ifdef ENABLE_NAPI_MANAGER
1178     LocationErrCode errorCode = CheckLocationSwitchEnable();
1179     if (errorCode != ERRCODE_SUCCESS) {
1180         HandleSyncErrCode(env, errorCode);
1181         return false;
1182     }
1183 #endif
1184     auto cachedCallbackHost = g_cachedLocationCallbacks.GetCallbackPtr(env, handler);
1185     if (cachedCallbackHost) {
1186         auto cachedCallback = sptr<ICachedLocationsCallback>(cachedCallbackHost);
1187 #ifdef ENABLE_NAPI_MANAGER
1188         errorCode = UnSubscribeCacheLocationChangeV9(cachedCallback);
1189         if (errorCode != ERRCODE_SUCCESS) {
1190             HandleSyncErrCode(env, errorCode);
1191             return false;
1192         }
1193 #else
1194         UnSubscribeCacheLocationChange(cachedCallback);
1195 #endif
1196         g_cachedLocationCallbacks.DeleteCallback(env, handler);
1197         cachedCallbackHost->DeleteHandler();
1198         cachedCallbackHost = nullptr;
1199         return true;
1200     } else {
1201         LBSLOGI(LOCATION_NAPI, "%{public}s, the callback is not in the map", __func__);
1202 #ifdef ENABLE_NAPI_MANAGER
1203         HandleSyncErrCode(env, ERRCODE_NOT_SUPPORTED);
1204 #endif
1205     }
1206     return false;
1207 }
1208 
OffCountryCodeChangeCallback(const napi_env & env,const napi_value & handler)1209 bool OffCountryCodeChangeCallback(const napi_env& env, const napi_value& handler)
1210 {
1211     auto callbackHost = g_countryCodeCallbacks.GetCallbackPtr(env, handler);
1212     if (callbackHost) {
1213 #ifdef ENABLE_NAPI_MANAGER
1214         LocationErrCode errorCode = UnsubscribeCountryCodeChangeV9(callbackHost);
1215         if (errorCode != ERRCODE_SUCCESS) {
1216             HandleSyncErrCode(env, errorCode);
1217             return false;
1218         }
1219 #else
1220         UnsubscribeCountryCodeChange(callbackHost);
1221 #endif
1222         g_countryCodeCallbacks.DeleteCallback(env, handler);
1223         callbackHost->DeleteHandler();
1224         callbackHost = nullptr;
1225         return true;
1226     }
1227     return false;
1228 }
1229 
Off(napi_env env,napi_callback_info cbinfo)1230 napi_value Off(napi_env env, napi_callback_info cbinfo)
1231 {
1232     InitOffFuncMap();
1233     size_t argc = PARAM3;
1234     napi_value argv[PARAM3] = {0};
1235     napi_value thisVar = nullptr;
1236     NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
1237     NAPI_ASSERT(env, g_locatorProxy != nullptr, "locator instance is null.");
1238 #ifdef ENABLE_NAPI_MANAGER
1239     if (argc < PARAM1) {
1240         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1241         return UndefinedNapiValue(env);
1242     }
1243 #endif
1244     napi_valuetype eventName = napi_undefined;
1245     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &eventName));
1246 #ifdef ENABLE_NAPI_MANAGER
1247     if (eventName != napi_string) {
1248         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1249         return UndefinedNapiValue(env);
1250     }
1251 #else
1252     NAPI_ASSERT(env, eventName == napi_string, "type mismatch for parameter 1");
1253 #endif
1254     LBSLOGI(LOCATION_NAPI, "Off function entry");
1255 
1256     char type[64] = {0};
1257     size_t typeLen = 0;
1258     NAPI_CALL(env, napi_get_value_string_utf8(env, argv[PARAM0], type, sizeof(type), &typeLen));
1259     std::string event = type;
1260     LBSLOGI(LOCATION_NAPI, "Unsubscribe event: %{public}s", event.c_str());
1261     if (argc == PARAM1) {
1262         auto offAllCallbackFunc = g_offAllFuncMap.find(event);
1263         if (offAllCallbackFunc != g_offAllFuncMap.end() && offAllCallbackFunc->second != nullptr) {
1264             auto memberFunc = offAllCallbackFunc->second;
1265             (*memberFunc)(env);
1266         }
1267     } else if (argc == PARAM2) {
1268 #ifdef ENABLE_NAPI_MANAGER
1269         if (!CheckIfParamIsFunctionType(env, argv[PARAM1])) {
1270             HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1271             return UndefinedNapiValue(env);
1272         }
1273 #else
1274         NAPI_ASSERT(env, CheckIfParamIsFunctionType(env, argv[PARAM1]),
1275             "callback should be function, mismatch for param.");
1276 #endif
1277         auto offCallbackFunc = g_offFuncMap.find(event);
1278         if (offCallbackFunc != g_offFuncMap.end() && offCallbackFunc->second != nullptr) {
1279             auto singleMemberFunc = offCallbackFunc->second;
1280             (*singleMemberFunc)(env, argv[PARAM1]);
1281         }
1282 #ifdef ENABLE_NAPI_MANAGER
1283     } else if (argc == PARAM3 && event == "gnssFenceStatusChange") {
1284         LocationErrCode errorCode = UnSubscribeFenceStatusChangeV9(env, argv[PARAM1], argv[PARAM2]);
1285         if (errorCode != ERRCODE_SUCCESS) {
1286             HandleSyncErrCode(env, errorCode);
1287         }
1288     } else {
1289         HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1290 #else
1291     } else if (argc == PARAM3 && event == "fenceStatusChange") {
1292         UnSubscribeFenceStatusChange(env, argv[PARAM1], argv[PARAM2]);
1293 #endif
1294     }
1295     return UndefinedNapiValue(env);
1296 }
1297 
GetCurrentLocation(napi_env env,napi_callback_info cbinfo)1298 napi_value GetCurrentLocation(napi_env env, napi_callback_info cbinfo)
1299 {
1300     size_t argc = PARAM3;
1301     napi_value argv[PARAM3] = {0};
1302     napi_value thisVar = nullptr;
1303 
1304     NAPI_CALL(env, napi_get_cb_info(env, cbinfo, &argc, argv, &thisVar, nullptr));
1305 
1306     napi_valuetype valueType = napi_undefined;
1307     NAPI_ASSERT(env, g_locatorProxy != nullptr, "locator instance is null.");
1308     LBSLOGI(LOCATION_NAPI, "GetCurrentLocation enter");
1309 
1310     if (argc == PARAM1) {
1311         NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valueType));
1312 #ifdef ENABLE_NAPI_MANAGER
1313         if (valueType != napi_function && valueType != napi_object) {
1314             HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1315             return UndefinedNapiValue(env);
1316         }
1317 #else
1318         NAPI_ASSERT(env, valueType == napi_function || valueType == napi_object, "type mismatch for parameter 2");
1319 #endif
1320     }
1321     if (argc == PARAM2) {
1322         napi_valuetype valueType1 = napi_undefined;
1323         NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valueType));
1324         NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valueType1));
1325 #ifdef ENABLE_NAPI_MANAGER
1326         if (valueType != napi_object || valueType1 != napi_function) {
1327             HandleSyncErrCode(env, ERRCODE_INVALID_PARAM);
1328             return UndefinedNapiValue(env);
1329         }
1330 #else
1331         NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 1");
1332         NAPI_ASSERT(env, valueType1 == napi_function, "type mismatch for parameter 2");
1333 #endif
1334     }
1335 #ifdef ENABLE_NAPI_MANAGER
1336     return RequestLocationOnceV9(env, argc, argv);
1337 #else
1338     return RequestLocationOnce(env, argc, argv);
1339 #endif
1340 }
1341 
1342 #ifdef ENABLE_NAPI_MANAGER
CheckLocationSwitchEnable()1343 LocationErrCode CheckLocationSwitchEnable()
1344 {
1345     bool isEnabled = false;
1346     LocationErrCode errorCode = g_locatorProxy->IsLocationEnabledV9(isEnabled);
1347     if (errorCode != ERRCODE_SUCCESS) {
1348         return errorCode;
1349     }
1350     if (!isEnabled) {
1351         return ERRCODE_SWITCH_OFF;
1352     }
1353     return ERRCODE_SUCCESS;
1354 }
1355 #endif
1356 }  // namespace Location
1357 }  // namespace OHOS
1358