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