* 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 "ability_record.h"
#include <charconv>
#include <singleton.h>
#include "ability_manager_service.h"
#include "ability_resident_process_rdb.h"
#include "ability_scheduler_stub.h"
#include "agent_extension_connection_constants.h"
#include "app_exit_reason_data_manager.h"
#include "appfreeze_manager.h"
#include "app_utils.h"
#include "array_wrapper.h"
#include "accesstoken_kit.h"
#include "configuration_convertor.h"
#include "connection_state_manager.h"
#include "common_event_manager.h"
#include "dms_util.h"
#include "error_msg_util.h"
#include "foreground_app_connection_manager.h"
#include "freeze_util.h"
#include "global_constant.h"
#include "hitrace_meter.h"
#include "image_source.h"
#include "json_utils.h"
#include "last_exit_detail_info.h"
#include "main_element_utils.h"
#include "multi_instance_utils.h"
#include "os_account_manager_wrapper.h"
#include "ui_service_extension_connection_constants.h"
#include "res_sched_util.h"
#include "scene_board_judgement.h"
#include "startup_util.h"
#include "system_ability_token_callback.h"
#include "ui_extension_wrapper.h"
#ifdef SUPPORT_UPMS
#include "uri_permission_manager_client.h"
#endif
#include "param.h"
#include "permission_constants.h"
#include "process_options.h"
#include "session_info.h"
#include "uri_utils.h"
#include "user_controller/user_controller.h"
#include "utils/state_utils.h"
#include "utils/ability_event_util.h"
#ifdef SUPPORT_GRAPHICS
#include "image_source.h"
#endif
#ifdef SUPPORT_SCREEN
#include "locale_config.h"
#endif
#include "xcollie/process_kill_reason.h"
#include "parameters.h"
namespace OHOS {
using AbilityRuntime::FreezeUtil;
namespace AAFwk {
using namespace OHOS::Security;
using namespace OHOS::AAFwk::PermissionConstants;
using namespace OHOS::AbilityRuntime::GlobalConstant;
const std::string ERROR_INFO_ENHANCE = "errorInfoEnhance";
const std::string MULTI_THREAD = "multiThread";
const std::string DMS_PROCESS_NAME = "distributedsched";
const std::string DMS_MISSION_ID = "dmsMissionId";
const std::string DMS_SRC_NETWORK_ID = "dmsSrcNetworkId";
const std::string ABILITY_OWNER_USERID = "AbilityMS_Owner_UserId";
const std::u16string SYSTEM_ABILITY_TOKEN_CALLBACK = u"ohos.aafwk.ISystemAbilityTokenCallback";
const std::string SHOW_ON_LOCK_SCREEN = "ShowOnLockScreen";
#ifdef WITH_DLP
const std::string DLP_BUNDLE_NAME = "com.ohos.dlpmanager";
#endif
const std::string COMPONENT_STARTUP_NEW_RULES = "component.startup.newRules";
const std::string KEY_MISSION_ID = "ohos.anco.param.missionId";
const std::string PARAMS_FILE_SAVING_URL_KEY = "pick_path_return";
const std::string SHELL_ASSISTANT_DIEREASON = "crash_die";
const std::string PARAM_MISSION_AFFINITY_KEY = "ohos.anco.param.missionAffinity";
const std::string DISTRIBUTED_FILES_PATH = "/data/storage/el2/distributedfiles/";
const std::string UIEXTENSION_ABILITY_ID = "ability.want.params.uiExtensionAbilityId";
const std::string UIEXTENSION_ROOT_HOST_PID = "ability.want.params.uiExtensionRootHostPid";
const std::string UIEXTENSION_HOST_PID = "ability.want.params.uiExtensionHostPid";
const std::string UIEXTENSION_HOST_UID = "ability.want.params.uiExtensionHostUid";
const std::string UIEXTENSION_HOST_BUNDLENAME = "ability.want.params.uiExtensionHostBundleName";
const std::string UIEXTENSION_BIND_ABILITY_ID = "ability.want.params.uiExtensionBindAbilityId";
const std::string UIEXTENSION_NOTIFY_BIND = "ohos.uiextension.params.notifyProcessBind";
constexpr const char* PARAM_SEND_RESULT_CALLER_BUNDLENAME = "ohos.anco.param.sendResultCallderBundleName";
constexpr const char* PARAM_SEND_RESULT_CALLER_TOKENID = "ohos.anco.param.sendResultCallerTokenId";
constexpr const char* PARAM_RESV_ANCO_IS_NEED_UPDATE_NAME = "ohos.anco.param.isNeedUpdateName";
constexpr const char* DLP_PARAMS_SECURITY_FLAG = "ohos.dlp.params.securityFlag";
constexpr const char* SPECIFIED_ABILITY_FLAG = "ohos.ability.params.specifiedAbilityFlag";
constexpr const char* UIEXTENSION_LAUNCH_TIMESTAMP_HIGH = "ohos.ability.params.uiExtensionLaunchTimestampHigh";
constexpr const char* UIEXTENSION_LAUNCH_TIMESTAMP_LOW = "ohos.ability.params.uiExtensionLaunchTimestampLow";
constexpr const char* DEVELOPER_MODE_STATE = "const.security.developermode.state";
constexpr const char* APP_PROVISION_TYPE_DEBUG = "debug";
constexpr const char* DMS_CALLER_BUNDLE_NAME = "ohos.dms.param.sourceCallerBundleName";
constexpr const char* DMS_CALLER_ABILITY_NAME = "ohos.dms.param.sourceCallerAbilityName";
constexpr const char* DMS_CALLER_NATIVE_NAME = "ohos.dms.param.sourceCallerNativeName";
constexpr const char* DMS_CALLER_APP_ID = "ohos.dms.param.sourceCallerAppId";
constexpr const char* DMS_CALLER_APP_IDENTIFIER = "ohos.dms.param.sourceCallerAppIdentifier";
constexpr const char* IS_HOOK = "ohos.ability_runtime.is_hook";
constexpr const char* HIDDEN_START_AUTOSTARTUP = "hiddenStartAutoStartup";
const int32_t SHELL_ASSISTANT_DIETYPE = 0;
std::atomic<int64_t> AbilityRecord::abilityRecordId = 0;
const int32_t DEFAULT_USER_ID = 0;
const int32_t SEND_RESULT_CANCELED = -1;
const int VECTOR_SIZE = 2;
const int LOAD_TIMEOUT_ASANENABLED = 150;
const int TERMINATE_TIMEOUT_ASANENABLED = 150;
const int HALF_TIMEOUT = 2;
const int MAX_URI_COUNT = 500;
const int RESTART_SCENEBOARD_DELAY = 500;
constexpr int32_t DMS_UID = 5522;
constexpr int32_t SCHEDULER_DIED_TIMEOUT = 60000;
const std::string JSON_KEY_ERR_MSG = "errMsg";
const int32_t BY_CALL_HALF_TIMEOUT_MS = 2500;
const int32_t BY_CALL_TIMEOUT_MS = 5000;
constexpr int32_t NON_BY_CALL = 0;
constexpr int32_t CALL_TO_BACKGROUND = 1;
constexpr int32_t CALL_TO_FOREGROUND = 2;
const bool BETA_VERSION = OHOS::system::GetParameter("const.logsystem.versiontype", "unknown") == "beta";
auto g_addLifecycleEventTask = [](sptr<Token> token, std::string &methodName) {
CHECK_POINTER_LOG(token, "token is nullptr");
std::string entry = std::string("AbilityRecord::") + methodName + "; the " + methodName + " lifecycle starts.";
FreezeUtil::GetInstance().AddLifecycleEvent(token->AsObject(), entry);
};
AbilityRecord::AbilityRecord(const Want &want, const AppExecFwk::AbilityInfo &abilityInfo,
const AppExecFwk::ApplicationInfo &applicationInfo, int requestCode)
: want_(want), requestCode_(requestCode), abilityInfo_(abilityInfo)
{
abilityInfo_.applicationInfo = applicationInfo;
recordId_ = abilityRecordId++;
auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
if (abilityMgr) {
bool isRootLauncher = (abilityInfo_.applicationInfo.bundleName == AbilityConfig::LAUNCHER_BUNDLE_NAME);
restartMax_ = AmsConfigurationParameter::GetInstance().GetMaxRestartNum(isRootLauncher);
bool flag = abilityMgr->GetStartUpNewRuleFlag();
want_.SetParam(COMPONENT_STARTUP_NEW_RULES, flag);
}
restartCount_ = restartMax_;
isAppAutoStartup_ = want_.GetBoolParam(Want::PARAM_APP_AUTO_STARTUP_LAUNCH_REASON, false);
if (want_.HasParameter(Want::PARAM_APP_AUTO_STARTUP_LAUNCH_REASON)) {
want_.RemoveParam(Want::PARAM_APP_AUTO_STARTUP_LAUNCH_REASON);
}
SetDebugAppByWaitingDebugFlag();
launchDebugInfo_.Update(want_);
}
AbilityRecord::~AbilityRecord()
{
if (token_) {
FreezeUtil::GetInstance().DeleteLifecycleEvent(token_->AsObject());
}
FreezeUtil::GetInstance().DeleteAppLifecycleEvent(GetPid());
if (scheduler_ != nullptr && schedulerDeathRecipient_ != nullptr) {
auto object = scheduler_->AsObject();
if (object != nullptr) {
object->RemoveDeathRecipient(schedulerDeathRecipient_);
}
}
want_.CloseAllFd();
}
std::shared_ptr<AbilityRecord> AbilityRecord::CreateAbilityRecord(const AbilityRequest &abilityRequest)
{
auto abilityRecord = std::make_shared<AbilityRecord>(
abilityRequest.want, abilityRequest.abilityInfo, abilityRequest.appInfo, abilityRequest.requestCode);
abilityRecord->Init(abilityRequest);
return abilityRecord;
}
void AbilityRecord::Init(const AbilityRequest &abilityRequest)
{
SetUid(abilityRequest.uid);
int32_t appIndex = 0;
if (abilityRequest.isWebSandBoxClone) {
appIndex = abilityRequest.abilityInfo.applicationInfo.appIndex;
InitSandboxCloneParams(abilityRequest);
TAG_LOGD(AAFwkTag::ABILITYMGR, "Web sandbox clone, using appIndex from abilityInfo: %{public}d", appIndex);
} else {
(void)AbilityRuntime::StartupUtil::GetAppIndex(abilityRequest.want, appIndex);
}
SetAppIndex(appIndex);
SetSecurityFlag(abilityRequest.want.GetBoolParam(DLP_PARAMS_SECURITY_FLAG, false));
SetCallerAccessTokenId(abilityRequest.callerAccessTokenId);
if (abilityRequest.processOptions != nullptr) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "isPreloadStart:%{public}d", abilityRequest.processOptions->isPreloadStart);
SetPreloadStart(abilityRequest.processOptions->isPreloadStart);
}
sessionInfo_ = abilityRequest.sessionInfo;
if (AppUtils::GetInstance().IsMultiProcessModel() && abilityRequest.abilityInfo.isStageBasedModel &&
abilityRequest.abilityInfo.type == AppExecFwk::AbilityType::PAGE && !abilityRequest.customProcess.empty()) {
SetCustomProcessFlag(abilityRequest.customProcess);
}
if (abilityRequest.sessionInfo != nullptr) {
instanceKey_ = abilityRequest.sessionInfo->instanceKey;
}
lifecycleDeal_ = std::make_unique<LifecycleDeal>();
token_ = sptr<Token>::MakeSptr(weak_from_this());
if (abilityInfo_.applicationInfo.isLauncherApp) {
isLauncherAbility_ = true;
}
if (abilityRequest.startSetting != nullptr) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "abilityRequest.startSetting...");
SetStartSetting(abilityRequest.startSetting);
}
if (abilityRequest.IsCallType(AbilityCallType::CALL_REQUEST_TYPE)) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "abilityRequest.callType is CALL_REQUEST_TYPE.");
SetStartedByCall(true);
}
InitPluginAbility(abilityRequest);
collaboratorType_ = abilityRequest.collaboratorType;
missionAffinity_ = abilityRequest.want.GetStringParam(PARAM_MISSION_AFFINITY_KEY);
auto userId = abilityRequest.appInfo.uid / BASE_USER_RANGE;
if ((userId == 0 || AppUtils::GetInstance().InResidentWhiteList(abilityRequest.abilityInfo.bundleName)) &&
DelayedSingleton<ResidentProcessManager>::GetInstance()->IsResidentAbility(
abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name, userId)) {
keepAliveBundle_ = true;
}
}
void AbilityRecord::InitSandboxCloneParams(const AbilityRequest &abilityRequest)
{
if (abilityRequest.sandboxCloneParams == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "abilityRequest.sandboxCloneParams is nullptr");
return;
}
auto sandboxCloneParams = std::make_shared<SandboxCloneParams>();
sandboxCloneParams->callerBundleName = abilityRequest.sandboxCloneParams->callerBundleName;
sandboxCloneParams->callerTokenId = abilityRequest.sandboxCloneParams->callerTokenId;
sandboxCloneParams->sandBoxCloneIndex = abilityRequest.sandboxCloneParams->sandBoxCloneIndex;
sandboxCloneParams->creatorBundleName = abilityRequest.sandboxCloneParams->creatorBundleName;
SetSandboxCloneParams(sandboxCloneParams);
TAG_LOGD(AAFwkTag::ABILITYMGR, "InitSandboxCloneParams, callerBundleName = %{public}s, callerTokenId = %{public}d, "
"sandBoxCloneIndex = %{public}d, creatorBundleName = %{public}s", sandboxCloneParams->callerBundleName.c_str(),
sandboxCloneParams->callerTokenId, sandboxCloneParams->sandBoxCloneIndex,
sandboxCloneParams->creatorBundleName.c_str());
}
AbilityRecordType AbilityRecord::GetAbilityRecordType()
{
return AbilityRecordType::BASE_ABILITY;
}
void AbilityRecord::SetUid(int32_t uid)
{
uid_ = uid;
}
int32_t AbilityRecord::GetUid()
{
return uid_;
}
pid_t AbilityRecord::GetPid() const
{
return pid_;
}
void AbilityRecord::SetPid(pid_t pid)
{
pid_ = pid;
}
void AbilityRecord::LoadUIAbility()
{
SetLoading(true);
int loadTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * LOAD_TIMEOUT_MULTIPLE;
if (abilityInfo_.applicationInfo.asanEnabled || abilityInfo_.applicationInfo.tsanEnabled) {
loadTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * LOAD_TIMEOUT_ASANENABLED;
} else {
int coldStartTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * COLDSTART_TIMEOUT_MULTIPLE;
std::lock_guard guard(wantLock_);
loadTimeout = want_.GetBoolParam("coldStart", false) ? coldStartTimeout : loadTimeout;
}
if (IsPreloadStart() && !IsPreloaded()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "preload, no event sent");
return;
}
if (isPrelaunch_) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "prelaunch, no event sent");
return;
}
SendEvent(AbilityManagerService::LOAD_HALF_TIMEOUT_MSG, loadTimeout / HALF_TIMEOUT);
SendEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, loadTimeout);
std::string methodName = "LoadAbility";
g_addLifecycleEventTask(token_, methodName);
}
int AbilityRecord::LoadAbility(bool isShellCall, bool isStartupHide, pid_t callingPid,
uint64_t loadAbilityCallbackId, pid_t selfPid)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGI(AAFwkTag::ABILITYMGR, "LoadLifecycle: abilityName:%{public}s", abilityInfo_.name.c_str());
startTime_ = AbilityUtil::SystemTimeMillis();
lifeCycleStateInfo_.launchParam.launchUptime = startTime_;
lifeCycleStateInfo_.launchParam.launchUTCTime = AbilityUtil::UTCTimeMillis();
CHECK_POINTER_AND_RETURN(token_, ERR_INVALID_VALUE);
if (!IsDebug() && abilityInfo_.type != AppExecFwk::AbilityType::DATA) {
LoadUIAbility();
}
std::string appName = abilityInfo_.applicationInfo.name;
CHECK_TRUE_RETURN_RET(appName.empty(), ERR_INVALID_VALUE, "app name empty");
CHECK_TRUE_RETURN_RET(!CanRestartRootLauncher(), ERR_INVALID_VALUE, "root launcher restart out of max");
if (isRestarting_) {
restartTime_ = AbilityUtil::SystemTimeMillis();
}
sptr<Token> callerToken = nullptr;
auto caller = GetCallerRecord();
if (caller) {
callerToken = caller->GetToken();
}
std::lock_guard guard(wantLock_);
want_.SetParam(ABILITY_OWNER_USERID, ownerMissionUserId_);
want_.SetParam(IS_HOOK, isHook_);
firstCallerBundleName_ = want_.GetStringParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME);
AbilityRuntime::LoadParam loadParam;
loadParam.abilityRecordId = recordId_;
loadParam.isShellCall = Rosen::SceneBoardJudgement::IsSceneBoardEnabled() ? isShellCall
: AAFwk::PermissionVerification::GetInstance()->IsShellCall();
loadParam.token = token_;
loadParam.preToken = callerToken;
loadParam.instanceKey = instanceKey_;
loadParam.customProcessFlag = GetCustomProcessFlag();
loadParam.isStartupHide = isStartupHide;
loadParam.callingPid = callingPid;
loadParam.loadAbilityCallbackId = loadAbilityCallbackId;
loadParam.isPrelaunch = isPrelaunch_;
loadParam.isPreloadStart = isPreloadStart_;
loadParam.selfPid = selfPid;
loadParam.byCallStatus = GetByCallStatus();
loadParam.isGamePrelaunch = IsGameSAPreLaunch();
FillProcessInfoFromSession(loadParam);
auto userId = abilityInfo_.uid / BASE_USER_RANGE;
bool isMainUIAbility =
MainElementUtils::IsMainUIAbility(abilityInfo_.bundleName, abilityInfo_.name, userId);
MainElementUtils::SetMainUIAbilityKeepAliveFlag(isMainUIAbility,
abilityInfo_.bundleName, loadParam);
auto result = DelayedSingleton<AppScheduler>::GetInstance()->LoadAbility(
loadParam, abilityInfo_, abilityInfo_.applicationInfo, want_);
want_.RemoveParam(IS_HOOK);
want_.RemoveParam(ABILITY_OWNER_USERID);
want_.RemoveParam(Want::PARAMS_REAL_CALLER_KEY);
if (DelayedSingleton<AppScheduler>::GetInstance()->IsAttachDebug(abilityInfo_.bundleName)) {
SetAttachDebug(true);
}
if (result == ERR_OK) {
AbilityRuntime::UserController::GetInstance().AddToUserLockedBundleList(abilityInfo_.bundleName, userId);
}
if (abilityInfo_.type == AppExecFwk::AbilityType::PAGE &&
!abilityInfo_.applicationInfo.isBundleFirstLaunched) {
auto userId = abilityInfo_.uid / BASE_USER_RANGE;
std::string callerBundleName = firstCallerBundleName_.empty() ? "_system" : firstCallerBundleName_;
ffrt::submit([this, appInfo = abilityInfo_.applicationInfo, userId, callerBundleName]() {
AbilityEventUtil::HandleBundleFirstLaunch(appInfo, userId, callerBundleName);
}, ffrt::task_attr().name("HandleBundleFirstLaunch"));
}
return result;
}
bool AbilityRecord::CanRestartRootLauncher()
{
if (isLauncherRoot_ && isRestarting_ && IsLauncherAbility() && (restartCount_ < 0)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "root launcher restart out of max");
return false;
}
return true;
}
bool AbilityRecord::CanRestartResident()
{
auto isKeepAlive = GetKeepAlive();
TAG_LOGD(AAFwkTag::ABILITYMGR, "isKeepAlive: %{public}d, isRestarting: %{public}d, restartCount: %{public}d",
isKeepAlive, isRestarting_, restartCount_);
if (isKeepAlive && isRestarting_ && (restartCount_ < 0)) {
int restartIntervalTime = 0;
auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
if (abilityMgr) {
restartIntervalTime = AmsConfigurationParameter::GetInstance().GetRestartIntervalTime();
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "restartTime: %{public}lld, now: %{public}lld, intervalTine:%{public}d",
static_cast<unsigned long long>(restartTime_),
static_cast<unsigned long long>(AbilityUtil::SystemTimeMillis()), restartIntervalTime);
if ((AbilityUtil::SystemTimeMillis() - restartTime_) < restartIntervalTime) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "resident restart out of max");
return false;
}
}
return true;
}
void AbilityRecord::ForegroundAbility(uint32_t sceneFlag)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
isWindowStarted_ = true;
TAG_LOGI(AAFwkTag::ABILITYMGR, "ForegroundLifecycle %{public}s", abilityInfo_.name.c_str());
CHECK_POINTER(lifecycleDeal_);
#ifdef SUPPORT_SCREEN
SetAbilityStateInner(AbilityState::FOREGROUNDING);
#endif
lifeCycleStateInfo_.sceneFlag = sceneFlag;
auto want = GetWant();
UpdateDmsCallerInfo(want);
AbilityRuntime::ErrorMsgGuard errorMsgGuard(token_ ? token_->AsObject() : nullptr,
reinterpret_cast<uintptr_t>(GetScheduler().GetRefPtr()), "ScheduleAbilityTransaction");
if (AAFwk::AppUtils::GetInstance().IsStartSpecifiedProcess() && GetApplicationInfo().isSystemApp) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "GetSpecifiedFlag: %{public}s", GetSpecifiedFlag().c_str());
want.SetParam(SPECIFIED_ABILITY_FLAG, GetSpecifiedFlag());
}
lifecycleDeal_->ForegroundNew(want, lifeCycleStateInfo_, GetSessionInfo());
RemoveSpecifiedWantParam(AbilityRuntime::GlobalConstant::GAME_PRELAUNCH);
SetIsNewWant(false);
if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
lifeCycleStateInfo_.sceneFlag = 0;
lifeCycleStateInfo_.sceneFlagBak = 0;
}
{
std::lock_guard guard(wantLock_);
InsightIntentExecuteParam::RemoveInsightIntent(want_);
isLaunching_ = false;
}
}
void AbilityRecord::ForegroundUIExtensionAbility(uint32_t sceneFlag)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGI(AAFwkTag::ABILITYMGR, "ForegroundUIExtensionAbility:%{public}s/%{public}s",
GetInfoBundleName().c_str(), GetInfoAbilityName().c_str());
CHECK_POINTER(lifecycleDeal_);
if (IsAbilityState(AbilityState::BACKGROUND)) {
SendAppStartupTypeEvent(AppExecFwk::AppStartType::HOT);
}
#ifdef SUPPORT_SCREEN
SetAbilityStateInner(AbilityState::FOREGROUNDING);
#endif
lifeCycleStateInfo_.sceneFlag = sceneFlag;
lifecycleDeal_->ForegroundNew(GetWant(), lifeCycleStateInfo_, GetSessionInfo());
lifeCycleStateInfo_.sceneFlag = 0;
lifeCycleStateInfo_.sceneFlagBak = 0;
{
std::lock_guard guard(wantLock_);
InsightIntentExecuteParam::RemoveInsightIntent(want_);
isLaunching_ = false;
}
}
void AbilityRecord::ProcessForegroundAbility(uint32_t tokenId, const ForegroundOptions &options)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::ABILITYMGR, "ability record: %{public}s/%{public}s", GetInfoBundleName().c_str(),
GetInfoAbilityName().c_str());
needCheckAutoStartupStatusBar_ = GetBoolParam(HIDDEN_START_AUTOSTARTUP, false);
RemoveSpecifiedWantParam(HIDDEN_START_AUTOSTARTUP);
#ifdef SUPPORT_UPMS
{
std::lock_guard guard(wantLock_);
std::string targetBundleName = abilityInfo_.applicationInfo.bundleName;
bool isNotifyCollaborator = !options.targetGrantBundleName.empty();
if (isNotifyCollaborator) {
targetBundleName = options.targetGrantBundleName;
}
if (options.callerTypeForAnco == static_cast<int32_t>(CallerTypeForAnco::QUERY)) {
tokenId = options.realCallerTokenId;
}
GrantUriPermission(want_, targetBundleName, false, tokenId, isNotifyCollaborator);
}
#endif
if (!isReady_) {
isPrelaunch_ = false;
TAG_LOGD(AAFwkTag::ABILITYMGR, "To load ability.");
lifeCycleStateInfo_.sceneFlagBak = options.sceneFlag;
LoadAbility(options.isShellCall, options.isStartupHide, options.callingPid,
options.loadAbilityCallbackId, options.selfPid);
return;
}
if (options.requestCode != DEFAULT_REQUEST_CODE &&
ForegroundAppConnectionManager::IsForegroundAppConnection(GetAbilityInfo(), GetCallerRecord())) {
ReportAbilityConnectionRelations();
}
PostForegroundTimeoutTask();
if (IsAbilityState(AbilityState::FOREGROUND)) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "Activate %{public}s/%{public}s", GetInfoBundleName().c_str(),
GetInfoAbilityName().c_str());
if (IsFrozenByPreload()) {
SetFrozenByPreload(false);
auto ret =
DelayedSingleton<AppScheduler>::GetInstance()->NotifyPreloadAbilityStateChanged(token_, false);
TAG_LOGI(AAFwkTag::ABILITYMGR, "NotifyPreloadAbilityStateChanged by start, ret: %{public}d", ret);
}
ForegroundAbility(options.sceneFlag);
return;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "MoveToForeground, %{public}s/%{public}s", GetInfoBundleName().c_str(),
GetInfoAbilityName().c_str());
lifeCycleStateInfo_.sceneFlagBak = options.sceneFlag;
ResSchedUtil::GetInstance().ReportEventToRSS(GetUid(), GetAbilityInfo().bundleName,
"THAW_BY_FOREGROUND_ABILITY", GetPid(), GetCallerRecord() ? GetCallerRecord()->GetPid() : -1);
if (isPrelaunch_) {
SendAppStartupTypeEvent(AppExecFwk::AppStartType::WARM, AppExecFwk::AppStartReason::PRE_LAUNCH);
isPrelaunch_ = false;
} else {
SendAppStartupTypeEvent(AppExecFwk::AppStartType::HOT);
}
SetAbilityStateInner(AbilityState::FOREGROUNDING);
DelayedSingleton<AppScheduler>::GetInstance()->MoveToForeground(token_);
}
void AbilityRecord::PostForegroundTimeoutTask()
{
if (IsDebug() || (IsPreloadStart() && !IsPreloaded())) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "isDebug=%{public}d, isPreload=%{public}d, preloaded=%{public}d, no event sent",
IsDebug(), IsPreloadStart(), IsPreloaded());
return;
}
int radio = BETA_VERSION ? FOREGROUND_TIMEOUT_MULTIPLE_BETA : FOREGROUND_TIMEOUT_MULTIPLE;
int foregroundTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * radio;
if (InsightIntentExecuteParam::IsInsightIntentExecute(GetWant())) {
foregroundTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() *
INSIGHT_INTENT_TIMEOUT_MULTIPLE;
}
SendEvent(AbilityManagerService::FOREGROUND_HALF_TIMEOUT_MSG, foregroundTimeout / HALF_TIMEOUT);
SendEvent(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, foregroundTimeout);
std::string methodName = "ProcessForegroundAbility";
g_addLifecycleEventTask(token_, methodName);
ResSchedUtil::GetInstance().ReportLoadingEventToRss(LoadingStage::FOREGROUND_BEGIN, GetPid(), GetUid(),
foregroundTimeout, GetAbilityRecordId());
}
void AbilityRecord::RemoveForegroundTimeoutTask()
{
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
CHECK_POINTER(handler);
handler->RemoveEvent(AbilityManagerService::FOREGROUND_HALF_TIMEOUT_MSG, GetAbilityRecordId());
handler->RemoveEvent(AbilityManagerService::FOREGROUND_TIMEOUT_MSG, GetAbilityRecordId());
}
void AbilityRecord::RemoveLoadTimeoutTask()
{
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
CHECK_POINTER(handler);
TAG_LOGI(AAFwkTag::ABILITYMGR, "RemoveLoadTimeoutTask:%{public}" PRId64, GetAbilityRecordId());
handler->RemoveEvent(AbilityManagerService::LOAD_HALF_TIMEOUT_MSG, GetAbilityRecordId());
handler->RemoveEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, GetAbilityRecordId());
}
#ifdef SUPPORT_SCREEN
void AbilityRecord::SetAbilityTransitionInfo(sptr<AbilityTransitionInfo>& info) const
{
info->abilityToken_ = token_;
info->missionId_ = missionId_;
info->abilityName_ = abilityInfo_.name;
info->bundleName_ = abilityInfo_.bundleName;
info->windowModes_ = abilityInfo_.windowModes;
info->maxWindowRatio_ = abilityInfo_.maxWindowRatio;
info->minWindowRatio_ = abilityInfo_.minWindowRatio;
info->maxWindowWidth_ = abilityInfo_.maxWindowWidth;
info->minWindowWidth_ = abilityInfo_.minWindowWidth;
info->maxWindowHeight_ = abilityInfo_.maxWindowHeight;
info->minWindowHeight_ = abilityInfo_.minWindowHeight;
info->orientation_ = abilityInfo_.orientation;
info->apiCompatibleVersion_ = abilityInfo_.applicationInfo.apiCompatibleVersion;
}
sptr<AbilityTransitionInfo> AbilityRecord::CreateAbilityTransitionInfo()
{
sptr<AbilityTransitionInfo> info = new AbilityTransitionInfo();
SetAbilityTransitionInfo(info);
SetStartingWindow(true);
return info;
}
std::shared_ptr<Want> AbilityRecord::GetWantFromMission() const
{
auto missionListWrap = DelayedSingleton<AbilityManagerService>::GetInstance()->GetMissionListWrap();
if (missionListWrap == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "null missionListWrap");
return nullptr;
}
InnerMissionInfo innerMissionInfo;
int getMission = missionListWrap->GetInnerMissionInfoById(missionId_, innerMissionInfo);
if (getMission != ERR_OK) {
TAG_LOGE(
AAFwkTag::ABILITYMGR, "no find mission info by missionId: %{public}d", missionId_);
return nullptr;
}
return std::make_shared<Want>(innerMissionInfo.missionInfo.want);
}
void AbilityRecord::SetShowWhenLocked(const AppExecFwk::AbilityInfo &abilityInfo,
sptr<AbilityTransitionInfo> &info) const
{
for (const auto &data : abilityInfo.metaData.customizeData) {
if (data.name == SHOW_ON_LOCK_SCREEN) {
info->isShowWhenLocked_ = true;
break;
}
}
}
void AbilityRecord::SetAbilityTransitionInfo(const AppExecFwk::AbilityInfo &abilityInfo,
sptr<AbilityTransitionInfo> &info) const
{
info->abilityName_ = abilityInfo.name;
info->bundleName_ = abilityInfo.bundleName;
info->windowModes_ = abilityInfo.windowModes;
info->orientation_ = abilityInfo.orientation;
info->apiCompatibleVersion_ = abilityInfo.applicationInfo.apiCompatibleVersion;
SetShowWhenLocked(abilityInfo, info);
}
sptr<IWindowManagerServiceHandler> AbilityRecord::GetWMSHandler() const
{
auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
if (!abilityMgr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "%{public}s, fail", __func__);
return nullptr;
}
return abilityMgr->GetWMSHandler();
}
void AbilityRecord::SetWindowModeAndDisplayId(sptr<AbilityTransitionInfo> &info,
const std::shared_ptr<Want> &want) const
{
if (!want) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "%{public}s, want invalid", __func__);
return;
}
auto mode = want->GetIntParam(Want::PARAM_RESV_WINDOW_MODE, -1);
auto displayId = want->GetIntParam(Want::PARAM_RESV_DISPLAY_ID, -1);
if (mode != -1) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "%{public}s: origin window mode: %{public}d", __func__, mode);
info->mode_ = static_cast<uint32_t>(mode);
}
if (displayId != -1) {
info->displayId_ = static_cast<uint64_t>(displayId);
}
}
sptr<AbilityTransitionInfo> AbilityRecord::CreateAbilityTransitionInfo(
const std::shared_ptr<StartOptions> &startOptions, const std::shared_ptr<Want> &want) const
{
sptr<AbilityTransitionInfo> info = new AbilityTransitionInfo();
if (startOptions != nullptr) {
info->mode_ = static_cast<uint32_t>(startOptions->GetWindowMode());
TAG_LOGI(AAFwkTag::ABILITYMGR, "window mode:%{public}d", info->mode_);
info->displayId_ = static_cast<uint64_t>(startOptions->GetDisplayID());
} else {
SetWindowModeAndDisplayId(info, want);
}
return info;
}
sptr<AbilityTransitionInfo> AbilityRecord::CreateAbilityTransitionInfo(const AbilityRequest &abilityRequest) const
{
sptr<AbilityTransitionInfo> info = new AbilityTransitionInfo();
auto abilityStartSetting = abilityRequest.startSetting;
if (abilityStartSetting) {
auto windowMode = abilityStartSetting->GetProperty(AbilityStartSetting::WINDOW_MODE_KEY);
auto displayId = abilityStartSetting->GetProperty(AbilityStartSetting::WINDOW_DISPLAY_ID_KEY);
try {
info->mode_ = static_cast<uint32_t>(std::stoi(windowMode));
info->displayId_ = static_cast<uint64_t>(std::stoi(displayId));
} catch (...) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "windowMode: stoi(%{public}s) failed", windowMode.c_str());
TAG_LOGW(AAFwkTag::ABILITYMGR, "displayId: stoi(%{public}s) failed", displayId.c_str());
}
} else {
SetWindowModeAndDisplayId(info, std::make_shared<Want>(abilityRequest.want));
}
return info;
}
sptr<AbilityTransitionInfo> AbilityRecord::CreateAbilityTransitionInfo(
const std::shared_ptr<StartOptions> &startOptions, const std::shared_ptr<Want> &want,
const AbilityRequest &abilityRequest)
{
sptr<AbilityTransitionInfo> info;
if (startOptions) {
info = CreateAbilityTransitionInfo(startOptions, want);
} else {
info = CreateAbilityTransitionInfo(abilityRequest);
}
SetAbilityTransitionInfo(info);
SetStartingWindow(true);
return info;
}
bool AbilityRecord::ReportAtomicServiceDrawnCompleteEvent()
{
if (abilityInfo_.applicationInfo.bundleType != AppExecFwk::BundleType::ATOMIC_SERVICE) {
return false;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "Report atomic service first frame complete event.");
AAFwk::EventInfo eventInfo;
eventInfo.abilityName = abilityInfo_.name;
eventInfo.moduleName = abilityInfo_.moduleName;
eventInfo.bundleName = abilityInfo_.bundleName;
auto eventName = AAFwk::EventName::ATOMIC_SERVICE_DRAWN_COMPLETE;
AAFwk::EventReport::SendAtomicServiceEvent(eventName, HISYSEVENT_BEHAVIOR, eventInfo);
return true;
}
void AbilityRecord::SetCompleteFirstFrameDrawing(const bool flag)
{
isCompleteFirstFrameDrawing_ = flag;
}
bool AbilityRecord::IsCompleteFirstFrameDrawing() const
{
return isCompleteFirstFrameDrawing_;
}
bool AbilityRecord::GetColdStartFlag()
{
return coldStart_;
}
void AbilityRecord::SetColdStartFlag(bool isColdStart)
{
coldStart_ = isColdStart;
}
#endif
void AbilityRecord::BackgroundAbility(const Closure &task)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGI(AAFwkTag::ABILITYMGR, "BackgroundLifecycle %{public}s/%{public}s",
GetInfoBundleName().c_str(), GetInfoAbilityName().c_str());
if (lifecycleDeal_ == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null lifecycleDeal_");
return;
}
if (!IsDebug()) {
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (handler && task) {
int backgroundTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * BACKGROUND_TIMEOUT_MULTIPLE;
if (InsightIntentExecuteParam::IsInsightIntentExecute(GetWant())) {
backgroundTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() *
INSIGHT_INTENT_TIMEOUT_MULTIPLE;
}
handler->SubmitTask(task, "background_" + std::to_string(recordId_), backgroundTimeout, false);
if (abilityInfo_.type == AppExecFwk::AbilityType::PAGE) {
std::string methodName = "BackgroundAbility";
g_addLifecycleEventTask(token_, methodName);
}
}
} else {
TAG_LOGI(AAFwkTag::ABILITYMGR, "debug mode, no need to handle");
}
if (!IsTerminating() || IsRestarting()) {
SaveAbilityState();
}
#ifdef SUPPORT_SCREEN
SetAbilityStateInner(AbilityState::BACKGROUNDING);
#endif
lifecycleDeal_->BackgroundNew(GetWant(), lifeCycleStateInfo_, GetSessionInfo());
std::lock_guard guard(wantLock_);
isLaunching_ = false;
}
bool AbilityRecord::PrepareTerminateAbility(bool isSCBCall)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
if (lifecycleDeal_ == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null lifecycleDeal_");
return false;
}
if (!isSCBCall) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "triggered by user clicking window x");
return lifecycleDeal_->PrepareTerminateAbility();
}
std::unique_lock<std::mutex> lock(isPrepareTerminateAbilityMutex_);
isPrepareTerminateAbilityCalled_.store(true);
isPrepareTerminate_ = false;
isPrepareTerminateAbilityDone_.store(false);
auto condition = [weak = weak_from_this()] {
auto self = weak.lock();
if (self == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null self");
return false;
}
return self->isPrepareTerminateAbilityDone_.load();
};
auto task = [weak = weak_from_this()]() {
auto self = weak.lock();
if (self == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null abilityRecord, prepareTerminateAbility error");
return;
}
if (!self->lifecycleDeal_ || !self->lifecycleDeal_->PrepareTerminateAbility()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "PrepareTerminateAbility error");
self->isPrepareTerminateAbilityDone_.store(true);
self->isPrepareTerminateAbilityCalled_.store(false);
self->isPrepareTerminateAbilityCv_.notify_all();
}
};
ffrt::submit(task);
if (!isPrepareTerminateAbilityCv_.wait_for(lock,
std::chrono::milliseconds(GlobalConstant::PREPARE_TERMINATE_TIMEOUT_TIME), condition)) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "wait timeout");
return false;
}
return isPrepareTerminate_;
}
void AbilityRecord::PrepareTerminateAbilityDone(bool isTerminate)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "call PrepareTerminateAbilityDone");
std::unique_lock<std::mutex> lock(isPrepareTerminateAbilityMutex_);
if (!isPrepareTerminateAbilityCalled_.load()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "prepare terminate not called");
return;
}
isPrepareTerminate_ = isTerminate;
isPrepareTerminateAbilityDone_.store(true);
isPrepareTerminateAbilityCalled_.store(false);
isPrepareTerminateAbilityCv_.notify_one();
}
void AbilityRecord::CancelPrepareTerminate()
{
TAG_LOGI(AAFwkTag::ABILITYMGR,
"canceling prepare terminate,bundle=%{public}s,module=%{public}s,ability=%{public}s",
abilityInfo_.bundleName.c_str(), abilityInfo_.moduleName.c_str(), abilityInfo_.name.c_str());
std::unique_lock<std::mutex> lock(isPrepareTerminateAbilityMutex_);
if (!isPrepareTerminateAbilityCalled_.load()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "prepare terminate not called");
return;
}
isPrepareTerminate_ = true;
isPrepareTerminateAbilityDone_.store(true);
isPrepareTerminateAbilityCalled_.store(false);
isPrepareTerminateAbilityCv_.notify_one();
}
int AbilityRecord::TerminateAbility()
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGI(AAFwkTag::ABILITYMGR, "TerminateAbility:%{public}s", abilityInfo_.name.c_str());
NotifyCallersOnTerminate();
#ifdef WITH_DLP
HandleDlpClosed();
#endif
AAFwk::EventInfo eventInfo;
BuildTerminateAbilityEventInfo(eventInfo, 0);
if (clearMissionFlag_) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "deleteAbilityRecoverInfo before clearMission");
(void)DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
DeleteAbilityRecoverInfo(GetAbilityInfo().applicationInfo.accessTokenId, GetAbilityInfo().moduleName,
GetAbilityInfo().name);
}
ResSchedUtil::GetInstance().ReportLoadingEventToRss(LoadingStage::DESTROY_END, GetPid(), GetUid(),
0, GetRecordId());
AAFwk::EventReport::SendAbilityEvent(AAFwk::EventName::TERMINATE_ABILITY, HISYSEVENT_BEHAVIOR, eventInfo);
auto ret = DelayedSingleton<AppScheduler>::GetInstance()->TerminateAbility(token_, clearMissionFlag_);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "terminate ability failed: %{public}d", ret);
}
return ret;
}
void AbilityRecord::BuildTerminateAbilityEventInfo(EventInfo &eventInfo, int32_t errCode)
{
eventInfo.bundleName = GetAbilityInfo().bundleName;
eventInfo.abilityName = GetAbilityInfo().name;
eventInfo.appIndex = abilityInfo_.applicationInfo.appIndex;
eventInfo.errCode = errCode;
}
void AbilityRecord::SendTerminateAbilityErrorEvent(int32_t errCode)
{
EventInfo eventInfo;
BuildTerminateAbilityEventInfo(eventInfo, errCode);
EventReport::SendAbilityEvent(EventName::TERMINATE_ABILITY_ERROR, HISYSEVENT_FAULT, eventInfo);
}
const AppExecFwk::AbilityInfo &AbilityRecord::GetAbilityInfo() const
{
return abilityInfo_;
}
const AppExecFwk::ApplicationInfo &AbilityRecord::GetApplicationInfo() const
{
return abilityInfo_.applicationInfo;
}
AbilityState AbilityRecord::GetAbilityState() const
{
return currentState_.load();
}
WindowConfig AbilityRecord::GetAbilityWindowConfig() const
{
return windowConfig_;
}
bool AbilityRecord::IsForeground() const
{
auto state = currentState_.load();
return state == AbilityState::FOREGROUND || state == AbilityState::FOREGROUNDING;
}
AbilityVisibilityState AbilityRecord::GetAbilityVisibilityState() const
{
return abilityVisibilityState_.load();
}
void AbilityRecord::SetAbilityVisibilityState(AbilityVisibilityState state)
{
abilityVisibilityState_.store(state);
}
void AbilityRecord::UpdateAbilityVisibilityState()
{
if (GetAbilityVisibilityState() == AbilityVisibilityState::INITIAL) {
auto state = AbilityVisibilityState::UNSPECIFIED;
auto sessionInfo = GetSessionInfo();
if (sessionInfo && sessionInfo->processOptions &&
(ProcessOptions::IsNewProcessMode(sessionInfo->processOptions->processMode) ||
sessionInfo->processOptions->isStartFromNDK)) {
auto startupVisibility = sessionInfo->processOptions->startupVisibility;
if (startupVisibility == StartupVisibility::STARTUP_SHOW) {
state = AbilityVisibilityState::FOREGROUND_SHOW;
} else if (startupVisibility == StartupVisibility::STARTUP_HIDE) {
state = AbilityVisibilityState::FOREGROUND_HIDE;
}
}
SetAbilityVisibilityState(state);
}
}
#ifdef SUPPORT_SCREEN
void AbilityRecord::SetAbilityStateInner(AbilityState state)
{
currentState_.store(state);
if (state == AbilityState::BACKGROUND) {
isAbilityForegrounding_ = false;
}
auto collaborator = DelayedSingleton<AbilityManagerService>::GetInstance()->GetCollaborator(
collaboratorType_);
if (collaborator != nullptr) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "notify collaborator, missionId:%{public}d, state:%{public}d", missionId_,
static_cast<int32_t>(state));
int ret = ERR_OK;
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
auto sessionInfo = GetSessionInfo();
if (sessionInfo == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null sessionInfo");
return;
}
int32_t persistentId = sessionInfo->persistentId;
switch (state) {
case AbilityState::BACKGROUNDING: {
ret = collaborator->NotifyMoveMissionToBackground(persistentId, GetOwnerMissionUserId(),
isFromScreenOffBackground_);
break;
}
case AbilityState::TERMINATING: {
ret = collaborator->NotifyTerminateMission(persistentId, GetOwnerMissionUserId());
break;
}
default:
break;
}
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "failed,err: %{public}d", ret);
}
return;
}
switch (state) {
case AbilityState::FOREGROUNDING: {
ret = collaborator->NotifyMoveMissionToForeground(missionId_, GetOwnerMissionUserId());
break;
}
case AbilityState::BACKGROUNDING: {
ret = collaborator->NotifyMoveMissionToBackground(missionId_, GetOwnerMissionUserId(),
isFromScreenOffBackground_);
break;
}
case AbilityState::TERMINATING: {
ret = collaborator->NotifyTerminateMission(missionId_, GetOwnerMissionUserId());
break;
}
default:
break;
}
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "failed, err: %{public}d", ret);
}
}
auto missionListWrap = DelayedSingleton<AbilityManagerService>::GetInstance()->GetMissionListWrap();
if (missionListWrap != nullptr) {
missionListWrap->SetMissionAbilityState(missionId_, state);
}
}
#endif
bool AbilityRecord::GetAbilityForegroundingFlag() const
{
return isAbilityForegrounding_;
}
#ifdef SUPPORT_SCREEN
void AbilityRecord::SetAbilityState(AbilityState state)
{
SetAbilityStateInner(state);
if (state == AbilityState::FOREGROUND || state == AbilityState::ACTIVE || state == AbilityState::BACKGROUND) {
SetRestarting(false);
}
if (state == AbilityState::FOREGROUND) {
ResSchedUtil::GetInstance().ReportLoadingEventToRss(LoadingStage::FOREGROUND_END, GetPid(),
GetUid(), 0, GetAbilityRecordId());
}
}
#endif
void AbilityRecord::SetScheduler(const sptr<IAbilityScheduler> &scheduler)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "SetScheduler, bundlename: %{public}s, %{public}s",
abilityInfo_.name.c_str(), abilityInfo_.applicationInfo.bundleName.c_str());
CHECK_POINTER(lifecycleDeal_);
if (scheduler != nullptr) {
if (scheduler_ != nullptr && schedulerDeathRecipient_ != nullptr) {
auto schedulerObject = scheduler_->AsObject();
if (schedulerObject != nullptr) {
schedulerObject->RemoveDeathRecipient(schedulerDeathRecipient_);
}
}
if (schedulerDeathRecipient_ == nullptr) {
schedulerDeathRecipient_ =
new AbilitySchedulerRecipient([thisWeakPtr = weak_from_this()](const wptr<IRemoteObject> &remote) {
auto abilityRecord = thisWeakPtr.lock();
if (abilityRecord) {
abilityRecord->OnSchedulerDied(remote);
}
});
}
isReady_ = true;
scheduler_ = scheduler;
lifecycleDeal_->SetScheduler(scheduler);
auto schedulerObject = scheduler_->AsObject();
if (schedulerObject == nullptr || !schedulerObject->AddDeathRecipient(schedulerDeathRecipient_)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "AddDeathRecipient failed");
}
SetPid(IPCSkeleton::GetCallingPid());
AfterLoaded();
NotifyMissionBindPid();
#ifdef WITH_DLP
HandleDlpAttached();
#endif
} else {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null scheduler");
isReady_ = false;
isWindowAttached_ = false;
SetIsNewWant(false);
if (scheduler_ != nullptr && schedulerDeathRecipient_ != nullptr) {
auto schedulerObject = scheduler_->AsObject();
if (schedulerObject != nullptr) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "RemoveDeathRecipient");
schedulerObject->RemoveDeathRecipient(schedulerDeathRecipient_);
}
}
scheduler_ = scheduler;
SetPid(0);
}
}
void AbilityRecord::AfterLoaded()
{
FreezeUtil::GetInstance().DeleteAppLifecycleEvent(GetPid());
if (GetAbilityInfo().extensionAbilityType != AppExecFwk::ExtensionAbilityType::SERVICE) {
ResSchedUtil::GetInstance().ReportLoadingEventToRss(LoadingStage::LOAD_END, GetPid(),
GetUid(), 0, GetAbilityRecordId());
}
if (IsSceneBoard()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "Sceneboard Added");
}
}
sptr<Token> AbilityRecord::GetToken() const
{
return token_;
}
bool AbilityRecord::IsReady() const
{
return isReady_;
}
bool AbilityRecord::IsLauncherAbility() const
{
return isLauncherAbility_;
}
bool AbilityRecord::IsTerminating() const
{
return isTerminating_;
}
void AbilityRecord::SetTerminatingState()
{
isTerminating_ = true;
}
bool AbilityRecord::IsNewWant() const
{
return lifeCycleStateInfo_.isNewWant;
}
void AbilityRecord::SetIsNewWant(bool isNewWant)
{
lifeCycleStateInfo_.isNewWant = isNewWant;
}
bool AbilityRecord::IsCreateByConnect() const
{
return isCreateByConnect_;
}
void AbilityRecord::SetCreateByConnectMode(bool isCreatedByConnect)
{
isCreateByConnect_ = isCreatedByConnect;
}
void AbilityRecord::Activate()
{
TAG_LOGI(AAFwkTag::SERVICE_EXT, "activate");
CHECK_POINTER(lifecycleDeal_);
if (!IsDebug()) {
int activeTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * ACTIVE_TIMEOUT_MULTIPLE;
SendEvent(AbilityManagerService::ACTIVE_TIMEOUT_MSG, activeTimeout);
}
#ifdef SUPPORT_SCREEN
SetAbilityStateInner(AbilityState::ACTIVATING);
#endif
lifecycleDeal_->Activate(GetWant(), lifeCycleStateInfo_);
}
void AbilityRecord::Inactivate()
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::SERVICE_EXT, "Inactivate:%{public}s.", abilityInfo_.name.c_str());
CHECK_POINTER(lifecycleDeal_);
if (!IsDebug()) {
bool useOldMultiple = abilityInfo_.name == AbilityConfig::LAUNCHER_ABILITY_NAME ||
abilityInfo_.name == AbilityConfig::CALLUI_ABILITY_NAME;
auto timeoutMultiple = useOldMultiple ? INACTIVE_TIMEOUT_MULTIPLE : INACTIVE_TIMEOUT_MULTIPLE_NEW;
auto inactiveTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * timeoutMultiple;
SendEvent(AbilityManagerService::INACTIVE_TIMEOUT_MSG, inactiveTimeout);
}
#ifdef SUPPORT_SCREEN
SetAbilityStateInner(AbilityState::INACTIVATING);
#endif
Want want = GetWant();
UpdateDmsCallerInfo(want);
lifecycleDeal_->Inactivate(want, lifeCycleStateInfo_, GetSessionInfo());
}
void AbilityRecord::Terminate(const Closure &task)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::ABILITYMGR, "Terminate: %{public}s.", GetURI().c_str());
CHECK_POINTER(lifecycleDeal_);
if (!IsDebug()) {
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (handler && task) {
int terminateTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * TERMINATE_TIMEOUT_MULTIPLE;
if (abilityInfo_.applicationInfo.asanEnabled) {
terminateTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * TERMINATE_TIMEOUT_ASANENABLED;
}
if (!isReady_) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "terminate with not ready");
terminateTimeout = 0;
}
handler->SubmitTask(task, "terminate_" + std::to_string(recordId_), terminateTimeout);
ResSchedUtil::GetInstance().ReportLoadingEventToRss(LoadingStage::DESTROY_BEGIN, GetPid(), GetUid(),
terminateTimeout, GetRecordId());
}
} else {
TAG_LOGI(AAFwkTag::ABILITYMGR, "debug mode, no need to handle");
}
#ifdef WITH_DLP
HandleDlpClosed();
#endif
#ifdef SUPPORT_SCREEN
SetAbilityStateInner(AbilityState::TERMINATING);
#endif
lifecycleDeal_->Terminate(GetWant(), lifeCycleStateInfo_, GetSessionInfo());
ReportAbilityConnectionForResultTerminate();
if (GetCallerInfo() != nullptr && UIExtensionWrapper::IsUIExtension(GetAbilityInfo().extensionAbilityType)) {
DelayedSingleton<ForegroundAppConnectionManager>::GetInstance()->AbilityRemovePidConnection(
GetCallerInfo()->callerPid, GetPid(), GetAbilityRecordId());
}
}
void AbilityRecord::ShareData(const int32_t &uniqueId)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "ShareData:%{public}s", abilityInfo_.name.c_str());
CHECK_POINTER(lifecycleDeal_);
if (!IsDebug()) {
int loadTimeout =
AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * SHAREDATA_TIMEOUT_MULTIPLE;
TAG_LOGD(AAFwkTag::ABILITYMGR, "loadTimeOut %{public}d.", loadTimeout);
SendEvent(AbilityManagerService::SHAREDATA_TIMEOUT_MSG, loadTimeout, uniqueId);
}
lifecycleDeal_->ShareData(uniqueId);
}
void AbilityRecord::CommandAbility()
{
TAG_LOGD(AAFwkTag::SERVICE_EXT, "startId_:%{public}d.", startId_);
Want want = GetWant();
UpdateDmsCallerInfo(want);
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->CommandAbility(want, false, startId_);
}
void AbilityRecord::CommandAbilityWindow(const sptr<SessionInfo> &sessionInfo, WindowCommand winCmd)
{
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->CommandAbilityWindow(GetWant(), sessionInfo, winCmd);
}
void AbilityRecord::SaveAbilityState()
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->SaveAbilityState();
}
void AbilityRecord::SaveAbilityState(const PacMap &inState)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
stateDatas_ = inState;
}
void AbilityRecord::SaveAbilityWindowConfig(const WindowConfig &windowConfig)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "call");
windowConfig_ = windowConfig;
}
void AbilityRecord::RestoreAbilityState()
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "call");
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->RestoreAbilityState(stateDatas_);
stateDatas_.Clear();
isRestarting_ = false;
}
int AbilityRecord::GetRequestCode() const
{
return requestCode_;
}
void AbilityRecord::SetResult(const std::shared_ptr<AbilityResult> &result)
{
std::lock_guard guard(resultLock_);
result_ = result;
}
std::shared_ptr<AbilityResult> AbilityRecord::GetResult() const
{
std::lock_guard guard(resultLock_);
return result_;
}
void AbilityRecord::SendResult(bool isSandboxApp, uint32_t tokeId, bool schedulerdied)
{
std::lock_guard<ffrt::mutex> guard(lock_);
CHECK_POINTER(scheduler_);
auto result = GetResult();
CHECK_POINTER(result);
TAG_LOGI(AAFwkTag::ABILITYMGR, "SendResult:%{public}s,tokeId:%{public}u,%{public}d, requestCode:%{public}d",
abilityInfo_.name.c_str(), tokeId, static_cast<int32_t>(schedulerdied), result->requestCode_);
#ifdef SUPPORT_UPMS
if (!schedulerdied) {
GrantUriPermission(result->resultWant_, abilityInfo_.applicationInfo.bundleName, isSandboxApp, tokeId, false);
}
#endif
if (result->requestCode_ != -1) {
scheduler_->SendResult(result->requestCode_, result->resultCode_, result->resultWant_);
} else {
TAG_LOGD(AAFwkTag::ABILITYMGR, "requestCode_ -1");
}
SetResult(nullptr);
}
void AbilityRecord::SendResultByBackToCaller(const std::shared_ptr<AbilityResult> &result)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "SendResultByBackToCaller:%{public}s", abilityInfo_.name.c_str());
std::lock_guard<ffrt::mutex> guard(lock_);
CHECK_POINTER(scheduler_);
CHECK_POINTER(result);
scheduler_->SendResult(result->requestCode_, result->resultCode_, result->resultWant_);
}
void AbilityRecord::SendSandboxSavefileResult(const Want &want, int resultCode, int requestCode)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "SendSandboxSavefileResult:%{public}s", abilityInfo_.name.c_str());
auto uriParam = want.GetParams().GetParam(PARAMS_FILE_SAVING_URL_KEY);
auto uriArray = AAFwk::IArray::Query(uriParam);
long arraySize = 0;
if (uriArray && uriArray->GetLength(arraySize) == ERR_OK &&
arraySize > 0 && AAFwk::Array::IsStringArray(uriArray)) {
for (long i = 0; i < arraySize; i++) {
sptr<AAFwk::IInterface> iface = nullptr;
if (uriArray->Get(i, iface) != ERR_OK) {
continue;
}
AAFwk::IString* iuri = AAFwk::IString::Query(iface);
if (!iuri) {
continue;
}
std::string uriStr;
if (iuri->GetString(uriStr) != ERR_OK) {
continue;
}
Uri uri(uriStr);
uint32_t initiatorTokenId = IPCSkeleton::GetCallingTokenID();
#ifdef SUPPORT_UPMS
auto flag = Want::FLAG_AUTH_WRITE_URI_PERMISSION | Want::FLAG_AUTH_READ_URI_PERMISSION;
auto ret = IN_PROCESS_CALL(UriPermissionManagerClient::GetInstance().GrantUriPermission(uri,
flag, abilityInfo_.bundleName, appIndex_, initiatorTokenId));
if (ret != ERR_OK) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "GrantUriPermission failed");
}
#endif
}
} else {
TAG_LOGW(AAFwkTag::ABILITYMGR, "uri illegal for request: %{public}d", requestCode);
}
auto scheduler = scheduler_;
if (scheduler) {
scheduler->SendResult(requestCode, resultCode, want);
}
}
void AbilityRecord::SendResultToCallers(bool schedulerdied)
{
for (auto caller : GetCallerRecordList()) {
if (caller == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "null caller");
continue;
}
std::shared_ptr<AbilityRecord> callerAbilityRecord = caller->GetCaller();
if (callerAbilityRecord != nullptr && callerAbilityRecord->GetResult() != nullptr) {
bool isSandboxApp = AbilityRuntime::GlobalConstant::IsDlpIndex(appIndex_);
callerAbilityRecord->SendResult(isSandboxApp, abilityInfo_.applicationInfo.accessTokenId, schedulerdied);
} else {
std::shared_ptr<SystemAbilityCallerRecord> callerSystemAbilityRecord = caller->GetSaCaller();
if (callerSystemAbilityRecord != nullptr) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "send result to system ability");
callerSystemAbilityRecord->SendResultToSystemAbility(caller->GetRequestCode(),
callerSystemAbilityRecord, abilityInfo_.applicationInfo.uid,
abilityInfo_.applicationInfo.accessTokenId, schedulerdied);
}
}
}
}
std::shared_ptr<AbilityRecord> AbilityRecord::GetCallerByRequestCode(int32_t requestCode, int32_t pid)
{
for (auto caller : GetCallerRecordList()) {
if (caller == nullptr) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "null caller");
continue;
}
std::shared_ptr<AbilityRecord> callerAbilityRecord = caller->GetCaller();
if (callerAbilityRecord == nullptr || callerAbilityRecord->GetPid() != pid) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "callerAbility not match");
continue;
}
if (caller->IsHistoryRequestCode(requestCode)) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "found callerAbility");
return callerAbilityRecord;
}
}
TAG_LOGI(AAFwkTag::ABILITYMGR, "Can't found caller");
return nullptr;
}
void AbilityRecord::SaveResultToCallers(const int resultCode, const Want *resultWant)
{
auto callerRecordList = GetCallerRecordList();
if (callerRecordList.empty()) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "callerRecordList is empty");
return;
}
auto latestCaller = callerRecordList.back();
for (auto caller : callerRecordList) {
if (caller == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "null caller");
continue;
}
if (caller == latestCaller) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "latestCaller");
SaveResult(resultCode, resultWant, caller);
continue;
}
SaveResult(SEND_RESULT_CANCELED, resultWant, caller);
}
}
void AbilityRecord::SaveResult(int resultCode, const Want *resultWant, std::shared_ptr<CallerRecord> caller)
{
std::lock_guard<ffrt::mutex> guard(lock_);
std::shared_ptr<AbilityRecord> callerAbilityRecord = caller->GetCaller();
if (callerAbilityRecord != nullptr) {
Want* newWant = const_cast<Want*>(resultWant);
if (callerAbilityRecord->GetApplicationInfo().name == AppUtils::GetInstance().GetBrokerDelegateBundleName()) {
newWant->SetParam(std::string(PARAM_SEND_RESULT_CALLER_BUNDLENAME), abilityInfo_.applicationInfo.name);
newWant->SetParam(std::string(PARAM_SEND_RESULT_CALLER_TOKENID), static_cast<int32_t>(
abilityInfo_.applicationInfo.accessTokenId));
}
callerAbilityRecord->SetResult(
std::make_shared<AbilityResult>(caller->GetRequestCode(), resultCode, *newWant));
} else {
std::shared_ptr<SystemAbilityCallerRecord> callerSystemAbilityRecord = caller->GetSaCaller();
if (callerSystemAbilityRecord != nullptr) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "caller is system ability");
Want* newWant = const_cast<Want*>(resultWant);
if (want_.GetBoolParam(PARAM_RESV_ANCO_IS_NEED_UPDATE_NAME, false)) {
want_.RemoveParam(PARAM_RESV_ANCO_IS_NEED_UPDATE_NAME);
callerSystemAbilityRecord->SetResult(*newWant, resultCode);
} else {
callerSystemAbilityRecord->SetResultToSystemAbility(callerSystemAbilityRecord, *newWant,
resultCode);
}
}
}
}
void SystemAbilityCallerRecord::SetResultToSystemAbility(
std::shared_ptr<SystemAbilityCallerRecord> callerSystemAbilityRecord,
Want &resultWant, int resultCode)
{
std::vector<std::string> data;
std::string srcAbilityId = callerSystemAbilityRecord->GetSrcAbilityId();
SplitStr(srcAbilityId, "_", data);
if (data.size() != VECTOR_SIZE) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "check size failed");
return;
}
std::string srcDeviceId = data[0];
TAG_LOGD(AAFwkTag::ABILITYMGR, "Get srcDeviceId = %{public}s", DmsUtil::AnonymizeDeviceId(srcDeviceId).c_str());
int missionId = atoi(data[1].c_str());
TAG_LOGI(AAFwkTag::ABILITYMGR, "get missionId: %{public}d", missionId);
resultWant.SetParam(DMS_SRC_NETWORK_ID, srcDeviceId);
resultWant.SetParam(DMS_MISSION_ID, missionId);
callerSystemAbilityRecord->SetResult(resultWant, resultCode);
}
void SystemAbilityCallerRecord::SendResultToSystemAbility(int requestCode,
const std::shared_ptr<SystemAbilityCallerRecord> callerSystemAbilityRecord,
int32_t callerUid, uint32_t accessToken, bool schedulerdied)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "call");
if (callerSystemAbilityRecord == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null record");
return;
}
int resultCode = callerSystemAbilityRecord->GetResultCode();
Want resultWant = callerSystemAbilityRecord->GetResultWant();
sptr<IRemoteObject> callerToken = callerSystemAbilityRecord->GetCallerToken();
if (!schedulerdied) {
callerUid = IPCSkeleton::GetCallingUid();
accessToken = IPCSkeleton::GetCallingTokenID();
}
TAG_LOGI(AAFwkTag::ABILITYMGR, "Try to SendResult");
if (callerToken == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null callerToken");
return;
}
MessageParcel data;
if (!data.WriteInterfaceToken(SYSTEM_ABILITY_TOKEN_CALLBACK)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "write interface token failed");
return;
}
if (!data.WriteParcelable(&resultWant)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "writeParcelable failed");
return;
}
if (!data.WriteInt32(callerUid)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "write callerUid failed");
return;
}
if (!data.WriteInt32(requestCode)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "write requestCode failed");
return;
}
if (!data.WriteUint32(accessToken)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "write accessToken failed");
return;
}
if (!data.WriteInt32(resultCode)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "write resultCode failed");
return;
}
MessageParcel reply;
MessageOption option(MessageOption::TF_SYNC);
int result = callerToken->SendRequest(ISystemAbilityTokenCallback::SEND_RESULT, data, reply, option);
if (result != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "error: %{public}d", result);
}
}
void AbilityRecord::RemoveSpecifiedWantParam(const std::string &key)
{
std::lock_guard guard(wantLock_);
want_.RemoveParam(key);
}
void AbilityRecord::RemoveCallerRequestCode(std::shared_ptr<AbilityRecord> callerAbilityRecord, int32_t requestCode)
{
if (callerAbilityRecord == nullptr) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "null record");
return;
}
bool removePidConnection = false;
{
std::lock_guard guard(callerListLock_);
for (auto it = callerList_.begin(); it != callerList_.end(); it++) {
if ((*it) != nullptr && (*it)->GetCaller() == callerAbilityRecord) {
(*it)->RemoveHistoryRequestCode(requestCode);
if (!(*it)->HasForResultRequestCode()) {
removePidConnection = true;
}
if ((*it)->GetRequestCodeSet().empty()) {
callerList_.erase(it);
TAG_LOGI(AAFwkTag::ABILITYMGR, "remove callerRecord");
}
break;
}
}
}
if (removePidConnection) {
DelayedSingleton<ForegroundAppConnectionManager>::GetInstance()->AbilityRemovePidConnection(
callerAbilityRecord->GetPid(), GetPid(), GetAbilityRecordId());
}
}
void AbilityRecord::AddCallerRecord(const sptr<IRemoteObject> &callerToken, int requestCode, const Want &want,
std::string srcAbilityId, uint32_t callingTokenId)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::ABILITYMGR, "call, callingTokenId:%{public}u,requestCode:%{public}d",
callingTokenId, requestCode);
auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
if (abilityRecord == nullptr) {
RecordSaCallerInfo(want);
}
if (!srcAbilityId.empty() && IsSystemAbilityCall(callerToken, callingTokenId)) {
AddSystemAbilityCallerRecord(callerToken, requestCode, srcAbilityId);
return;
}
if (!abilityRecord) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "nullptr");
return;
}
auto isExist = [&abilityRecord](const std::shared_ptr<CallerRecord> &callerRecord) {
return (callerRecord->GetCaller() == abilityRecord);
};
std::lock_guard guard(callerListLock_);
auto record = std::find_if(callerList_.begin(), callerList_.end(), isExist);
auto newCallerRecord = std::make_shared<CallerRecord>(requestCode, abilityRecord);
if (record != callerList_.end()) {
newCallerRecord->SetRequestCodeSet((*record)->GetRequestCodeSet());
callerList_.erase(record);
}
newCallerRecord->AddHistoryRequestCode(requestCode);
callerList_.emplace_back(newCallerRecord);
lifeCycleStateInfo_.caller.requestCode = requestCode;
lifeCycleStateInfo_.caller.deviceId = abilityRecord->GetAbilityInfo().deviceId;
lifeCycleStateInfo_.caller.bundleName = abilityRecord->GetAbilityInfo().bundleName;
lifeCycleStateInfo_.caller.abilityName = abilityRecord->GetAbilityInfo().name;
TAG_LOGD(AAFwkTag::ABILITYMGR, "caller %{public}s, %{public}s, callerSize: %{public}zu",
abilityRecord->GetAbilityInfo().bundleName.c_str(),
abilityRecord->GetAbilityInfo().name.c_str(), callerList_.size());
}
bool AbilityRecord::IsSystemAbilityCall(const sptr<IRemoteObject> &callerToken, uint32_t callingTokenId)
{
if (callerToken == nullptr) {
return false;
}
auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
if (abilityRecord != nullptr) {
return false;
}
uint32_t tokenId = 0;
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
tokenId = callingTokenId;
} else {
tokenId = IPCSkeleton::GetCallingTokenID();
}
auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
bool isNativeCall = tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE;
if (!isNativeCall) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "not native call");
return false;
}
AccessToken::NativeTokenInfo nativeTokenInfo;
int32_t result = AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, nativeTokenInfo);
if (result == ERR_OK && (nativeTokenInfo.processName == DMS_PROCESS_NAME ||
want_.GetBoolParam(PARAM_RESV_ANCO_IS_NEED_UPDATE_NAME, false))) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "system ability call");
return true;
}
return false;
}
void AbilityRecord::AddSystemAbilityCallerRecord(const sptr<IRemoteObject> &callerToken, int requestCode,
std::string srcAbilityId)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "add system ability caller record");
std::shared_ptr<SystemAbilityCallerRecord> systemAbilityRecord =
std::make_shared<SystemAbilityCallerRecord>(srcAbilityId, callerToken);
auto isExist = [&srcAbilityId](const std::shared_ptr<CallerRecord> &callerRecord) {
std::shared_ptr<SystemAbilityCallerRecord> saCaller = callerRecord->GetSaCaller();
return (saCaller != nullptr && saCaller->GetSrcAbilityId() == srcAbilityId);
};
std::lock_guard guard(callerListLock_);
auto record = std::find_if(callerList_.begin(), callerList_.end(), isExist);
if (record != callerList_.end()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "find same system ability caller record");
callerList_.erase(record);
}
callerList_.emplace_back(std::make_shared<CallerRecord>(requestCode, systemAbilityRecord));
TAG_LOGI(AAFwkTag::ABILITYMGR, "add system ability record end");
}
void AbilityRecord::RecordSaCallerInfo(const Want &want)
{
saCallerInfo_ = std::make_shared<CallerAbilityInfo>();
saCallerInfo_->callerTokenId = want.GetIntParam(Want::PARAM_RESV_CALLER_TOKEN, 0);
saCallerInfo_->callerUid = want.GetIntParam(Want::PARAM_RESV_CALLER_UID, 0);
saCallerInfo_->callerPid = want.GetIntParam(Want::PARAM_RESV_CALLER_PID, 0);
saCallerInfo_->callerNativeName = want.GetStringParam(Want::PARAM_RESV_CALLER_NATIVE_NAME);
}
std::list<std::shared_ptr<CallerRecord>> AbilityRecord::GetCallerRecordList() const
{
std::lock_guard guard(callerListLock_);
return callerList_;
}
std::shared_ptr<AbilityRecord> AbilityRecord::GetCallerRecord() const
{
std::lock_guard guard(callerListLock_);
if (callerList_.empty()) {
return nullptr;
}
if (callerList_.back() == nullptr) {
return nullptr;
}
return callerList_.back()->GetCaller();
}
std::shared_ptr<CallerAbilityInfo> AbilityRecord::GetCallerInfo() const
{
std::lock_guard guard(callerListLock_);
if (callerList_.empty() || callerList_.back() == nullptr) {
return saCallerInfo_;
}
return callerList_.back()->GetCallerInfo();
}
void AbilityRecord::GetAbilityTypeString(std::string &typeStr)
{
AppExecFwk::AbilityType type = GetAbilityInfo().type;
switch (type) {
#ifdef SUPPORT_GRAPHICS
case AppExecFwk::AbilityType::PAGE: {
typeStr = "PAGE";
break;
}
#endif
case AppExecFwk::AbilityType::SERVICE: {
typeStr = UIExtensionWrapper::IsUIExtension(GetAbilityInfo().extensionAbilityType) ?
"UIEXTENSION" : "SERVICE";
break;
}
case AppExecFwk::AbilityType::DATA: {
typeStr = "DATA";
break;
}
default: {
typeStr = "UNKNOWN";
break;
}
}
}
std::string AbilityRecord::ConvertAbilityState(const AbilityState &state)
{
return StateUtils::StateToStrMap(state);
}
std::string AbilityRecord::ConvertAppState(const AppState &state)
{
return StateUtils::AppStateToStrMap(state);
}
int AbilityRecord::ConvertLifeCycleToAbilityState(const AbilityLifeCycleState &state)
{
return StateUtils::ConvertStateMap(state);
}
void AbilityRecord::Dump(std::vector<std::string> &info)
{
std::string dumpInfo = " AbilityRecord ID #" + std::to_string(recordId_);
info.push_back(dumpInfo);
dumpInfo = " app name [" + GetAbilityInfo().applicationName + "]";
info.push_back(dumpInfo);
dumpInfo = " main name [" + GetAbilityInfo().name + "]";
info.push_back(dumpInfo);
dumpInfo = " bundle name [" + GetAbilityInfo().bundleName + "]";
info.push_back(dumpInfo);
std::string isKeepAlive = GetKeepAlive() ? "true" : "false";
dumpInfo = " isKeepAlive: " + isKeepAlive;
info.push_back(dumpInfo);
std::string typeStr;
GetAbilityTypeString(typeStr);
dumpInfo = " ability type [" + typeStr + "]";
info.push_back(dumpInfo);
dumpInfo = " previous ability app name [NULL]";
dumpInfo.append("\n");
dumpInfo += " previous ability file name [NULL]";
info.push_back(dumpInfo);
dumpInfo = " next ability app name [NULL]";
dumpInfo.append("\n");
dumpInfo += " next ability file name [NULL]";
info.push_back(dumpInfo);
dumpInfo = " state #" + AbilityRecord::ConvertAbilityState(GetAbilityState()) + " start time [" +
std::to_string(startTime_) + "]";
info.push_back(dumpInfo);
dumpInfo = " app state #" + AbilityRecord::ConvertAppState(appState_);
info.push_back(dumpInfo);
dumpInfo = " ready #" + std::to_string(isReady_) + " window attached #" +
std::to_string(isWindowAttached_) + " launcher #" + std::to_string(isLauncherAbility_);
info.push_back(dumpInfo);
if (isLauncherRoot_) {
dumpInfo = " can restart num #" + std::to_string(restartCount_);
info.push_back(dumpInfo);
}
}
void AbilityRecord::DumpAbilityState(
std::vector<std::string> &info, bool isClient, const std::vector<std::string> ¶ms)
{
std::string dumpInfo = " AbilityRecord ID #" + std::to_string(recordId_);
info.push_back(dumpInfo);
dumpInfo = " app name [" + GetAbilityInfo().applicationName + "]";
info.push_back(dumpInfo);
dumpInfo = " main name [" + GetAbilityInfo().name + "]";
info.push_back(dumpInfo);
dumpInfo = " bundle name [" + GetAbilityInfo().bundleName + "]";
info.push_back(dumpInfo);
std::string typeStr;
GetAbilityTypeString(typeStr);
dumpInfo = " ability type [" + typeStr + "]";
info.push_back(dumpInfo);
dumpInfo = " state #" + AbilityRecord::ConvertAbilityState(GetAbilityState()) + " start time [" +
std::to_string(startTime_) + "]";
info.push_back(dumpInfo);
dumpInfo = " app state #" + AbilityRecord::ConvertAppState(appState_);
info.push_back(dumpInfo);
dumpInfo = " ready #" + std::to_string(isReady_) + " window attached #" +
std::to_string(isWindowAttached_) + " launcher #" + std::to_string(isLauncherAbility_);
info.push_back(dumpInfo);
dumpInfo = " callee connections: ";
info.push_back(dumpInfo);
if (callContainer_) {
callContainer_->Dump(info);
}
std::string isKeepAlive = GetKeepAlive() ? "true" : "false";
dumpInfo = " isKeepAlive: " + isKeepAlive;
info.push_back(dumpInfo);
if (isLauncherRoot_) {
dumpInfo = " can restart num #" + std::to_string(restartCount_);
info.push_back(dumpInfo);
}
auto missionAffinity = GetMissionAffinity();
if (!missionAffinity.empty()) {
dumpInfo = " missionAffinity: " + missionAffinity;
info.push_back(dumpInfo);
}
DumpClientInfo(info, params, isClient, params.empty());
}
void AbilityRecord::SetStartTime()
{
int64_t expected = 0;
int64_t desired = AbilityUtil::SystemTimeMillis();
startTime_.compare_exchange_strong(expected, desired);
}
int64_t AbilityRecord::GetStartTime() const
{
return startTime_;
}
void AbilityRecord::RemoveAbilityDeathRecipient() const
{
if (scheduler_ == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "null scheduler_");
return;
}
if (schedulerDeathRecipient_ == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "null schedulerDeathRecipient_");
return;
}
auto schedulerObject = scheduler_->AsObject();
if (schedulerObject != nullptr) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "RemoveDeathRecipient");
schedulerObject->RemoveDeathRecipient(schedulerDeathRecipient_);
}
}
void AbilityRecord::OnSchedulerDied(const wptr<IRemoteObject> &remote)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "OnSchedulerDied called");
std::lock_guard<ffrt::mutex> guard(lock_);
if (IsAbilityDiedHandled()) {
return;
}
CHECK_POINTER(scheduler_);
auto object = remote.promote();
CHECK_POINTER(object);
if (object != scheduler_->AsObject()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "ability died: scheduler not matches remote");
return;
}
if (scheduler_ != nullptr && schedulerDeathRecipient_ != nullptr) {
auto schedulerObject = scheduler_->AsObject();
if (schedulerObject != nullptr) {
schedulerObject->RemoveDeathRecipient(schedulerDeathRecipient_);
}
}
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->SetScheduler(nullptr);
isWindowAttached_ = false;
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
CHECK_POINTER(handler);
TAG_LOGI(AAFwkTag::ABILITYMGR, "Ability on scheduler died: '%{public}s'", abilityInfo_.name.c_str());
auto task = [ability = shared_from_this()]() {
CHECK_POINTER_LOG(ability, "ability nullptr");
DelayedSingleton<AbilityManagerService>::GetInstance()->OnAbilityDied(ability);
};
std::string typeName = abilityInfo_.type == AppExecFwk::AbilityType::PAGE ? "(uiability)" : "(extension)";
handler->SubmitTask(task, AAFwk::TaskAttribute{
.taskName_ = "OnSchedulerDied" + typeName,
.timeoutMillis_ = SCHEDULER_DIED_TIMEOUT
});
auto resultTask = [want = GetWant(), ability = shared_from_this()]() {
ability->SaveResultToCallers(-1, &want);
ability->SendResultToCallers(true);
};
handler->SubmitTask(resultTask);
#ifdef SUPPORT_GRAPHICS
NotifyAnimationAbilityDied();
#endif
#ifdef WITH_DLP
HandleDlpClosed();
#endif
NotifyRemoveShellProcess(CollaboratorType::RESERVE_TYPE);
NotifyRemoveShellProcess(CollaboratorType::OTHERS_TYPE);
}
bool AbilityRecord::IsAbilityDiedHandled()
{
if (handledAbilityDied_) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "abilityDied already handled");
return handledAbilityDied_;
}
handledAbilityDied_ = true;
return false;
}
void AbilityRecord::OnProcessDied(bool isKeepAliveDied)
{
CancelPrepareTerminate();
std::lock_guard<ffrt::mutex> guard(lock_);
if (!IsSceneBoard() && scheduler_ != nullptr && !isKeepAliveDied) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "OnProcessDied: '%{public}s', attached.", abilityInfo_.name.c_str());
return;
}
if (IsAbilityDiedHandled()) {
return;
}
if (scheduler_ != nullptr && schedulerDeathRecipient_ != nullptr) {
auto schedulerObject = scheduler_->AsObject();
if (schedulerObject != nullptr) {
schedulerObject->RemoveDeathRecipient(schedulerDeathRecipient_);
}
}
if (lifecycleDeal_ != nullptr) {
lifecycleDeal_->SetScheduler(nullptr);
}
isWindowAttached_ = false;
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
CHECK_POINTER(handler);
TAG_LOGI(AAFwkTag::ABILITYMGR, "OnProcessDied: '%{public}s'", abilityInfo_.name.c_str());
auto task = [ability = shared_from_this()]() {
CHECK_POINTER_LOG(ability, "ability nullptr");
DelayedSingleton<AbilityManagerService>::GetInstance()->OnAbilityDied(ability);
};
if (IsSceneBoard()) {
handler->SubmitTask(task, RESTART_SCENEBOARD_DELAY);
} else {
handler->SubmitTask(task);
}
auto uriTask = [want = GetWant(), ability = shared_from_this()]() {
ability->SaveResultToCallers(-1, &want);
ability->SendResultToCallers(true);
};
handler->SubmitTask(uriTask);
#ifdef SUPPORT_GRAPHICS
NotifyAnimationAbilityDied();
#endif
#ifdef WITH_DLP
HandleDlpClosed();
#endif
NotifyRemoveShellProcess(CollaboratorType::RESERVE_TYPE);
NotifyRemoveShellProcess(CollaboratorType::OTHERS_TYPE);
}
void AbilityRecord::NotifyAnimationAbilityDied()
{
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
return;
}
if (missionId_ != -1) {
#ifdef SUPPORT_SCREEN
if (GetWMSHandler()) {
sptr<AbilityTransitionInfo> info = new AbilityTransitionInfo();
SetAbilityTransitionInfo(info);
TAG_LOGI(AAFwkTag::ABILITYMGR, "UIAbiltiy abnormal death");
GetWMSHandler()->NotifyAnimationAbilityDied(info);
}
#endif
}
}
bool AbilityRecord::IsNeverStarted() const
{
if (UIExtensionWrapper::IsUIExtension(GetAbilityInfo().extensionAbilityType)) {
return startId_ == 0;
}
return startId_ == 0 && IsCreateByConnect();
}
void AbilityRecord::AddStartId()
{
startId_++;
}
int AbilityRecord::GetStartId() const
{
return startId_;
}
void AbilityRecord::SetIsUninstallAbility()
{
isUninstall_ = true;
}
bool AbilityRecord::IsUninstallAbility() const
{
return isUninstall_;
}
void AbilityRecord::SetLauncherRoot()
{
isLauncherRoot_ = true;
}
bool AbilityRecord::IsLauncherRoot() const
{
return isLauncherRoot_;
}
bool AbilityRecord::IsAbilityState(const AbilityState &state) const
{
return (currentState_.load() == state);
}
bool AbilityRecord::IsActiveState() const
{
return (IsAbilityState(AbilityState::ACTIVE) || IsAbilityState(AbilityState::ACTIVATING) ||
IsAbilityState(AbilityState::INITIAL) || IsAbilityState(AbilityState::FOREGROUND) ||
IsAbilityState(AbilityState::FOREGROUNDING));
}
void AbilityRecord::SendEvent(uint32_t msg, uint32_t timeOut, int32_t param, bool isExtension,
const std::string &taskName)
{
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
CHECK_POINTER(handler);
param = (param == -1) ? recordId_ : param;
auto eventWrap = EventWrap(msg, param, isExtension, taskName);
eventWrap.SetTimeout(timeOut);
if (!handler->SendEvent(eventWrap, timeOut, false)) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "failed: %{public}u, %{public}d", msg, param);
}
}
void AbilityRecord::SetWant(const Want &want)
{
std::lock_guard guard(wantLock_);
if (abilityInfo_.type == AppExecFwk::AbilityType::PAGE && isLaunching_) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "uIAbility launching");
return;
}
auto multiThread = want_.GetBoolParam(MULTI_THREAD, false);
auto errorInfoEnhance = want_.GetBoolParam(ERROR_INFO_ENHANCE, false);
want_.CloseAllFd();
want_ = want;
if (launchDebugInfo_.isDebugAppSet) {
want_.SetParam(AbilityConfig::DEBUG_APP, launchDebugInfo_.debugApp);
} else {
want_.RemoveParam(AbilityConfig::DEBUG_APP);
}
if (launchDebugInfo_.isNativeDebugSet) {
want_.SetParam(AbilityConfig::NATIVE_DEBUG, launchDebugInfo_.nativeDebug);
} else {
want_.RemoveParam(AbilityConfig::NATIVE_DEBUG);
}
if (launchDebugInfo_.isPerfCmdSet) {
want_.SetParam(AbilityConfig::PERF_CMD, launchDebugInfo_.perfCmd);
} else {
want_.RemoveParam(AbilityConfig::PERF_CMD);
}
if (multiThread) {
want_.SetParam(MULTI_THREAD, true);
}
if (errorInfoEnhance) {
want_.SetParam(ERROR_INFO_ENHANCE, true);
}
if (want_.HasParameter(UISERVICEHOSTPROXY_KEY)) {
want_.RemoveParam(UISERVICEHOSTPROXY_KEY);
}
if (want_.HasParameter(AgentRuntime::AGENTEXTENSIONHOSTPROXY_KEY)) {
want_.RemoveParam(AgentRuntime::AGENTEXTENSIONHOSTPROXY_KEY);
}
if (want_.HasParameter(AgentRuntime::AGENTID_KEY)) {
want_.RemoveParam(AgentRuntime::AGENTID_KEY);
}
if (want_.HasParameter(AgentRuntime::AGENT_CARD_TYPE_KEY)) {
want_.RemoveParam(AgentRuntime::AGENT_CARD_TYPE_KEY);
}
if (want_.HasParameter(AgentRuntime::AGENT_VERIFICATION_NONCE_KEY)) {
want_.RemoveParam(AgentRuntime::AGENT_VERIFICATION_NONCE_KEY);
}
}
Want AbilityRecord::GetWant() const
{
std::lock_guard guard(wantLock_);
return want_;
}
std::string AbilityRecord::GetAbilityName() const
{
std::lock_guard guard(wantLock_);
return want_.GetAbilityNameRef();
}
std::string AbilityRecord::GetBundleName() const
{
std::lock_guard guard(wantLock_);
return want_.GetBundleNameRef();
}
std::string AbilityRecord::GetModuleName() const
{
std::lock_guard guard(wantLock_);
return want_.GetModuleNameRef();
}
std::string AbilityRecord::GetStringParam(const std::string &key) const
{
std::lock_guard guard(wantLock_);
return want_.GetStringParam(key);
}
int AbilityRecord::GetIntParam(const std::string &key, int defaultValue) const
{
std::lock_guard guard(wantLock_);
return want_.GetIntParam(key, defaultValue);
}
bool AbilityRecord::GetBoolParam(const std::string &key, bool defaultValue) const
{
std::lock_guard guard(wantLock_);
return want_.GetBoolParam(key, defaultValue);
}
bool AbilityRecord::HasParameter(const std::string &key) const
{
std::lock_guard guard(wantLock_);
return want_.HasParameter(key);
}
void AbilityRecord::RemoveSignatureInfo()
{
std::lock_guard guard(wantLock_);
want_.RemoveParam(Want::PARAM_RESV_CALLER_APP_ID);
want_.RemoveParam(Want::PARAM_RESV_CALLER_APP_IDENTIFIER);
}
AppExecFwk::ElementName AbilityRecord::GetElementName() const
{
std::lock_guard guard(wantLock_);
return want_.GetElement();
}
bool AbilityRecord::IsDebugApp() const
{
std::lock_guard guard(wantLock_);
return launchDebugInfo_.debugApp;
}
bool AbilityRecord::IsDebug() const
{
std::lock_guard guard(wantLock_);
if (launchDebugInfo_.debugApp || launchDebugInfo_.nativeDebug ||
!launchDebugInfo_.perfCmd.empty() || isAttachDebug_ || isAssertDebug_) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "debug mode, no need to handle");
return true;
}
return false;
}
void AbilityRecord::SetWindowMode(int32_t windowMode)
{
std::lock_guard guard(wantLock_);
want_.SetParam(Want::PARAM_RESV_WINDOW_MODE, windowMode);
}
void AbilityRecord::RemoveWindowMode()
{
std::lock_guard guard(wantLock_);
want_.RemoveParam(Want::PARAM_RESV_WINDOW_MODE);
}
void AbilityRecord::UpdateRecoveryInfo(bool hasRecoverInfo)
{
hasRecoverInfo_ = hasRecoverInfo;
if (hasRecoverInfo) {
std::lock_guard guard(wantLock_);
want_.SetParam(Want::PARAM_ABILITY_RECOVERY_RESTART, true);
}
}
bool AbilityRecord::GetRecoveryInfo()
{
std::lock_guard guard(wantLock_);
return want_.GetBoolParam(Want::PARAM_ABILITY_RECOVERY_RESTART, false);
}
void AbilityRecord::EvaluateRecoveryLaunchReason()
{
if (!hasRecoverInfo_) {
return;
}
if (lifeCycleStateInfo_.launchParam.launchReason == LaunchReason::LAUNCHREASON_APP_RECOVERY) {
hasRecoverInfo_ = false;
return;
}
auto setting = GetStartSetting();
bool isStartByScb = setting != nullptr &&
setting->GetProperty(AbilityStartSetting::IS_START_BY_SCB_KEY) == "true";
auto lastExitReason = lifeCycleStateInfo_.launchParam.lastExitReason;
bool isEligible = isStartByScb &&
(lastExitReason == LastExitReason::LASTEXITREASON_PERFORMANCE_CONTROL ||
lastExitReason == LastExitReason::LASTEXITREASON_RESOURCE_CONTROL);
if (isEligible) {
SetLaunchReason(LaunchReason::LAUNCHREASON_APP_RECOVERY);
} else {
TAG_LOGI(AAFwkTag::ABILITYMGR,
"recovery gate failed, isStartByScb=%{public}d, lastExitReason=%{public}d",
isStartByScb, static_cast<int32_t>(lastExitReason));
std::lock_guard guard(wantLock_);
want_.SetParam(Want::PARAM_ABILITY_RECOVERY_RESTART, false);
}
hasRecoverInfo_ = false;
}
void AbilityRecord::SetStartSetting(const std::shared_ptr<AbilityStartSetting> &setting)
{
lifeCycleStateInfo_.setting = setting;
}
std::shared_ptr<AbilityStartSetting> AbilityRecord::GetStartSetting() const
{
return lifeCycleStateInfo_.setting;
}
void AbilityRecord::SetSandboxCloneParams(const std::shared_ptr<SandboxCloneParams> ¶ms)
{
sandboxCloneParams_ = params;
}
std::shared_ptr<SandboxCloneParams> AbilityRecord::GetSandboxCloneParams() const
{
return sandboxCloneParams_;
}
void AbilityRecord::SetRestarting(const bool isRestart)
{
isRestarting_ = isRestart;
TAG_LOGD(AAFwkTag::ABILITYMGR, "SetRestarting: %{public}d", isRestarting_);
if ((isLauncherRoot_ && IsLauncherAbility()) || GetKeepAlive()) {
restartCount_ = isRestart ? (--restartCount_) : restartMax_;
TAG_LOGD(AAFwkTag::ABILITYMGR, "root launcher or resident process's restart count: %{public}d", restartCount_);
}
}
void AbilityRecord::SetRestarting(const bool isRestart, int32_t canRestartCount)
{
isRestarting_ = isRestart;
TAG_LOGD(
AAFwkTag::ABILITYMGR, "SetRestarting: %{public}d, restart count: %{public}d", isRestarting_, canRestartCount);
if ((isLauncherRoot_ && IsLauncherAbility()) || GetKeepAlive()) {
restartCount_ = isRestart ? canRestartCount : restartMax_;
TAG_LOGI(AAFwkTag::ABILITYMGR, "root launcher or resident process's restart count: %{public}d", restartCount_);
}
}
int32_t AbilityRecord::GetRestartCount() const
{
return restartCount_;
}
void AbilityRecord::SetRestartCount(int32_t restartCount)
{
restartCount_ = restartCount;
}
bool AbilityRecord::IsRestarting() const
{
return isRestarting_;
}
bool AbilityRecord::GetKeepAlive() const
{
std::vector<std::pair<std::string, std::string>> trustAbilities{
{ AbilityConfig::SCENEBOARD_BUNDLE_NAME, AbilityConfig::SCENEBOARD_ABILITY_NAME },
{ AbilityConfig::SYSTEM_UI_BUNDLE_NAME, AbilityConfig::SYSTEM_UI_ABILITY_NAME },
{ AbilityConfig::LAUNCHER_BUNDLE_NAME, AbilityConfig::LAUNCHER_ABILITY_NAME }
};
for (const auto &pair : trustAbilities) {
if (pair.first == abilityInfo_.bundleName && pair.second == abilityInfo_.name) {
return true;
}
}
bool keepAliveEnable = keepAliveBundle_;
AmsResidentProcessRdb::GetInstance().GetResidentProcessEnable(
abilityInfo_.applicationInfo.bundleName, keepAliveEnable);
return keepAliveEnable;
}
void AbilityRecord::SetLoading(bool status)
{
isLoading_ = status;
}
bool AbilityRecord::IsLoading() const
{
return isLoading_;
}
int64_t AbilityRecord::GetRestartTime()
{
return restartTime_;
}
void AbilityRecord::SetRestartTime(const int64_t restartTime)
{
restartTime_ = restartTime;
}
void AbilityRecord::SetAppState(const AppState &state)
{
appState_ = state;
}
AppState AbilityRecord::GetAppState() const
{
return appState_;
}
void AbilityRecord::SetLaunchReason(const LaunchReason &reason)
{
if (isAppAutoStartup_) {
lifeCycleStateInfo_.launchParam.launchReason = LaunchReason::LAUNCHREASON_AUTO_STARTUP;
return;
}
lifeCycleStateInfo_.launchParam.launchReason = reason;
}
void AbilityRecord::SetLaunchReasonMessage(const std::string &launchReasonMessage)
{
lifeCycleStateInfo_.launchParam.launchReasonMessage = launchReasonMessage;
}
void AbilityRecord::SetLastExitReason(const ExitReason &exitReason, const AppExecFwk::RunningProcessInfo &processInfo,
const int64_t timestamp, bool withKillMsg)
{
std::string exitMsg = exitReason.exitMsg;
std::string killMsg = "";
if (withKillMsg) {
killMsg = exitReason.exitMsg;
}
LastExitDetailInfo lastExitDetailInfo = {};
lastExitDetailInfo.pid = processInfo.pid_;
lastExitDetailInfo.uid = processInfo.uid_;
lastExitDetailInfo.exitSubReason = exitReason.subReason;
lastExitDetailInfo.rss = processInfo.rssValue;
lastExitDetailInfo.pss = processInfo.pssValue;
lastExitDetailInfo.processState = static_cast<int32_t>(processInfo.state_);
lastExitDetailInfo.timestamp = timestamp;
lastExitDetailInfo.processName = processInfo.processName_;
lastExitDetailInfo.exitMsg = killMsg;
if (exitReason.killId != DEFAULT_INVALID_VALUE) {
lastExitDetailInfo.killReason = HiviewDFX::ProcessKillReason::GetKillReason(exitReason.killId);
}
lifeCycleStateInfo_.launchParam.lastExitReason = CovertAppExitReasonToLastReason(exitReason.reason);
lifeCycleStateInfo_.launchParam.lastExitMessage = exitMsg;
lifeCycleStateInfo_.launchParam.lastExitDetailInfo = lastExitDetailInfo;
}
LastExitReason AbilityRecord::CovertAppExitReasonToLastReason(const Reason exitReason)
{
switch (exitReason) {
case REASON_NORMAL:
return LASTEXITREASON_NORMAL;
case REASON_CPP_CRASH:
return LASTEXITREASON_CPP_CRASH;
case REASON_JS_ERROR:
return LASTEXITREASON_JS_ERROR;
case REASON_APP_FREEZE:
return LASTEXITREASON_APP_FREEZE;
case REASON_PERFORMANCE_CONTROL:
return LASTEXITREASON_PERFORMANCE_CONTROL;
case REASON_RESOURCE_CONTROL:
return LASTEXITREASON_RESOURCE_CONTROL;
case REASON_UPGRADE:
return LASTEXITREASON_UPGRADE;
case REASON_USER_REQUEST:
return LASTEXITREASON_USER_REQUEST;
case REASON_SIGNAL:
return LASTEXITREASON_SIGNAL;
case REASON_UNKNOWN:
default:
return LASTEXITREASON_UNKNOWN;
}
}
void AbilityRecord::NotifyContinuationResult(int32_t result)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "NotifyContinuationResult");
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->NotifyContinuationResult(result);
}
void AbilityRecord::SetMissionId(int32_t missionId)
{
std::lock_guard guard(wantLock_);
missionId_ = missionId;
want_.RemoveParam(KEY_MISSION_ID);
want_.SetParam(KEY_MISSION_ID, missionId_);
}
void AbilityRecord::SetSessionInfo(sptr<SessionInfo> sessionInfo)
{
std::lock_guard guard(sessionLock_);
sessionInfo_ = sessionInfo;
}
sptr<SessionInfo> AbilityRecord::GetSessionInfo() const
{
std::lock_guard guard(sessionLock_);
return sessionInfo_;
}
void AbilityRecord::FillProcessInfoFromSession(AbilityRuntime::LoadParam &loadParam) const
{
auto sessionInfo = GetSessionInfo();
if (sessionInfo != nullptr && sessionInfo->processOptions != nullptr) {
loadParam.processMode = static_cast<int32_t>(sessionInfo->processOptions->processMode);
loadParam.requestId = sessionInfo->requestId;
}
}
void AbilityRecord::UpdateSessionInfo(sptr<IRemoteObject> sessionToken)
{
{
std::lock_guard guard(sessionLock_);
if (sessionInfo_ == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "null sessionInfo_");
return;
}
sessionInfo_->sessionToken = sessionToken;
}
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->UpdateSessionToken(sessionToken);
}
void AbilityRecord::SetMinimizeReason(bool fromUser)
{
minimizeReason_ = fromUser;
}
void AbilityRecord::SetSceneFlag(uint32_t sceneFlag)
{
lifeCycleStateInfo_.sceneFlag = sceneFlag;
}
void AbilityRecord::SetIsFromScreenOffBackground(bool isFromScreenOffBackground)
{
isFromScreenOffBackground_ = isFromScreenOffBackground;
}
bool AbilityRecord::IsFromScreenOffBackground() const
{
return isFromScreenOffBackground_;
}
void AbilityRecord::SetAppIndex(const int32_t appIndex)
{
appIndex_ = appIndex;
}
int32_t AbilityRecord::GetAppIndex() const
{
return appIndex_;
}
void AbilityRecord::SetWantAppIndex(const int32_t appIndex)
{
std::lock_guard guard(wantLock_);
want_.SetParam(Want::PARAM_APP_CLONE_INDEX_KEY, appIndex);
}
int32_t AbilityRecord::GetWantAppIndex() const
{
std::lock_guard guard(wantLock_);
return want_.GetIntParam(Want::PARAM_APP_CLONE_INDEX_KEY, 0);
}
bool AbilityRecord::IsMinimizeFromUser() const
{
return minimizeReason_;
}
void AbilityRecord::SetClearMissionFlag(bool clearMissionFlag)
{
clearMissionFlag_= clearMissionFlag;
}
bool AbilityRecord::IsClearMissionFlag()
{
return clearMissionFlag_;
}
int32_t AbilityRecord::GetMissionId() const
{
return missionId_;
}
void AbilityRecord::SetSpecifiedFlag(const std::string &flag)
{
specifiedFlag_ = flag;
lifeCycleStateInfo_.launchParam.specifiedId = flag;
}
std::string AbilityRecord::GetSpecifiedFlag() const
{
return specifiedFlag_;
}
bool AbilityRecord::IsStartedByCall() const
{
return isStartedByCall_;
}
void AbilityRecord::SetStartedByCall(const bool isFlag)
{
isStartedByCall_ = isFlag;
}
int32_t AbilityRecord::GetByCallStatus() const
{
if (!isStartedByCall_) {
return NON_BY_CALL;
}
if (want_.GetBoolParam(Want::PARAM_RESV_CALL_TO_FOREGROUND, false)) {
return CALL_TO_FOREGROUND;
}
return CALL_TO_BACKGROUND;
}
bool AbilityRecord::IsStartToBackground() const
{
return isStartToBackground_;
}
void AbilityRecord::SetStartToBackground(const bool flag)
{
isStartToBackground_ = flag;
}
bool AbilityRecord::IsStartToForeground() const
{
return isStartToForeground_;
}
void AbilityRecord::SetStartToForeground(const bool flag)
{
isStartToForeground_ = flag;
}
void AbilityRecord::PostStartAbilityByCallTimeoutTask(bool isHalf)
{
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
CHECK_POINTER(handler);
auto timeoutTask = [isHalf, ability = shared_from_this()]() {
std::string abilityName = ability->GetAbilityInfo().name;
std::string bundleName = ability->GetAbilityInfo().bundleName;
auto pid = ability->GetPid();
auto uid = ability->GetUid();
if (pid == 0) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "ability:%{public}s, app fork fail/not run", abilityName.c_str());
return;
}
int typeId = AppExecFwk::AppfreezeManager::TypeAttribute::CRITICAL_TIMEOUT;
std::string msgContent = "ability:" + abilityName + " ";
std::string eventName;
FreezeUtil::TimeoutState state = FreezeUtil::TimeoutState::BY_CALL;
msgContent = isHalf ? msgContent + "call request half timeout." : msgContent + "call request timeout.";
eventName = isHalf ? AppExecFwk::AppFreezeType::LIFECYCLE_HALF_TIMEOUT_WARNING
: AppExecFwk::AppFreezeType::LIFECYCLE_TIMEOUT_WARNING;
TAG_LOGW(AAFwkTag::ABILITYMGR, "%{public}s: uid: %{public}d, pid: %{public}d, bundleName: %{public}s, "
"abilityName: %{public}s, msg: %{public}s", eventName.c_str(), uid, pid,
bundleName.c_str(), abilityName.c_str(), msgContent.c_str());
AppExecFwk::AppfreezeManager::ParamInfo info = { false, typeId, pid, eventName, bundleName };
FreezeUtil::LifecycleFlow flow;
if (ability->GetToken() != nullptr) {
flow.token = ability->GetToken()->AsObject();
flow.state = state;
}
info.msg = msgContent + "\nserver actions for ability:\n" +
FreezeUtil::GetInstance().GetLifecycleEvent(flow.token)
+ "\nserver actions for app:\n" + FreezeUtil::GetInstance().GetAppLifecycleEvent(pid);
if (!isHalf) {
FreezeUtil::GetInstance().DeleteLifecycleEvent(flow.token);
FreezeUtil::GetInstance().DeleteAppLifecycleEvent(pid);
}
AppExecFwk::AppfreezeManager::GetInstance()->LifecycleTimeoutHandle(info, flow);
};
auto timeoutMs = isHalf ? BY_CALL_HALF_TIMEOUT_MS : BY_CALL_TIMEOUT_MS;
std::string taskPrefix = isHalf ? "by_call_half_timeout_" : "by_call_timeout_";
handler->SubmitTask(timeoutTask, taskPrefix + std::to_string(recordId_), timeoutMs);
}
void AbilityRecord::CallRequest()
{
CHECK_POINTER(scheduler_);
std::string entry = "AbilityRecord::CallRequest Begin";
FreezeUtil::GetInstance().AddLifecycleEvent(token_, entry);
scheduler_->CallRequest();
PostStartAbilityByCallTimeoutTask(true);
PostStartAbilityByCallTimeoutTask(false);
}
void AbilityRecord::CancelStartAbilityByCallTimeoutTask() const
{
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (!handler) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "fail get AbilityEventHandler");
return;
}
if (GetToken() && GetToken()->AsObject()) {
FreezeUtil::GetInstance().DeleteLifecycleEvent(GetToken()->AsObject());
}
FreezeUtil::GetInstance().DeleteAppLifecycleEvent(GetPid());
handler->CancelTask("by_call_timeout_" + std::to_string(recordId_));
handler->CancelTask("by_call_half_timeout_" + std::to_string(recordId_));
}
bool AbilityRecord::CallRequestDone(const sptr<IRemoteObject> &callStub) const
{
CHECK_POINTER_RETURN_BOOL(callContainer_);
CancelStartAbilityByCallTimeoutTask();
if (!callContainer_->CallRequestDone(callStub)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "call failed");
return false;
}
return true;
}
ResolveResultType AbilityRecord::Resolve(const AbilityRequest &abilityRequest)
{
auto callback = abilityRequest.connect;
if (abilityRequest.callType != AbilityCallType::CALL_REQUEST_TYPE || !callback) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "only callType can create call record");
return ResolveResultType::NG_INNER_ERROR;
}
if (!callContainer_) {
callContainer_ = std::make_shared<CallContainer>();
if (!callContainer_) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "mark_shared error");
return ResolveResultType::NG_INNER_ERROR;
}
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "create call record for this resolve. callerUid:%{public}d ,targetname:%{public}s",
abilityRequest.callerUid,
abilityRequest.abilityInfo.name.c_str());
std::shared_ptr<CallRecord> callRecord = callContainer_->GetCallRecord(callback);
if (!callRecord) {
callRecord = CallRecord::CreateCallRecord(
abilityRequest.callerUid, shared_from_this(), callback, abilityRequest.callerToken);
if (!callRecord) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "mark_shared error");
return ResolveResultType::NG_INNER_ERROR;
}
}
callContainer_->AddCallRecord(callback, callRecord);
if (callRecord->IsCallState(CallState::REQUESTED) && callRecord->GetCallStub()) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "this record has requested.");
if (!callRecord->SchedulerConnectDone()) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "this callrecord has requested, but callback failed.");
return ResolveResultType::NG_INNER_ERROR;
}
return ResolveResultType::OK_HAS_REMOTE_OBJ;
}
callRecord->SetCallState(CallState::REQUESTING);
return ResolveResultType::OK_NO_REMOTE_OBJ;
}
bool AbilityRecord::ReleaseCall(const sptr<IAbilityConnection>& connect)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "ability release call record by callback.");
CHECK_POINTER_RETURN_BOOL(callContainer_);
return callContainer_->RemoveCallRecord(connect);
}
bool AbilityRecord::IsExistConnection(const sptr<IAbilityConnection> &connect)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "ability find call record by callback.");
CHECK_POINTER_RETURN_BOOL(callContainer_);
return callContainer_->IsExistConnection(connect);
}
bool AbilityRecord::IsNeedToCallRequest() const
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "ability release call record by callback.");
if (callContainer_ == nullptr) {
return false;
}
return callContainer_->IsNeedToCallRequest();
}
void AbilityRecord::NotifyCallersOnTerminate()
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "Notify callers on terminate: %{public}s",
abilityInfo_.name.c_str());
if (callContainer_ == nullptr) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "callContainer_ is null, no callers to notify");
return;
}
AppExecFwk::ElementName element(abilityInfo_.deviceId, abilityInfo_.bundleName,
abilityInfo_.name, abilityInfo_.moduleName);
callContainer_->NotifyAllCallDisconnect(element);
}
void AbilityRecord::ContinueAbility(const std::string& deviceId, uint32_t versionCode)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "ContinueAbility");
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->ContinueAbility(deviceId, versionCode);
}
void AbilityRecord::SetSwitchingPause(bool state)
{
isSwitchingPause_ = state;
}
bool AbilityRecord::IsSwitchingPause()
{
return isSwitchingPause_;
}
void AbilityRecord::SetOwnerMissionUserId(int32_t userId)
{
ownerMissionUserId_ = userId;
}
int32_t AbilityRecord::GetOwnerMissionUserId()
{
return ownerMissionUserId_;
}
void AbilityRecord::DumpClientInfo(std::vector<std::string> &info, const std::vector<std::string> ¶ms,
bool isClient, bool dumpConfig) const
{
if (!scheduler_ || !isReady_) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "something nullptr.");
return;
}
if (!isClient) {
return;
}
std::unique_lock<ffrt::mutex> lock(dumpLock_);
scheduler_->DumpAbilityInfo(params, info);
TAG_LOGI(AAFwkTag::ABILITYMGR, "dump begin wait");
isDumpTimeout_ = false;
std::chrono::milliseconds timeout { DUMP_TIMEOUT_MULTIPLE };
if (dumpCondition_.wait_for(lock, timeout) == ffrt::cv_status::timeout) {
isDumpTimeout_ = true;
}
TAG_LOGI(AAFwkTag::ABILITYMGR, "dump done and begin parse");
if (!isDumpTimeout_) {
std::lock_guard<ffrt::mutex> infoLock(dumpInfoLock_);
for (auto one : dumpInfos_) {
info.emplace_back(one);
}
}
if (!dumpConfig) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "not dumpConfig");
return;
}
AppExecFwk::Configuration config;
if (DelayedSingleton<AppScheduler>::GetInstance()->GetConfiguration(config) == ERR_OK) {
info.emplace_back(" configuration: " + config.GetName());
}
}
void AbilityRecord::DumpAbilityInfoDone(std::vector<std::string> &infos)
{
TAG_LOGI(AAFwkTag::ABILITYMGR, "call");
if (isDumpTimeout_) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "%{public}s, time out", __func__);
return;
}
{
std::lock_guard<ffrt::mutex> infoLock(dumpInfoLock_);
dumpInfos_.clear();
for (auto info : infos) {
dumpInfos_.emplace_back(info);
}
}
dumpCondition_.notify_all();
}
#ifdef SUPPORT_UPMS
void AbilityRecord::GrantUriPermission(Want &want, std::string targetBundleName, bool isSandboxApp,
uint32_t tokenId, bool isNotifyCollaborator)
{
if (specifyTokenId_ > 0) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "specifyTokenId: %{public}u, cleaned", specifyTokenId_);
tokenId = specifyTokenId_;
specifyTokenId_ = 0;
}
auto caller = GetCallerRecord();
if (caller && AbilityRuntime::GlobalConstant::IsDlpIndex(caller->appIndex_)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "DLP sandbox can not grant UriPermission");
return;
}
auto callerTokenId = tokenId > 0 ? tokenId :
static_cast<uint32_t>(want.GetIntParam(Want::PARAM_RESV_CALLER_TOKEN, 0));
TAG_LOGD(AAFwkTag::ABILITYMGR, "callerTokenId:%{public}u, tokenId:%{public}u", callerTokenId, tokenId);
GrantUriPermissionInfo grantInfo;
grantInfo.callerTokenId = callerTokenId;
grantInfo.collaboratorType = collaboratorType_;
grantInfo.isSandboxApp = isSandboxApp;
grantInfo.appIndex = appIndex_;
grantInfo.targetBundleName = targetBundleName;
grantInfo.userId = GetOwnerMissionUserId();
grantInfo.flag = want.GetFlags();
grantInfo.isNotifyCollaborator = isNotifyCollaborator;
grantInfo.targetUid = uid_;
grantInfo.callerUid = want.GetIntParam(Want::PARAM_RESV_CALLER_UID, IPCSkeleton::GetCallingUid());
if (!isNotifyCollaborator) {
grantInfo.targetAbilityName = abilityInfo_.name;
}
UriUtils::GetInstance().GrantUriPermission(want, grantInfo);
}
void AbilityRecord::GrantUriPermission(const std::vector<std::string> &uriVec, int32_t flag,
const std::string &targetBundleName, uint32_t callerTokenId)
{
if (uriVec.empty() || flag == 0 || targetBundleName.empty()) {
return;
}
UriUtils::GetInstance().GrantUriPermission(uriVec, flag, targetBundleName, appIndex_, callerTokenId);
}
void AbilityRecord::GrantUriPermission()
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
{
std::lock_guard guard(wantLock_);
GrantUriPermission(want_, abilityInfo_.applicationInfo.bundleName, false, 0, false);
}
}
#endif
#ifdef WITH_DLP
void AbilityRecord::HandleDlpAttached()
{
if (abilityInfo_.bundleName == DLP_BUNDLE_NAME) {
DelayedSingleton<ConnectionStateManager>::GetInstance()->AddDlpManager(shared_from_this());
}
if (AbilityRuntime::GlobalConstant::IsDlpIndex(appIndex_)) {
DelayedSingleton<ConnectionStateManager>::GetInstance()->AddDlpAbility(shared_from_this());
}
}
void AbilityRecord::HandleDlpClosed()
{
if (abilityInfo_.bundleName == DLP_BUNDLE_NAME) {
DelayedSingleton<ConnectionStateManager>::GetInstance()->RemoveDlpManager(shared_from_this());
}
if (AbilityRuntime::GlobalConstant::IsDlpIndex(appIndex_)) {
DelayedSingleton<ConnectionStateManager>::GetInstance()->RemoveDlpAbility(shared_from_this());
}
}
#endif
void AbilityRecord::NotifyRemoveShellProcess(int32_t type)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "type is : %{public}d", type);
if (abilityInfo_.bundleName == AppUtils::GetInstance().GetBrokerDelegateBundleName()) {
auto collaborator = DelayedSingleton<AbilityManagerService>::GetInstance()->GetCollaborator(type);
if (collaborator == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null collaborator");
return;
}
int ret = collaborator->NotifyRemoveShellProcess(pid_, SHELL_ASSISTANT_DIETYPE, SHELL_ASSISTANT_DIEREASON);
TAG_LOGI(AAFwkTag::ABILITYMGR, "notify broker params pid: %{public}d", pid_);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "failed, err: %{public}d", ret);
}
}
}
void AbilityRecord::NotifyMissionBindPid()
{
if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
return;
}
auto sessionInfo = GetSessionInfo();
if (sessionInfo == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "null sessionInfo");
return;
}
int32_t persistentId = sessionInfo->persistentId;
if (abilityInfo_.bundleName == AppUtils::GetInstance().GetBrokerDelegateBundleName()) {
auto collaborator = DelayedSingleton<AbilityManagerService>::GetInstance()->GetCollaborator(
CollaboratorType::RESERVE_TYPE);
if (collaborator == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null collaborator");
return;
}
collaborator->NotifyMissionBindPid(persistentId, pid_, GetOwnerMissionUserId());
}
}
int32_t AbilityRecord::GetCurrentAccountId() const
{
std::vector<int32_t> osActiveAccountIds;
ErrCode ret = AppExecFwk::OsAccountManagerWrapper::
QueryActiveOsAccountIds(osActiveAccountIds);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "queryActiveOsAccountIds failed");
return DEFAULT_USER_ID;
}
if (osActiveAccountIds.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "empty QueryActiveOsAccountIds");
return DEFAULT_USER_ID;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "osActiveAccountId: %{public}d", osActiveAccountIds.front());
return osActiveAccountIds.front();
}
void AbilityRecord::SetPendingState(AbilityState state)
{
pendingState_.store(state);
}
AbilityState AbilityRecord::GetPendingState() const
{
return pendingState_.load();
}
int32_t AbilityRecord::GetCollaboratorType() const
{
return collaboratorType_;
}
std::string AbilityRecord::GetMissionAffinity() const
{
return missionAffinity_;
}
void AbilityRecord::SetLockedState(bool lockedState)
{
lockedState_ = lockedState;
}
bool AbilityRecord::GetLockedState()
{
return lockedState_;
}
void AbilityRecord::SetAttachDebug(const bool isAttachDebug)
{
isAttachDebug_ = isAttachDebug;
}
void AbilityRecord::SetAssertDebug(bool isAssertDebug)
{
isAssertDebug_ = isAssertDebug;
}
void AbilityRecord::AddAbilityWindowStateMap(uint64_t uiExtensionComponentId,
AbilityWindowState abilityWindowState)
{
abilityWindowStateMap_[uiExtensionComponentId] = abilityWindowState;
}
void AbilityRecord::RemoveAbilityWindowStateMap(uint64_t uiExtensionComponentId)
{
if (abilityWindowStateMap_.find(uiExtensionComponentId) != abilityWindowStateMap_.end()) {
abilityWindowStateMap_.erase(uiExtensionComponentId);
}
}
bool AbilityRecord::IsAbilityWindowReady()
{
for (auto &item:abilityWindowStateMap_) {
if (item.second == AbilityWindowState::BACKGROUNDING ||
item.second == AbilityWindowState::TERMINATING) {
return false;
}
}
return true;
}
void AbilityRecord::SetAbilityWindowState(const sptr<SessionInfo> &sessionInfo, WindowCommand winCmd, bool isFinished)
{
if (sessionInfo == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "null sessionInfo");
return;
}
if (isFinished) {
if (winCmd == WIN_CMD_FOREGROUND) {
AddAbilityWindowStateMap(sessionInfo->uiExtensionComponentId, AbilityWindowState::FOREGROUND);
} else if (winCmd == WIN_CMD_BACKGROUND) {
AddAbilityWindowStateMap(sessionInfo->uiExtensionComponentId, AbilityWindowState::BACKGROUND);
} else if (winCmd == WIN_CMD_DESTROY) {
RemoveAbilityWindowStateMap(sessionInfo->uiExtensionComponentId);
}
} else {
if (winCmd == WIN_CMD_FOREGROUND) {
AddAbilityWindowStateMap(sessionInfo->uiExtensionComponentId, AbilityWindowState::FOREGROUNDING);
} else if (winCmd == WIN_CMD_BACKGROUND) {
AddAbilityWindowStateMap(sessionInfo->uiExtensionComponentId, AbilityWindowState::BACKGROUNDING);
} else if (winCmd == WIN_CMD_DESTROY) {
AddAbilityWindowStateMap(sessionInfo->uiExtensionComponentId, AbilityWindowState::TERMINATING);
}
}
}
int32_t AbilityRecord::CreateModalUIExtension(const Want &want)
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
CHECK_POINTER_AND_RETURN(scheduler_, INNER_ERR);
return scheduler_->CreateModalUIExtension(want);
}
void AbilityRecord::SetURI(const std::string &uri)
{
uri_ = uri;
}
std::string AbilityRecord::GetURI() const
{
if (uri_.empty()) {
auto bundleName = abilityInfo_.bundleName;
if (MultiInstanceUtils::IsMultiInstanceApp(abilityInfo_.applicationInfo)) {
bundleName = bundleName + '-' + GetInstanceKey();
} else if (AbilityRuntime::StartupUtil::IsSupportAppClone(abilityInfo_.extensionAbilityType)) {
if (appIndex_ > 0) {
bundleName = std::to_string(appIndex_) + bundleName;
}
}
return AppExecFwk::ElementName(abilityInfo_.deviceId, bundleName,
abilityInfo_.name, abilityInfo_.moduleName).GetURI();
}
return uri_;
}
void AbilityRecord::SetProcessName(const std::string &process)
{
abilityInfo_.process = process;
}
std::string AbilityRecord::GetProcessName() const
{
return abilityInfo_.process;
}
void AbilityRecord::SetCustomProcessFlag(const std::string &process)
{
customProcessFlag_ = process;
}
std::string AbilityRecord::GetCustomProcessFlag() const
{
return customProcessFlag_;
}
void AbilityRecord::SetExtensionProcessMode(const uint32_t &extensionProcessMode)
{
extensionProcessMode_ = extensionProcessMode;
}
uint32_t AbilityRecord::GetExtensionProcessMode() const
{
return extensionProcessMode_;
}
void AbilityRecord::SetUIExtensionAbilityId(const int32_t uiExtensionAbilityId)
{
uiExtensionAbilityId_ = uiExtensionAbilityId;
}
int32_t AbilityRecord::GetUIExtensionAbilityId() const
{
return uiExtensionAbilityId_;
}
bool AbilityRecord::BackgroundAbilityWindowDelayed()
{
return backgroundAbilityWindowDelayed_.load();
}
void AbilityRecord::DoBackgroundAbilityWindowDelayed(bool needBackground)
{
backgroundAbilityWindowDelayed_.store(needBackground);
}
bool AbilityRecord::IsSceneBoard() const
{
return AbilityUtil::IsSceneBoard(abilityInfo_.bundleName, abilityInfo_.name);
}
void AbilityRecord::SetRestartAppFlag(bool isRestartApp)
{
isRestartApp_ = isRestartApp;
}
bool AbilityRecord::GetRestartAppFlag() const
{
return isRestartApp_;
}
void AbilityRecord::SetSpecifyTokenId(uint32_t specifyTokenId)
{
specifyTokenId_ = specifyTokenId;
}
void AbilityRecord::SetKillForPermissionUpdateFlag(bool isKillForPermissionUpdate)
{
isKillForPermissionUpdate_ = isKillForPermissionUpdate;
}
bool AbilityRecord::GetKillForPermissionUpdateFlag() const
{
return isKillForPermissionUpdate_;
}
void AbilityRecord::UpdateUIExtensionInfo(const WantParams &wantParams)
{
if (!UIExtensionWrapper::IsUIExtension(GetAbilityInfo().extensionAbilityType)) {
return;
}
std::lock_guard guard(wantLock_);
if (want_.HasParameter(UIEXTENSION_ABILITY_ID)) {
want_.RemoveParam(UIEXTENSION_ABILITY_ID);
}
want_.SetParam(UIEXTENSION_ABILITY_ID, wantParams.GetIntParam(UIEXTENSION_ABILITY_ID, -1));
if (want_.HasParameter(UIEXTENSION_ROOT_HOST_PID)) {
want_.RemoveParam(UIEXTENSION_ROOT_HOST_PID);
}
want_.SetParam(UIEXTENSION_ROOT_HOST_PID, wantParams.GetIntParam(UIEXTENSION_ROOT_HOST_PID, -1));
}
void AbilityRecord::SetDebugAppByWaitingDebugFlag()
{
if (!(abilityInfo_.applicationInfo.debug &&
abilityInfo_.applicationInfo.appProvisionType == APP_PROVISION_TYPE_DEBUG) ||
!system::GetBoolParameter(DEVELOPER_MODE_STATE, false)) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "Not meeting the set debugging conditions.");
return;
}
if (IN_PROCESS_CALL(DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->IsWaitingDebugApp(
abilityInfo_.applicationInfo.bundleName))) {
{
std::lock_guard guard(wantLock_);
want_.SetParam(AbilityConfig::DEBUG_APP, true);
}
launchDebugInfo_.isDebugAppSet = true;
launchDebugInfo_.debugApp = true;
IN_PROCESS_CALL_WITHOUT_RET(
DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->ClearNonPersistWaitingDebugFlag());
}
}
void AbilityRecord::SaveConnectWant(const Want &want)
{
std::lock_guard guard(connectWantLock_);
if (connectWant_ == nullptr) {
connectWant_ = std::make_shared<Want>(want);
}
}
void AbilityRecord::UpdateConnectWant()
{
std::lock_guard guard(connectWantLock_);
if (connectWant_ != nullptr) {
SetWant(*connectWant_);
}
}
void AbilityRecord::RemoveConnectWant()
{
std::lock_guard guard(connectWantLock_);
connectWant_.reset();
}
void AbilityRecord::UpdateDmsCallerInfo(Want &want)
{
if (want.GetIntParam(Want::PARAM_RESV_CALLER_UID, 0) != DMS_UID) {
return;
}
want.SetParam(Want::PARAM_RESV_CALLER_TOKEN, -1);
want.SetParam(Want::PARAM_RESV_CALLER_UID, -1);
want.SetParam(Want::PARAM_RESV_CALLER_PID, -1);
want.SetParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME, want.GetStringParam(DMS_CALLER_BUNDLE_NAME));
want.RemoveParam(DMS_CALLER_BUNDLE_NAME);
want.SetParam(Want::PARAM_RESV_CALLER_ABILITY_NAME, want.GetStringParam(DMS_CALLER_ABILITY_NAME));
want.RemoveParam(DMS_CALLER_ABILITY_NAME);
want.SetParam(Want::PARAM_RESV_CALLER_NATIVE_NAME, want.GetStringParam(DMS_CALLER_NATIVE_NAME));
want.RemoveParam(DMS_CALLER_NATIVE_NAME);
want.SetParam(Want::PARAM_RESV_CALLER_APP_ID, want.GetStringParam(DMS_CALLER_APP_ID));
want.RemoveParam(DMS_CALLER_APP_ID);
want.SetParam(Want::PARAM_RESV_CALLER_APP_IDENTIFIER, want.GetStringParam(DMS_CALLER_APP_IDENTIFIER));
want.RemoveParam(DMS_CALLER_APP_IDENTIFIER);
}
void AbilityRecord::SetDebugUIExtension()
{
if (!UIExtensionWrapper::IsUIExtension(GetAbilityInfo().extensionAbilityType)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "Not UIExtension");
return;
}
std::lock_guard guard(wantLock_);
want_.SetParam(AbilityConfig::DEBUG_APP, true);
launchDebugInfo_.isDebugAppSet = true;
launchDebugInfo_.debugApp = true;
}
void AbilityRecord::SetDebugApp(bool isDebugApp)
{
std::lock_guard guard(wantLock_);
want_.SetParam(AbilityConfig::DEBUG_APP, isDebugApp);
launchDebugInfo_.isDebugAppSet = true;
launchDebugInfo_.debugApp = isDebugApp;
}
void AbilityRecord::NotifyAbilitiesRequestDone(const std::string &requestKey, int32_t resultCode)
{
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->NotifyAbilitiesRequestDone(requestKey, resultCode);
}
void AbilityRecord::UpdateUIExtensionBindInfo(const WantParams &wantParams)
{
if (!UIExtensionWrapper::IsUIExtension(GetAbilityInfo().extensionAbilityType)) {
TAG_LOGE(AAFwkTag::UI_EXT, "abilityType not match");
return;
}
std::lock_guard guard(wantLock_);
if (want_.HasParameter(UIEXTENSION_BIND_ABILITY_ID)) {
want_.RemoveParam(UIEXTENSION_BIND_ABILITY_ID);
}
want_.SetParam(UIEXTENSION_BIND_ABILITY_ID, wantParams.GetIntParam(UIEXTENSION_BIND_ABILITY_ID, -1));
if (want_.HasParameter(UIEXTENSION_NOTIFY_BIND)) {
want_.RemoveParam(UIEXTENSION_NOTIFY_BIND);
}
want_.SetParam(UIEXTENSION_NOTIFY_BIND, wantParams.GetIntParam(UIEXTENSION_NOTIFY_BIND, -1));
if (want_.HasParameter(UIEXTENSION_HOST_PID)) {
want_.RemoveParam(UIEXTENSION_HOST_PID);
}
want_.SetParam(UIEXTENSION_HOST_PID, wantParams.GetIntParam(UIEXTENSION_HOST_PID, -1));
if (want_.HasParameter(UIEXTENSION_HOST_UID)) {
want_.RemoveParam(UIEXTENSION_HOST_UID);
}
want_.SetParam(UIEXTENSION_HOST_UID, wantParams.GetIntParam(UIEXTENSION_HOST_UID, -1));
if (want_.HasParameter(UIEXTENSION_HOST_BUNDLENAME)) {
want_.RemoveParam(UIEXTENSION_HOST_BUNDLENAME);
}
want_.SetParam(UIEXTENSION_HOST_BUNDLENAME, wantParams.GetStringParam(UIEXTENSION_HOST_BUNDLENAME));
}
void AbilityRecord::NotifyAbilityRequestFailure(const std::string &requestId, const AppExecFwk::ElementName &element,
const std::string &message, int32_t resultCode)
{
CHECK_POINTER(lifecycleDeal_);
nlohmann::json jsonObject = nlohmann::json {
{ JSON_KEY_ERR_MSG, message },
};
lifecycleDeal_->NotifyAbilityRequestFailure(requestId, element, jsonObject.dump(), resultCode);
}
void AbilityRecord::NotifyAbilityRequestSuccess(const std::string &requestId, const AppExecFwk::ElementName &element)
{
CHECK_POINTER(lifecycleDeal_);
lifecycleDeal_->NotifyAbilityRequestSuccess(requestId, element);
}
void AbilityRecord::SendAppStartupTypeEvent(const AppExecFwk::AppStartType startType,
const AppExecFwk::AppStartReason startReason)
{
AAFwk::EventInfo eventInfo;
auto abilityInfo = GetAbilityInfo();
eventInfo.abilityName = abilityInfo.name;
auto applicationInfo = GetApplicationInfo();
eventInfo.bundleName = applicationInfo.name;
eventInfo.versionName = applicationInfo.versionName;
eventInfo.versionCode = applicationInfo.versionCode;
eventInfo.pid = static_cast<int32_t>(GetPid());
eventInfo.startType = static_cast<int32_t>(startType);
eventInfo.startReason = static_cast<int32_t>(startReason);
AAFwk::EventReport::SendAppEvent(AAFwk::EventName::APP_STARTUP_TYPE, HISYSEVENT_BEHAVIOR, eventInfo);
}
void AbilityRecord::AddUIExtensionLaunchTimestamp()
{
if (sessionInfo_ == nullptr) {
TAG_LOGW(AAFwkTag::UI_EXT, "null sessionInfo_");
return;
}
if (sessionInfo_->uiExtensionUsage != AAFwk::UIExtensionUsage::MODAL) {
TAG_LOGD(AAFwkTag::UI_EXT, "not modal uiExtension");
return;
}
std::lock_guard guard(wantLock_);
struct timespec ts;
int64_t launchTimestamp = -1;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
launchTimestamp = (ts.tv_sec * 1000LL) + (ts.tv_nsec / 1000000LL);
int32_t high = static_cast<int32_t>(static_cast<uint32_t>(launchTimestamp >> 32));
int32_t low = static_cast<int32_t>(static_cast<uint32_t>(launchTimestamp & 0xFFFFFFFFLL));
want_.SetParam(UIEXTENSION_LAUNCH_TIMESTAMP_HIGH, high);
want_.SetParam(UIEXTENSION_LAUNCH_TIMESTAMP_LOW, low);
} else {
TAG_LOGE(AAFwkTag::UI_EXT, "clock_gettime failed: %{public}s", strerror(errno));
}
}
void AbilityRecord::RemoveUIExtensionLaunchTimestamp()
{
std::lock_guard guard(wantLock_);
want_.RemoveParam(UIEXTENSION_LAUNCH_TIMESTAMP_HIGH);
want_.RemoveParam(UIEXTENSION_LAUNCH_TIMESTAMP_LOW);
}
bool AbilityRecord::ReportAbilityConnectionRelations()
{
auto recordCallerInfo = GetCallerInfo();
CHECK_POINTER_RETURN_BOOL(recordCallerInfo);
auto targetPid = GetPid();
auto targetUid = GetUid();
auto callerPid = recordCallerInfo->callerPid;
auto callerUid = recordCallerInfo->callerUid;
auto callerBundleName = recordCallerInfo->callerBundleName;
auto targetBundleName = GetBundleName();
if (targetPid <= 0 || targetUid <= 0 || callerPid <= 0 || callerUid <= 0) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "Invalid target process: targetPid=%{public}d, targetUid=%{public}d, "
"callerPid=%{public}d, callerUid=%{public}d", targetPid, targetUid, callerPid, callerUid);
return false;
}
TAG_LOGD(AAFwkTag::ABILITYMGR,
"ConnectionInfo: targetPid=%{public}d, targetUid=%{public}d, targetBundleName=%{public}s, "
"callerPid=%{public}d, callerUid=%{public}d, callerBundleName=%{public}s",
targetPid, targetUid, targetBundleName.c_str(), callerPid, callerUid, callerBundleName.c_str());
ForegroundAppConnectionInfo info(callerPid, targetPid, callerUid, targetUid, callerBundleName, targetBundleName);
DelayedSingleton<ForegroundAppConnectionManager>::GetInstance()->AbilityAddPidConnection(info,
GetAbilityRecordId());
return true;
}
void AbilityRecord::ReportAbilityConnectionForResultTerminate()
{
TAG_LOGD(AAFwkTag::ABILITYMGR, "call IsForResultTerminate");
std::vector<int32_t> notifyCallerPids;
int32_t curPid = GetPid();
int32_t curRecordId = GetAbilityRecordId();
{
std::lock_guard guard(callerListLock_);
for (auto caller : callerList_) {
if (caller == nullptr) {
continue;
}
auto requestCodeSet = caller->GetRequestCodeSet();
bool isForResultTerminate = false;
for (auto requestCode : requestCodeSet) {
if (requestCode != DEFAULT_REQUEST_CODE) {
isForResultTerminate = true;
break;
}
}
if (isForResultTerminate) {
auto callerInfo = caller->GetCallerInfo();
if (callerInfo == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "callerInfo is null");
continue;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "found forResult callerPid %{public}d", callerInfo->callerPid);
notifyCallerPids.emplace_back(callerInfo->callerPid);
}
}
}
for (auto pid : notifyCallerPids) {
DelayedSingleton<ForegroundAppConnectionManager>::GetInstance()->AbilityRemovePidConnection(pid,
curPid, curRecordId);
}
}
void AbilityRecord::SetPromotePriority(bool promotePriority)
{
if (!promotePriority) {
uiAbilityProperty_.reset();
return;
}
if (uiAbilityProperty_ == nullptr) {
uiAbilityProperty_ = std::make_shared<UIAbilityProperty>();
}
uiAbilityProperty_->promotePriority = promotePriority;
uiAbilityProperty_->byCallCallerSaUid = IPCSkeleton::GetCallingUid();
uiAbilityProperty_->byCallCallerSaPid = IPCSkeleton::GetCallingPid();
}
bool AbilityRecord::GetPromotePriority()
{
return uiAbilityProperty_ != nullptr && uiAbilityProperty_->promotePriority && GetPid() > 0;
}
bool AbilityRecord::PromotePriority()
{
if (IsStartedByCall() && GetPromotePriority()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "promoting priority: %{public}s", GetAbilityInfo().bundleName.c_str());
ResSchedUtil::GetInstance().PromotePriorityToRSS(uiAbilityProperty_->byCallCallerSaUid,
uiAbilityProperty_->byCallCallerSaPid, GetAbilityInfo().bundleName, GetUid(), GetPid());
return true;
}
return false;
}
void AbilityRecord::AddPluginAbility(std::shared_ptr<AbilityRecord> pluginAbility)
{
if (!pluginAbility) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "pluginAbility is null");
return;
}
std::lock_guard<std::mutex> lock(pluginMutex_);
for (const auto weakPlugin : pluginAbilityList_) {
auto plugin = weakPlugin.lock();
if (plugin == pluginAbility) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "Plugin %{public}s already exists in list",
plugin->GetAbilityInfo().name.c_str());
return;
}
}
pluginAbilityList_.push_back(pluginAbility);
TAG_LOGI(AAFwkTag::ABILITYMGR, "Add plugin: %{public}s to host: %{public}s",
pluginAbility->GetAbilityInfo().name.c_str(), abilityInfo_.name.c_str());
}
void AbilityRecord::RemovePluginAbility(std::shared_ptr<AbilityRecord> pluginAbility)
{
std::lock_guard<std::mutex> lock(pluginMutex_);
for (auto it = pluginAbilityList_.begin(); it != pluginAbilityList_.end(); ++it) {
auto plugin = it->lock();
if (plugin == pluginAbility) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "Remove plugin success");
pluginAbilityList_.erase(it);
break;
}
}
}
std::vector<std::shared_ptr<AbilityRecord>> AbilityRecord::GetPluginAbilities() const
{
std::vector<std::shared_ptr<AbilityRecord>> validPlugins;
std::lock_guard<std::mutex> lock(pluginMutex_);
for (const auto weakPlugin : pluginAbilityList_) {
auto plugin = weakPlugin.lock();
if (plugin && plugin->GetAbilityState() != AbilityState::TERMINATING) {
validPlugins.push_back(plugin);
}
}
return validPlugins;
}
void AbilityRecord::ClearPluginAbilities()
{
std::lock_guard<std::mutex> lock(pluginMutex_);
pluginAbilityList_.clear();
}
void AbilityRecord::InitPluginAbility(const AbilityRequest &abilityRequest)
{
if (!AbilityRuntime::StartupUtil::IsStartPlugin(abilityRequest.want)) {
return;
}
isPluginAbility_ = true;
auto hostAbility = Token::GetAbilityRecordByToken(abilityRequest.callerToken);
if (hostAbility == nullptr) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "Plugin %{public}s: cannot find host by callerToken",
abilityInfo_.name.c_str());
return;
}
hostAbility->AddPluginAbility(shared_from_this());
TAG_LOGI(AAFwkTag::ABILITYMGR, "Plugin initialized: host=%{public}s, plugin=%{public}s",
hostAbility->GetAbilityInfo().name.c_str(), abilityInfo_.name.c_str());
}
void AbilityRecord::PluginCompleteTerminate()
{
if (!IsPluginAbility()) {
return;
}
auto hostAbility = GetCallerRecord();
if (hostAbility) {
hostAbility->RemovePluginAbility(shared_from_this());
TAG_LOGI(AAFwkTag::ABILITYMGR, "Plugin %{public}s removed from host %{public}s",
GetAbilityInfo().name.c_str(),
hostAbility->GetAbilityInfo().name.c_str());
}
}
void AbilityRecord::SetAppRecoveryFlag(int flag)
{
TAG_LOGE(AAFwkTag::ABILITYMGR, "SetAppRecoveryFlag:%{public}d", flag);
appRecoveryFlag_ = flag;
}
int AbilityRecord::GetAppRecoveryFlag() const
{
return appRecoveryFlag_;
}
}
}