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