• 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 
16 #include "report_manager.h"
17 
18 #include <cmath>
19 #include "privacy_kit.h"
20 #include "common_utils.h"
21 #include "fusion_controller.h"
22 #include "i_locator_callback.h"
23 #include "location_log.h"
24 #include "locator_ability.h"
25 #include "locator_background_proxy.h"
26 #include "location_log_event_ids.h"
27 #include "location_data_rdb_manager.h"
28 #include "common_hisysevent.h"
29 #include "permission_manager.h"
30 #include "hook_utils.h"
31 #include "poi_info_manager.h"
32 #include "parameter.h"
33 
34 namespace OHOS {
35 namespace Location {
36 const long NANOS_PER_MILLI = 1000000L;
37 const int MAX_SA_SCHEDULING_JITTER_MS = 200;
38 static constexpr double MAXIMUM_FUZZY_LOCATION_DISTANCE = 4000.0; // Unit m
39 static constexpr double MINIMUM_FUZZY_LOCATION_DISTANCE = 3000.0; // Unit m
40 static constexpr int CACHED_TIME = 25;
41 static constexpr int MAX_LOCATION_REPORT_DELAY_TIME = 30000; // Unit ms
42 static constexpr int MIN_RESET_TIME_THRESHOLD = 1 * 60 * 60 * 1000; // Unit ms
43 
GetInstance()44 ReportManager* ReportManager::GetInstance()
45 {
46     static ReportManager data;
47     return &data;
48 }
49 
ReportManager()50 ReportManager::ReportManager()
51 {
52     clock_gettime(CLOCK_REALTIME, &lastUpdateTime_);
53     offsetRandom_ = CommonUtils::DoubleRandom(0, 1);
54     lastResetRecordTime_ = CommonUtils::GetSinceBootTime();
55 }
56 
~ReportManager()57 ReportManager::~ReportManager() {}
58 
OnReportLocation(const std::unique_ptr<Location> & location,std::string abilityName)59 bool ReportManager::OnReportLocation(const std::unique_ptr<Location>& location, std::string abilityName)
60 {
61     auto fusionController = FusionController::GetInstance();
62     PoiInfoManager::GetInstance()->UpdateCachedPoiInfo(location);
63     UpdateCacheLocation(location, abilityName);
64     auto locatorAbility = LocatorAbility::GetInstance();
65     auto requestMap = locatorAbility->GetRequests();
66     if (requestMap == nullptr) {
67         return false;
68     }
69     auto requestListIter = requestMap->find(abilityName);
70     if (requestListIter == requestMap->end()) {
71         return false;
72     }
73     auto requestList = requestListIter->second;
74     auto deadRequests = std::make_unique<std::list<std::shared_ptr<Request>>>();
75     for (auto iter = requestList.begin(); iter != requestList.end(); iter++) {
76         auto request = *iter;
77         WriteNetWorkReportEvent(abilityName, request, location);
78         if (abilityName == NETWORK_ABILITY) {
79             if (request->GetUuid() == location->GetUuid() || location->GetIsFromMock()) {
80                 ProcessRequestForReport(request, deadRequests, location, abilityName);
81                 break;
82             }
83         } else if (abilityName == GNSS_ABILITY || abilityName == PASSIVE_ABILITY) {
84             ProcessRequestForReport(request, deadRequests, location, abilityName);
85         }
86     }
87     for (auto iter = deadRequests->begin(); iter != deadRequests->end(); ++iter) {
88         auto request = *iter;
89         if (request == nullptr) {
90             continue;
91         }
92         auto requestManger = RequestManager::GetInstance();
93         if (requestManger != nullptr) {
94             requestManger->UpdateRequestRecord(request, false);
95             requestManger->UpdateUsingPermission(request, false);
96         }
97     }
98     if (deadRequests->size() > 0) {
99         locatorAbility->ApplyRequests(1);
100         deadRequests->clear();
101     }
102     return true;
103 }
104 
UpdateLocationByRequest(const uint32_t tokenId,const uint64_t tokenIdEx,std::unique_ptr<Location> & location)105 void ReportManager::UpdateLocationByRequest(const uint32_t tokenId, const uint64_t tokenIdEx,
106     std::unique_ptr<Location>& location)
107 {
108     if (location == nullptr) {
109         return;
110     }
111     if (!PermissionManager::CheckSystemPermission(tokenId, tokenIdEx)) {
112         location->SetIsSystemApp(0);
113     } else {
114         location->SetIsSystemApp(1);
115     }
116 }
117 
ProcessRequestForReport(std::shared_ptr<Request> & request,std::unique_ptr<std::list<std::shared_ptr<Request>>> & deadRequests,const std::unique_ptr<Location> & location,std::string abilityName)118 bool ReportManager::ProcessRequestForReport(std::shared_ptr<Request>& request,
119     std::unique_ptr<std::list<std::shared_ptr<Request>>>& deadRequests,
120     const std::unique_ptr<Location>& location, std::string abilityName)
121 {
122     if (location == nullptr ||
123         request == nullptr || request->GetRequestConfig() == nullptr || !request->GetIsRequesting()) {
124         return false;
125     }
126     std::unique_ptr<Location> fuseLocation;
127     std::unique_ptr<Location> finalLocation;
128     if (IsRequestFuse(request)) {
129         if (request->GetBestLocation() == nullptr ||
130             request->GetBestLocation()->GetLocationSourceType() == 0) {
131             request->SetBestLocation(std::make_unique<Location>(cacheGnssLocation_));
132         }
133         fuseLocation = FusionController::GetInstance()->GetFuseLocation(location, request->GetBestLocation());
134         if (request->GetLastLocation() != nullptr && request->GetLastLocation()->LocationEqual(fuseLocation)) {
135             return false;
136         }
137         NeedUpdateTimeStamp(fuseLocation, request);
138         request->SetBestLocation(fuseLocation);
139     }
140     if (LocationDataRdbManager::QuerySwitchState() != ENABLED &&
141         !LocatorAbility::GetInstance()->GetLocationSwitchIgnoredFlag(request->GetTokenId())) {
142         LBSLOGE(REPORT_MANAGER, "QuerySwitchState is DISABLED");
143         return false;
144     }
145     auto locatorAbility = LocatorAbility::GetInstance();
146     finalLocation = GetPermittedLocation(request, IsRequestFuse(request) ? fuseLocation : location);
147     if (!ResultCheck(finalLocation, request)) {
148         // add location permission using record
149         int permUsedType = request->GetPermUsedType();
150         locatorAbility->UpdatePermissionUsedRecord(request->GetTokenId(),
151             ACCESS_APPROXIMATELY_LOCATION, permUsedType, 0, 1);
152         return false;
153     }
154     LocationReportDelayTimeCheck(finalLocation, request);
155     UpdateLocationByRequest(request->GetTokenId(), request->GetTokenIdEx(), finalLocation);
156     finalLocation = ExecuteReportProcess(request, finalLocation, abilityName);
157     if (finalLocation == nullptr) {
158         LBSLOGE(REPORT_MANAGER, "%{public}s no need report location", __func__);
159         return false;
160     }
161     bool isNeedPoi = request->GetRequestConfig()->GetIsNeedPoi();
162     if (isNeedPoi && PermissionManager::CheckLocationPermission(request->GetTokenId(), request->GetFirstTokenId())) {
163         PoiInfoManager::GetInstance()->UpdateLocationPoiInfo(finalLocation);
164     }
165     request->SetLastLocation(finalLocation);
166     if (!ReportLocationByCallback(request, finalLocation)) {
167         return false;
168     }
169     int fixTime = request->GetRequestConfig()->GetFixNumber();
170     if (fixTime > 0 && !request->GetRequestConfig()->IsRequestForAccuracy()) {
171         deadRequests->push_back(request);
172         return false;
173     }
174     return true;
175 }
176 
ReportLocationByCallback(std::shared_ptr<Request> & request,const std::unique_ptr<Location> & finalLocation)177 bool ReportManager::ReportLocationByCallback(std::shared_ptr<Request>& request,
178     const std::unique_ptr<Location>& finalLocation)
179 {
180     auto locatorCallback = request->GetLocatorCallBack();
181     if (locatorCallback != nullptr) {
182         // add location permission using record
183         auto locatorAbility = LocatorAbility::GetInstance();
184         int ret = locatorAbility->UpdatePermissionUsedRecord(request->GetTokenId(),
185             ACCESS_APPROXIMATELY_LOCATION, request->GetPermUsedType(), 1, 0);
186         if (ret != ERRCODE_SUCCESS && locatorAbility->IsHapCaller(request->GetTokenId())) {
187             LBSLOGE(REPORT_MANAGER, "UpdatePermissionUsedRecord failed ret=%{public}d", ret);
188             RequestManager::GetInstance()->ReportLocationError(LOCATING_FAILED_LOCATION_PERMISSION_DENIED, request);
189             return false;
190         }
191         LBSLOGW(REPORT_MANAGER, "report location to %{public}d, uuid : %{public}s, bundleName : %{public}s," \
192             "uid : %{public}d, TimeSinceBoot : %{public}s, SourceType : %{public}d",
193             request->GetTokenId(), request->GetUuid().c_str(), request->GetPackageName().c_str(), request->GetUid(),
194             std::to_string(finalLocation->GetTimeSinceBoot()).c_str(), finalLocation->GetLocationSourceType());
195         locatorCallback->OnLocationReport(finalLocation);
196         RequestManager::GetInstance()->UpdateLocationError(request);
197     }
198     return true;
199 }
200 
LocationReportDelayTimeCheck(const std::unique_ptr<Location> & location,const std::shared_ptr<Request> & request)201 void ReportManager::LocationReportDelayTimeCheck(const std::unique_ptr<Location>& location,
202     const std::shared_ptr<Request>& request)
203 {
204     if (location == nullptr || request == nullptr) {
205         return;
206     }
207     int64_t currentTime = CommonUtils::GetSinceBootTime();
208     long deltaMs = (currentTime - location->GetTimeSinceBoot()) / NANOS_PER_MILLI;
209     if (deltaMs > MAX_LOCATION_REPORT_DELAY_TIME) {
210         long recordDeltaMs = (currentTime - lastResetRecordTime_) / NANOS_PER_MILLI;
211         if (recordDeltaMs < MIN_RESET_TIME_THRESHOLD) {
212             return;
213         }
214         LBSLOGE(REPORT_MANAGER, "%{public}s: %{public}d check fail, current deltaMs = %{public}ld", __func__,
215             request->GetTokenId(), deltaMs);
216         lastResetRecordTime_ = currentTime;
217         _exit(0);
218     }
219 }
220 
ExecuteReportProcess(std::shared_ptr<Request> & request,std::unique_ptr<Location> & location,std::string abilityName)221 std::unique_ptr<Location> ReportManager::ExecuteReportProcess(std::shared_ptr<Request>& request,
222     std::unique_ptr<Location>& location, std::string abilityName)
223 {
224     LocationSupplicantInfo reportStruct;
225     reportStruct.request = *request;
226     reportStruct.location = *location;
227     reportStruct.abilityName = abilityName;
228     reportStruct.retCode = true;
229     HookUtils::ExecuteHook(
230         LocationProcessStage::LOCATOR_SA_LOCATION_REPORT_PROCESS, (void *)&reportStruct, nullptr);
231     if (!reportStruct.retCode) {
232         return nullptr;
233     }
234     return std::make_unique<Location>(reportStruct.location);
235 }
236 
ExecuteLocationProcess(const std::shared_ptr<Request> & request,const std::unique_ptr<Location> & location)237 std::unique_ptr<Location> ReportManager::ExecuteLocationProcess(const std::shared_ptr<Request>& request,
238     const std::unique_ptr<Location>& location)
239 {
240     LocationSupplicantInfo reportStruct;
241     reportStruct.request = *request;
242     reportStruct.location = *location;
243     HookUtils::ExecuteHook(
244         LocationProcessStage::LOCATION_REPORT_PROCESS, (void *)&reportStruct, nullptr);
245     return std::make_unique<Location>(reportStruct.location);
246 }
247 
GetPermittedLocation(const std::shared_ptr<Request> & request,const std::unique_ptr<Location> & location)248 std::unique_ptr<Location> ReportManager::GetPermittedLocation(const std::shared_ptr<Request>& request,
249     const std::unique_ptr<Location>& location)
250 {
251     if (location == nullptr) {
252         return nullptr;
253     }
254     std::string bundleName = request->GetPackageName();
255     auto tokenId = request->GetTokenId();
256     auto firstTokenId = request->GetFirstTokenId();
257     auto tokenIdEx = request->GetTokenIdEx();
258     auto uid =  request->GetUid();
259     if (bundleName.length() == 0) {
260         if (!CommonUtils::GetBundleNameByUid(uid, bundleName)) {
261             LBSLOGD(REPORT_MANAGER, "Fail to Get bundle name: uid = %{public}d.", uid);
262         }
263     }
264     if (request->GetRequestConfig()->GetFixNumber() == 0 &&
265         IsAppBackground(bundleName, tokenId, tokenIdEx, uid, request->GetPid()) &&
266         !PermissionManager::CheckBackgroundPermission(tokenId, firstTokenId)) {
267         //app background, no background permission, not ContinuousTasks
268         RequestManager::GetInstance()->ReportLocationError(LOCATING_FAILED_BACKGROUND_PERMISSION_DENIED, request);
269         return nullptr;
270     }
271     AppIdentity identity;
272     identity.SetUid(request->GetUid());
273     identity.SetTokenId(request->GetTokenId());
274     identity.SetBundleName(bundleName);
275     int currentUserId = LocatorBackgroundProxy::GetInstance()->getCurrentUserId();
276     if (!CommonUtils::IsAppBelongCurrentAccount(identity, currentUserId)) {
277         //app is not in current user, not need to report
278         LBSLOGI(REPORT_MANAGER, "GetPermittedLocation uid: %{public}d CheckAppForUser fail", tokenId);
279         auto locationErrorCallback = request->GetLocationErrorCallBack();
280         if (locationErrorCallback != nullptr) {
281             locationErrorCallback->OnErrorReport(LOCATING_FAILED_LOCATION_PERMISSION_DENIED);
282         }
283         return nullptr;
284     }
285     std::unique_ptr<Location> finalLocation = ExecuteLocationProcess(request, location);
286     // for api8 and previous version, only ACCESS_LOCATION permission granted also report original location info.
287     if (PermissionManager::CheckLocationPermission(tokenId, firstTokenId)) {
288         return finalLocation;
289     }
290     if (PermissionManager::CheckApproximatelyPermission(tokenId, firstTokenId)) {
291         LBSLOGI(REPORT_MANAGER, "%{public}d has ApproximatelyLocation permission", tokenId);
292         finalLocation = ApproximatelyLocation(location, request);
293         return finalLocation;
294     }
295     LBSLOGE(REPORT_MANAGER, "%{public}d has no location permission failed", tokenId);
296     RequestManager::GetInstance()->ReportLocationError(LOCATING_FAILED_LOCATION_PERMISSION_DENIED, request);
297     return nullptr;
298 }
299 
ReportRemoteCallback(const sptr<ILocatorCallback> & locatorCallback,int type,int result)300 bool ReportManager::ReportRemoteCallback(const sptr<ILocatorCallback>& locatorCallback, int type, int result)
301 {
302     switch (type) {
303         case ILocatorCallback::RECEIVE_LOCATION_STATUS_EVENT: {
304             locatorCallback->OnLocatingStatusChange(result);
305             break;
306         }
307         case ILocatorCallback::RECEIVE_ERROR_INFO_EVENT: {
308             locatorCallback->OnErrorReport(result);
309             break;
310         }
311         default:
312             return false;
313     }
314     return true;
315 }
316 
ResultCheck(const std::unique_ptr<Location> & location,const std::shared_ptr<Request> & request)317 bool ReportManager::ResultCheck(const std::unique_ptr<Location>& location,
318     const std::shared_ptr<Request>& request)
319 {
320     if (request == nullptr || location == nullptr) {
321         return false;
322     }
323     if (ProxyFreezeManager::GetInstance()->IsProxyPid(request->GetPid())) {
324         LBSLOGE(REPORT_MANAGER, "pid:%{public}d is proxy by freeze, no need to report", request->GetPid());
325         return false;
326     }
327     int permissionLevel = PermissionManager::GetPermissionLevel(request->GetTokenId(), request->GetFirstTokenId());
328     if (request->GetLastLocation() == nullptr || request->GetRequestConfig() == nullptr) {
329         return true;
330     }
331     float maxAcc = request->GetRequestConfig()->GetMaxAccuracy();
332     LBSLOGD(REPORT_MANAGER, "acc ResultCheck :  %{public}f - %{public}f", maxAcc, location->GetAccuracy());
333     if ((permissionLevel == PERMISSION_ACCURATE) &&
334         (maxAcc > 0) && (location->GetAccuracy() > maxAcc)) {
335         auto locatorCallback = request->GetLocatorCallBack();
336         if (locatorCallback != nullptr) {
337             ReportRemoteCallback(locatorCallback, ILocatorCallback::RECEIVE_ERROR_INFO_EVENT,
338                 LocationErrCode::ERRCODE_LOCATING_ACC_FAIL);
339         } else {
340             LBSLOGE(REPORT_MANAGER, "ReportManager null LocatorCallback");
341         }
342         LBSLOGE(REPORT_MANAGER, "accuracy check fail, do not report location");
343         return false;
344     }
345     if (CommonUtils::DoubleEqual(request->GetLastLocation()->GetLatitude(), MIN_LATITUDE - 1) ||
346         request->GetLastLocation()->GetIsFromMock() != location->GetIsFromMock()) {
347         LBSLOGD(REPORT_MANAGER, "no valid cache location, no need to check");
348         return true;
349     }
350     int minTime = request->GetRequestConfig()->GetTimeInterval();
351     long deltaMs = (location->GetTimeSinceBoot() - request->GetLastLocation()->GetTimeSinceBoot()) / NANOS_PER_MILLI;
352     if (deltaMs < (minTime * MILLI_PER_SEC - MAX_SA_SCHEDULING_JITTER_MS)) {
353         LBSLOGE(REPORT_MANAGER,
354             "%{public}d timeInterval check fail, do not report location, current deltaMs = %{public}ld",
355             request->GetTokenId(), deltaMs);
356         return false;
357     }
358 
359     double distanceInterval = request->GetRequestConfig()->GetDistanceInterval();
360     double deltaDis = CommonUtils::CalDistance(location->GetLatitude(), location->GetLongitude(),
361         request->GetLastLocation()->GetLatitude(), request->GetLastLocation()->GetLongitude());
362     if (deltaDis - distanceInterval < 0) {
363         LBSLOGE(REPORT_MANAGER, "%{public}d distanceInterval check fail, do not report location",
364             request->GetTokenId());
365         return false;
366     }
367     return true;
368 }
369 
UpdateCacheLocation(const std::unique_ptr<Location> & location,std::string abilityName)370 void ReportManager::UpdateCacheLocation(const std::unique_ptr<Location>& location, std::string abilityName)
371 {
372     if (abilityName == GNSS_ABILITY) {
373         if (HookUtils::CheckGnssLocationValidity(location)) {
374             cacheGnssLocation_ = *location;
375             UpdateLastLocation(location);
376         }
377     } else if (abilityName == NETWORK_ABILITY && location->GetLocationSourceType() != INDOOR_TYPE) {
378         cacheNlpLocation_ = *location;
379         UpdateLastLocation(location);
380     } else {
381         UpdateLastLocation(location);
382     }
383 }
384 
UpdateLastLocation(const std::unique_ptr<Location> & location)385 void ReportManager::UpdateLastLocation(const std::unique_ptr<Location>& location)
386 {
387     auto locatorBackgroundProxy = LocatorBackgroundProxy::GetInstance();
388     int currentUserId = locatorBackgroundProxy->getCurrentUserId();
389     std::unique_lock<std::mutex> lock(lastLocationMutex_);
390     lastLocationsMap_[currentUserId] = std::make_shared<Location>(*location);
391 }
392 
GetLastLocation()393 std::unique_ptr<Location> ReportManager::GetLastLocation()
394 {
395     auto locatorBackgroundProxy = LocatorBackgroundProxy::GetInstance();
396     int currentUserId = locatorBackgroundProxy->getCurrentUserId();
397     LBSLOGI(LOCATOR_STANDARD, "GetCacheLocation GetLastLocation currentUserId = %{public}d ", currentUserId);
398     std::unique_lock<std::mutex> lock(lastLocationMutex_);
399     auto iter = lastLocationsMap_.find(currentUserId);
400     if (iter == lastLocationsMap_.end()) {
401         return nullptr;
402     }
403     std::unique_ptr<Location> lastLocation = std::make_unique<Location>(*(iter->second));
404     if (CommonUtils::DoubleEqual(lastLocation->GetLatitude(), MIN_LATITUDE - 1)) {
405         return nullptr;
406     }
407     PoiInfoManager::GetInstance()->UpdateLocationPoiInfo(lastLocation);
408     return lastLocation;
409 }
410 
GetCacheLocation(const std::shared_ptr<Request> & request)411 std::unique_ptr<Location> ReportManager::GetCacheLocation(const std::shared_ptr<Request>& request)
412 {
413     int64_t curTime = CommonUtils::GetCurrentTimeStamp();
414     std::unique_ptr<Location> cacheLocation = nullptr;
415     std::string packageName = request->GetPackageName();
416     int cachedTime = CACHED_TIME;
417     cachedTime = HookUtils::ExecuteHookReportManagerGetCacheLocation(packageName, request->GetNlpRequestType());
418     if (!CommonUtils::DoubleEqual(cacheGnssLocation_.GetLatitude(), MIN_LATITUDE - 1) &&
419         (curTime - cacheGnssLocation_.GetTimeStamp() / MILLI_PER_SEC) <= cachedTime) {
420         cacheLocation = std::make_unique<Location>(cacheGnssLocation_);
421     } else if (!CommonUtils::DoubleEqual(cacheNlpLocation_.GetLatitude(), MIN_LATITUDE - 1) &&
422         (curTime - cacheNlpLocation_.GetTimeStamp() / MILLI_PER_SEC) <= cachedTime) {
423         cacheLocation = std::make_unique<Location>(cacheNlpLocation_);
424     }
425     std::unique_ptr<Location> finalLocation = GetPermittedLocation(request, cacheLocation);
426     if (!ResultCheck(finalLocation, request)) {
427         return nullptr;
428     }
429     UpdateLocationByRequest(request->GetTokenId(), request->GetTokenIdEx(), finalLocation);
430     PoiInfoManager::GetInstance()->UpdateLocationPoiInfo(finalLocation);
431     return finalLocation;
432 }
433 
UpdateRandom()434 void ReportManager::UpdateRandom()
435 {
436     auto locatorAbility = LocatorAbility::GetInstance();
437     int num = locatorAbility->GetActiveRequestNum();
438     if (num > 0) {
439         LBSLOGD(REPORT_MANAGER, "Exists %{public}d active request, cannot refresh offset", num);
440         return;
441     }
442     struct timespec now;
443     clock_gettime(CLOCK_REALTIME, &now);
444     if (abs(now.tv_sec - lastUpdateTime_.tv_sec) > LONG_TIME_INTERVAL) {
445         offsetRandom_ = CommonUtils::DoubleRandom(0, 1);
446     }
447 }
448 
ApproximatelyLocation(const std::unique_ptr<Location> & location,const std::shared_ptr<Request> & request)449 std::unique_ptr<Location> ReportManager::ApproximatelyLocation(
450     const std::unique_ptr<Location>& location, const std::shared_ptr<Request>& request)
451 {
452     std::string bundleName = request->GetPackageName();
453     bool isNeedLocation = request->GetRequestConfig()->GetIsNeedLocation();
454     bool isNeedPoi = request->GetRequestConfig()->GetIsNeedPoi();
455     std::unique_ptr<Location> coarseLocation = std::make_unique<Location>(*location);
456     double startLat = coarseLocation->GetLatitude();
457     double startLon = coarseLocation->GetLongitude();
458     double brg = offsetRandom_ * DIS_FROMLL_PARAMETER * M_PI; // 2PI
459     double dist = offsetRandom_ * (MAXIMUM_FUZZY_LOCATION_DISTANCE -
460         MINIMUM_FUZZY_LOCATION_DISTANCE) + MINIMUM_FUZZY_LOCATION_DISTANCE;
461     double perlat = (DIS_FROMLL_PARAMETER * M_PI * EARTH_RADIUS) / DEGREE_DOUBLE_PI; // the radian value of per degree
462 
463     double lat = startLat + (dist * sin(brg)) / perlat;
464     double lon;
465     if (cos(brg) < 0) {
466         lon = startLon - (dist * DEGREE_DOUBLE_PI) / (DIS_FROMLL_PARAMETER * M_PI * EARTH_RADIUS);
467     } else {
468         lon = startLon + (dist * DEGREE_DOUBLE_PI) / (DIS_FROMLL_PARAMETER * M_PI * EARTH_RADIUS);
469     }
470     if (lat < -MAX_LATITUDE) {
471         lat = -MAX_LATITUDE;
472     } else if (lat > MAX_LATITUDE) {
473         lat = MAX_LATITUDE;
474     } else {
475         lat = std::round(lat * std::pow(10, 8)) / std::pow(10, 8); // 8 decimal
476     }
477     if (lon < -MAX_LONGITUDE) {
478         lon = -MAX_LONGITUDE;
479     } else if (lon > MAX_LONGITUDE) {
480         lon = MAX_LONGITUDE;
481     } else {
482         lon = std::round(lon * std::pow(10, 8)) / std::pow(10, 8); // 8 decimal
483     }
484     coarseLocation->SetLatitude(lat);
485     coarseLocation->SetLongitude(lon);
486     coarseLocation->SetAccuracy(DEFAULT_APPROXIMATELY_ACCURACY); // approximately location acc
487     std::vector<std::string> emptyAdds;
488     coarseLocation->SetAdditions(emptyAdds, false);
489     PoiInfo emptyPoiInfo;
490     coarseLocation->SetPoiInfo(emptyPoiInfo);
491     coarseLocation->SetAdditionSize(0);
492     if (!isNeedLocation && isNeedPoi) {
493         auto locatorCallback = request->GetLocatorCallBack();
494         if (locatorCallback != nullptr) {
495             locatorCallback->OnErrorReport(LocationErrCode::ERRCODE_PERMISSION_DENIED);
496         } else {
497             LBSLOGI(REPORT_MANAGER, "null locatorCallback");
498         }
499     }
500     return coarseLocation;
501 }
502 
IsRequestFuse(const std::shared_ptr<Request> & request)503 bool ReportManager::IsRequestFuse(const std::shared_ptr<Request>& request)
504 {
505     if (request == nullptr || request->GetRequestConfig() == nullptr) {
506         return false;
507     }
508     if (request->GetRequestConfig()->GetFixNumber() == 1 && request->GetRequestConfig()->IsRequestForAccuracy()) {
509         return false;
510     }
511     if ((request->GetRequestConfig()->GetScenario() == SCENE_UNSET &&
512         request->GetRequestConfig()->GetPriority() == PRIORITY_LOW_POWER) ||
513         request->GetRequestConfig()->GetScenario() == SCENE_NO_POWER ||
514         request->GetRequestConfig()->GetScenario() == SCENE_DAILY_LIFE_SERVICE ||
515         request->GetRequestConfig()->GetScenario() == LOCATION_SCENE_DAILY_LIFE_SERVICE ||
516         request->GetRequestConfig()->GetScenario() == LOCATION_SCENE_LOW_POWER_CONSUMPTION ||
517         request->GetRequestConfig()->GetScenario() == LOCATION_SCENE_NO_POWER_CONSUMPTION) {
518         return false;
519     }
520     return true;
521 }
522 
WriteNetWorkReportEvent(std::string abilityName,const std::shared_ptr<Request> & request,const std::unique_ptr<Location> & location)523 void ReportManager::WriteNetWorkReportEvent(std::string abilityName, const std::shared_ptr<Request>& request,
524     const std::unique_ptr<Location>& location)
525 {
526     if (abilityName == NETWORK_ABILITY && request != nullptr) {
527         WriteLocationInnerEvent(RECEIVE_NETWORK_LOCATION, {
528             "PackageName", request->GetPackageName(),
529             "abilityName", abilityName,
530             "requestAddress", request->GetUuid(),
531             "latitude", std::to_string(location->GetLatitude()),
532             "longitude", std::to_string(location->GetLongitude()),
533             "accuracy", std::to_string(location->GetAccuracy())
534         });
535     }
536 }
537 
IsAppBackground(std::string bundleName,uint32_t tokenId,uint64_t tokenIdEx,pid_t uid,pid_t pid)538 bool ReportManager::IsAppBackground(std::string bundleName, uint32_t tokenId, uint64_t tokenIdEx, pid_t uid, pid_t pid)
539 {
540     auto locatorBackgroundProxy = LocatorBackgroundProxy::GetInstance();
541     if (!locatorBackgroundProxy->IsAppBackground(uid, bundleName)) {
542         return false;
543     }
544     if (!HookUtils::ExecuteHookWhenCheckIsAppBackground(bundleName)) {
545         return false;
546     }
547     if (locatorBackgroundProxy->IsAppHasFormVisible(tokenId, tokenIdEx)) {
548         return false;
549     }
550     if (locatorBackgroundProxy->IsAppInLocationContinuousTasks(uid, pid)) {
551         return false;
552     }
553     return true;
554 }
555 
IsCacheGnssLocationValid()556 bool ReportManager::IsCacheGnssLocationValid()
557 {
558     int64_t curTime = CommonUtils::GetCurrentTimeStamp();
559     if (!CommonUtils::DoubleEqual(cacheGnssLocation_.GetLatitude(), MIN_LATITUDE - 1) &&
560         (curTime - cacheGnssLocation_.GetTimeStamp() / MILLI_PER_SEC) <= CACHED_TIME) {
561         return true;
562     }
563     return false;
564 }
565 
NeedUpdateTimeStamp(std::unique_ptr<Location> & fuseLocation,const std::shared_ptr<Request> & request)566 bool ReportManager::NeedUpdateTimeStamp(std::unique_ptr<Location>& fuseLocation,
567     const std::shared_ptr<Request>& request)
568 {
569     auto lastLocation = request->GetLastLocation();
570     if (lastLocation == nullptr || fuseLocation == nullptr) {
571         return false;
572     }
573     int64_t curTime = CommonUtils::GetSinceBootTime();
574     int minTime = request->GetRequestConfig()->GetTimeInterval();
575     long deltaMsLast =
576         (fuseLocation->GetTimeSinceBoot() - request->GetLastLocation()->GetTimeSinceBoot()) / NANOS_PER_MILLI;
577     long deltaMsCurrent = (curTime - request->GetLastLocation()->GetTimeSinceBoot()) / NANOS_PER_MILLI;
578     long timeInterval = minTime * MILLI_PER_SEC - MAX_SA_SCHEDULING_JITTER_MS;
579     if (deltaMsLast < timeInterval && deltaMsCurrent >= timeInterval) {
580         LBSLOGI(REPORT_MANAGER, "update fuseLocation timestamp, before: %{public}s after:%{public}s",
581             std::to_string(fuseLocation->GetTimeSinceBoot()).c_str(),
582             std::to_string(lastLocation->GetTimeSinceBoot() + timeInterval).c_str());
583         fuseLocation->SetTimeSinceBoot(lastLocation->GetTimeSinceBoot() + timeInterval * NANOS_PER_MILLI); // ns
584         fuseLocation->SetTimeStamp(lastLocation->GetTimeStamp() + timeInterval); // ms
585         return true;
586     }
587     return false;
588 }
589 } // namespace OHOS
590 } // namespace Location
591