• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #include "constant_definition.h"
17 #include "geofence_sdk.h"
18 #include "geolocationmanager_impl.h"
19 #include "geolocationmanager_utils.h"
20 #include "cached_locations_callback.h"
21 #include "location_error_callback.h"
22 #include "location_switch_callback.h"
23 #include "locator_callback.h"
24 #include "gnss_status_callback.h"
25 #include "nmea_message_callback.h"
26 #include "country_code_callback.h"
27 
28 namespace OHOS {
29 namespace GeoLocationManager {
30 std::list<sptr<LocatorCallback>> g_locationCallbacks;
31 std::list<sptr<LocationErrorCallback>> g_locationErrorCallbackHosts;
32 std::list<sptr<LocationSwitchCallback>> g_switchCallbacks;
33 std::list<sptr<CachedLocationsCallback>> g_cachedLocationCallbacks;
34 std::list<sptr<GnssStatusCallback>> g_gnssStatusInfoCallbacks;
35 std::list<sptr<NmeaMessageCallback>> g_nmeaCallbacks;
36 std::list<sptr<CountryCodeCallback>> g_countryCodeCallbacks;
37 
38 std::unique_ptr<Location::CachedGnssLocationsRequest> cachedRequest =
39     std::make_unique<Location::CachedGnssLocationsRequest>();
40 
41 auto g_locatorProxy = Location::Locator::GetInstance();
42 auto g_geofenceClient = Location::GeofenceManager::GetInstance();
43 
44 const int MIN_TIMEOUTMS_FOR_LOCATIONONCE = 1000;
45 
CreateSingleLocationCallbackHost()46 sptr<LocatorCallback> CreateSingleLocationCallbackHost()
47 {
48     auto callbackHost =
49         sptr<LocatorCallback>(new (std::nothrow) LocatorCallback());
50     if (callbackHost) {
51         callbackHost->SetFixNumber(1);
52     }
53     return callbackHost;
54 }
55 
CjIsRequestConfigValid(const std::unique_ptr<Location::RequestConfig> & config)56 bool CjIsRequestConfigValid(const std::unique_ptr<Location::RequestConfig>& config)
57 {
58     if (config == nullptr) {
59         return false;
60     }
61     if ((config->GetScenario() > Location::SCENE_NO_POWER || config->GetScenario() < Location::SCENE_UNSET) &&
62         (config->GetScenario() > Location::LOCATION_SCENE_DAILY_LIFE_SERVICE ||
63         config->GetScenario() < Location::LOCATION_SCENE_NAVIGATION) &&
64         (config->GetScenario() > Location::LOCATION_SCENE_NO_POWER_CONSUMPTION ||
65         config->GetScenario() < Location::LOCATION_SCENE_HIGH_POWER_CONSUMPTION)) {
66         return false;
67     }
68     if ((config->GetPriority() > Location::PRIORITY_FAST_FIRST_FIX ||
69         config->GetPriority() < Location::PRIORITY_UNSET) &&
70         (config->GetPriority() > Location::LOCATION_PRIORITY_LOCATING_SPEED ||
71         config->GetPriority() < Location::LOCATION_PRIORITY_ACCURACY)) {
72         return false;
73     }
74     if (config->GetTimeOut() < MIN_TIMEOUTMS_FOR_LOCATIONONCE) {
75         return false;
76     }
77     if (config->GetTimeInterval() < 0) {
78         return false;
79     }
80     if (config->GetDistanceInterval() < 0) {
81         return false;
82     }
83     if (config->GetMaxAccuracy() < 0) {
84         return false;
85     }
86     return true;
87 }
88 
CheckLocationSwitchEnable()89 Location::LocationErrCode CheckLocationSwitchEnable()
90 {
91     bool isEnabled = false;
92     Location::LocationErrCode errorCode = g_locatorProxy->IsLocationEnabledV9(isEnabled);
93     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
94         return errorCode;
95     }
96     if (!isEnabled) {
97         return Location::LocationErrCode::ERRCODE_SWITCH_OFF;
98     }
99     return Location::LocationErrCode::ERRCODE_SUCCESS;
100 }
101 
CjGetCurrentLocationType(std::unique_ptr<Location::RequestConfig> & config)102 int CjGetCurrentLocationType(std::unique_ptr<Location::RequestConfig>& config)
103 {
104     if (config->GetPriority() == Location::LOCATION_PRIORITY_ACCURACY ||
105         (config->GetScenario() == Location::SCENE_UNSET && config->GetPriority() == Location::PRIORITY_ACCURACY) ||
106         config->GetScenario() == Location::SCENE_NAVIGATION ||
107         config->GetScenario() == Location::SCENE_TRAJECTORY_TRACKING ||
108         config->GetScenario() == Location::SCENE_CAR_HAILING) {
109         return Location::LOCATION_PRIORITY_ACCURACY;
110     } else {
111         return Location::LOCATION_PRIORITY_LOCATING_SPEED;
112     }
113 }
114 
CheckLocationSwitchState()115 Location::LocationErrCode CheckLocationSwitchState()
116 {
117     bool isEnabled = false;
118     Location::LocationErrCode errorCode = g_locatorProxy->IsLocationEnabledV9(isEnabled);
119     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
120         return errorCode;
121     }
122     if (!isEnabled) {
123         return Location::LocationErrCode::ERRCODE_SWITCH_OFF;
124     }
125     return Location::LocationErrCode::ERRCODE_SUCCESS;
126 }
127 
GetLastLocation(int32_t & errCode)128 CJLocation GetLastLocation(int32_t& errCode)
129 {
130     if (g_locatorProxy == nullptr) {
131         errCode = ERRCODE_MEMORY_ERROR;
132         return CJLocation{0};
133     }
134     errCode = CheckLocationSwitchState();
135     if (errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
136         return CJLocation{0};
137     }
138     std::unique_ptr<Location::Location> loc;
139     errCode = g_locatorProxy->GetCachedLocationV9(loc);
140     if (loc == nullptr) {
141         return CJLocation{0};
142     }
143     return NativeLocationToCJLocation(*loc);
144 }
145 
IsLocationEnabled(int32_t & errCode)146 bool IsLocationEnabled(int32_t& errCode)
147 {
148     if (g_locatorProxy == nullptr) {
149         errCode = ERRCODE_MEMORY_ERROR;
150         return false;
151     }
152     bool isEnabled = false;
153     errCode = g_locatorProxy->IsLocationEnabledV9(isEnabled);
154     return isEnabled;
155 }
156 
IsGeocoderAvailable(int32_t & errCode)157 bool IsGeocoderAvailable(int32_t& errCode)
158 {
159     if (g_locatorProxy == nullptr) {
160         errCode = ERRCODE_MEMORY_ERROR;
161         return false;
162     }
163 
164     bool isAvailable = false;
165     errCode = g_locatorProxy->IsGeoServiceAvailableV9(isAvailable);
166     return isAvailable;
167 }
168 
GetCachedGnssLocationsSize(int32_t & errCode)169 int32_t GetCachedGnssLocationsSize(int32_t& errCode)
170 {
171     if (g_locatorProxy == nullptr) {
172         errCode = ERRCODE_MEMORY_ERROR;
173         return 0;
174     }
175     errCode = CheckLocationSwitchState();
176     if (errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
177         return 0;
178     }
179     int32_t locationSize = -1;
180     g_locatorProxy->GetCachedGnssLocationsSizeV9(locationSize);
181     errCode = Location::LocationErrCode::ERRCODE_NOT_SUPPORTED;
182     return locationSize;
183 }
184 
GetCurrentLocation(int32_t & errCode)185 CJLocation GetCurrentLocation(int32_t& errCode)
186 {
187     auto requestConfig = std::make_unique<Location::RequestConfig>();
188     requestConfig->SetPriority(Location::PRIORITY_FAST_FIRST_FIX);
189     requestConfig->SetFixNumber(1);
190     return GetCurrentLocation(requestConfig, errCode);
191 }
192 
GetCurrentLocationCurrent(CJCurrentLocationRequest request,int32_t & errCode)193 CJLocation GetCurrentLocationCurrent(CJCurrentLocationRequest request, int32_t& errCode)
194 {
195     auto requestConfig = std::make_unique<Location::RequestConfig>();
196     CJCurrentLocationRequestToRequestConfig(request, requestConfig);
197     requestConfig->SetFixNumber(1);
198     return GetCurrentLocation(requestConfig, errCode);
199 }
200 
GetCurrentLocationSingle(CJSingleLocationRequest request,int32_t & errCode)201 CJLocation GetCurrentLocationSingle(CJSingleLocationRequest request, int32_t& errCode)
202 {
203     auto requestConfig = std::make_unique<Location::RequestConfig>();
204     CJSingleLocationRequestRequestToRequestConfig(request, requestConfig);
205     requestConfig->SetFixNumber(1);
206     return GetCurrentLocation(requestConfig, errCode);
207 }
208 
StartLocating(std::unique_ptr<Location::RequestConfig> & requestConfig,sptr<LocatorCallback> singleLocatorCallbackHost,int32_t & errCode)209 void StartLocating(std::unique_ptr<Location::RequestConfig>& requestConfig,
210     sptr<LocatorCallback> singleLocatorCallbackHost, int32_t& errCode)
211 {
212     auto timeout = requestConfig->GetTimeOut();
213     auto request = std::move(requestConfig);
214     auto callbackPtr = sptr<Location::ILocatorCallback>(singleLocatorCallbackHost);
215     errCode = g_locatorProxy->StartLocatingV9(request, callbackPtr);
216     if (errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
217         singleLocatorCallbackHost->SetCount(0);
218         return;
219     }
220     if (timeout > Location::DEFAULT_TIMEOUT_30S) {
221         singleLocatorCallbackHost->Wait(Location::DEFAULT_TIMEOUT_30S);
222         if (singleLocatorCallbackHost->GetSingleLocation() == nullptr) {
223             singleLocatorCallbackHost->Wait(timeout - Location::DEFAULT_TIMEOUT_30S);
224         }
225     } else {
226         singleLocatorCallbackHost->Wait(timeout);
227     }
228     g_locatorProxy->StopLocating(callbackPtr);
229     if (singleLocatorCallbackHost->GetCount() != 0 &&
230         singleLocatorCallbackHost->GetSingleLocation() == nullptr) {
231         std::unique_ptr<Location::Location> location = nullptr;
232         g_locatorProxy->GetCachedLocationV9(location);
233         if (location != nullptr) {
234             singleLocatorCallbackHost->SetSingleLocation(location);
235         } else {
236             errCode = Location::LocationErrCode::ERRCODE_LOCATING_FAIL;
237         }
238     }
239     singleLocatorCallbackHost->SetCount(1);
240 }
241 
GetCurrentLocation(std::unique_ptr<Location::RequestConfig> & requestConfig,int32_t & errCode)242 CJLocation GetCurrentLocation(std::unique_ptr<Location::RequestConfig>& requestConfig, int32_t& errCode)
243 {
244     if (g_locatorProxy == nullptr) {
245         errCode = ERRCODE_MEMORY_ERROR;
246         return CJLocation{0};
247     }
248     auto singleLocatorCallbackHost = CreateSingleLocationCallbackHost();
249     if (!CjIsRequestConfigValid(requestConfig) || singleLocatorCallbackHost == nullptr) {
250         errCode = Location::LocationErrCode::ERRCODE_INVALID_PARAM;
251         return CJLocation{0};
252     }
253     singleLocatorCallbackHost->SetLocationPriority(CjGetCurrentLocationType(requestConfig));
254     errCode = CheckLocationSwitchEnable();
255     if (errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
256         return CJLocation{0};
257     }
258 
259     StartLocating(requestConfig, singleLocatorCallbackHost, errCode);
260     if (errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
261         return CJLocation{0};
262     }
263 
264     std::unique_ptr<Location::Location> location =
265         std::make_unique<Location::Location>(*singleLocatorCallbackHost->GetSingleLocation());
266     if (location == nullptr) {
267         errCode = Location::LocationErrCode::ERRCODE_LOCATING_FAIL;
268         return CJLocation{0};
269     }
270     errCode = Location::LocationErrCode::ERRCODE_SUCCESS;
271     if (singleLocatorCallbackHost) {
272         singleLocatorCallbackHost = nullptr;
273     }
274     return NativeLocationToCJLocation(*location);
275 }
276 
FlushCachedGnssLocations(int32_t & errCode)277 void FlushCachedGnssLocations(int32_t& errCode)
278 {
279     if (g_locatorProxy == nullptr) {
280         errCode = ERRCODE_MEMORY_ERROR;
281         return;
282     }
283     Location::LocationErrCode errorCode = CheckLocationSwitchState();
284     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
285         errCode = errorCode;
286         return;
287     }
288     g_locatorProxy->FlushCachedGnssLocationsV9();
289     errCode = Location::LocationErrCode::ERRCODE_NOT_SUPPORTED;
290 }
291 
SendCommand(CJLocationCommand command,int32_t & errCode)292 void SendCommand(CJLocationCommand command, int32_t& errCode)
293 {
294     if (g_locatorProxy == nullptr) {
295         errCode = ERRCODE_MEMORY_ERROR;
296         return;
297     }
298     auto ptr = std::make_unique<Location::LocationCommand>();
299     ptr->scenario = command.scenario;
300     ptr->command = command.command;
301     errCode = g_locatorProxy->SendCommandV9(ptr);
302 }
303 
GetCountryCode(int32_t & errCode)304 CJCountryCode GetCountryCode(int32_t& errCode)
305 {
306     if (g_locatorProxy == nullptr) {
307         errCode = ERRCODE_MEMORY_ERROR;
308         return CJCountryCode{0};
309     }
310     std::shared_ptr<Location::CountryCode> country = std::make_shared<Location::CountryCode>();
311     errCode = g_locatorProxy->GetIsoCountryCodeV9(country);
312     return CJCountryCode{ .country = MallocCString(country->GetCountryCodeStr()),
313         .type = country->GetCountryCodeType() };
314 }
315 
GetAddressesFromLocation(CJReverseGeoCodeRequest request,int32_t & errCode)316 CJGeoAddressArr GetAddressesFromLocation(CJReverseGeoCodeRequest request, int32_t& errCode)
317 {
318     if (g_locatorProxy == nullptr) {
319         errCode = ERRCODE_MEMORY_ERROR;
320         return CJGeoAddressArr{0};
321     }
322     MessageParcel reverseGeoCodeRequest;
323     bool ret = CJReverseGeoCodeRequestToMessageParcel(request, reverseGeoCodeRequest);
324     if (!ret) {
325         errCode = Location::LocationErrCode::ERRCODE_INVALID_PARAM;
326         return CJGeoAddressArr{0};
327     }
328 
329     bool isAvailable = false;
330     errCode = g_locatorProxy->IsGeoServiceAvailableV9(isAvailable);
331     if (errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
332         return CJGeoAddressArr{0};
333     }
334     if (!isAvailable) {
335         errCode = Location::LocationErrCode::ERRCODE_REVERSE_GEOCODING_FAIL;
336         return CJGeoAddressArr{0};
337     }
338     std::list<std::shared_ptr<Location::GeoAddress>> replyList;
339     errCode = g_locatorProxy->GetAddressByCoordinateV9(reverseGeoCodeRequest, replyList);
340     if (replyList.empty() || errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
341         return CJGeoAddressArr{0};
342     }
343     return ListGeoAddressToCJGeoAddressArr(replyList);
344 }
345 
GetAddressesFromLocationName(CJGeoCodeRequest request,int32_t & errCode)346 CJGeoAddressArr GetAddressesFromLocationName(CJGeoCodeRequest request, int32_t& errCode)
347 {
348     if (g_locatorProxy == nullptr) {
349         errCode = ERRCODE_MEMORY_ERROR;
350         return CJGeoAddressArr{0};
351     }
352     MessageParcel geoCodeRequest;
353     bool ret = CJGeoCodeRequestToMessageParcel(request, geoCodeRequest);
354     if (!ret) {
355         errCode = Location::LocationErrCode::ERRCODE_INVALID_PARAM;
356         return CJGeoAddressArr{0};
357     }
358 
359     bool isAvailable = false;
360     errCode = g_locatorProxy->IsGeoServiceAvailableV9(isAvailable);
361     if (errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
362         return CJGeoAddressArr{0};
363     }
364     if (!isAvailable) {
365         errCode = Location::LocationErrCode::ERRCODE_GEOCODING_FAIL;
366         return CJGeoAddressArr{0};
367     }
368     std::list<std::shared_ptr<Location::GeoAddress>> replyList;
369     errCode = g_locatorProxy->GetAddressByLocationNameV9(geoCodeRequest, replyList);
370     if (replyList.empty() || errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
371         return CJGeoAddressArr{0};
372     }
373     return ListGeoAddressToCJGeoAddressArr(replyList);
374 }
375 
OnLocationChange(std::unique_ptr<OHOS::Location::RequestConfig> & requestConfig,int64_t callbackId)376 int32_t OnLocationChange(std::unique_ptr<OHOS::Location::RequestConfig>& requestConfig, int64_t callbackId)
377 {
378     if (g_locatorProxy == nullptr) {
379         return ERRCODE_MEMORY_ERROR;
380     }
381     Location::LocationErrCode errorCode = CheckLocationSwitchEnable();
382     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
383         return errorCode;
384     }
385     if (!CjIsRequestConfigValid(requestConfig)) {
386         return Location::LocationErrCode::ERRCODE_INVALID_PARAM;
387     }
388     auto locatorCallbackHost = sptr<LocatorCallback>(new (std::nothrow) LocatorCallback(callbackId));
389     if (locatorCallbackHost == nullptr) {
390         return ERRCODE_MEMORY_ERROR;
391     }
392     auto locatorCallback = sptr<Location::ILocatorCallback>(locatorCallbackHost);
393     errorCode = g_locatorProxy->StartLocatingV9(requestConfig, locatorCallback);
394     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
395         return errorCode;
396     }
397     g_locationCallbacks.push_back(locatorCallbackHost);
398     return errorCode;
399 }
400 
OnLocationRequest(CJLocationRequest request,int64_t callbackId)401 int32_t OnLocationRequest(CJLocationRequest request, int64_t callbackId)
402 {
403     auto requestConfig = std::make_unique<Location::RequestConfig>();
404     CJLocationRequestToRequestConfig(request, requestConfig);
405     return OnLocationChange(requestConfig, callbackId);
406 }
407 
OnContinuousLocationRequest(CJContinuousLocationRequest request,int64_t callbackId)408 int32_t OnContinuousLocationRequest(CJContinuousLocationRequest request, int64_t callbackId)
409 {
410     auto requestConfig = std::make_unique<Location::RequestConfig>();
411     CJContinuousLocationRequestToRequestConfig(request, requestConfig);
412     return OnLocationChange(requestConfig, callbackId);
413 }
414 
OffLocationChange(int64_t callbackId)415 int32_t OffLocationChange(int64_t callbackId)
416 {
417     if (g_locatorProxy == nullptr) {
418         return ERRCODE_MEMORY_ERROR;
419     }
420     for (auto it = g_locationCallbacks.begin(); it != g_locationCallbacks.end();) {
421         if (*it == nullptr) {
422             it = g_locationCallbacks.erase(it);
423             continue;
424         }
425         if (((**it).GetCallBackId() != callbackId)) {
426             ++it;
427             continue;
428         }
429         auto locatorCallback = sptr<Location::ILocatorCallback>(*it);
430         Location::LocationErrCode errorCode = g_locatorProxy->StopLocatingV9(locatorCallback);
431         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
432             return errorCode;
433         }
434         it = g_locationCallbacks.erase(it);
435     }
436     return Location::LocationErrCode::ERRCODE_SUCCESS;
437 }
438 
OffLocationChangeAll()439 int32_t OffLocationChangeAll()
440 {
441     if (g_locatorProxy == nullptr) {
442         return ERRCODE_MEMORY_ERROR;
443     }
444     for (auto it = g_locationCallbacks.begin(); it != g_locationCallbacks.end();) {
445         if (*it == nullptr) {
446             it = g_locationCallbacks.erase(it);
447             continue;
448         }
449         auto locatorCallback = sptr<Location::ILocatorCallback>(*it);
450         Location::LocationErrCode errorCode = g_locatorProxy->StopLocatingV9(locatorCallback);
451         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
452             return errorCode;
453         }
454         it = g_locationCallbacks.erase(it);
455     }
456     return Location::LocationErrCode::ERRCODE_SUCCESS;
457 }
458 
OnLocationError(int64_t callbackId)459 int32_t OnLocationError(int64_t callbackId)
460 {
461     if (g_locatorProxy == nullptr) {
462         return ERRCODE_MEMORY_ERROR;
463     }
464     auto locationErrorCallbackHost = sptr<LocationErrorCallback>(new (std::nothrow) LocationErrorCallback(callbackId));
465     if (locationErrorCallbackHost == nullptr) {
466         return ERRCODE_MEMORY_ERROR;
467     }
468     auto locationErrorCallback = sptr<Location::ILocatorCallback>(locationErrorCallbackHost);
469     Location::LocationErrCode errorCode = g_locatorProxy->SubscribeLocationError(locationErrorCallback);
470     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
471         return errorCode;
472     }
473     g_locationErrorCallbackHosts.push_back(locationErrorCallbackHost);
474     return errorCode;
475 }
476 
OffLocationError(int64_t callbackId)477 int32_t OffLocationError(int64_t callbackId)
478 {
479     if (g_locatorProxy == nullptr) {
480         return ERRCODE_MEMORY_ERROR;
481     }
482     for (auto it = g_locationErrorCallbackHosts.begin(); it != g_locationErrorCallbackHosts.end();) {
483         if (*it == nullptr) {
484             it = g_locationErrorCallbackHosts.erase(it);
485             continue;
486         }
487         if (((**it).GetCallBackId() != callbackId)) {
488             ++it;
489             continue;
490         }
491         auto locatorCallback = sptr<Location::ILocatorCallback>(*it);
492         Location::LocationErrCode errorCode = g_locatorProxy->UnSubscribeLocationError(locatorCallback);
493         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
494             return errorCode;
495         }
496         it = g_locationErrorCallbackHosts.erase(it);
497     }
498     return Location::LocationErrCode::ERRCODE_SUCCESS;
499 }
500 
OffLocationErrorAll()501 int32_t OffLocationErrorAll()
502 {
503     if (g_locatorProxy == nullptr) {
504         return ERRCODE_MEMORY_ERROR;
505     }
506     for (auto it = g_locationErrorCallbackHosts.begin(); it != g_locationErrorCallbackHosts.end();) {
507         if (*it == nullptr) {
508             it = g_locationErrorCallbackHosts.erase(it);
509             continue;
510         }
511         auto locatorCallback = sptr<Location::ILocatorCallback>(*it);
512         Location::LocationErrCode errorCode = g_locatorProxy->UnSubscribeLocationError(locatorCallback);
513         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
514             return errorCode;
515         }
516         it = g_locationErrorCallbackHosts.erase(it);
517     }
518     return Location::LocationErrCode::ERRCODE_SUCCESS;
519 }
520 
OnLocationEnabledChange(int64_t callbackId)521 int32_t OnLocationEnabledChange(int64_t callbackId)
522 {
523     if (g_locatorProxy == nullptr) {
524         return ERRCODE_MEMORY_ERROR;
525     }
526     auto switchCallbackHost = sptr<LocationSwitchCallback>(new (std::nothrow) LocationSwitchCallback(callbackId));
527     if (switchCallbackHost == nullptr) {
528         return ERRCODE_MEMORY_ERROR;
529     }
530     Location::LocationErrCode errorCode = g_locatorProxy->RegisterSwitchCallbackV9(switchCallbackHost);
531     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
532         return errorCode;
533     }
534     g_switchCallbacks.push_back(switchCallbackHost);
535     return errorCode;
536 }
537 
OffLocationEnabledChange(int64_t callbackId)538 int32_t OffLocationEnabledChange(int64_t callbackId)
539 {
540     if (g_locatorProxy == nullptr) {
541         return ERRCODE_MEMORY_ERROR;
542     }
543     for (auto it = g_switchCallbacks.begin(); it != g_switchCallbacks.end();) {
544         if (*it == nullptr) {
545             it = g_switchCallbacks.erase(it);
546             continue;
547         }
548         if (((**it).GetCallBackId() != callbackId)) {
549             ++it;
550             continue;
551         }
552         Location::LocationErrCode errorCode = g_locatorProxy->UnregisterSwitchCallbackV9(*it);
553         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
554             return errorCode;
555         }
556         it = g_switchCallbacks.erase(it);
557     }
558     return Location::LocationErrCode::ERRCODE_SUCCESS;
559 }
560 
OffLocationEnabledChangeAll()561 int32_t OffLocationEnabledChangeAll()
562 {
563     if (g_locatorProxy == nullptr) {
564         return ERRCODE_MEMORY_ERROR;
565     }
566     for (auto it = g_switchCallbacks.begin(); it != g_switchCallbacks.end();) {
567         if (*it == nullptr) {
568             it = g_switchCallbacks.erase(it);
569             continue;
570         }
571         Location::LocationErrCode errorCode = g_locatorProxy->UnregisterSwitchCallbackV9(*it);
572         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
573             return errorCode;
574         }
575         it = g_switchCallbacks.erase(it);
576     }
577     return Location::LocationErrCode::ERRCODE_SUCCESS;
578 }
579 
OnCachedGnssLocationsChange(CJCachedGnssLocationsRequest request,int64_t callbackId)580 int32_t OnCachedGnssLocationsChange(CJCachedGnssLocationsRequest request,
581     int64_t callbackId)
582 {
583     if (g_locatorProxy == nullptr) {
584         return ERRCODE_MEMORY_ERROR;
585     }
586     CJCachedGnssLocationsRequestToCachedLocationRequest(request, cachedRequest);
587     auto cachedCallbackHost = sptr<CachedLocationsCallback>(new (std::nothrow) CachedLocationsCallback(callbackId));
588     if (cachedCallbackHost == nullptr) {
589         return ERRCODE_MEMORY_ERROR;
590     }
591     Location::LocationErrCode errorCode = CheckLocationSwitchEnable();
592     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
593         return errorCode;
594     }
595     auto cachedCallback = sptr<Location::ICachedLocationsCallback>(cachedCallbackHost);
596     errorCode = g_locatorProxy->RegisterCachedLocationCallbackV9(cachedRequest, cachedCallback);
597     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
598         return Location::LocationErrCode::ERRCODE_NOT_SUPPORTED;
599     }
600     g_cachedLocationCallbacks.push_back(cachedCallbackHost);
601     return errorCode;
602 }
603 
OffCachedGnssLocationsChange(int64_t callbackId)604 int32_t OffCachedGnssLocationsChange(int64_t callbackId)
605 {
606     if (g_locatorProxy == nullptr) {
607         return ERRCODE_MEMORY_ERROR;
608     }
609     for (auto it = g_cachedLocationCallbacks.begin(); it != g_cachedLocationCallbacks.end();) {
610         if (*it == nullptr) {
611             it = g_cachedLocationCallbacks.erase(it);
612             continue;
613         }
614         if (((**it).GetCallBackId() != callbackId)) {
615             ++it;
616             continue;
617         }
618         auto cachedCallback = sptr<Location::ICachedLocationsCallback>(*it);
619         g_locatorProxy->UnregisterCachedLocationCallbackV9(cachedCallback);
620         Location::LocationErrCode errorCode = Location::LocationErrCode::ERRCODE_NOT_SUPPORTED;
621         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
622             return errorCode;
623         }
624         it = g_cachedLocationCallbacks.erase(it);
625     }
626     return Location::LocationErrCode::ERRCODE_SUCCESS;
627 }
628 
OffCachedGnssLocationsChangeAll()629 int32_t OffCachedGnssLocationsChangeAll()
630 {
631     if (g_locatorProxy == nullptr) {
632         return ERRCODE_MEMORY_ERROR;
633     }
634     for (auto it = g_cachedLocationCallbacks.begin(); it != g_cachedLocationCallbacks.end();) {
635         if (*it == nullptr) {
636             it = g_cachedLocationCallbacks.erase(it);
637             continue;
638         }
639         auto cachedCallback = sptr<Location::ICachedLocationsCallback>(*it);
640         g_locatorProxy->UnregisterCachedLocationCallbackV9(cachedCallback);
641         Location::LocationErrCode errorCode = Location::LocationErrCode::ERRCODE_NOT_SUPPORTED;
642         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
643             return errorCode;
644         }
645         it = g_cachedLocationCallbacks.erase(it);
646     }
647     return Location::LocationErrCode::ERRCODE_SUCCESS;
648 }
649 
OnSatelliteStatusChange(int64_t callbackId)650 int32_t OnSatelliteStatusChange(int64_t callbackId)
651 {
652     if (g_locatorProxy == nullptr) {
653         return ERRCODE_MEMORY_ERROR;
654     }
655     auto gnssCallbackHost = sptr<GnssStatusCallback>(new (std::nothrow) GnssStatusCallback(callbackId));
656     if (gnssCallbackHost == nullptr) {
657         return ERRCODE_MEMORY_ERROR;
658     }
659     Location::LocationErrCode errorCode = CheckLocationSwitchEnable();
660     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
661         return errorCode;
662     }
663     errorCode = g_locatorProxy->RegisterGnssStatusCallbackV9(gnssCallbackHost);
664     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
665         return errorCode;
666     }
667     g_gnssStatusInfoCallbacks.push_back(gnssCallbackHost);
668     return errorCode;
669 }
670 
OffSatelliteStatusChange(int64_t callbackId)671 int32_t OffSatelliteStatusChange(int64_t callbackId)
672 {
673     if (g_locatorProxy == nullptr) {
674         return ERRCODE_MEMORY_ERROR;
675     }
676     for (auto it = g_gnssStatusInfoCallbacks.begin(); it != g_gnssStatusInfoCallbacks.end();) {
677         if (*it == nullptr) {
678             it = g_gnssStatusInfoCallbacks.erase(it);
679             continue;
680         }
681         if (((**it).GetCallBackId() != callbackId)) {
682             ++it;
683             continue;
684         }
685         Location::LocationErrCode errorCode = g_locatorProxy->UnregisterGnssStatusCallbackV9(*it);
686         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
687             return errorCode;
688         }
689         it = g_gnssStatusInfoCallbacks.erase(it);
690     }
691     return Location::LocationErrCode::ERRCODE_SUCCESS;
692 }
693 
OffSatelliteStatusChangeAll()694 int32_t OffSatelliteStatusChangeAll()
695 {
696     if (g_locatorProxy == nullptr) {
697         return ERRCODE_MEMORY_ERROR;
698     }
699     for (auto it = g_gnssStatusInfoCallbacks.begin(); it != g_gnssStatusInfoCallbacks.end();) {
700         if (*it == nullptr) {
701             it = g_gnssStatusInfoCallbacks.erase(it);
702             continue;
703         }
704         Location::LocationErrCode errorCode = g_locatorProxy->UnregisterGnssStatusCallbackV9(*it);
705         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
706             return errorCode;
707         }
708         it = g_gnssStatusInfoCallbacks.erase(it);
709     }
710     return Location::LocationErrCode::ERRCODE_SUCCESS;
711 }
712 
OnNmeaMessage(int64_t callbackId)713 int32_t OnNmeaMessage(int64_t callbackId)
714 {
715     if (g_locatorProxy == nullptr) {
716         return ERRCODE_MEMORY_ERROR;
717     }
718     auto nmeaCallbackHost = sptr<NmeaMessageCallback>(new (std::nothrow) NmeaMessageCallback(callbackId));
719     if (nmeaCallbackHost == nullptr) {
720         return ERRCODE_MEMORY_ERROR;
721     }
722     Location::LocationErrCode errorCode = CheckLocationSwitchEnable();
723     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
724         return errorCode;
725     }
726     errorCode = g_locatorProxy->RegisterNmeaMessageCallbackV9(nmeaCallbackHost);
727     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
728         return errorCode;
729     }
730     g_nmeaCallbacks.push_back(nmeaCallbackHost);
731     return errorCode;
732 }
733 
OffNmeaMessage(int64_t callbackId)734 int32_t OffNmeaMessage(int64_t callbackId)
735 {
736     if (g_locatorProxy == nullptr) {
737         return ERRCODE_MEMORY_ERROR;
738     }
739     for (auto it = g_nmeaCallbacks.begin(); it != g_nmeaCallbacks.end();) {
740         if (*it == nullptr) {
741             it = g_nmeaCallbacks.erase(it);
742             continue;
743         }
744         if (((**it).GetCallBackId() != callbackId)) {
745             ++it;
746             continue;
747         }
748         Location::LocationErrCode errorCode = g_locatorProxy->UnregisterNmeaMessageCallbackV9(*it);
749         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
750             return errorCode;
751         }
752         it = g_nmeaCallbacks.erase(it);
753     }
754     return Location::LocationErrCode::ERRCODE_SUCCESS;
755 }
756 
OffNmeaMessageAll()757 int32_t OffNmeaMessageAll()
758 {
759     if (g_locatorProxy == nullptr) {
760         return ERRCODE_MEMORY_ERROR;
761     }
762     for (auto it = g_nmeaCallbacks.begin(); it != g_nmeaCallbacks.end();) {
763         if (*it == nullptr) {
764             it = g_nmeaCallbacks.erase(it);
765             continue;
766         }
767         Location::LocationErrCode errorCode = g_locatorProxy->UnregisterNmeaMessageCallbackV9(*it);
768         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
769             return errorCode;
770         }
771         it = g_nmeaCallbacks.erase(it);
772     }
773     return Location::LocationErrCode::ERRCODE_SUCCESS;
774 }
775 
OnCountryCodeChange(int64_t callbackId)776 int32_t OnCountryCodeChange(int64_t callbackId)
777 {
778     if (g_locatorProxy == nullptr) {
779         return ERRCODE_MEMORY_ERROR;
780     }
781     auto callbackHost = sptr<CountryCodeCallback>(new (std::nothrow) CountryCodeCallback(callbackId));
782     if (callbackHost == nullptr) {
783         return ERRCODE_MEMORY_ERROR;
784     }
785     auto callbackPtr = sptr<Location::ICountryCodeCallback>(callbackHost);
786     Location::LocationErrCode errorCode = g_locatorProxy->RegisterCountryCodeCallbackV9(callbackPtr->AsObject());
787     if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
788         return errorCode;
789     }
790     g_countryCodeCallbacks.push_back(callbackHost);
791     return errorCode;
792 }
793 
OffCountryCodeChange(int64_t callbackId)794 int32_t OffCountryCodeChange(int64_t callbackId)
795 {
796     if (g_locatorProxy == nullptr) {
797         return ERRCODE_MEMORY_ERROR;
798     }
799     for (auto it = g_countryCodeCallbacks.begin(); it != g_countryCodeCallbacks.end();) {
800         if (*it == nullptr) {
801             it = g_countryCodeCallbacks.erase(it);
802             continue;
803         }
804         if (((**it).GetCallBackId() != callbackId)) {
805             ++it;
806             continue;
807         }
808         Location::LocationErrCode errorCode = g_locatorProxy->UnregisterCountryCodeCallbackV9(*it);
809         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
810             return errorCode;
811         }
812         it = g_countryCodeCallbacks.erase(it);
813     }
814     return Location::LocationErrCode::ERRCODE_SUCCESS;
815 }
816 
OffCountryCodeChangeAll()817 int32_t OffCountryCodeChangeAll()
818 {
819     if (g_locatorProxy == nullptr) {
820         return ERRCODE_MEMORY_ERROR;
821     }
822     for (auto it = g_countryCodeCallbacks.begin(); it != g_countryCodeCallbacks.end();) {
823         if (*it == nullptr) {
824             it = g_countryCodeCallbacks.erase(it);
825             continue;
826         }
827         Location::LocationErrCode errorCode = g_locatorProxy->UnregisterCountryCodeCallbackV9(*it);
828         if (errorCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
829             return errorCode;
830         }
831         it = g_countryCodeCallbacks.erase(it);
832     }
833     return Location::LocationErrCode::ERRCODE_SUCCESS;
834 }
835 
GetGeofenceSupportedCoordTypes(int32_t & errCode)836 CArrI32 GetGeofenceSupportedCoordTypes(int32_t& errCode)
837 {
838     CArrI32 res = CArrI32{0};
839     if (g_geofenceClient == nullptr) {
840         errCode = ERRCODE_MEMORY_ERROR;
841         return res;
842     }
843     std::vector<Location::CoordinateSystemType> coordinateSystemTypes;
844     errCode = g_geofenceClient->GetGeofenceSupportedCoordTypes(coordinateSystemTypes);
845     if (errCode != Location::LocationErrCode::ERRCODE_SUCCESS) {
846         return res;
847     }
848     if (coordinateSystemTypes.size() == 0) {
849         return res;
850     }
851     int32_t* head = static_cast<int32_t*>(malloc(sizeof(int32_t) * coordinateSystemTypes.size()));
852     if (head == nullptr) {
853         errCode = ERRCODE_MEMORY_ERROR;
854         return res;
855     }
856     for (size_t i = 0; i < coordinateSystemTypes.size(); i++) {
857         head[i] = coordinateSystemTypes[i];
858     }
859     res.head = head;
860     res.size = static_cast<int64_t>(coordinateSystemTypes.size());
861     return res;
862 }
863 }
864 }
865