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 "request_manager.h"
17 
18 #include "privacy_kit.h"
19 #include "privacy_error.h"
20 
21 #include "common_utils.h"
22 #include "constant_definition.h"
23 #ifdef FEATURE_GNSS_SUPPORT
24 #include "gnss_ability_proxy.h"
25 #endif
26 #include "fusion_controller.h"
27 #include "location_log.h"
28 #include "location_sa_load_manager.h"
29 #include "locator_ability.h"
30 #include "locator_background_proxy.h"
31 #include "locator_event_manager.h"
32 #ifdef FEATURE_NETWORK_SUPPORT
33 #include "network_ability_proxy.h"
34 #endif
35 #ifdef FEATURE_PASSIVE_SUPPORT
36 #include "passive_ability_proxy.h"
37 #endif
38 #include "request_config.h"
39 #include "location_log_event_ids.h"
40 #include "common_hisysevent.h"
41 #include "hook_utils.h"
42 #include "permission_manager.h"
43 #ifdef DEVICE_STANDBY_ENABLE
44 #include "standby_service_client.h"
45 #endif
46 
47 #ifdef RES_SCHED_SUPPROT
48 #include "res_type.h"
49 #include "res_sched_client.h"
50 #endif
51 
52 #include "location_data_rdb_manager.h"
53 
54 namespace OHOS {
55 namespace Location {
56 ffrt::mutex RequestManager::requestMutex_;
57 
GetInstance()58 RequestManager* RequestManager::GetInstance()
59 {
60     static RequestManager data;
61     return &data;
62 }
63 
RequestManager()64 RequestManager::RequestManager()
65 {
66     isDeviceIdleMode_.store(false);
67     isDeviceStillState_.store(false);
68     auto locatorDftManager = LocatorDftManager::GetInstance();
69     if (locatorDftManager != nullptr) {
70         locatorDftManager->Init();
71     }
72 }
73 
~RequestManager()74 RequestManager::~RequestManager()
75 {
76 }
77 
InitSystemListeners()78 bool RequestManager::InitSystemListeners()
79 {
80     LBSLOGI(REQUEST_MANAGER, "Init system listeners.");
81     return true;
82 }
83 
UpdateUsingPermission(std::shared_ptr<Request> request,const bool isStart)84 bool RequestManager::UpdateUsingPermission(std::shared_ptr<Request> request, const bool isStart)
85 {
86     std::unique_lock<ffrt::mutex> lock(permissionRecordMutex_, std::defer_lock);
87     lock.lock();
88     if (request == nullptr) {
89         LBSLOGE(REQUEST_MANAGER, "request is null");
90         lock.unlock();
91         return false;
92     }
93     bool ret = UpdateUsingApproximatelyPermission(request, isStart);
94     lock.unlock();
95     return ret;
96 }
97 
UpdateUsingApproximatelyPermission(std::shared_ptr<Request> request,const bool isStart)98 bool RequestManager::UpdateUsingApproximatelyPermission(std::shared_ptr<Request> request, const bool isStart)
99 {
100     auto locatorAbility = LocatorAbility::GetInstance();
101     uint32_t callingTokenId = request->GetTokenId();
102     int ret;
103     if (isStart && !request->GetApproximatelyPermState()) {
104         IncreaseWorkingPidsCount(request->GetPid());
105         bool isNeedStart = IsNeedStartUsingPermission(request->GetPid());
106         if (isNeedStart) {
107             ret = PrivacyKit::StartUsingPermission(callingTokenId, ACCESS_APPROXIMATELY_LOCATION, request->GetPid());
108             if (ret != ERRCODE_SUCCESS && ret != Security::AccessToken::ERR_PERMISSION_ALREADY_START_USING &&
109                 locatorAbility->IsHapCaller(request->GetTokenId())) {
110                 DecreaseWorkingPidsCount(request->GetPid());
111                 LBSLOGE(REQUEST_MANAGER, "StartUsingPermission failed ret=%{public}d", ret);
112                 return false;
113             }
114         }
115         request->SetApproximatelyPermState(true);
116         ret = locatorAbility->UpdatePermissionUsedRecord(request->GetTokenId(),
117             ACCESS_APPROXIMATELY_LOCATION, request->GetPermUsedType(), 1, 0);
118         if (ret != ERRCODE_SUCCESS && locatorAbility->IsHapCaller(callingTokenId)) {
119             LBSLOGE(REQUEST_MANAGER, "UpdatePermissionUsedRecord failed ret=%{public}d", ret);
120             return false;
121         }
122     } else if (!isStart && request->GetApproximatelyPermState()) {
123         DecreaseWorkingPidsCount(request->GetPid());
124         bool isNeedStop = IsNeedStopUsingPermission(request->GetPid());
125         if (isNeedStop) {
126             ret = PrivacyKit::StopUsingPermission(callingTokenId, ACCESS_APPROXIMATELY_LOCATION, request->GetPid());
127             if (ret != ERRCODE_SUCCESS && locatorAbility->IsHapCaller(callingTokenId)) {
128                 LBSLOGE(REQUEST_MANAGER, "StopUsingPermission failed ret=%{public}d", ret);
129                 return false;
130             }
131         }
132         request->SetApproximatelyPermState(false);
133     }
134     return true;
135 }
136 
IncreaseWorkingPidsCount(const pid_t pid)137 void RequestManager::IncreaseWorkingPidsCount(const pid_t pid)
138 {
139     std::unique_lock<ffrt::mutex> uniquelock(workingPidsCountMutex_);
140     if (workingPidsCountMap_.count(pid) > 0) {
141         workingPidsCountMap_[pid] = workingPidsCountMap_[pid] + 1;
142     } else {
143         workingPidsCountMap_.insert(std::make_pair(pid, 1));
144     }
145 }
146 
DecreaseWorkingPidsCount(const pid_t pid)147 void RequestManager::DecreaseWorkingPidsCount(const pid_t pid)
148 {
149     std::unique_lock<ffrt::mutex> uniquelock(workingPidsCountMutex_);
150     if (workingPidsCountMap_.count(pid) > 0) {
151         workingPidsCountMap_[pid] = workingPidsCountMap_[pid] - 1;
152         if (workingPidsCountMap_[pid] < 0) {
153             LBSLOGE(REQUEST_MANAGER, "working pid less 0, pid=%{public}d", pid);
154         }
155     }
156 }
157 
IsNeedStartUsingPermission(const pid_t pid)158 bool RequestManager::IsNeedStartUsingPermission(const pid_t pid)
159 {
160     std::unique_lock<ffrt::mutex> uniquelock(workingPidsCountMutex_);
161     if (workingPidsCountMap_.count(pid) <= 0) {
162         return false;
163     }
164     if (workingPidsCountMap_[pid] == 1) {
165         return true;
166     }
167     return false;
168 }
169 
IsNeedStopUsingPermission(const pid_t pid)170 bool RequestManager::IsNeedStopUsingPermission(const pid_t pid)
171 {
172     std::unique_lock<ffrt::mutex> uniquelock(workingPidsCountMutex_);
173     if (workingPidsCountMap_.count(pid) <= 0) {
174         return false;
175     }
176     if (workingPidsCountMap_[pid] <= 0) {
177         workingPidsCountMap_.erase(pid);
178         return true;
179     }
180     return false;
181 }
182 
HandleStartLocating(std::shared_ptr<Request> request)183 void RequestManager::HandleStartLocating(std::shared_ptr<Request> request)
184 {
185     auto locatorAbility = LocatorAbility::GetInstance();
186     auto locatorDftManager = LocatorDftManager::GetInstance();
187     if (locatorAbility == nullptr || locatorDftManager == nullptr) {
188         return;
189     }
190     // restore request to all request list
191     bool isNewRequest = RestorRequest(request);
192     // update request map
193     if (isNewRequest) {
194         locatorAbility->RegisterPermissionCallback(request->GetTokenId(),
195             {ACCESS_APPROXIMATELY_LOCATION, ACCESS_LOCATION, ACCESS_BACKGROUND_LOCATION});
196         UpdateRequestRecord(request, true);
197         locatorDftManager->LocationSessionStart(request);
198     }
199     // process location request
200     HandleRequest();
201 }
202 
RestorRequest(std::shared_ptr<Request> newRequest)203 bool RequestManager::RestorRequest(std::shared_ptr<Request> newRequest)
204 {
205     std::unique_lock lock(requestMutex_);
206 
207     auto locatorAbility = LocatorAbility::GetInstance();
208     if (locatorAbility == nullptr) {
209         return false;
210     }
211     auto receivers = locatorAbility->GetReceivers();
212     if (receivers == nullptr) {
213         LBSLOGE(REQUEST_MANAGER, "receivers is empty");
214         return false;
215     }
216     if (newRequest == nullptr) {
217         LBSLOGE(REQUEST_MANAGER, "newRequest is empty");
218         return false;
219     }
220     newRequest->SetRequesting(true);
221     sptr<IRemoteObject> newCallback = newRequest->GetLocatorCallBack()->AsObject();
222 
223     LBSLOGI(REQUEST_MANAGER, "add request:%{public}s", newRequest->ToString().c_str());
224     // if callback and request config type is same, take new request configuration over the old one in request list
225     // otherwise, add restore the new request in the list.
226     auto iterator = receivers->find(newCallback);
227     if (iterator == receivers->end()) {
228         std::list<std::shared_ptr<Request>> requestList;
229         requestList.push_back(newRequest);
230         receivers->insert(make_pair(newCallback, requestList));
231         LBSLOGD(REQUEST_MANAGER, "add new receiver with new callback");
232         return true;
233     }
234 
235     sptr<RequestConfig> newConfig = newRequest->GetRequestConfig();
236     auto requestWithSameCallback = &(iterator->second);
237     for (auto iter = requestWithSameCallback->begin(); iter != requestWithSameCallback->end(); ++iter) {
238         auto request = *iter;
239         if (request == nullptr) {
240             continue;
241         }
242         auto requestConfig = request->GetRequestConfig();
243         if (requestConfig == nullptr || newConfig == nullptr) {
244             continue;
245         }
246         if (newConfig->IsSame(*requestConfig)) {
247             request->SetRequestConfig(*newConfig);
248             LBSLOGI(REQUEST_MANAGER, "find same type request, update request configuration");
249             return false;
250         }
251     }
252     requestWithSameCallback->push_back(newRequest);
253     LBSLOGD(REQUEST_MANAGER, "add new receiver with old callback");
254     return true;
255 }
256 
UpdateRequestRecord(std::shared_ptr<Request> request,bool shouldInsert)257 void RequestManager::UpdateRequestRecord(std::shared_ptr<Request> request, bool shouldInsert)
258 {
259     std::shared_ptr<std::list<std::string>> proxys = std::make_shared<std::list<std::string>>();
260     request->GetProxyName(proxys);
261     if (proxys->empty()) {
262         LBSLOGE(REQUEST_MANAGER, "can not get proxy name according to request configuration");
263         return;
264     }
265 
266     for (std::list<std::string>::iterator iter = proxys->begin(); iter != proxys->end(); ++iter) {
267         std::string abilityName = *iter;
268         UpdateRequestRecord(request, abilityName, shouldInsert);
269     }
270 }
271 
UpdateRequestRecord(std::shared_ptr<Request> request,std::string abilityName,bool shouldInsert)272 void RequestManager::UpdateRequestRecord(std::shared_ptr<Request> request, std::string abilityName, bool shouldInsert)
273 {
274     auto locatorAbility = LocatorAbility::GetInstance();
275     if (locatorAbility == nullptr) {
276         LBSLOGE(REQUEST_MANAGER, "locatorAbility is null");
277         return;
278     }
279     std::unique_lock lock(requestMutex_);
280     auto requests = locatorAbility->GetRequests();
281     if (requests == nullptr) {
282         LBSLOGE(REQUEST_MANAGER, "requests map is empty");
283         return;
284     }
285     auto mapIter = requests->find(abilityName);
286     if (mapIter == requests->end()) {
287         LBSLOGE(REQUEST_MANAGER, "can not find %{public}s ability request list.", abilityName.c_str());
288         return;
289     }
290 
291     auto list = &(mapIter->second);
292     LBSLOGD(REQUEST_MANAGER, "%{public}s ability current request size %{public}s",
293         abilityName.c_str(), std::to_string(list->size()).c_str());
294     if (shouldInsert) {
295         list->push_back(request);
296         HandleChrEvent(*list);
297         UpdateRunningUids(request, abilityName, true);
298     } else {
299         for (auto iter = list->begin(); iter != list->end();) {
300             auto findRequest = *iter;
301             if (request == findRequest) {
302                 iter = list->erase(iter);
303                 UpdateRunningUids(findRequest, abilityName, false);
304                 LBSLOGD(REQUEST_MANAGER, "find request");
305             } else {
306                 ++iter;
307             }
308         }
309     }
310     LBSLOGD(REQUEST_MANAGER, "%{public}s ability request size %{public}s",
311         abilityName.c_str(), std::to_string(list->size()).c_str());
312 }
313 
HandleChrEvent(std::list<std::shared_ptr<Request>> requests)314 void RequestManager::HandleChrEvent(std::list<std::shared_ptr<Request>> requests)
315 {
316     if (requests.size() > LBS_REQUEST_MAX_SIZE) {
317         std::vector<std::string> names;
318         std::vector<std::string> values;
319         int index = 0;
320         for (auto it = requests.begin(); it != requests.end(); ++it, ++index) {
321             auto request = *it;
322             if (request == nullptr) {
323                 continue;
324             }
325             names.push_back(std::to_string(index));
326             std::string packageName = request->GetPackageName();
327             values.push_back(packageName);
328         }
329         WriteLocationInnerEvent(LBS_REQUEST_TOO_MUCH, names, values);
330     }
331 }
332 
HandleStopLocating(sptr<ILocatorCallback> callback)333 void RequestManager::HandleStopLocating(sptr<ILocatorCallback> callback)
334 {
335     if (callback == nullptr) {
336         LBSLOGE(REQUEST_MANAGER, "stop locating but callback is null");
337         return;
338     }
339     auto locatorAbility = LocatorAbility::GetInstance();
340     if (locatorAbility == nullptr) {
341         LBSLOGE(REQUEST_MANAGER, "locatorAbility is null");
342         return;
343     }
344     std::unique_lock<ffrt::mutex> lock(requestMutex_, std::defer_lock);
345     lock.lock();
346     auto receivers = locatorAbility->GetReceivers();
347     if (receivers == nullptr) {
348         LBSLOGE(REQUEST_MANAGER, "receivers map is empty");
349         lock.unlock();
350         return;
351     }
352     sptr<IRemoteObject> deadCallback = callback->AsObject();
353     // get dead request list
354     LBSLOGD(REQUEST_MANAGER, "stop callback");
355     auto iterator = receivers->find(deadCallback);
356     if (iterator == receivers->end()) {
357         LBSLOGE(REQUEST_MANAGER, "this callback has no record in receiver map");
358         lock.unlock();
359         return;
360     }
361 
362     auto requests = iterator->second;
363     auto deadRequests = std::make_shared<std::list<std::shared_ptr<Request>>>();
364     for (auto iter = requests.begin(); iter != requests.end(); ++iter) {
365         auto request = *iter;
366         locatorAbility->UnregisterPermissionCallback(request->GetTokenId());
367         deadRequests->push_back(request);
368         HookUtils::ExecuteHookWhenStopLocation(request);
369         LBSLOGI(REQUEST_MANAGER, "remove request:%{public}s", request->ToString().c_str());
370     }
371     LBSLOGD(REQUEST_MANAGER, "get %{public}s dead request", std::to_string(deadRequests->size()).c_str());
372     // update request map
373     if (deadRequests->size() == 0) {
374         lock.unlock();
375         return;
376     }
377     iterator->second.clear();
378     receivers->erase(iterator);
379     lock.unlock();
380     DeleteRequestRecord(deadRequests);
381     deadRequests->clear();
382     // process location request
383     HandleRequest();
384 }
385 
DeleteRequestRecord(std::shared_ptr<std::list<std::shared_ptr<Request>>> requests)386 void RequestManager::DeleteRequestRecord(std::shared_ptr<std::list<std::shared_ptr<Request>>> requests)
387 {
388     for (auto iter = requests->begin(); iter != requests->end(); ++iter) {
389         auto request = *iter;
390         UpdateRequestRecord(request, false);
391         UpdateUsingPermission(request, false);
392         if (request->GetLocatorCallBack() != nullptr && request->GetLocatorCallbackRecipient() != nullptr) {
393             request->GetLocatorCallBack()->AsObject()->RemoveDeathRecipient(request->GetLocatorCallbackRecipient());
394         }
395         auto locatorBackgroundProxy = LocatorBackgroundProxy::GetInstance();
396         if (locatorBackgroundProxy == nullptr) {
397             LBSLOGE(REQUEST_MANAGER, "DeleteRequestRecord: LocatorBackgroundProxy is nullptr.");
398             break;
399         }
400         locatorBackgroundProxy->OnDeleteRequestRecord(request);
401     }
402 }
403 
HandleRequest()404 void RequestManager::HandleRequest()
405 {
406     auto locatorAbility = LocatorAbility::GetInstance();
407     if (locatorAbility == nullptr) {
408         LBSLOGE(REQUEST_MANAGER, "locatorAbility is null");
409         return;
410     }
411     std::unique_lock<ffrt::mutex> lock(requestMutex_, std::defer_lock);
412     lock.lock();
413     auto requests = locatorAbility->GetRequests();
414     lock.unlock();
415     if (requests == nullptr) {
416         LBSLOGE(REQUEST_MANAGER, "requests map is empty");
417         return;
418     }
419     std::map<std::string, std::list<std::shared_ptr<Request>>>::iterator iter;
420     for (iter = requests->begin(); iter != requests->end(); ++iter) {
421         std::string abilityName = iter->first;
422         std::list<std::shared_ptr<Request>> requestList = iter->second;
423         HandleRequest(abilityName, requestList);
424     }
425 }
426 
HandleRequest(std::string abilityName,std::list<std::shared_ptr<Request>> list)427 void RequestManager::HandleRequest(std::string abilityName, std::list<std::shared_ptr<Request>> list)
428 {
429     // generate work record, and calculate interval
430     std::shared_ptr<WorkRecord> workRecord = std::make_shared<WorkRecord>();
431     for (auto iter = list.begin(); iter != list.end(); iter++) {
432         auto request = *iter;
433         if (!AddRequestToWorkRecord(abilityName, request, workRecord)) {
434             WriteLocationInnerEvent(REMOVE_REQUEST, {"PackageName", request->GetPackageName(),
435                     "abilityName", abilityName, "requestAddress", request->GetUuid()});
436             UpdateUsingPermission(request, false);
437             continue;
438         }
439         if (!ActiveLocatingStrategies(request)) {
440             continue;
441         }
442         LBSLOGD(REQUEST_MANAGER, "add pid:%{public}d uid:%{public}d %{public}s", request->GetPid(), request->GetUid(),
443             request->GetPackageName().c_str());
444     }
445     LBSLOGD(REQUEST_MANAGER, "detect %{public}s ability requests(size:%{public}s) work record:%{public}s",
446         abilityName.c_str(), std::to_string(list.size()).c_str(), workRecord->ToString().c_str());
447 
448     ProxySendLocationRequest(abilityName, *workRecord);
449 }
450 
ActiveLocatingStrategies(const std::shared_ptr<Request> & request)451 bool RequestManager::ActiveLocatingStrategies(const std::shared_ptr<Request>& request)
452 {
453     if (request == nullptr) {
454         return false;
455     }
456     auto requestConfig = request->GetRequestConfig();
457     if (requestConfig == nullptr) {
458         return false;
459     }
460     int requestType = requestConfig->GetScenario();
461     if (requestType == SCENE_UNSET) {
462         requestType = requestConfig->GetPriority();
463     }
464     auto fusionController = FusionController::GetInstance();
465     if (fusionController != nullptr) {
466         fusionController->ActiveFusionStrategies(requestType);
467     }
468     return true;
469 }
470 
471 /**
472  * determine whether the request is valid.
473  */
IsRequestAvailable(std::shared_ptr<Request> & request)474 bool RequestManager::IsRequestAvailable(std::shared_ptr<Request>& request)
475 {
476     if (!request->GetIsRequesting()) {
477         return false;
478     }
479     // for frozen app, do not add to workRecord
480     if (LocatorAbility::GetInstance()->IsProxyPid(request->GetPid())) {
481         return false;
482     }
483     AppIdentity identity;
484     identity.SetUid(request->GetUid());
485     identity.SetTokenId(request->GetTokenId());
486     if (!CommonUtils::IsAppBelongCurrentAccount(identity)) {
487         LBSLOGD(REPORT_MANAGER, "AddRequestToWorkRecord uid: %{public}d ,CheckAppIsCurrentUser fail",
488             request->GetUid());
489         return false;
490     }
491     // for once_request app, if it has timed out, do not add to workRecord
492     int64_t curTime = CommonUtils::GetCurrentTime();
493     if (request->GetRequestConfig()->GetFixNumber() == 1 &&
494         fabs(curTime - request->GetRequestConfig()->GetTimeStamp()) >
495         (request->GetRequestConfig()->GetTimeOut() / MILLI_PER_SEC)) {
496         LBSLOGE(LOCATOR, "%{public}d has timed out.", request->GetPid());
497         return false;
498     }
499     return true;
500 }
501 
IsStandby()502 void RequestManager::IsStandby()
503 {
504 #ifdef DEVICE_STANDBY_ENABLE
505     LBSLOGI(LOCATOR, "%{public}s called", __func__);
506     bool isStandby = false;
507     DevStandbyMgr::StandbyServiceClient& standbyServiceClient = DevStandbyMgr::StandbyServiceClient::GetInstance();
508     ErrCode code = standbyServiceClient.IsDeviceInStandby(isStandby);
509     if (code == ERR_OK && isStandby) {
510         isDeviceIdleMode_.store(true);
511         LBSLOGI(LOCATOR, "isStandby = true");
512         return;
513     }
514 #endif
515     isDeviceIdleMode_.store(false);
516     LBSLOGI(LOCATOR, "isStandby = false");
517 }
518 
AddRequestToWorkRecord(std::string abilityName,std::shared_ptr<Request> & request,std::shared_ptr<WorkRecord> & workRecord)519 bool RequestManager::AddRequestToWorkRecord(std::string abilityName, std::shared_ptr<Request>& request,
520     std::shared_ptr<WorkRecord>& workRecord)
521 {
522     if (request == nullptr) {
523         return false;
524     }
525     if (!IsRequestAvailable(request)) {
526         return false;
527     }
528     if (LocationDataRdbManager::QuerySwitchState() != ENABLED) {
529         RequestManager::GetInstance()->ReportLocationError(LOCATING_FAILED_LOCATION_SWITCH_OFF, request);
530         LBSLOGE(LOCATOR, "%{public}s line:%{public}d the location switch is off", __func__, __LINE__);
531         return false;
532     }
533     uint32_t tokenId = request->GetTokenId();
534     uint32_t firstTokenId = request->GetFirstTokenId();
535     // if location access permission granted, add request info to work record
536     if (!PermissionManager::CheckLocationPermission(tokenId, firstTokenId) &&
537         !PermissionManager::CheckApproximatelyPermission(tokenId, firstTokenId)) {
538         RequestManager::GetInstance()->ReportLocationError(LOCATING_FAILED_LOCATION_PERMISSION_DENIED, request);
539         LBSLOGI(LOCATOR, "CheckLocationPermission return false, tokenId=%{public}d", tokenId);
540         return false;
541     }
542     std::string bundleName = "";
543     pid_t uid = request->GetUid();
544     pid_t pid = request->GetPid();
545     if (!CommonUtils::GetBundleNameByUid(uid, bundleName)) {
546         LBSLOGD(REPORT_MANAGER, "Fail to Get bundle name: uid = %{public}d.", uid);
547     }
548     auto requestConfig = request->GetRequestConfig();
549     if (requestConfig == nullptr) {
550         return false;
551     }
552     auto reportManager = ReportManager::GetInstance();
553     if (requestConfig->GetFixNumber() == 0 && reportManager->IsAppBackground(bundleName, tokenId,
554         request->GetTokenIdEx(), uid, pid)&&
555         !PermissionManager::CheckBackgroundPermission(tokenId, firstTokenId)) {
556         RequestManager::GetInstance()->ReportLocationError(LOCATING_FAILED_BACKGROUND_PERMISSION_DENIED, request);
557         LBSLOGE(REPORT_MANAGER, "CheckBackgroundPermission return false, tokenId=%{public}d", tokenId);
558         return false;
559     }
560 
561     if (HookUtils::ExecuteHookWhenAddWorkRecord(isDeviceStillState_.load(), isDeviceIdleMode_.load(),
562         abilityName, bundleName)) {
563         LBSLOGI(REQUEST_MANAGER, "Enter idle and still status, not add request");
564         return false;
565     }
566     if (!UpdateUsingPermission(request, true)) {
567         return false;
568     }
569     // add request info to work record
570     if (workRecord != nullptr) {
571         request->SetNlpRequestType();
572         workRecord->Add(request);
573     }
574     return true;
575 }
576 
ProxySendLocationRequest(std::string abilityName,WorkRecord & workRecord)577 void RequestManager::ProxySendLocationRequest(std::string abilityName, WorkRecord& workRecord)
578 {
579     int systemAbilityId = CommonUtils::AbilityConvertToId(abilityName);
580     if (!SaLoadWithStatistic::InitLocationSa(systemAbilityId)) {
581         return ;
582     }
583     sptr<IRemoteObject> remoteObject = CommonUtils::GetRemoteObject(systemAbilityId, CommonUtils::InitDeviceId());
584     if (remoteObject == nullptr) {
585         LBSLOGE(LOCATOR, "%{public}s: remote obj is nullptr", __func__);
586         return;
587     }
588     LBSLOGI(LOCATOR, "%{public}s: %{public}s workRecord uid_ size %{public}d",
589         __func__, abilityName.c_str(), workRecord.Size());
590     workRecord.SetDeviceId(CommonUtils::InitDeviceId());
591     if (abilityName == GNSS_ABILITY) {
592 #ifdef FEATURE_GNSS_SUPPORT
593         std::unique_ptr<GnssAbilityProxy> gnssProxy = std::make_unique<GnssAbilityProxy>(remoteObject);
594         gnssProxy->SendLocationRequest(workRecord);
595 #endif
596     } else if (abilityName == NETWORK_ABILITY) {
597 #ifdef FEATURE_NETWORK_SUPPORT
598         std::unique_ptr<NetworkAbilityProxy> networkProxy = std::make_unique<NetworkAbilityProxy>(remoteObject);
599         networkProxy->SendLocationRequest(workRecord);
600 #endif
601     } else if (abilityName == PASSIVE_ABILITY) {
602 #ifdef FEATURE_PASSIVE_SUPPORT
603         std::unique_ptr<PassiveAbilityProxy> passiveProxy = std::make_unique<PassiveAbilityProxy>(remoteObject);
604         passiveProxy->SendLocationRequest(workRecord);
605 #endif
606     }
607 }
608 
GetRemoteObject(std::string abilityName)609 sptr<IRemoteObject> RequestManager::GetRemoteObject(std::string abilityName)
610 {
611     sptr<IRemoteObject> remoteObject = nullptr;
612     auto locatorAbility = LocatorAbility::GetInstance();
613     if (locatorAbility == nullptr) {
614         LBSLOGE(REQUEST_MANAGER, "locatorAbility is null");
615         return remoteObject;
616     }
617     auto remoteManagerMap = locatorAbility->GetProxyMap();
618     if (remoteManagerMap == nullptr) {
619         LBSLOGE(REQUEST_MANAGER, "proxy map is empty");
620         return remoteObject;
621     }
622     auto remoteObjectIter = remoteManagerMap->find(abilityName);
623     if (remoteObjectIter == remoteManagerMap->end()) {
624         LBSLOGE(REQUEST_MANAGER, "sa init fail!");
625         return remoteObject;
626     }
627     remoteObject = remoteObjectIter->second;
628     return remoteObject;
629 }
630 
HandlePowerSuspendChanged(int32_t pid,int32_t uid,int32_t state)631 void RequestManager::HandlePowerSuspendChanged(int32_t pid, int32_t uid, int32_t state)
632 {
633     if (!IsUidInProcessing(uid)) {
634         LBSLOGD(REQUEST_MANAGER, "Current uid : %{public}d is not locating.", uid);
635         return;
636     }
637     LocatorAbility::GetInstance()->ApplyRequests(1);
638 }
639 
IsUidInProcessing(int32_t uid)640 bool RequestManager::IsUidInProcessing(int32_t uid)
641 {
642     std::unique_lock<ffrt::mutex> lock(runningUidsMutex_);
643     auto iter = runningUidMap_.find(uid);
644     if (iter == runningUidMap_.end()) {
645         return false;
646     }
647     return true;
648 }
649 
UpdateRunningUids(const std::shared_ptr<Request> & request,std::string abilityName,bool isAdd)650 void RequestManager::UpdateRunningUids(const std::shared_ptr<Request>& request, std::string abilityName, bool isAdd)
651 {
652     std::unique_lock<ffrt::mutex> lock(runningUidsMutex_);
653     auto uid = request->GetUid();
654     auto pid = request->GetPid();
655     int32_t uidCount = 0;
656     auto iter = runningUidMap_.find(uid);
657     if (iter != runningUidMap_.end()) {
658         uidCount = iter->second;
659         runningUidMap_.erase(uid);
660     }
661     if (isAdd) {
662         auto requestConfig = request->GetRequestConfig();
663         WriteLocationInnerEvent(ADD_REQUEST, {
664             "PackageName", request->GetPackageName(),
665             "abilityName", abilityName,
666             "requestAddress", request->GetUuid(),
667             "scenario", std::to_string(requestConfig->GetScenario()),
668             "priority", std::to_string(requestConfig->GetPriority()),
669             "timeInterval", std::to_string(requestConfig->GetTimeInterval()),
670             "maxAccuracy", std::to_string(requestConfig->GetMaxAccuracy())});
671         uidCount += 1;
672         if (uidCount == 1) {
673             WriteAppLocatingStateEvent("start", pid, uid);
674             ReportDataToResSched("start", pid, uid);
675         }
676     } else {
677         WriteLocationInnerEvent(REMOVE_REQUEST, {"PackageName", request->GetPackageName(),
678                     "abilityName", abilityName, "requestAddress", request->GetUuid()});
679         uidCount -= 1;
680         if (uidCount == 0) {
681             WriteAppLocatingStateEvent("stop", pid, uid);
682             ReportDataToResSched("stop", pid, uid);
683         }
684     }
685     if (uidCount > 0) {
686         runningUidMap_.insert(std::make_pair(uid, uidCount));
687     }
688 }
689 
ReportDataToResSched(std::string state,const pid_t pid,const pid_t uid)690 void RequestManager::ReportDataToResSched(std::string state, const pid_t pid, const pid_t uid)
691 {
692 #ifdef RES_SCHED_SUPPROT
693     std::unordered_map<std::string, std::string> payload;
694     payload["pid"] = std::to_string(pid);
695     payload["uid"] = std::to_string(uid);
696     payload["state"] = state;
697     uint32_t type = ResourceSchedule::ResType::RES_TYPE_LOCATION_STATUS_CHANGE;
698     int64_t value =  ResourceSchedule::ResType::LocationStatus::APP_LOCATION_STATUE_CHANGE;
699     ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, value, payload);
700 #endif
701 }
702 
RegisterLocationErrorCallback(sptr<ILocatorCallback> callback,AppIdentity identity)703 void RequestManager::RegisterLocationErrorCallback(
704     sptr<ILocatorCallback> callback, AppIdentity identity)
705 {
706     sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow)
707         LocatorErrCallbackDeathRecipient(identity.GetTokenId()));
708     callback->AsObject()->AddDeathRecipient(death);
709     std::shared_ptr<LocationErrRequest> locatorErrRequest = std::make_shared<LocationErrRequest>();
710     locatorErrRequest->SetUid(identity.GetUid());
711     locatorErrRequest->SetPid(identity.GetPid());
712     locatorErrRequest->SetLocatorErrCallbackRecipient(death);
713     std::unique_lock<ffrt::mutex> lock(locationErrorCallbackMutex_);
714     locationErrorCallbackMap_[callback->AsObject()] = locatorErrRequest;
715     LBSLOGD(LOCATOR, "after RegisterLocationErrorCallback, callback size:%{public}s",
716         std::to_string(locationErrorCallbackMap_.size()).c_str());
717 }
718 
UnRegisterLocationErrorCallback(sptr<ILocatorCallback> callback)719 void RequestManager::UnRegisterLocationErrorCallback(
720     sptr<ILocatorCallback> callback)
721 {
722     std::unique_lock<ffrt::mutex> lock(locationErrorCallbackMutex_);
723     auto iter = locationErrorCallbackMap_.find(callback->AsObject());
724     if (iter != locationErrorCallbackMap_.end()) {
725         auto locatorErrorCallback = iter->first;
726         auto locatorErrRequest = iter->second;
727         locatorErrorCallback->RemoveDeathRecipient(locatorErrRequest->GetLocatorErrCallbackRecipient());
728         locationErrorCallbackMap_.erase(iter);
729     }
730     LBSLOGD(LOCATOR, "after UnRegisterLocationErrorCallback, callback size:%{public}s",
731         std::to_string(locationErrorCallbackMap_.size()).c_str());
732 }
733 
ReportLocationError(const int errorCode,std::shared_ptr<Request> request)734 void RequestManager::ReportLocationError(const int errorCode, std::shared_ptr<Request> request)
735 {
736     std::unique_lock<ffrt::mutex> lock(locationErrorCallbackMutex_);
737     for (auto iter : locationErrorCallbackMap_) {
738         auto locatorErrRequest = iter.second;
739         if (locatorErrRequest == nullptr) {
740             continue;
741         }
742         if (LocatorAbility::GetInstance()->IsProxyPid(locatorErrRequest->GetPid()) ||
743             (request->GetUid() != 0 && (request->GetUid() != locatorErrRequest->GetUid()))) {
744             continue;
745         }
746         if (locatorErrRequest->GetLastReportErrcode() != LOCATING_FAILED_DEFAULT &&
747             locatorErrRequest->GetLastReportErrcode() == errorCode) {
748             continue;
749         }
750         sptr<ILocatorCallback> locatorErrorCallback = iface_cast<ILocatorCallback>(iter.first);
751         if (locatorErrorCallback == nullptr) {
752             continue;
753         }
754         locatorErrorCallback->OnErrorReport(errorCode);
755         locatorErrRequest->SetLastReportErrcode(errorCode);
756     }
757 }
758 
UpdateLocationError(std::shared_ptr<Request> request)759 void RequestManager::UpdateLocationError(std::shared_ptr<Request> request)
760 {
761     std::unique_lock<ffrt::mutex> lock(locationErrorCallbackMutex_);
762     for (auto iter : locationErrorCallbackMap_) {
763         auto locatorErrRequest = iter.second;
764         if (request->GetUid() != 0 && (request->GetUid() == locatorErrRequest->GetUid())) {
765             locatorErrRequest->SetLastReportErrcode(LOCATING_FAILED_DEFAULT);
766         }
767     }
768 }
769 
SyncStillMovementState(bool state)770 void RequestManager::SyncStillMovementState(bool state)
771 {
772     bool newDeviceState = false;
773     bool oldDeviceState = false;
774     oldDeviceState = isDeviceStillState_.load() && isDeviceIdleMode_.load();
775     isDeviceStillState_.store(state);
776     LBSLOGI(REQUEST_MANAGER, "device movement state change, isDeviceStillState_ %{public}d",
777         isDeviceStillState_.load());
778     newDeviceState = isDeviceStillState_.load() && isDeviceIdleMode_.load();
779     if (newDeviceState != oldDeviceState) {
780         HandleRequest();
781     }
782 }
783 
SyncIdleState(bool state)784 void RequestManager::SyncIdleState(bool state)
785 {
786     bool newDeviceState = false;
787     bool oldDeviceState = false;
788     oldDeviceState = isDeviceStillState_.load() && isDeviceIdleMode_.load();
789     isDeviceIdleMode_.store(state);
790     LBSLOGI(REQUEST_MANAGER, "device idle mode change, isDeviceIdleMode_ %{public}d",
791         isDeviceIdleMode_.load());
792     newDeviceState = isDeviceStillState_.load() && isDeviceIdleMode_.load();
793     if (newDeviceState != oldDeviceState) {
794         HandleRequest();
795     }
796 }
797 
LocatorErrCallbackDeathRecipient(int32_t tokenId)798 LocatorErrCallbackDeathRecipient::LocatorErrCallbackDeathRecipient(int32_t tokenId)
799 {
800     tokenId_ = tokenId;
801 }
802 
~LocatorErrCallbackDeathRecipient()803 LocatorErrCallbackDeathRecipient::~LocatorErrCallbackDeathRecipient()
804 {
805 }
806 
OnRemoteDied(const wptr<IRemoteObject> & remote)807 void LocatorErrCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
808 {
809     sptr<ILocatorCallback> callback = iface_cast<ILocatorCallback>(remote.promote());
810     auto requestManager = RequestManager::GetInstance();
811     if (requestManager != nullptr) {
812         requestManager->UnRegisterLocationErrorCallback(callback);
813         LBSLOGI(REQUEST_MANAGER, "locatorerr callback OnRemoteDied tokenId = %{public}d", tokenId_);
814     }
815 }
816 
LocationErrRequest()817 LocationErrRequest::LocationErrRequest()
818 {
819     uid_ = 0;
820     pid_ = 0;
821     lastReportErrcode_ = LOCATING_FAILED_DEFAULT;
822     locatorErrCallbackRecipient_ = nullptr;
823 }
824 
~LocationErrRequest()825 LocationErrRequest::~LocationErrRequest() {}
826 
GetUid()827 pid_t LocationErrRequest::GetUid()
828 {
829     return uid_;
830 }
831 
SetUid(pid_t uid)832 void LocationErrRequest::SetUid(pid_t uid)
833 {
834     uid_ = uid;
835 }
836 
GetPid()837 pid_t LocationErrRequest::GetPid()
838 {
839     return pid_;
840 }
841 
SetPid(pid_t pid)842 void LocationErrRequest::SetPid(pid_t pid)
843 {
844     pid_ = pid;
845 }
846 
GetLastReportErrcode()847 int32_t LocationErrRequest::GetLastReportErrcode()
848 {
849     return lastReportErrcode_;
850 }
851 
SetLastReportErrcode(int32_t lastReportErrcode)852 void LocationErrRequest::SetLastReportErrcode(int32_t lastReportErrcode)
853 {
854     lastReportErrcode_ = lastReportErrcode;
855 }
856 
SetLocatorErrCallbackRecipient(const sptr<IRemoteObject::DeathRecipient> & recipient)857 void LocationErrRequest::SetLocatorErrCallbackRecipient(const sptr<IRemoteObject::DeathRecipient>& recipient)
858 {
859     locatorErrCallbackRecipient_ = recipient;
860 }
861 
GetLocatorErrCallbackRecipient()862 sptr<IRemoteObject::DeathRecipient> LocationErrRequest::GetLocatorErrCallbackRecipient()
863 {
864     return locatorErrCallbackRecipient_;
865 }
866 } // namespace Location
867 } // namespace OHOS
868