* Copyright (c) 2021-2026 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;
constexpr const char* PENDING_WANT_MANAGER = "PendingWantManager";
PendingWantManager::PendingWantManager()
{
taskHandler_ = TaskHandlerWrap::CreateQueueHandler(PENDING_WANT_MANAGER);
}
PendingWantManager::~PendingWantManager()
{
}
sptr<IWantSender> PendingWantManager::GetWantSender(int32_t callingUid, int32_t uid, const bool isSystemApp,
const WantSenderInfo &wantSenderInfo, const sptr<IRemoteObject> &callerToken, int32_t appIndex,
int32_t publisherUid)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
if (wantSenderInfo.type != static_cast<int32_t>(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<int32_t>(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<int32_t>(OperationType::SEND_COMMON_EVENT) &&
!isSystemApp && !AAFwk::PermissionVerification::GetInstance()->IsSACall()) {
for (auto it = info.allWants.begin(); it != info.allWants.end();) {
if (info.bundleName != it->want.GetBundleNameRef()) {
it = info.allWants.erase(it);
} else {
it->want.RemoveParam("ohos.extra.param.key.appCloneIndex");
it++;
}
}
}
return GetWantSenderLocked(callingUid, uid, wantSenderInfo.userId, info, callerToken, appIndex, publisherUid);
}
void SendWantAgentNumberEvent(std::shared_ptr<PendingWantKey> pendingKey, int32_t wantAgentNumber)
{
std::string bundleName = pendingKey->GetBundleName();
std::int32_t appIndex = pendingKey->GetAppIndex();
EventInfo eventInfo;
eventInfo.callerBundleName = bundleName;
eventInfo.callerUid = appIndex;
eventInfo.wantAgentNumber = wantAgentNumber;
EventReport::SendWantAgentEvent(EventName::WANTAGENT_NUMBER, HISYSEVENT_STATISTIC, eventInfo);
}
void PendingWantManager::HandleAddWantAgentNumber(std::shared_ptr<PendingWantKey> pendingKey)
{
if (pendingKey == nullptr) {
return;
}
TAG_LOGD(AAFwkTag::WANTAGENT, "add wantAgent number");
std::string bundleName = pendingKey->GetBundleName();
std::lock_guard<ffrt::mutex> locker(countMutex_);
auto it = wantAgentCount_.find(bundleName);
if (it == wantAgentCount_.end()) {
wantAgentCount_.insert(std::make_pair(bundleName, AgentCount{1, 1, false}));
return;
}
it->second.currentNumber = it->second.currentNumber + 1;
if (it->second.DFXFlag) {
TAG_LOGD(AAFwkTag::WANTAGENT, "wantagent current number: %{public}d", it->second.currentNumber);
if ((it->second.currentNumber > WANTAGENT_NUMBER_THRESHOLD) &&
(it->second.currentNumber - it->second.latestMinNumber > WANTAGENT_FLOAT_THRESHOLD)) {
if (it->second.currentNumber % DFX_INTERVAL == 0) {
SendWantAgentNumberEvent(pendingKey, it->second.currentNumber);
}
}
} else {
if (it->second.currentNumber > WANTAGENT_NUMBER_THRESHOLD) {
SendWantAgentNumberEvent(pendingKey, it->second.currentNumber);
it->second.DFXFlag = true;
}
}
}
void PendingWantManager::AddWantAgentNumber(std::shared_ptr<PendingWantKey> pendingKey)
{
if (PermissionVerification::GetInstance()->IsSystemAppCall() ||
PermissionVerification::GetInstance()->IsSACall()) {
TAG_LOGD(AAFwkTag::WANTAGENT, "systemCall");
return;
}
HandleAddWantAgentNumber(pendingKey);
}
void PendingWantManager::HandleReduceWantAgentNumber(std::shared_ptr<PendingWantKey> pendingKey)
{
if (pendingKey == nullptr) {
return;
}
TAG_LOGD(AAFwkTag::WANTAGENT, "reduce wantAgent number");
std::string bundleName = pendingKey->GetBundleName();
std::lock_guard<ffrt::mutex> locker(countMutex_);
auto it = wantAgentCount_.find(bundleName);
if (it == wantAgentCount_.end()) {
TAG_LOGD(AAFwkTag::WANTAGENT, "No WantAgent");
} else {
if (it->second.currentNumber == 1) {
wantAgentCount_.erase(bundleName);
} else {
it->second.currentNumber = it->second.currentNumber - 1;
it->second.latestMinNumber = it->second.currentNumber;
}
}
}
void PendingWantManager::ReduceWantAgentNumber(std::shared_ptr<PendingWantKey> pendingKey)
{
if (PermissionVerification::GetInstance()->IsSystemAppCall() ||
PermissionVerification::GetInstance()->IsSACall()) {
TAG_LOGD(AAFwkTag::WANTAGENT, "systemCall");
return;
}
HandleReduceWantAgentNumber(pendingKey);
}
sptr<IWantSender> PendingWantManager::GetWantSenderLocked(const int32_t callingUid, const int32_t uid,
const int32_t userId, WantSenderInfo &wantSenderInfo, const sptr<IRemoteObject> &callerToken, int32_t appIndex,
int32_t publisherUid)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
bool needCreate = (static_cast<uint32_t>(wantSenderInfo.flags) &
static_cast<uint32_t>(Flags::NO_BUILD_FLAG)) == 0;
bool needCancel = (static_cast<uint32_t>(wantSenderInfo.flags) &
static_cast<uint32_t>(Flags::CANCEL_PRESENT_FLAG)) != 0;
bool needUpdate = (static_cast<uint32_t>(wantSenderInfo.flags) &
static_cast<uint32_t>(Flags::UPDATE_PRESENT_FLAG)) != 0;
std::shared_ptr<PendingWantKey> pendingKey = std::make_shared<PendingWantKey>();
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<ffrt::mutex> 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);
ref->SetPublisherUid(publisherUid);
}
return ref;
}
MakeWantSenderCanceledLocked(*ref);
ReduceWantAgentNumber(ref->GetKey());
wantRecords_.erase(ref->GetKey());
}
if (!needCreate) {
return (ref != nullptr) ? ref : nullptr;
}
sptr<PendingWantRecord> rec =
new (std::nothrow) PendingWantRecord(shared_from_this(), uid, IPCSkeleton::GetCallingTokenID(),
callerToken, pendingKey);
if (rec != nullptr) {
rec->SetCallerUid(callingUid);
rec->SetPublisherUid(publisherUid);
pendingKey->SetCode(PendingRecordIdCreate());
AddWantAgentNumber(pendingKey);
wantRecords_.insert(std::make_pair(pendingKey, rec));
TAG_LOGI(AAFwkTag::WANTAGENT,
"wantRecords_ size %{public}zu, bundleName=%{public}s, flags=%{public}d, type=%{public}d, code=%{public}d",
wantRecords_.size(), pendingKey->GetBundleName().c_str(), pendingKey->GetFlags(), pendingKey->GetType(),
pendingKey->GetCode());
return rec;
}
return nullptr;
}
void PendingWantManager::MakeWantSenderCanceledLocked(PendingWantRecord &record)
{
TAG_LOGI(AAFwkTag::WANTAGENT, "cancel");
record.SetCanceled();
for (auto &callback : record.GetCancelCallbacks()) {
callback->Send(record.GetKey()->GetRequestCode());
}
if (record.GetKey() != nullptr && record.GetKey()->GetCode() > 0) {
record.GetKey()->ClearAllWantsInfosFd();
}
}
sptr<PendingWantRecord> PendingWantManager::GetPendingWantRecordByKey(const std::shared_ptr<PendingWantKey> &key)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
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<PendingWantKey> &inputKey, const std::shared_ptr<PendingWantKey> &key)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
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<IWantSender> target, SenderInfo &senderInfo)
{
SenderInfo info = 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<IRemoteObject> 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<PendingWantRecord> record = static_cast<PendingWantRecord*>(target.GetRefPtr());
if (!CheckPermission(record)) {
if (senderInfo.finishedReceiver != nullptr) {
Want want;
record->BuildSendWant(info, want);
WantParams wantParams = {};
senderInfo.finishedReceiver->PerformReceive(want, senderInfo.code, "", wantParams, false, false, 0);
}
return ERR_INVALID_VALUE;
}
return record->SenderInner(senderInfo);
}
int32_t PendingWantManager::SendLocalWantSender(const SenderInfo &senderInfo)
{
int32_t result = NO_ERROR;
switch (senderInfo.operType) {
case static_cast<int32_t>(OperationType::START_ABILITY): {
result = PendingWantStartAbility(senderInfo.want, senderInfo.startOptions,
senderInfo.callerToken, -1, senderInfo.uid, senderInfo.tokenId, -1);
break;
}
case static_cast<int32_t>(OperationType::START_SERVICE): {
result = PendingWantStartAbility(senderInfo.want, nullptr,
senderInfo.callerToken, -1, senderInfo.uid, senderInfo.tokenId, -1);
break;
}
default: {
break;
}
}
bool sendFinish = (senderInfo.finishedReceiver != nullptr);
if (sendFinish && result != ERR_WANTAGENT_CANCELED) {
WantParams wantParams = {};
senderInfo.finishedReceiver->PerformReceive(senderInfo.want, senderInfo.code, "", wantParams, false, false, 0);
}
return result;
}
void PendingWantManager::CancelWantSender(const bool isSystemAppCall, const sptr<IWantSender> &sender)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
if (sender == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null sender");
return;
}
auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
if (!isSaCall && !isSystemAppCall) {
TAG_LOGE(AAFwkTag::WANTAGENT, "cannot send");
return;
}
sptr<IRemoteObject> obj = sender->AsObject();
if (obj == nullptr || obj->IsProxyObject()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "target object null or a proxy");
return;
}
sptr<PendingWantRecord> record = static_cast<PendingWantRecord*>(sender.GetRefPtr());
CancelWantSenderLocked(*record, true);
}
void PendingWantManager::CancelWantSenderLocked(PendingWantRecord &record, bool cleanAbility)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
std::lock_guard<ffrt::mutex> locker(mutex_);
MakeWantSenderCanceledLocked(record);
if (cleanAbility) {
ReduceWantAgentNumber(record.GetKey());
wantRecords_.erase(record.GetKey());
}
}
int32_t PendingWantManager::DeviceIdDetermine(const Want &want, const sptr<StartOptions> &startOptions,
const sptr<IRemoteObject> &callerToken, int32_t requestCode, const int32_t callerUid, int32_t callerTokenId,
int32_t userId)
{
int32_t result = ERR_OK;
std::string localDeviceId;
DelayedSingleton<AbilityManagerService>::GetInstance()->GetLocalDeviceId(localDeviceId);
if (want.GetDeviceIdRef() == "" || want.GetDeviceIdRef() == localDeviceId) {
if (!startOptions) {
result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbilityWithSpecifyTokenIdInner(
want, callerToken, callerTokenId, true, userId, requestCode);
} 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<AbilityManagerService>::GetInstance()->StartAbilityWithSpecifyTokenIdInner(
want, *startOptions, callerToken, true, userId, requestCode, callerTokenId);
}
if (result != ERR_OK && result != START_ABILITY_WAITING) {
TAG_LOGE(AAFwkTag::WANTAGENT, "startAbility failed");
}
return result;
}
sptr<IRemoteObject> remoteObject =
OHOS::DelayedSingleton<SaMgrClient>::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, callerTokenId);
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> &startOptions,
const sptr<IRemoteObject> &callerToken, int32_t requestCode, const int32_t callerUid, int32_t callerTokenId,
int32_t userId)
{
TAG_LOGI(AAFwkTag::WANTAGENT, "start ability");
int32_t result = DeviceIdDetermine(want, startOptions, callerToken, requestCode, callerUid, callerTokenId, userId);
return result;
}
int32_t PendingWantManager::PendingWantStartServiceExtension(Want &want, const sptr<IRemoteObject> &callerToken)
{
TAG_LOGI(AAFwkTag::WANTAGENT, "start service extension");
if (!PermissionVerification::GetInstance()->IsSystemAppCall() &&
!PermissionVerification::GetInstance()->IsSACall()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "non-system app called");
return ERR_INVALID_VALUE;
}
want.SetFlags(0);
return DelayedSingleton<AbilityManagerService>::GetInstance()->StartExtensionAbility(want, callerToken);
}
int32_t PendingWantManager::PendingWantStartAbilitys(const std::vector<WantsInfo> &wantsInfo,
const sptr<StartOptions> &startOptions, const sptr<IRemoteObject> &callerToken, int32_t requestCode,
const int32_t callerUid, int32_t callerTokenId, int32_t userId)
{
TAG_LOGI(AAFwkTag::WANTAGENT, "start abilitys");
int32_t result = ERR_OK;
for (const auto &item : wantsInfo) {
auto res = DeviceIdDetermine(item.want, startOptions, callerToken, requestCode, callerUid, callerTokenId,
userId);
if (res != ERR_OK && res != START_ABILITY_WAITING) {
result = res;
}
}
return result;
}
int32_t PendingWantManager::PendingWantPublishCommonEvent(
const Want &want, const SenderInfo &senderInfo, int32_t publisherUid, int32_t callerTokenId)
{
TAG_LOGI(AAFwkTag::WANTAGENT, "publish common event");
CommonEventData eventData;
eventData.SetWant(want);
eventData.SetCode(senderInfo.code);
CommonEventPublishInfo eventPublishData;
if (!want.GetBundleNameRef().empty()) {
TAG_LOGI(AAFwkTag::WANTAGENT, "eventPublishData set bundleName: %{public}s", want.GetBundleNameRef().c_str());
eventPublishData.SetBundleName(want.GetBundleNameRef());
}
if (!senderInfo.requiredPermission.empty()) {
std::vector<std::string> permissions;
permissions.emplace_back(senderInfo.requiredPermission);
eventPublishData.SetSubscriberPermissions(permissions);
}
bool result = IN_PROCESS_CALL(DelayedSingleton<EventFwk::CommonEvent>::GetInstance()->PublishCommonEvent(
eventData, eventPublishData, nullptr, publisherUid, callerTokenId));
return (result ? ERR_OK : (-1));
}
int32_t PendingWantManager::PendingRecordIdCreate()
{
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
static std::atomic_int id(0);
return ++id;
}
sptr<PendingWantRecord> PendingWantManager::GetPendingWantRecordByCode(int32_t code)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGI(AAFwkTag::WANTAGENT, "resuest code:%{public}d", code);
std::lock_guard<ffrt::mutex> 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<IWantSender> &target)
{
if (target == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null target");
return -1;
}
sptr<IRemoteObject> obj = target->AsObject();
if (obj == nullptr || obj->IsProxyObject()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object");
return -1;
}
sptr<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(target.GetRefPtr());
auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode());
return ((record != nullptr) ? (record->GetUid()) : (-1));
}
int32_t PendingWantManager::GetPendingWantUserId(const sptr<IWantSender> &target)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
if (target == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null target");
return -1;
}
sptr<IRemoteObject> obj = target->AsObject();
if (obj == nullptr || obj->IsProxyObject()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object");
return -1;
}
sptr<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(target.GetRefPtr());
auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode());
return ((record != nullptr) ? (record->GetKey()->GetUserId()) : (-1));
}
std::string PendingWantManager::GetPendingWantBundleName(const sptr<IWantSender> &target)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
if (target == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null target");
return "";
}
sptr<IRemoteObject> obj = target->AsObject();
if (obj == nullptr || obj->IsProxyObject()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object");
return "";
}
sptr<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(target.GetRefPtr());
auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode());
if (record != nullptr) {
return record->GetKey()->GetBundleName();
}
return "";
}
int32_t PendingWantManager::GetPendingWantCode(const sptr<IWantSender> &target)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
if (target == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null target");
return -1;
}
sptr<IRemoteObject> obj = target->AsObject();
if (obj == nullptr || obj->IsProxyObject()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object");
return -1;
}
sptr<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(target.GetRefPtr());
auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode());
return ((record != nullptr) ? (record->GetKey()->GetCode()) : (-1));
}
int32_t PendingWantManager::GetPendingWantType(const sptr<IWantSender> &target)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
if (target == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null target");
return -1;
}
sptr<IRemoteObject> obj = target->AsObject();
if (obj == nullptr || obj->IsProxyObject()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object");
return -1;
}
sptr<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(target.GetRefPtr());
auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode());
return ((record != nullptr) ? (record->GetKey()->GetType()) : (-1));
}
void PendingWantManager::RegisterCancelListener(const sptr<IWantSender> &sender, const sptr<IWantReceiver> &recevier)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGI(AAFwkTag::WANTAGENT, "begin");
if ((sender == nullptr) || (recevier == nullptr)) {
TAG_LOGE(AAFwkTag::WANTAGENT, "sender or recevier null");
return;
}
sptr<IRemoteObject> obj = sender->AsObject();
if (obj == nullptr || obj->IsProxyObject()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object");
return;
}
sptr<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(sender.GetRefPtr());
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<ffrt::mutex> locker(mutex_);
if (!cancel) {
record->RegisterCancelListener(recevier);
}
}
void PendingWantManager::UnregisterCancelListener(const sptr<IWantSender> &sender, const sptr<IWantReceiver> &recevier)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
if (sender == nullptr || recevier == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "sender or recevier null");
return;
}
sptr<IRemoteObject> obj = sender->AsObject();
if (obj == nullptr || obj->IsProxyObject()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "target obj null or a proxy object");
return;
}
sptr<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(sender.GetRefPtr());
auto record = GetPendingWantRecordByCode(targetRecord->GetKey()->GetCode());
if (record == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null record");
return;
}
std::lock_guard<ffrt::mutex> locker(mutex_);
record->UnregisterCancelListener(recevier);
}
int32_t PendingWantManager::GetPendingRequestWant(const sptr<IWantSender> &target, std::shared_ptr<Want> &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<IRemoteObject> 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<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(target.GetRefPtr());
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, request code=%{public}d", targetRecord->GetKey()->GetCode());
return ERR_INVALID_VALUE;
}
want.reset(new (std::nothrow) Want(record->GetKey()->GetRequestWant()));
return NO_ERROR;
}
int32_t PendingWantManager::GetPendingRequestWantFromProxy(const sptr<IWantSender> &target, std::shared_ptr<Want> &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<IRemoteObject> 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<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(target.GetRefPtr());
if (targetRecord == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null targetRecord");
return ERR_INVALID_VALUE;
}
want.reset(new (std::nothrow) Want(targetRecord->GetKey()->GetRequestWant()));
return NO_ERROR;
}
int32_t PendingWantManager::GetWantSenderInfo(const sptr<IWantSender> &target, std::shared_ptr<WantSenderInfo> &info)
{
TAG_LOGD(AAFwkTag::WANTAGENT, "begin");
if (target == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null target");
return ERR_INVALID_VALUE;
}
sptr<IRemoteObject> 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<PendingWantRecord> targetRecord = static_cast<PendingWantRecord*>(target.GetRefPtr());
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();
wantSenderInfo.appIndex = record->GetKey()->GetAppIndex();
wantSenderInfo.userId = record->GetKey()->GetUserId();
auto wantSenderInfoTemp = new (std::nothrow) WantSenderInfo(wantSenderInfo);
if (wantSenderInfoTemp == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "null wantSenderInfo");
return ERR_INVALID_VALUE;
}
info.reset(wantSenderInfoTemp);
return NO_ERROR;
}
void PendingWantManager::ClearPendingWantRecord(const std::string &bundleName, int32_t uid)
{
CHECK_POINTER(taskHandler_);
TAG_LOGI(AAFwkTag::WANTAGENT, "begin");
auto task = [bundleName, uid, thisWeakPtr = weak_from_this()]() {
auto wantManager = thisWeakPtr.lock();
if (wantManager) {
wantManager->ClearPendingWantRecordTask(bundleName, uid);
}
};
taskHandler_->SubmitTask(task);
}
void PendingWantManager::ClearPendingWantRecordTask(const std::string &bundleName, int32_t uid)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGI(AAFwkTag::WANTAGENT, "begin");
std::lock_guard<ffrt::mutex> locker(mutex_);
auto iter = wantRecords_.begin();
while (iter != wantRecords_.end()) {
bool hasBundle = false;
const auto &pendingRecord = iter->second;
if ((pendingRecord != nullptr)) {
std::vector<std::string> bundleNameVec;
pendingRecord->GetKey()->GetAllBundleNames(bundleNameVec);
for (const auto &bundleItem: bundleNameVec) {
if (bundleItem == bundleName && uid == pendingRecord->GetUid()) {
hasBundle = true;
break;
}
}
if (hasBundle) {
ReduceWantAgentNumber(iter->first);
iter = wantRecords_.erase(iter);
TAG_LOGI(AAFwkTag::WANTAGENT, "wantRecords_ size %{public}zu", wantRecords_.size());
} else {
++iter;
}
} else {
++iter;
}
}
}
bool PendingWantManager::CheckPermission(sptr<PendingWantRecord> record)
{
if (record == nullptr) {
TAG_LOGE(AAFwkTag::WANTAGENT, "record is nullptr");
return false;
}
int32_t type = static_cast<int32_t>(OperationType::UNKNOWN_TYPE);
if (record->GetCanceled() != true) {
type = record->GetKey()->GetType();
}
if (type == static_cast<int32_t>(OperationType::START_ABILITY) ||
type == static_cast<int32_t>(OperationType::START_ABILITIES) ||
type == static_cast<int32_t>(OperationType::START_SERVICE) ||
type == static_cast<int32_t>(OperationType::START_FOREGROUND_SERVICE)) {
return CheckCallerPermission();
}
return true;
}
bool PendingWantManager::CheckCallerPermission()
{
auto callerPid = IPCSkeleton::GetCallingPid();
AppExecFwk::RunningProcessInfo processInfo;
DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(callerPid, processInfo);
auto permission = DelayedSingleton<PermissionVerification>::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<Rosen::MainWindowState> windowStates;
Rosen::WSError ret = sceneSessionManager->GetMainWindowStatesByPid(pid, windowStates);
if (ret != Rosen::WSError::WS_OK || windowStates.empty()) {
TAG_LOGE(AAFwkTag::WANTAGENT, "fail GetWindow");
return false;
}
for (auto &windowState : windowStates) {
if (!windowState.isPcOrPadEnableActivation_ && !windowState.isForegroundInteractive_) {
TAG_LOGI(AAFwkTag::WANTAGENT, "window interactive");
return false;
}
}
return true;
}
void PendingWantManager::Dump(std::vector<std::string> &info)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::WANTAGENT, "dump begin");
std::string dumpInfo = " PendingWantRecords:";
info.push_back(dumpInfo);
std::lock_guard<ffrt::mutex> locker(mutex_);
for (const auto &item : wantRecords_) {
const auto &pendingKey = item.first;
if (!pendingKey) {
continue;
}
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.GetDeviceIdRef() + "//" +
Want.want.GetBundleNameRef() + "/" + Want.want.GetAbilityNameRef() + "]";
info.push_back(dumpInfo);
dumpInfo = " resolved types [" + Want.resolvedTypes + "]";
info.push_back(dumpInfo);
}
}
}
void PendingWantManager::DumpByRecordId(std::vector<std::string> &info, const std::string &args)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::WANTAGENT, "dump by id begin");
std::string dumpInfo = " PendingWantRecords:";
info.push_back(dumpInfo);
std::lock_guard<ffrt::mutex> locker(mutex_);
for (const auto &item : wantRecords_) {
const auto &pendingKey = item.first;
if (pendingKey && (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.GetDeviceIdRef() + "//" +
Want.want.GetBundleNameRef() + "/" + Want.want.GetAbilityNameRef() + "]";
info.push_back(dumpInfo);
dumpInfo = " resolved types [" + Want.resolvedTypes + "]";
info.push_back(dumpInfo);
}
}
}
}
int32_t PendingWantManager::GetAllRunningInstanceKeysByBundleName(
const std::string &bundleName, std::vector<std::string> &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));
}
}
}