Add abilityState check for startUIAbility

Signed-off-by: wangzhen <wangzhen346@huawei.com>
Change-Id: I9dcbad881c6bebd0c20757289900ebefc565deb7
This commit is contained in:
wangzhen
2024-11-19 19:45:20 +08:00
parent a7d2cb2c80
commit 85d9f3a3bc
8 changed files with 125 additions and 16 deletions
@@ -99,6 +99,7 @@ constexpr const char* ERROR_MSG_INVALID_APP_INSTANCE_KEY = "The app instance key
constexpr const char* ERROR_MSG_UPPER_LIMIT = "The number of app instances reaches the limit.";
constexpr const char* ERROR_MSG_APP_INSTANCE_KEY_NOT_SUPPORT = "The APP_INSTANCE_KEY cannot be specified.";
constexpr const char* ERROR_MSG_CREATE_NEW_INSTANCE_NOT_SUPPORT = "Creating a new instance is not supported.";
constexpr const char* ERROR_MSG_UI_ABILITY_IS_STARTING = "The UIAbility is in starting state.";
// follow ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST of appexecfwk_errors.h in bundle_framework
constexpr int32_t ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST = 8521220;
@@ -170,6 +171,7 @@ static std::unordered_map<AbilityErrorCode, const char*> ERR_CODE_MAP = {
{ AbilityErrorCode::ERROR_CODE_UPPER_LIMIT, ERROR_MSG_UPPER_LIMIT },
{ AbilityErrorCode::ERROR_CODE_APP_INSTANCE_KEY_NOT_SUPPORT, ERROR_MSG_APP_INSTANCE_KEY_NOT_SUPPORT },
{ AbilityErrorCode::ERROR_CODE_CREATE_NEW_INSTANCE_NOT_SUPPORT, ERROR_MSG_CREATE_NEW_INSTANCE_NOT_SUPPORT },
{ AbilityErrorCode::ERROR_CODE_UI_ABILITY_IS_STARTING, ERROR_MSG_UI_ABILITY_IS_STARTING},
};
static std::unordered_map<int32_t, AbilityErrorCode> INNER_TO_JS_ERROR_CODE_MAP {
@@ -244,6 +246,7 @@ static std::unordered_map<int32_t, AbilityErrorCode> INNER_TO_JS_ERROR_CODE_MAP
{ERR_UPPER_LIMIT, AbilityErrorCode::ERROR_CODE_UPPER_LIMIT},
{ERR_APP_INSTANCE_KEY_NOT_SUPPORT, AbilityErrorCode::ERROR_CODE_APP_INSTANCE_KEY_NOT_SUPPORT},
{ERR_CREATE_NEW_INSTANCE_NOT_SUPPORT, AbilityErrorCode::ERROR_CODE_CREATE_NEW_INSTANCE_NOT_SUPPORT},
{ERR_UI_ABILITY_IS_STARTING, AbilityErrorCode::ERROR_CODE_UI_ABILITY_IS_STARTING},
};
}
@@ -650,12 +650,17 @@ enum {
* Result (2097278) for replying failed while executing insight intent.
*/
ERR_INSIGHT_INTENT_EXECUTE_REPLY_FAILED = 2097278,
/*
* Result (2097278) for get target bundle info failed.
* Result (2097279) for get target bundle info failed.
*/
ERR_GET_TARGET_BUNDLE_INFO_FAILED = 2097279,
/*
* Result (2097280) for UIAbility in starting state.
*/
ERR_UI_ABILITY_IS_STARTING = 2097280,
/**
* Native error(3000000) for target bundle not exist.
*/
@@ -180,6 +180,9 @@ enum class AbilityErrorCode {
// Target application not found.
ERROR_CODE_GET_BUNFLE_INFO_FAILED = 16000081,
// UIAbility is in starting state.
ERROR_CODE_UI_ABILITY_IS_STARTING = 16000082,
// invalid caller.
ERROR_CODE_INVALID_CALLER = 16200001,
@@ -455,6 +455,10 @@ private:
bool &isColdStart);
std::shared_ptr<AbilityRecord> FindRecordFromTmpMap(const AbilityRequest &abilityRequest);
bool AddStartCallerTimestamp(int32_t callerUid);
std::shared_ptr<AbilityRecord> FindRecordFromSessionMap(const AbilityRequest &abilityRequest);
bool HasAbilityRequest(const AbilityRequest &abilityRequest);
void AddAbilityRequest(const AbilityRequest &abilityRequest);
void RemoveAbilityRequest(const AbilityRequest &abilityRequest);
int32_t userId_ = -1;
mutable ffrt::mutex sessionLock_;
@@ -475,6 +479,7 @@ private:
ffrt::mutex startUIAbilityCallerTimestampsLock_;
std::map<int32_t, std::vector<int64_t>> startUIAbilityCallerTimestamps_;
std::list<std::shared_ptr<AbilityRequest>> startAbilityCheckList_;
};
} // namespace AAFwk
} // namespace OHOS
@@ -104,6 +104,7 @@ using OHOS::Security::AccessToken::AccessTokenKit;
namespace OHOS {
using AbilityRuntime::FreezeUtil;
using namespace AbilityRuntime::ServerConstant;
namespace AAFwk {
using AutoStartupInfo = AbilityRuntime::AutoStartupInfo;
using GetExtensionAbilityInfoFlag = AppExecFwk::GetExtensionAbilityInfoFlag;
@@ -252,7 +253,6 @@ constexpr const char* NEED_STARTINGWINDOW = "ohos.ability.NeedStartingWindow";
constexpr const char* PERMISSIONMGR_BUNDLE_NAME = "com.ohos.permissionmanager";
constexpr const char* PERMISSIONMGR_ABILITY_NAME = "com.ohos.permissionmanager.GrantAbility";
constexpr const char* SCENEBOARD_BUNDLE_NAME = "com.ohos.sceneboard";
constexpr const char* IS_CALL_BY_SCB = "isCallBySCB";
constexpr const char* SPECIFY_TOKEN_ID = "specifyTokenId";
constexpr const char* PROCESS_SUFFIX = "embeddable";
constexpr int32_t DEFAULT_DMS_MISSION_ID = -1;
@@ -1262,7 +1262,7 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptr<IRemot
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
ReportEventToRSS(abilityInfo, abilityRequest.callerToken);
abilityRequest.userId = oriValidUserId;
abilityRequest.want.SetParam(IS_CALL_BY_SCB, false);
abilityRequest.want.SetParam(ServerConstant::IS_CALL_BY_SCB, false);
// other sa or shell can not use continueSessionId and persistentId
auto abilityRecord = Token::GetAbilityRecordByToken(abilityRequest.callerToken);
if (abilityRecord == nullptr &&
@@ -1549,7 +1549,7 @@ int AbilityManagerService::StartAbilityDetails(const Want &want, const AbilitySt
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
UpdateCallerInfoUtil::GetInstance().UpdateCallerInfo(abilityRequest.want, callerToken);
abilityRequest.userId = oriValidUserId;
abilityRequest.want.SetParam(IS_CALL_BY_SCB, false);
abilityRequest.want.SetParam(ServerConstant::IS_CALL_BY_SCB, false);
auto uiAbilityManager = GetUIAbilityManagerByUserId(oriValidUserId);
CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE);
return uiAbilityManager->NotifySCBToStartUIAbility(abilityRequest);
@@ -1941,7 +1941,7 @@ int AbilityManagerService::StartAbilityForOptionInner(const Want &want, const St
abilityRequest.want.RemoveParam(PARAM_SPECIFIED_PROCESS_FLAG);
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
abilityRequest.userId = oriValidUserId;
abilityRequest.want.SetParam(IS_CALL_BY_SCB, false);
abilityRequest.want.SetParam(ServerConstant::IS_CALL_BY_SCB, false);
abilityRequest.processOptions = startOptions.processOptions;
if (IPCSkeleton::GetCallingTokenID() == abilityRequest.appInfo.accessTokenId) {
abilityRequest.startWindowOption = startOptions.startWindowOption;
@@ -2223,7 +2223,7 @@ int AbilityManagerService::StartUIAbilityBySCBDefault(sptr<SessionInfo> sessionI
return ERR_APP_CLONE_INDEX_INVALID;
}
StartAbilityInfoWrap threadLocalInfo(sessionInfo->want, currentUserId, appIndex, sessionInfo->callerToken);
if (sessionInfo->want.GetBoolParam(IS_CALL_BY_SCB, true)) {
if (sessionInfo->want.GetBoolParam(ServerConstant::IS_CALL_BY_SCB, true)) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "interceptorExecuter_ called");
auto shouldBlockFunc = [aams = shared_from_this()]() { return aams->ShouldBlockAllAppStart(); };
AbilityInterceptorParam interceptorParam = AbilityInterceptorParam(sessionInfo->want, requestCode,
@@ -2246,7 +2246,7 @@ int AbilityManagerService::StartUIAbilityBySCBDefault(sptr<SessionInfo> sessionI
return result;
}
if (sessionInfo->want.GetBoolParam(IS_CALL_BY_SCB, true)) {
if (sessionInfo->want.GetBoolParam(ServerConstant::IS_CALL_BY_SCB, true)) {
if (sessionInfo->startSetting != nullptr) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "Start by scb, last not.");
sessionInfo->startSetting->AddProperty(AbilityStartSetting::IS_START_BY_SCB_KEY, "true");
@@ -2270,7 +2270,7 @@ int AbilityManagerService::StartUIAbilityBySCBDefault(sptr<SessionInfo> sessionI
return ERR_INVALID_VALUE;
}
if (sessionInfo->want.GetBoolParam(IS_CALL_BY_SCB, true)) {
if (sessionInfo->want.GetBoolParam(ServerConstant::IS_CALL_BY_SCB, true)) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "afterCheckExecuter_ called");
if (sessionInfo->want.GetBoolParam("ohos.ability.params.isSkipErmsFromSCB", false)) {
abilityRequest.want.RemoveParam("ohos.ability.params.isSkipErmsFromSCB");
@@ -2312,8 +2312,6 @@ int32_t AbilityManagerService::StartUIAbilityBySCBDefaultCommon(AbilityRequest &
ReportAbilityAssociatedStartInfoToRSS(abilityInfo, RES_TYPE_SCB_START_ABILITY, sessionInfo->callerToken);
auto uiAbilityManager = GetUIAbilityManagerByUid(IPCSkeleton::GetCallingUid());
CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE);
// here we don't need want param "IS_CALL_BY_SCB" any more, remove it.
(sessionInfo->want).RemoveParam(IS_CALL_BY_SCB);
return uiAbilityManager->StartUIAbility(abilityRequest, sessionInfo, sceneFlag, isColdStart);
}
@@ -7507,7 +7505,7 @@ int AbilityManagerService::StartAbilityByCall(const Want &want, const sptr<IAbil
}
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
ReportEventToRSS(abilityRequest.abilityInfo, callerToken);
abilityRequest.want.SetParam(IS_CALL_BY_SCB, false);
abilityRequest.want.SetParam(ServerConstant::IS_CALL_BY_SCB, false);
auto uiAbilityManager = GetUIAbilityManagerByUserId(oriValidUserId);
CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_INVALID_VALUE);
return uiAbilityManager->ResolveLocked(abilityRequest);
@@ -12033,7 +12031,7 @@ int32_t AbilityManagerService::PreStartInner(const FreeInstallInfo& taskInfo)
// sceneboard
abilityRequest.userId = oriValidUserId;
abilityRequest.want.SetParam(IS_CALL_BY_SCB, false);
abilityRequest.want.SetParam(ServerConstant::IS_CALL_BY_SCB, false);
std::string sessionId = std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
abilityRequest.want.SetParam(KEY_SESSION_ID, sessionId);
@@ -397,13 +397,13 @@ int MissionListManager::GetTargetMission(const AbilityRequest &abilityRequest, s
if (targetAbilityRecord->GetPendingState() != AbilityState::INITIAL) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "pending state is FOREGROUND or BACKGROUND, dropped.");
targetAbilityRecord->SetPendingState(AbilityState::FOREGROUND);
return ERR_OK;
return ERR_UI_ABILITY_IS_STARTING;
} else {
TAG_LOGD(AAFwkTag::ABILITYMGR, "pending state is not FOREGROUND or BACKGROUND");
targetAbilityRecord->SetPendingState(AbilityState::FOREGROUND);
if (targetAbilityRecord->IsLoading()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "ability: %{public}s is loading", abilityRequest.abilityInfo.name.c_str());
return ERR_OK;
return ERR_UI_ABILITY_IS_STARTING;
}
}
@@ -25,6 +25,7 @@
#include "hitrace_meter.h"
#include "permission_constants.h"
#include "process_options.h"
#include "server_constant.h"
#include "start_window_option.h"
#include "scene_board/status_bar_delegate_manager.h"
#include "session_manager_lite.h"
@@ -37,6 +38,7 @@
namespace OHOS {
using AbilityRuntime::FreezeUtil;
using namespace AbilityRuntime::ServerConstant;
namespace AAFwk {
namespace {
constexpr const char* SEPARATOR = ":";
@@ -73,6 +75,22 @@ auto g_deleteLifecycleEventTask = [](const sptr<Token> &token) {
CHECK_POINTER_LOG(token, "token is nullptr.");
FreezeUtil::GetInstance().DeleteLifecycleEvent(token->AsObject());
};
bool CompareTwoRequest(const AbilityRequest &left, const AbilityRequest &right)
{
int32_t leftIndex = 0;
(void)AbilityRuntime::StartupUtil::GetAppIndex(left.want, leftIndex);
int32_t rightIndex = 0;
(void)AbilityRuntime::StartupUtil::GetAppIndex(right.want, rightIndex);
auto LeftInstanceKey = left.want.GetStringParam(Want::APP_INSTANCE_KEY);
auto RightInstanceKey = right.want.GetStringParam(Want::APP_INSTANCE_KEY);
return leftIndex == rightIndex && LeftInstanceKey == RightInstanceKey &&
left.abilityInfo.name == right.abilityInfo.name &&
left.abilityInfo.bundleName == right.abilityInfo.bundleName &&
left.abilityInfo.moduleName == right.abilityInfo.moduleName;
}
}
UIAbilityLifecycleManager::UIAbilityLifecycleManager(int32_t userId): userId_(userId) {}
@@ -86,6 +104,11 @@ int UIAbilityLifecycleManager::StartUIAbility(AbilityRequest &abilityRequest, sp
TAG_LOGE(AAFwkTag::ABILITYMGR, "sessionInfo invalid");
return ERR_INVALID_VALUE;
}
auto isCallBySCB = sessionInfo->want.GetBoolParam(ServerConstant::IS_CALL_BY_SCB, true);
if (!isCallBySCB) {
RemoveAbilityRequest(abilityRequest);
}
sessionInfo->want.RemoveParam(ServerConstant::IS_CALL_BY_SCB);
abilityRequest.sessionInfo = sessionInfo;
TAG_LOGI(AAFwkTag::ABILITYMGR, "session:%{public}d. bundle:%{public}s, ability:%{public}s, instanceKey:%{public}s",
@@ -96,7 +119,7 @@ int UIAbilityLifecycleManager::StartUIAbility(AbilityRequest &abilityRequest, sp
TAG_LOGD(AAFwkTag::ABILITYMGR, "StartUIAbility");
uiAbilityRecord->SetSpecifyTokenId(abilityRequest.specifyTokenId);
if (uiAbilityRecord->GetPendingState() != AbilityState::INITIAL) {
if (isCallBySCB && uiAbilityRecord->GetPendingState() != AbilityState::INITIAL) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "pending state: FOREGROUND/ BACKGROUND, dropped");
uiAbilityRecord->SetPendingState(AbilityState::FOREGROUND);
return ERR_OK;
@@ -453,6 +476,20 @@ int UIAbilityLifecycleManager::NotifySCBToStartUIAbility(AbilityRequest &ability
++specifiedRequestId_;
return ERR_OK;
}
if (abilityRequest.abilityInfo.launchMode == AppExecFwk::LaunchMode::SINGLETON) {
if (HasAbilityRequest(abilityRequest)) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "multi start request");
return ERR_UI_ABILITY_IS_STARTING;
}
auto abilityRecord = FindRecordFromSessionMap(abilityRequest);
if (abilityRecord && abilityRecord->GetPendingState() == AbilityState::FOREGROUNDING) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "ability is starting");
return ERR_UI_ABILITY_IS_STARTING;
}
AddAbilityRequest(abilityRequest);
}
auto sessionInfo = CreateSessionInfo(abilityRequest);
sessionInfo->requestCode = abilityRequest.requestCode;
auto isCreating = abilityRequest.want.GetBoolParam(Want::CREATE_APP_INSTANCE_KEY, false);
@@ -2891,5 +2928,62 @@ void UIAbilityLifecycleManager::EnableListForSCBRecovery()
isSCBRecovery_ = true;
coldStartInSCBRecovery_.clear();
}
std::shared_ptr<AbilityRecord> UIAbilityLifecycleManager::FindRecordFromSessionMap(
const AbilityRequest &abilityRequest)
{
int32_t appIndex = 0;
(void)AbilityRuntime::StartupUtil::GetAppIndex(abilityRequest.want, appIndex);
auto instanceKey = abilityRequest.want.GetStringParam(Want::APP_INSTANCE_KEY);
for (const auto &[sessionId, abilityRecord] : sessionAbilityMap_) {
if (abilityRecord) {
const auto &info = abilityRecord->GetAbilityInfo();
if (info.name == abilityRequest.abilityInfo.name &&
info.bundleName == abilityRequest.abilityInfo.bundleName &&
info.moduleName == abilityRequest.abilityInfo.moduleName &&
appIndex == abilityRecord->GetAppIndex() && instanceKey == abilityRecord->GetInstanceKey()) {
return abilityRecord;
}
}
}
return nullptr;
}
bool UIAbilityLifecycleManager::HasAbilityRequest(const AbilityRequest &abilityRequest)
{
for (const auto &item : startAbilityCheckList_) {
if (item && CompareTwoRequest(*item, abilityRequest)) {
return true;
}
}
return false;
}
void UIAbilityLifecycleManager::AddAbilityRequest(const AbilityRequest &abilityRequest)
{
auto newRequest = std::make_shared<AbilityRequest>(abilityRequest);
startAbilityCheckList_.push_back(newRequest);
auto taskHandler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
CHECK_POINTER(taskHandler);
taskHandler->SubmitTask([wThis = weak_from_this(), wRequest = std::weak_ptr<AbilityRequest>(newRequest)]() {
auto pThis = wThis.lock();
auto request = wRequest.lock();
if (pThis && request) {
std::lock_guard guard(pThis->sessionLock_);
pThis->startAbilityCheckList_.remove(request);
}
}, GlobalConstant::COLDSTART_TIMEOUT_MULTIPLE * GlobalConstant::TIMEOUT_UNIT_TIME);
}
void UIAbilityLifecycleManager::RemoveAbilityRequest(const AbilityRequest &abilityRequest)
{
for (auto iter = startAbilityCheckList_.begin(); iter != startAbilityCheckList_.end(); ++iter) {
auto item = *iter;
if (item && CompareTwoRequest(*item, abilityRequest)) {
startAbilityCheckList_.erase(iter);
return;
}
}
}
} // namespace AAFwk
} // namespace OHOS
+1
View File
@@ -19,6 +19,7 @@
namespace OHOS::AbilityRuntime {
namespace ServerConstant {
constexpr const char* DLP_INDEX = "ohos.dlp.params.index";
constexpr const char* IS_CALL_BY_SCB = "isCallBySCB";
} // namespace ServerConstant
} // namespace OHOS::AbilityRuntime
#endif // OHOS_ABILITY_RUNTIME_SERVER_CONSTANT_H