* Copyright (c) 2024-2025 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 "start_ability_utils.h"
#include <random>
#include "ability_record.h"
#include "ability_util.h"
#include "app_scheduler.h"
#include "app_utils.h"
#include "global_constant.h"
#include "hitrace_meter.h"
#include "ipc_skeleton.h"
#include "multi_app_utils.h"
#include "permission_constants.h"
#include "permission_verification.h"
#include "server_constant.h"
#include "startup_util.h"
namespace OHOS {
namespace AAFwk {
namespace {
constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10;
constexpr const char* PARAM_RESV_ANCO_CALLER_UID = "ohos.anco.param.callerUid";
constexpr const char* PARAM_RESV_ANCO_CALLER_BUNDLENAME = "ohos.anco.param.callerBundleName";
bool HasAppInstanceSelector(const Want &want)
{
return want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY) ||
want.HasParameter(AbilityRuntime::ServerConstant::DLP_INDEX);
}
}
thread_local std::shared_ptr<StartAbilityInfo> StartAbilityUtils::startAbilityInfo;
thread_local std::shared_ptr<StartAbilityInfo> StartAbilityUtils::callerAbilityInfo;
thread_local bool StartAbilityUtils::skipCrowTest = false;
thread_local bool StartAbilityUtils::skipStartOther = false;
thread_local bool StartAbilityUtils::skipErms = false;
thread_local int32_t StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
thread_local bool StartAbilityUtils::isWantWithAppCloneIndex = false;
thread_local bool StartAbilityUtils::ermsSupportBackToCallerFlag = false;
thread_local bool StartAbilityUtils::startSpecifiedBySCB = false;
thread_local bool StartAbilityUtils::isSandBoxClone = false;
bool StartAbilityUtils::GetAppIndex(const Want &want, sptr<IRemoteObject> callerToken, int32_t &appIndex)
{
auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
if (abilityRecord && abilityRecord->GetApplicationInfo().bundleName == want.GetBundleNameRef() &&
AbilityRuntime::GlobalConstant::IsDlpIndex(abilityRecord->GetAppIndex())) {
appIndex = abilityRecord->GetAppIndex();
return true;
}
TAG_LOGI(AAFwkTag::ABILITYMGR, "appIndex:%{public}d", want.GetIntParam(Want::PARAM_APP_CLONE_INDEX_KEY, -1));
return AbilityRuntime::StartupUtil::GetAppIndex(want, appIndex);
}
bool StartAbilityUtils::GetApplicationInfo(const std::string &bundleName, int32_t userId,
AppExecFwk::ApplicationInfo &appInfo)
{
if (StartAbilityUtils::startAbilityInfo &&
StartAbilityUtils::startAbilityInfo->GetAppBundleName() == bundleName) {
appInfo = StartAbilityUtils::startAbilityInfo->abilityInfo.applicationInfo;
return true;
}
if (bundleName.empty()) {
return false;
}
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, false);
bool result = IN_PROCESS_CALL(
bms->GetApplicationInfo(bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
userId, appInfo)
);
if (!result) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "failed: %{public}s", bundleName.c_str());
return false;
}
return true;
}
bool StartAbilityUtils::GetCallerAbilityInfo(const sptr<IRemoteObject> &callerToken,
AppExecFwk::AbilityInfo &abilityInfo)
{
if (StartAbilityUtils::callerAbilityInfo) {
abilityInfo = StartAbilityUtils::callerAbilityInfo->abilityInfo;
} else {
if (callerToken == nullptr) {
return false;
}
auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
if (abilityRecord == nullptr) {
return false;
}
abilityInfo = abilityRecord->GetAbilityInfo();
}
return true;
}
std::vector<int32_t> StartAbilityUtils::GetCloneAppIndexes(const std::string &bundleName, int32_t userId)
{
std::vector<int32_t> appIndexes;
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, appIndexes);
IN_PROCESS_CALL_WITHOUT_RET(bms->GetCloneAppIndexes(bundleName, appIndexes, userId));
return appIndexes;
}
int32_t StartAbilityUtils::CheckAppProvisionMode(const Want& want, int32_t userId, sptr<IRemoteObject> callerToken)
{
auto abilityInfo = StartAbilityUtils::startAbilityInfo;
if (!abilityInfo || abilityInfo->GetAppBundleName() != want.GetBundleNameRef()) {
int32_t appIndex = 0;
if (!GetAppIndex(want, callerToken, appIndex)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid app clone index");
return ERR_APP_CLONE_INDEX_INVALID;
}
abilityInfo = StartAbilityInfo::CreateStartAbilityInfo(want, userId, appIndex, nullptr);
}
CHECK_POINTER_AND_RETURN(abilityInfo, GET_ABILITY_SERVICE_FAILED);
if (abilityInfo->status != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "unexpected abilityInfo status: %{public}d", abilityInfo->status);
return abilityInfo->status;
}
if ((abilityInfo->abilityInfo).applicationInfo.appProvisionType !=
AppExecFwk::Constants::APP_PROVISION_TYPE_DEBUG) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "window options invalid");
return ERR_NOT_IN_APP_PROVISION_MODE;
}
return ERR_OK;
}
StartAbilityInfoWrap::StartAbilityInfoWrap(const Want &want, int32_t validUserId, int32_t appIndex,
const sptr<IRemoteObject> &callerToken, bool isExtension)
{
if (StartAbilityUtils::startAbilityInfo != nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "startAbilityInfo created");
}
if (StartAbilityUtils::isSandBoxClone) {
return;
}
Want localWant = want;
if (!StartAbilityUtils::IsCallFromAncoShellOrBroker(callerToken)) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "not call from anco or broker.");
localWant.RemoveParam(PARAM_RESV_ANCO_CALLER_UID);
localWant.RemoveParam(PARAM_RESV_ANCO_CALLER_BUNDLENAME);
localWant.RemoveParam(Want::PARAM_RESV_CALLER_TOKEN);
localWant.RemoveParam(Want::PARAM_RESV_CALLER_UID);
localWant.RemoveParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME);
localWant.SetParam(Want::PARAM_RESV_CALLER_TOKEN, static_cast<int32_t>(IPCSkeleton::GetCallingTokenID()));
localWant.SetParam(Want::PARAM_RESV_CALLER_UID, IPCSkeleton::GetCallingUid());
}
if (isExtension) {
StartAbilityUtils::startAbilityInfo = StartAbilityInfo::CreateStartExtensionInfo(localWant,
validUserId, appIndex);
} else {
StartAbilityUtils::startAbilityInfo = StartAbilityInfo::CreateStartAbilityInfo(localWant,
validUserId, appIndex, callerToken);
}
if (StartAbilityUtils::startAbilityInfo != nullptr &&
StartAbilityUtils::startAbilityInfo->abilityInfo.type == AppExecFwk::AbilityType::EXTENSION) {
StartAbilityUtils::skipCrowTest = true;
StartAbilityUtils::skipStartOther = true;
}
if (StartAbilityUtils::callerAbilityInfo != nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "callerAbilityInfo created");
}
StartAbilityUtils::callerAbilityInfo = StartAbilityInfo::CreateCallerAbilityInfo(callerToken);
StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
StartAbilityUtils::ermsSupportBackToCallerFlag = false;
StartAbilityUtils::isWantWithAppCloneIndex = false;
if ((want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY) && appIndex >= 0 &&
appIndex < AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) || StartAbilityUtils::startSpecifiedBySCB) {
StartAbilityUtils::isWantWithAppCloneIndex = true;
}
}
StartAbilityInfoWrap::StartAbilityInfoWrap()
{
StartAbilityUtils::startAbilityInfo.reset();
StartAbilityUtils::callerAbilityInfo.reset();
StartAbilityUtils::skipCrowTest = false;
StartAbilityUtils::skipStartOther = false;
StartAbilityUtils::skipErms = false;
StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
StartAbilityUtils::isWantWithAppCloneIndex = false;
StartAbilityUtils::ermsSupportBackToCallerFlag = false;
StartAbilityUtils::isSandBoxClone = false;
}
StartAbilityInfoWrap::~StartAbilityInfoWrap()
{
StartAbilityUtils::startAbilityInfo.reset();
StartAbilityUtils::callerAbilityInfo.reset();
StartAbilityUtils::skipCrowTest = false;
StartAbilityUtils::skipStartOther = false;
StartAbilityUtils::skipErms = false;
StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
StartAbilityUtils::isWantWithAppCloneIndex = false;
StartAbilityUtils::ermsSupportBackToCallerFlag = false;
StartAbilityUtils::isSandBoxClone = false;
}
void StartAbilityInfoWrap::SetStartAbilityInfo(const AppExecFwk::AbilityInfo& abilityInfo)
{
if (StartAbilityUtils::startAbilityInfo != nullptr) {
return;
}
StartAbilityUtils::startAbilityInfo = std::make_shared<StartAbilityInfo>();
StartAbilityUtils::startAbilityInfo->abilityInfo = abilityInfo;
TAG_LOGD(AAFwkTag::ABILITYMGR, "SetStartAbilityInfo: cache set, bundle = %{public}s, appIndex = %{public}d",
abilityInfo.bundleName.c_str(), abilityInfo.applicationInfo.appIndex);
}
namespace {
std::shared_ptr<StartAbilityInfo> QueryAbilityInfo(const Want &want, int32_t userId, int32_t abilityInfoFlag,
int32_t appIndex, sptr<IRemoteObject> callerToken)
{
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, nullptr);
abilityInfoFlag |= static_cast<uint32_t>(AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_FUSION);
auto request = std::make_shared<StartAbilityInfo>();
if (appIndex > 0 && appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
IN_PROCESS_CALL_WITHOUT_RET(bms->QueryCloneAbilityInfo(want.GetElement(), abilityInfoFlag, appIndex,
request->abilityInfo, userId));
if (appIndex != request->abilityInfo.applicationInfo.appIndex) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "query appIndex no equal: want_%{public}d, bundle_%{public}d",
appIndex, request->abilityInfo.applicationInfo.appIndex);
}
return request;
}
if (appIndex == 0) {
if (AbilityRuntime::StartupUtil::IsStartPlugin(want)) {
auto caller = Token::GetAbilityRecordByToken(callerToken);
if (caller == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "caller is nullptr");
request->status = RESOLVE_ABILITY_ERR;
return request;
}
std::string hostBundleName = caller->GetAbilityInfo().bundleName;
TAG_LOGI(AAFwkTag::ABILITYMGR, "hostBundleName: %{public}s", hostBundleName.c_str());
auto element = want.GetElement();
auto pluginRet = IN_PROCESS_CALL(bms->GetPluginAbilityInfo(hostBundleName, element.GetBundleName(),
element.GetModuleNameRef(), element.GetAbilityName(), userId, request->abilityInfo));
if (pluginRet != ERR_OK) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "GetPluginAbilityInfo failed %{public}d", pluginRet);
request->status = RESOLVE_ABILITY_ERR;
}
request->isTargetPlugin = true;
} else {
IN_PROCESS_CALL_WITHOUT_RET(bms->QueryAbilityInfo(want, abilityInfoFlag, userId, request->abilityInfo));
}
} else {
IN_PROCESS_CALL_WITHOUT_RET(bms->GetSandboxAbilityInfo(want, appIndex,
abilityInfoFlag, userId, request->abilityInfo));
}
return request;
}
}
std::shared_ptr<StartAbilityInfo> StartAbilityInfo::CreateStartAbilityInfo(const Want &want, int32_t userId,
int32_t appIndex, sptr<IRemoteObject> callerToken)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, nullptr);
auto abilityInfoFlag = static_cast<uint32_t>(AbilityRuntime::StartupUtil::BuildAbilityInfoFlag()) |
static_cast<uint32_t>(AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL);
auto request = QueryAbilityInfo(want, userId, abilityInfoFlag, appIndex, callerToken);
if (request == nullptr || request->status != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "QueryAbilityInfo error");
return request;
}
request->customProcess = request->abilityInfo.process;
if (appIndex > 0 && appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
if (request->abilityInfo.name.empty() || request->abilityInfo.bundleName.empty()) {
std::string hostBundleName = "";
auto caller = Token::GetAbilityRecordByToken(callerToken);
if (caller) {
hostBundleName = caller->GetAbilityInfo().bundleName;
}
FindExtensionInfo(want, abilityInfoFlag, userId, appIndex, request, hostBundleName);
}
return request;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "abilityInfo customProcess: %{public}s", request->customProcess.c_str());
if (request->abilityInfo.name.empty() || request->abilityInfo.bundleName.empty()) {
std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
if (appIndex == 0) {
IN_PROCESS_CALL_WITHOUT_RET(bms->QueryExtensionAbilityInfos(want, abilityInfoFlag,
userId, extensionInfos));
} else {
IN_PROCESS_CALL_WITHOUT_RET(bms->GetSandboxExtAbilityInfos(want, appIndex,
abilityInfoFlag, userId, extensionInfos));
}
if (extensionInfos.size() <= 0) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty");
request->status = RESOLVE_ABILITY_ERR;
return request;
}
AppExecFwk::ExtensionAbilityInfo extensionInfo = extensionInfos.front();
if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty.");
request->status = RESOLVE_ABILITY_ERR;
return request;
}
request->extensionProcessMode = extensionInfo.extensionProcessMode;
request->skipAbilityStageLifecycle = extensionInfo.skipAbilityStageLifecycle;
AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, request->abilityInfo);
}
return request;
}
std::shared_ptr<StartAbilityInfo> StartAbilityInfo::CreateStartExtensionInfo(const Want &want, int32_t userId,
int32_t appIndex, const std::string &hostBundleName)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, nullptr);
auto abilityInfoFlag = static_cast<uint32_t>(AbilityRuntime::StartupUtil::BuildAbilityInfoFlag()) |
static_cast<uint32_t>(AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL);
auto abilityInfo = std::make_shared<StartAbilityInfo>();
if (appIndex > 0 && appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
FindExtensionInfo(want, abilityInfoFlag, userId, appIndex, abilityInfo, hostBundleName);
return abilityInfo;
}
std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
if (appIndex == 0) {
if (AbilityRuntime::StartupUtil::IsStartPlugin(want)) {
AppExecFwk::ExtensionAbilityInfo pluginExtensionInfo;
IN_PROCESS_CALL_WITHOUT_RET(bms->GetPluginExtensionInfo(hostBundleName, want, userId, pluginExtensionInfo));
extensionInfos.push_back(pluginExtensionInfo);
} else {
IN_PROCESS_CALL_WITHOUT_RET(bms->QueryExtensionAbilityInfos(want, abilityInfoFlag, userId, extensionInfos));
}
} else {
IN_PROCESS_CALL_WITHOUT_RET(bms->GetSandboxExtAbilityInfos(want, appIndex,
abilityInfoFlag, userId, extensionInfos));
}
if (extensionInfos.size() <= 0) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty");
abilityInfo->status = RESOLVE_ABILITY_ERR;
return abilityInfo;
}
AppExecFwk::ExtensionAbilityInfo extensionInfo = extensionInfos.front();
if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty");
abilityInfo->status = RESOLVE_ABILITY_ERR;
return abilityInfo;
}
abilityInfo->extensionProcessMode = extensionInfo.extensionProcessMode;
abilityInfo->customProcess = extensionInfo.customProcess;
TAG_LOGD(AAFwkTag::ABILITYMGR, "extensionInfo customProcess: %{public}s", abilityInfo->customProcess.c_str());
AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, abilityInfo->abilityInfo);
return abilityInfo;
}
void StartAbilityInfo::FindExtensionInfo(const Want &want, int32_t flags, int32_t userId,
int32_t appIndex, std::shared_ptr<StartAbilityInfo> abilityInfo, const std::string &hostBundleName)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
CHECK_POINTER_LOG(abilityInfo, "abilityInfo is invalid.");
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_LOG(bms, "bms is invalid.");
AppExecFwk::ExtensionAbilityInfo extensionInfo;
if (AbilityRuntime::StartupUtil::IsStartPlugin(want)) {
IN_PROCESS_CALL_WITHOUT_RET(bms->GetPluginExtensionInfo(hostBundleName, want, userId, extensionInfo));
} else {
IN_PROCESS_CALL_WITHOUT_RET(bms->QueryCloneExtensionAbilityInfoWithAppIndex(want.GetElement(),
flags, appIndex, extensionInfo, userId));
}
if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty");
abilityInfo->status = RESOLVE_ABILITY_ERR;
return;
}
abilityInfo->customProcess = extensionInfo.customProcess;
abilityInfo->skipAbilityStageLifecycle = extensionInfo.skipAbilityStageLifecycle;
TAG_LOGD(AAFwkTag::ABILITYMGR, "extensionInfo customProcess: %{public}s", abilityInfo->customProcess.c_str());
if (AbilityRuntime::StartupUtil::IsSupportAppClone(extensionInfo.type)) {
abilityInfo->extensionProcessMode = extensionInfo.extensionProcessMode;
AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, abilityInfo->abilityInfo);
} else {
abilityInfo->status = ERR_APP_CLONE_INDEX_INVALID;
}
}
std::shared_ptr<StartAbilityInfo> StartAbilityInfo::CreateCallerAbilityInfo(const sptr<IRemoteObject> &callerToken)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
if (callerToken == nullptr) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "not call from context.");
return nullptr;
}
auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
if (abilityRecord == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityRecord empty");
return nullptr;
}
auto request = std::make_shared<StartAbilityInfo>();
request->abilityInfo = abilityRecord->GetAbilityInfo();
return request;
}
bool StartAbilityUtils::IsCallFromAncoShellOrBroker(const sptr<IRemoteObject> &callerToken)
{
auto callingUid = IPCSkeleton::GetCallingUid();
if (callingUid == AppUtils::GetInstance().GetCollaboratorBrokerUID()) {
return true;
}
AppExecFwk::AbilityInfo callerAbilityInfo;
if (GetCallerAbilityInfo(callerToken, callerAbilityInfo)) {
return callerAbilityInfo.bundleName == AppUtils::GetInstance().GetBrokerDelegateBundleName();
}
return false;
}
void StartAbilityUtils::SetTargetCloneIndexInSameBundle(const Want &want, sptr<IRemoteObject> callerToken)
{
auto callerRecord = Token::GetAbilityRecordByToken(callerToken);
CHECK_POINTER(callerRecord);
if (callerRecord->GetAbilityInfo().bundleName != want.GetBundleNameRef()) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "not the same bundle");
return;
}
if (want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY)) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "want with app clone index.");
return;
}
int32_t appIndex = callerRecord->GetApplicationInfo().appIndex;
if (appIndex >= 0 && appIndex < AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
(const_cast<Want &>(want)).SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, appIndex);
} else if (AbilityRuntime::GlobalConstant::IsSandboxCloneIndex(appIndex)) {
(const_cast<Want &>(want)).SetParam(AbilityRuntime::GlobalConstant::SANDBOX_CLONE_INDEX, appIndex);
}
}
void StartAbilityUtils::ResolveTargetAppCloneIndex(const Want &want, sptr<IRemoteObject> callerToken, int32_t userId)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
if (HasAppInstanceSelector(want)) {
return;
}
SetTargetCloneIndexInSameBundle(want, callerToken);
if (HasAppInstanceSelector(want)) {
return;
}
int32_t appIndex = 0;
if (MultiAppUtils::GetPreferredAppCloneIndex(want.GetBundleNameRef(), userId, appIndex)) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "resolve app clone preference, bundle:%{public}s appIndex:%{public}d",
want.GetBundleNameRef().c_str(), appIndex);
(const_cast<Want &>(want)).SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, appIndex);
}
}
int32_t StartAbilityUtils::StartUIAbilitiesProcessAppIndex(Want &want,
sptr<IRemoteObject> callerToken, int32_t &appIndex)
{
SetTargetCloneIndexInSameBundle(want, callerToken);
if (!want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY)) {
want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
}
if (!StartAbilityUtils::GetAppIndex(want, callerToken, appIndex)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "StartUIAbilities GetAppIndex failed.");
return ERR_APP_CLONE_INDEX_INVALID;
}
return ERR_OK;
}
int32_t StartAbilityUtils::HandleSelfRedirection(bool isFromOpenLink,
const std::vector<AppExecFwk::AbilityInfo> &abilityInfos)
{
if (!isFromOpenLink || abilityInfos.empty() || abilityInfos.size() > 1) {
return ERR_OK;
}
const AppExecFwk::AbilityInfo &abilityInfo = abilityInfos[0];
if (abilityInfo.allowSelfRedirect || abilityInfo.linkType != AppExecFwk::LinkType::APP_LINK) {
return ERR_OK;
}
AppExecFwk::RunningProcessInfo processInfo;
DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(
IPCSkeleton::GetCallingPid(), processInfo);
if (processInfo.uid_ != abilityInfo.applicationInfo.uid) {
return ERR_OK;
}
return ERR_SELF_REDIRECTION_DISALLOWED;
}
std::string StartAbilityUtils::GenerateAsCallerForAncoSessionId()
{
auto timestamp = std::chrono::system_clock::now().time_since_epoch();
auto time = std::chrono::duration_cast<std::chrono::seconds>(timestamp).count();
std::random_device seed;
std::mt19937 rng(seed());
std::uniform_int_distribution<int> uni(0, INT_MAX);
int randomDigit = uni(rng);
std::string asCallerForAncoSessionId = std::to_string(time) + "_" + std::to_string(randomDigit);
return asCallerForAncoSessionId;
}
void StartAbilityUtils::RemoveAtomicServiceShareRouterIfNeeded(Want &want,
const AppExecFwk::AbilityInfo &targetAbilityInfo, uint32_t callerTokenId)
{
if (!want.HasParameter(Want::ATOMIC_SERVICE_SHARE_ROUTER)) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "No ATOMIC_SERVICE_SHARE_ROUTER parameter, skip check");
return;
}
bool isAtomicService = (targetAbilityInfo.applicationInfo.bundleType ==
AppExecFwk::BundleType::ATOMIC_SERVICE);
if (isAtomicService) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "Keep ATOMIC_SERVICE_SHARE_ROUTER");
return;
}
bool hasStartAbilityToPagePermission = PermissionVerification::GetInstance()->VerifyCallingPermission(
PermissionConstants::PERMISSION_START_ABILITY_TO_PAGE, callerTokenId);
if (!hasStartAbilityToPagePermission) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "Remove ATOMIC_SERVICE_SHARE_ROUTER: hasPermission=%{public}d",
hasStartAbilityToPagePermission);
want.RemoveParam(Want::ATOMIC_SERVICE_SHARE_ROUTER);
}
}
}
}