/* * Copyright (c) 2021-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "pending_want_manager.h" #include "ability_manager_service.h" #include "ability_util.h" #include "distributed_client.h" #include "hitrace_meter.h" #include "permission_constants.h" #include "session_manager_lite.h" #include "utils/app_mgr_util.h" #include "wm_common.h" namespace OHOS { namespace AAFwk { using namespace OHOS::EventFwk; using namespace std::chrono; using namespace std::placeholders; PendingWantManager::PendingWantManager() { } PendingWantManager::~PendingWantManager() { } sptr PendingWantManager::GetWantSender(int32_t callingUid, int32_t uid, const bool isSystemApp, const WantSenderInfo &wantSenderInfo, const sptr &callerToken, int32_t appIndex) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); if (wantSenderInfo.type != static_cast(OperationType::SEND_COMMON_EVENT)) { if (callingUid != uid && !isSystemApp && !AAFwk::PermissionVerification::GetInstance()->IsSACall()) { TAG_LOGE(AAFwkTag::WANTAGENT, "cannot send"); return nullptr; } } if (wantSenderInfo.type == static_cast(OperationType::START_SERVICE_EXTENSION) && !isSystemApp && !AAFwk::PermissionVerification::GetInstance()->IsSACall()) { TAG_LOGE(AAFwkTag::WANTAGENT, "non-system app called"); return nullptr; } WantSenderInfo info = wantSenderInfo; if (wantSenderInfo.type != static_cast(OperationType::SEND_COMMON_EVENT) && !isSystemApp && !AAFwk::PermissionVerification::GetInstance()->IsSACall()) { for (auto it = info.allWants.begin(); it != info.allWants.end(); ++it) { if (info.bundleName != it->want.GetBundle()) { info.allWants.erase(it); } else { it->want.RemoveParam("ohos.extra.param.key.appCloneIndex"); } } } return GetWantSenderLocked(callingUid, uid, wantSenderInfo.userId, info, callerToken, appIndex); } sptr PendingWantManager::GetWantSenderLocked(const int32_t callingUid, const int32_t uid, const int32_t userId, WantSenderInfo &wantSenderInfo, const sptr &callerToken, int32_t appIndex) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); bool needCreate = (static_cast(wantSenderInfo.flags) & static_cast(Flags::NO_BUILD_FLAG)) == 0; bool needCancel = (static_cast(wantSenderInfo.flags) & static_cast(Flags::CANCEL_PRESENT_FLAG)) != 0; bool needUpdate = (static_cast(wantSenderInfo.flags) & static_cast(Flags::UPDATE_PRESENT_FLAG)) != 0; std::shared_ptr pendingKey = std::make_shared(); pendingKey->SetBundleName(wantSenderInfo.bundleName); pendingKey->SetRequestWho(wantSenderInfo.resultWho); pendingKey->SetRequestCode(wantSenderInfo.requestCode); pendingKey->SetFlags(wantSenderInfo.flags); pendingKey->SetUserId(wantSenderInfo.userId); pendingKey->SetType(wantSenderInfo.type); pendingKey->SetAppIndex(appIndex); if (wantSenderInfo.allWants.size() > 0) { pendingKey->SetRequestWant(wantSenderInfo.allWants.back().want); pendingKey->SetRequestResolvedType(wantSenderInfo.allWants.back().resolvedTypes); pendingKey->SetAllWantsInfos(wantSenderInfo.allWants); } std::lock_guard locker(mutex_); auto ref = GetPendingWantRecordByKey(pendingKey); if (ref != nullptr) { if (!needCancel) { if (needUpdate && wantSenderInfo.allWants.size() > 0) { ref->GetKey()->SetRequestWant(wantSenderInfo.allWants.back().want); ref->GetKey()->SetRequestResolvedType(wantSenderInfo.allWants.back().resolvedTypes); wantSenderInfo.allWants.back().want = ref->GetKey()->GetRequestWant(); wantSenderInfo.allWants.back().resolvedTypes = ref->GetKey()->GetRequestResolvedType(); ref->GetKey()->SetAllWantsInfos(wantSenderInfo.allWants); ref->SetCallerUid(callingUid); } return ref; } MakeWantSenderCanceledLocked(*ref); wantRecords_.erase(ref->GetKey()); EraseBundleRecord(wantSenderInfo.allWants, ref->GetKey()); } if (!needCreate) { return (ref != nullptr) ? ref : nullptr; } sptr rec = new (std::nothrow) PendingWantRecord(shared_from_this(), uid, IPCSkeleton::GetCallingTokenID(), callerToken, pendingKey); if (rec != nullptr) { rec->SetCallerUid(callingUid); pendingKey->SetCode(PendingRecordIdCreate()); wantRecords_.insert(std::make_pair(pendingKey, rec)); InsertBundleRecord(wantSenderInfo.allWants, pendingKey); TAG_LOGD(AAFwkTag::WANTAGENT, "wantRecords_ size %{public}zu", wantRecords_.size()); return rec; } return nullptr; } void PendingWantManager::MakeWantSenderCanceledLocked(PendingWantRecord &record) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); record.SetCanceled(); for (auto &callback : record.GetCancelCallbacks()) { callback->Send(record.GetKey()->GetRequestCode()); } } sptr PendingWantManager::GetPendingWantRecordByKey(const std::shared_ptr &key) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); for (const auto &item : wantRecords_) { const auto pendingKey = item.first; const auto pendingRecord = item.second; if ((pendingRecord != nullptr) && CheckPendingWantRecordByKey(pendingKey, key)) { return pendingRecord; } } return nullptr; } bool PendingWantManager::CheckPendingWantRecordByKey( const std::shared_ptr &inputKey, const std::shared_ptr &key) { if (!inputKey || !key) { TAG_LOGW(AAFwkTag::WANTAGENT, "inputKey or key null"); return false; } if (inputKey->GetAppIndex() != key->GetAppIndex()) { return false; } if (inputKey->GetBundleName().compare(key->GetBundleName()) != 0) { return false; } if (inputKey->GetType() != key->GetType()) { return false; } if (inputKey->GetRequestWho().compare(key->GetRequestWho()) != 0) { return false; } if (inputKey->GetRequestCode() != key->GetRequestCode()) { return false; } if (inputKey->GetRequestResolvedType().compare(key->GetRequestResolvedType()) != 0) { return false; } if (inputKey->GetUserId() != key->GetUserId()) { return false; } if (!inputKey->IsEqualsRequestWant(key->GetRequestWantRef())) { return false; } return true; } int32_t PendingWantManager::SendWantSender(sptr target, const SenderInfo &senderInfo) { if (target == nullptr) { if (senderInfo.finishedReceiver != nullptr) { Want want; WantParams wantParams = {}; senderInfo.finishedReceiver->PerformReceive(want, senderInfo.code, "canceled", wantParams, false, false, 0); } TAG_LOGE(AAFwkTag::WANTAGENT, "null sender"); return ERR_INVALID_VALUE; } sptr obj = target->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { if (senderInfo.finishedReceiver != nullptr) { Want want; WantParams wantParams = {}; senderInfo.finishedReceiver->PerformReceive(want, senderInfo.code, "canceled", wantParams, false, false, 0); } TAG_LOGE(AAFwkTag::WANTAGENT, "target object null or a proxy"); return ERR_INVALID_VALUE; } sptr record = iface_cast(obj); SenderInfo info = senderInfo; return record->SenderInner(info); } void PendingWantManager::CancelWantSender(const bool isSystemApp, const sptr &sender) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); if (sender == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null sender"); return; } auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall(); if (!isSaCall && !isSystemApp) { TAG_LOGE(AAFwkTag::WANTAGENT, "cannot send"); return; } sptr obj = sender->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target object null or a proxy"); return; } sptr record = iface_cast(obj); CancelWantSenderLocked(*record, true); } void PendingWantManager::CancelWantSenderLocked(PendingWantRecord &record, bool cleanAbility) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); std::lock_guard locker(mutex_); MakeWantSenderCanceledLocked(record); if (cleanAbility) { wantRecords_.erase(record.GetKey()); if (record.GetKey() != nullptr) { EraseBundleRecord(record.GetKey()->GetAllWantsInfos(), record.GetKey()); } } } int32_t PendingWantManager::DeviceIdDetermine(const Want &want, const sptr &startOptions, const sptr &callerToken, int32_t requestCode, const int32_t callerUid, int32_t callerTokenId) { int32_t result = ERR_OK; std::string localDeviceId; DelayedSingleton::GetInstance()->GetLocalDeviceId(localDeviceId); if (want.GetElement().GetDeviceID() == "" || want.GetElement().GetDeviceID() == localDeviceId) { if (!startOptions) { result = DelayedSingleton::GetInstance()->StartAbilityWithSpecifyTokenIdInner( want, callerToken, callerTokenId, true, requestCode, callerUid); } else { TAG_LOGD(AAFwkTag::WANTAGENT, "StartOptions windowMode:%{public}d displayId:%{public}d \ withAnimation:%{public}d windowLeft:%{public}d windowTop:%{public}d windowWidth:%{public}d \ windowHeight:%{public}d", startOptions->GetWindowMode(), startOptions->GetDisplayID(), startOptions->GetWithAnimation(), startOptions->GetWindowLeft(), startOptions->GetWindowTop(), startOptions->GetWindowWidth(), startOptions->GetWindowHeight()); result = DelayedSingleton::GetInstance()->StartAbilityWithSpecifyTokenIdInner( want, *startOptions, callerToken, true, requestCode, callerUid, callerTokenId); } if (result != ERR_OK && result != START_ABILITY_WAITING) { TAG_LOGE(AAFwkTag::WANTAGENT, "startAbility failed"); } return result; } sptr remoteObject = OHOS::DelayedSingleton::GetInstance()->GetSystemAbility(DISTRIBUTED_SCHED_SA_ID); if (remoteObject == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "GetSystemAbility failed"); result = ERR_INVALID_VALUE; return result; } DistributedClient dmsClient; uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); int32_t callingUid = IPCSkeleton::GetCallingUid(); result = dmsClient.StartRemoteAbility(want, callingUid, requestCode, accessToken); if (result != ERR_OK) { TAG_LOGE(AAFwkTag::WANTAGENT, "StartRemoteAbility failed result = %{public}d", result); } return result; } int32_t PendingWantManager::PendingWantStartAbility(const Want &want, const sptr &startOptions, const sptr &callerToken, int32_t requestCode, const int32_t callerUid, int32_t callerTokenId) { TAG_LOGI(AAFwkTag::WANTAGENT, "begin"); if (!CheckCallerPermission()) { return ERR_INVALID_VALUE; } int32_t result = DeviceIdDetermine(want, startOptions, callerToken, requestCode, callerUid, callerTokenId); return result; } int32_t PendingWantManager::PendingWantStartServiceExtension(Want &want, const sptr &callerToken) { TAG_LOGI(AAFwkTag::WANTAGENT, "called"); if (!PermissionVerification::GetInstance()->IsSystemAppCall() && !PermissionVerification::GetInstance()->IsSACall()) { TAG_LOGE(AAFwkTag::WANTAGENT, "non-system app called"); return ERR_INVALID_VALUE; } //reset flags want.SetFlags(0); return DelayedSingleton::GetInstance()->StartExtensionAbility(want, callerToken); } int32_t PendingWantManager::PendingWantStartAbilitys(const std::vector &wantsInfo, const sptr &startOptions, const sptr &callerToken, int32_t requestCode, const int32_t callerUid, int32_t callerTokenId) { TAG_LOGI(AAFwkTag::WANTAGENT, "begin"); if (!CheckCallerPermission()) { return ERR_INVALID_VALUE; } int32_t result = ERR_OK; for (const auto &item : wantsInfo) { auto res = DeviceIdDetermine(item.want, startOptions, callerToken, requestCode, callerUid, callerTokenId); if (res != ERR_OK && res != START_ABILITY_WAITING) { result = res; } } return result; } int32_t PendingWantManager::PendingWantPublishCommonEvent( const Want &want, const SenderInfo &senderInfo, int32_t callerUid, int32_t callerTokenId) { TAG_LOGI(AAFwkTag::WANTAGENT, "begin"); CommonEventData eventData; eventData.SetWant(want); eventData.SetCode(senderInfo.code); CommonEventPublishInfo eventPublishData; if (!want.GetBundle().empty()) { TAG_LOGI(AAFwkTag::WANTAGENT, "eventPublishData set bundleName: %{public}s", want.GetBundle().c_str()); eventPublishData.SetBundleName(want.GetBundle()); } if (!senderInfo.requiredPermission.empty()) { std::vector permissions; permissions.emplace_back(senderInfo.requiredPermission); eventPublishData.SetSubscriberPermissions(permissions); } bool result = IN_PROCESS_CALL(DelayedSingleton::GetInstance()->PublishCommonEvent( eventData, eventPublishData, nullptr, callerUid, callerTokenId)); return ((result == true) ? ERR_OK : (-1)); } int32_t PendingWantManager::PendingRecordIdCreate() { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); static std::atomic_int id(0); return ++id; } sptr PendingWantManager::GetPendingWantRecordByCode(int32_t code) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); std::lock_guard locker(mutex_); auto iter = std::find_if(wantRecords_.begin(), wantRecords_.end(), [&code](const auto &pair) { return pair.second->GetKey()->GetCode() == code; }); return ((iter == wantRecords_.end()) ? nullptr : iter->second); } int32_t PendingWantManager::GetPendingWantUid(const sptr &target) { if (target == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null target"); return -1; } sptr obj = target->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return -1; } sptr targetRecord = iface_cast(obj); auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); return ((record != nullptr) ? (record->GetUid()) : (-1)); } int32_t PendingWantManager::GetPendingWantUserId(const sptr &target) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); if (target == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null target"); return -1; } sptr obj = target->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return -1; } sptr targetRecord = iface_cast(obj); auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); return ((record != nullptr) ? (record->GetKey()->GetUserId()) : (-1)); } std::string PendingWantManager::GetPendingWantBundleName(const sptr &target) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); if (target == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null target"); return ""; } sptr obj = target->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return ""; } sptr targetRecord = iface_cast(obj); auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); if (record != nullptr) { return record->GetKey()->GetBundleName(); } return ""; } int32_t PendingWantManager::GetPendingWantCode(const sptr &target) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); if (target == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null target"); return -1; } sptr obj = target->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return -1; } sptr targetRecord = iface_cast(obj); auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); return ((record != nullptr) ? (record->GetKey()->GetCode()) : (-1)); } int32_t PendingWantManager::GetPendingWantType(const sptr &target) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); if (target == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null target"); return -1; } sptr obj = target->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return -1; } sptr targetRecord = iface_cast(obj); auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); return ((record != nullptr) ? (record->GetKey()->GetType()) : (-1)); } void PendingWantManager::RegisterCancelListener(const sptr &sender, const sptr &recevier) { TAG_LOGI(AAFwkTag::WANTAGENT, "begin"); if ((sender == nullptr) || (recevier == nullptr)) { TAG_LOGE(AAFwkTag::WANTAGENT, "sender or recevier null"); return; } sptr obj = sender->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return; } sptr targetRecord = iface_cast(obj); auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); if (record == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null record. code = %{public}d", targetRecord->GetKey()->GetCode()); return; } bool cancel = record->GetCanceled(); std::lock_guard locker(mutex_); if (!cancel) { record->RegisterCancelListener(recevier); } } void PendingWantManager::UnregisterCancelListener(const sptr &sender, const sptr &recevier) { if (sender == nullptr || recevier == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "sender or recevier null"); return; } sptr obj = sender->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return; } sptr targetRecord = iface_cast(obj); auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); if (record == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null record"); return; } std::lock_guard locker(mutex_); record->UnregisterCancelListener(recevier); } int32_t PendingWantManager::GetPendingRequestWant(const sptr &target, std::shared_ptr &want) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); if (target == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null target"); return ERR_INVALID_VALUE; } sptr obj = target->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return ERR_INVALID_VALUE; } if (want == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null want"); return ERR_INVALID_VALUE; } sptr targetRecord = iface_cast(obj); if (targetRecord == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null targetRecord"); return ERR_INVALID_VALUE; } auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); if (record == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null record"); return ERR_INVALID_VALUE; } want.reset(new (std::nothrow) Want(record->GetKey()->GetRequestWant())); return NO_ERROR; } int32_t PendingWantManager::GetWantSenderInfo(const sptr &target, std::shared_ptr &info) { TAG_LOGD(AAFwkTag::WANTAGENT, "begin"); if (target == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null target"); return ERR_INVALID_VALUE; } sptr obj = target->AsObject(); if (obj == nullptr || obj->IsProxyObject()) { TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object"); return ERR_INVALID_VALUE; } if (info == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null info"); return ERR_INVALID_VALUE; } sptr targetRecord = iface_cast(obj); auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode()); if (record == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null record"); return ERR_INVALID_VALUE; } WantSenderInfo wantSenderInfo; wantSenderInfo.requestCode = record->GetKey()->GetRequestCode(); wantSenderInfo.type = record->GetKey()->GetType(); wantSenderInfo.flags = (uint32_t)(record->GetKey()->GetFlags()); wantSenderInfo.allWants = record->GetKey()->GetAllWantsInfos(); info.reset(new (std::nothrow) WantSenderInfo(wantSenderInfo)); return NO_ERROR; } void PendingWantManager::ClearPendingWantRecord(const std::string &bundleName, int32_t uid) { auto abilityManagerService = DelayedSingleton::GetInstance(); CHECK_POINTER(abilityManagerService); auto handler = abilityManagerService->GetTaskHandler(); CHECK_POINTER(handler); auto task = [bundleName, uid, self = shared_from_this()]() { self->ClearPendingWantRecordTask(bundleName, uid); }; handler->SubmitTask(task); } void PendingWantManager::ClearPendingWantRecordTask(const std::string &bundleName, int32_t uid) { if (!QueryRecordByBundle(bundleName)) { return; } std::lock_guard locker(mutex_); if (!QueryRecordByBundle(bundleName)) { return; } auto iter = wantRecords_.begin(); while (iter != wantRecords_.end()) { bool hasBundle = false; const auto &pendingRecord = iter->second; if ((pendingRecord != nullptr)) { auto wantInfos = pendingRecord->GetKey()->GetAllWantsInfos(); for (const auto &wantInfo: wantInfos) { if (wantInfo.want.GetBundle() == bundleName && uid == pendingRecord->GetUid()) { hasBundle = true; break; } } if (hasBundle) { EraseBundleRecord(wantInfos, pendingRecord->GetKey()); iter = wantRecords_.erase(iter); TAG_LOGI(AAFwkTag::WANTAGENT, "wantRecords_ size %{public}zu", wantRecords_.size()); } else { ++iter; } } else { ++iter; } } } bool PendingWantManager::CheckCallerPermission() { auto callerPid = IPCSkeleton::GetCallingPid(); AppExecFwk::RunningProcessInfo processInfo; DelayedSingleton::GetInstance()->GetRunningProcessInfoByPid(callerPid, processInfo); auto permission = DelayedSingleton::GetInstance(); if (permission == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null permission"); return false; } if ((!processInfo.isFocused && !processInfo.isAbilityForegrounding) || (!permission->IsSystemAppCall() && !CheckWindowState(callerPid))) { TAG_LOGW(AAFwkTag::WANTAGENT, "caller unfocused"); if (!permission->VerifyCallingPermission(PermissionConstants::PERMISSION_START_ABILITIES_FROM_BACKGROUND) && !permission->VerifyCallingPermission(PermissionConstants::PERMISSION_START_ABILIIES_FROM_BACKGROUND) && !permission->IsSACall()) { TAG_LOGW(AAFwkTag::WANTAGENT, "caller PERMISSION_DENIED"); return false; } } return true; } bool PendingWantManager::CheckWindowState(int32_t pid) { auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy(); if (sceneSessionManager == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "null manager"); return false; } std::vector windowStates; Rosen::WSError ret = sceneSessionManager->GetMainWindowStatesByPid(pid, windowStates); if (ret != Rosen::WSError::WS_OK) { TAG_LOGE(AAFwkTag::WANTAGENT, "fail GetWindow"); return false; } for (auto &windowState : windowStates) { if (!windowState.isPcOrPadEnableActivation_ && !windowState.isForegroundInteractive_) { TAG_LOGD(AAFwkTag::WANTAGENT, "window interactive"); return false; } } return true; } void PendingWantManager::Dump(std::vector &info) { TAG_LOGD(AAFwkTag::WANTAGENT, "dump begin"); std::string dumpInfo = " PendingWantRecords:"; info.push_back(dumpInfo); for (const auto &item : wantRecords_) { const auto &pendingKey = item.first; dumpInfo = " PendWantRecord ID #" + std::to_string(pendingKey->GetCode()) + " type #" + std::to_string(pendingKey->GetType()); info.push_back(dumpInfo); dumpInfo = " bundle name [" + pendingKey->GetBundleName() + "]"; info.push_back(dumpInfo); dumpInfo = " result who [" + pendingKey->GetRequestWho() + "]"; info.push_back(dumpInfo); dumpInfo = " request code #" + std::to_string(pendingKey->GetRequestCode()) + " flags #" + std::to_string(pendingKey->GetFlags()); info.push_back(dumpInfo); dumpInfo = " resolved type [" + pendingKey->GetRequestResolvedType() + "]"; info.push_back(dumpInfo); dumpInfo = " Wants:"; info.push_back(dumpInfo); auto Wants = pendingKey->GetAllWantsInfos(); for (const auto &Want : Wants) { dumpInfo = " uri [" + Want.want.GetElement().GetDeviceID() + "//" + Want.want.GetElement().GetBundleName() + "/" + Want.want.GetElement().GetAbilityName() + "]"; info.push_back(dumpInfo); dumpInfo = " resolved types [" + Want.resolvedTypes + "]"; info.push_back(dumpInfo); } } } void PendingWantManager::DumpByRecordId(std::vector &info, const std::string &args) { TAG_LOGD(AAFwkTag::WANTAGENT, "dump by id begin"); std::string dumpInfo = " PendingWantRecords:"; info.push_back(dumpInfo); for (const auto &item : wantRecords_) { const auto &pendingKey = item.first; if (args == std::to_string(pendingKey->GetCode())) { dumpInfo = " PendWantRecord ID #" + std::to_string(pendingKey->GetCode()) + " type #" + std::to_string(pendingKey->GetType()); info.push_back(dumpInfo); dumpInfo = " bundle name [" + pendingKey->GetBundleName() + "]"; info.push_back(dumpInfo); dumpInfo = " result who [" + pendingKey->GetRequestWho() + "]"; info.push_back(dumpInfo); dumpInfo = " request code #" + std::to_string(pendingKey->GetRequestCode()) + " flags #" + std::to_string(pendingKey->GetFlags()); info.push_back(dumpInfo); dumpInfo = " resolved type [" + pendingKey->GetRequestResolvedType() + "]"; info.push_back(dumpInfo); dumpInfo = " Wants:"; info.push_back(dumpInfo); auto Wants = pendingKey->GetAllWantsInfos(); for (const auto& Want : Wants) { dumpInfo = " uri [" + Want.want.GetElement().GetDeviceID() + "//" + Want.want.GetElement().GetBundleName() + "/" + Want.want.GetElement().GetAbilityName() + "]"; info.push_back(dumpInfo); dumpInfo = " resolved types [" + Want.resolvedTypes + "]"; info.push_back(dumpInfo); } } } } int32_t PendingWantManager::GetAllRunningInstanceKeysByBundleName( const std::string &bundleName, std::vector &appKeyVec) { if (bundleName.empty()) { TAG_LOGE(AAFwkTag::WANTAGENT, "bundle name is empty"); return ERR_INVALID_VALUE; } auto appMgr = AppMgrUtil::GetAppMgr(); if (appMgr == nullptr) { TAG_LOGE(AAFwkTag::WANTAGENT, "app mgr is null"); return OBJECT_NULL; } return IN_PROCESS_CALL(appMgr->GetAllRunningInstanceKeysByBundleName(bundleName, appKeyVec)); } void PendingWantManager::EraseBundleRecord( const std::vector &wantsInfos, std::shared_ptr key) { std::lock_guard locker(bundleRecordsMutex_); for (const auto &wantInfo : wantsInfos) { auto it = bundleRecords_.find(wantInfo.want.GetBundle()); if (it != bundleRecords_.end()) { auto &recordVec = it->second; recordVec.erase(std::remove_if(recordVec.begin(), recordVec.end(), [key](std::shared_ptr value) { return value == key; }), recordVec.end()); if (recordVec.empty()) { bundleRecords_.erase(wantInfo.want.GetBundle()); } } } } void PendingWantManager::InsertBundleRecord( const std::vector &wantsInfos, std::shared_ptr key) { std::lock_guard locker(bundleRecordsMutex_); for (const auto &wantInfo : wantsInfos) { auto it = bundleRecords_.find(wantInfo.want.GetBundle()); if (it != bundleRecords_.end()) { auto &recordVec = it->second; recordVec.emplace_back(key); } else { std::vector> pendingWantVector; pendingWantVector.emplace_back(key); bundleRecords_[wantInfo.want.GetBundle()] = pendingWantVector; } } } bool PendingWantManager::QueryRecordByBundle(const std::string &bundleName) { std::lock_guard locker(bundleRecordsMutex_); auto bundleIter = bundleRecords_.find(bundleName); if (bundleIter != bundleRecords_.end()) { return true; } return false; } } // namespace AAFwk } // namespace OHOS