From b5bdc4977fe332bf505a7521633077ebfa5993de Mon Sep 17 00:00:00 2001 From: xieqiongyang Date: Thu, 27 Apr 2023 12:03:24 +0000 Subject: [PATCH] closeUIAbilityBySCB Signed-off-by: xieqiongyang Change-Id: Ied88c11227cdac527d09c0d00ecafa8d5c2b1fc0 --- .../ability/native/new_ability_impl.cpp | 5 +- .../include/ability_manager_client.h | 8 ++ .../include/ability_manager_interface.h | 14 +++ .../include/ability_manager_proxy.h | 8 ++ .../include/ability_manager_service.h | 8 ++ .../abilitymgr/include/ability_manager_stub.h | 1 + .../ui_ability_lifecycle_manager.h | 14 ++- .../abilitymgr/src/ability_manager_client.cpp | 13 +++ .../abilitymgr/src/ability_manager_proxy.cpp | 37 ++++++++ .../src/ability_manager_service.cpp | 39 +++++++-- .../abilitymgr/src/ability_manager_stub.cpp | 12 +++ .../ui_ability_lifecycle_manager.cpp | 87 ++++++++++++++++++- services/common/include/event_report.h | 2 + 13 files changed, 239 insertions(+), 9 deletions(-) diff --git a/frameworks/native/ability/native/new_ability_impl.cpp b/frameworks/native/ability/native/new_ability_impl.cpp index 5a50fe4b987..6e148fdb437 100644 --- a/frameworks/native/ability/native/new_ability_impl.cpp +++ b/frameworks/native/ability/native/new_ability_impl.cpp @@ -15,6 +15,7 @@ #include "new_ability_impl.h" #include "hilog_wrapper.h" +#include "scene_board_judgement.h" namespace OHOS { namespace AppExecFwk { @@ -97,9 +98,11 @@ bool NewAbilityImpl::AbilityTransaction(const Want &want, const AAFwk::LifeCycle switch (targetState.state) { case AAFwk::ABILITY_STATE_INITIAL: { #ifdef SUPPORT_GRAPHICS - if (lifecycleState_ == AAFwk::ABILITY_STATE_FOREGROUND_NEW) { + if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled() && + lifecycleState_ == AAFwk::ABILITY_STATE_FOREGROUND_NEW) { Background(); } + #endif bool isAsyncCallback = false; Stop(isAsyncCallback); diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_client.h b/interfaces/inner_api/ability_manager/include/ability_manager_client.h index 9364f9b4518..7f33537e462 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -250,6 +250,14 @@ public: */ ErrCode TerminateUIExtensionAbility(const sptr &extensionSessionInfo, int resultCode = DEFAULT_INVAL_VALUE, const Want *resultWant = nullptr); + + /** + * CloseUIAbilityBySCB, close the special ability by scb. + * + * @param sessionInfo the session info of the ability to terminate. + * @return Returns ERR_OK on success, others on failure. + */ + ErrCode CloseUIAbilityBySCB(const sptr &sessionInfo); /** * SendResultToAbility with want, return resultWant from ability manager service. diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h index d001229fb79..fa8546bf150 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h @@ -270,6 +270,17 @@ public: return 0; } + /** + * CloseUIAbilityBySCB, close the special ability by scb. + * + * @param sessionInfo the session info of the ability to terminate. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int CloseUIAbilityBySCB(const sptr &sessionInfo) + { + return 0; + } + /** * SendResultToAbility, send the result to ability. * @@ -1176,6 +1187,9 @@ public: // ipc id for minimize ui ability by scb MINIMIZE_UI_ABILITY_BY_SCB, + // ipc id for close ui ability by scb + CLOSE_UI_ABILITY_BY_SCB, + // ipc id for continue ability(1101) START_CONTINUATION = 1101, diff --git a/services/abilitymgr/include/ability_manager_proxy.h b/services/abilitymgr/include/ability_manager_proxy.h index 4321392a445..3fbf75b098d 100644 --- a/services/abilitymgr/include/ability_manager_proxy.h +++ b/services/abilitymgr/include/ability_manager_proxy.h @@ -204,6 +204,14 @@ public: virtual int TerminateUIExtensionAbility(const sptr &extensionSessionInfo, int resultCode, const Want *resultWant) override; + /** + * CloseUIAbilityBySCB, close the special ability by scb. + * + * @param sessionInfo the session info of the ability to terminate. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int CloseUIAbilityBySCB(const sptr &sessionInfo) override; + /** * SendResultToAbility with want, return want from ability manager service.(Only used for dms) * diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index d9e9f3b2eaa..d60826e0cb5 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -254,6 +254,14 @@ public: virtual int TerminateUIExtensionAbility(const sptr &extensionSessionInfo, int resultCode = DEFAULT_INVAL_VALUE, const Want *resultWant = nullptr) override; + /** + * CloseUIAbilityBySCB, close the special ability by scb. + * + * @param sessionInfo the session info of the ability to terminate. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int CloseUIAbilityBySCB(const sptr &sessionInfo) override; + /** * SendResultToAbility with want, return want from ability manager service. * diff --git a/services/abilitymgr/include/ability_manager_stub.h b/services/abilitymgr/include/ability_manager_stub.h index b40c167c592..e5690fbde42 100644 --- a/services/abilitymgr/include/ability_manager_stub.h +++ b/services/abilitymgr/include/ability_manager_stub.h @@ -68,6 +68,7 @@ private: void ThirdStepInit(); int TerminateAbilityInner(MessageParcel &data, MessageParcel &reply); int TerminateUIExtensionAbilityInner(MessageParcel &data, MessageParcel &reply); + int CloseUIAbilityBySCBInner(MessageParcel &data, MessageParcel &reply); int SendResultToAbilityInner(MessageParcel &data, MessageParcel &reply); int TerminateAbilityByCallerInner(MessageParcel &data, MessageParcel &reply); int MinimizeAbilityInner(MessageParcel &data, MessageParcel &reply); diff --git a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h index c44aac8ab1e..b47328b5733 100644 --- a/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h +++ b/services/abilitymgr/include/scene_board/ui_ability_lifecycle_manager.h @@ -73,7 +73,7 @@ public: bool IsContainsAbility(const sptr &token) const; /** - * MinimizeUIAbility, minimize the special ability by board. + * MinimizeUIAbility, minimize the special ability by scb. * * @param abilityRecord, the ability to minimize. * @return Returns ERR_OK on success, others on failure. @@ -87,6 +87,14 @@ public: * @return Returns AbilityRecord shared_ptr. */ std::shared_ptr GetUIAbilityRecordBySessionInfo(const sptr &sessionInfo); + + /** + * CloseUIAbility, close the special ability by scb. + * + * @param abilityRecord, the ability to close. + * @return Returns ERR_OK on success, others on failure. + */ + int CloseUIAbility(const std::shared_ptr &abilityRecord); private: std::shared_ptr GetAbilityRecordByToken(const sptr &token) const; void UpdateAbilityRecordLaunchReason(const AbilityRequest &abilityRequest, @@ -106,9 +114,11 @@ private: void MoveToBackground(const std::shared_ptr &abilityRecord); void CompleteBackground(const std::shared_ptr &abilityRecord); void PrintTimeOutLog(const std::shared_ptr &ability, uint32_t msgId); - + void DelayCompleteTerminate(const std::shared_ptr &abilityRecord); + void CompleteTerminate(const std::shared_ptr &abilityRecord); mutable std::recursive_mutex sessionLock_; std::map> sessionAbilityMap_; + std::list> terminateAbilityList_; }; } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index 0735d4c9bfe..fa7e22d080e 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -261,6 +261,19 @@ ErrCode AbilityManagerClient::CloseAbility(const sptr &token, int return abms->CloseAbility(token, resultCode, resultWant); } +ErrCode AbilityManagerClient::CloseUIAbilityBySCB(const sptr &sessionInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (sessionInfo == nullptr) { + HILOG_ERROR("failed, sessionInfo is nullptr"); + return ERR_INVALID_VALUE; + } + auto abms = GetAbilityManager(); + CHECK_POINTER_RETURN_NOT_CONNECTED(abms); + HILOG_DEBUG("call"); + return abms->CloseUIAbilityBySCB(sessionInfo); +} + ErrCode AbilityManagerClient::MinimizeAbility(const sptr &token, bool fromUser) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); diff --git a/services/abilitymgr/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index ba4800660d1..d70a9f546c6 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -625,6 +625,43 @@ int AbilityManagerProxy::TerminateUIExtensionAbility(const sptr &ex return reply.ReadInt32(); } +int AbilityManagerProxy::CloseUIAbilityBySCB(const sptr &sessionInfo) +{ + int error; + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!WriteInterfaceToken(data)) { + return INNER_ERR; + } + + if (sessionInfo) { + if (!data.WriteBool(true) || !data.WriteParcelable(sessionInfo)) { + HILOG_ERROR("flag and sessionInfo write failed."); + return INNER_ERR; + } + } else { + if (!data.WriteBool(false)) { + HILOG_ERROR("flag write failed."); + return INNER_ERR; + } + } + + sptr remote = Remote(); + if (remote == nullptr) { + HILOG_ERROR("failed, Remote() is NULL"); + return INNER_ERR; + } + + error = remote->SendRequest(IAbilityManager::CLOSE_UI_ABILITY_BY_SCB, data, reply, option); + if (error != NO_ERROR) { + HILOG_ERROR("failed, Send request error: %{public}d", error); + return error; + } + return reply.ReadInt32(); +} + int AbilityManagerProxy::SendResultToAbility(int32_t requestCode, int32_t resultCode, Want& resultWant) { int error; diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 8df6c232b4d..327550be3d6 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -1583,6 +1583,40 @@ int AbilityManagerService::TerminateUIExtensionAbility(const sptr & return eventInfo.errCode; } +int AbilityManagerService::CloseUIAbilityBySCB(const sptr &sessionInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + HILOG_DEBUG("call"); + if (sessionInfo == nullptr || sessionInfo->sessionToken == nullptr) { + HILOG_ERROR("sessionInfo is nullptr"); + return ERR_INVALID_VALUE; + } + + if (!CheckCallingTokenId(BUNDLE_NAME_SCENEBOARD, U0_USER_ID)) { + HILOG_ERROR("Not sceneboard called, not allowed."); + return ERR_WRONG_INTERFACE_CALL; + } + + if (!uiAbilityLifecycleManager_) { + HILOG_ERROR("failed, uiAbilityLifecycleManager is nullptr"); + return ERR_INVALID_VALUE; + } + auto abilityRecord = uiAbilityLifecycleManager_->GetUIAbilityRecordBySessionInfo(sessionInfo); + CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE); + if (!IsAbilityControllerForeground(abilityRecord->GetAbilityInfo().bundleName)) { + return ERR_WOULD_BLOCK; + } + EventInfo eventInfo; + eventInfo.bundleName = abilityRecord->GetAbilityInfo().bundleName; + eventInfo.abilityName = abilityRecord->GetAbilityInfo().name; + EventReport::SendAbilityEvent(EventName::CLOSE_UI_ABILITY_BY_SCB, HiSysEventType::BEHAVIOR, eventInfo); + eventInfo.errCode = uiAbilityLifecycleManager_->CloseUIAbility(abilityRecord); + if (eventInfo.errCode != ERR_OK) { + EventReport::SendAbilityEvent(EventName::CLOSE_UI_ABILITY_BY_SCB_ERROR, HiSysEventType::FAULT, eventInfo); + } + return eventInfo.errCode; +} + int AbilityManagerService::SendResultToAbility(int32_t requestCode, int32_t resultCode, Want &resultWant) { HILOG_INFO("%{public}s", __func__); @@ -1865,11 +1899,6 @@ int AbilityManagerService::MinimizeUIAbilityBySCB(const sptr &sessi } auto abilityRecord = uiAbilityLifecycleManager_->GetUIAbilityRecordBySessionInfo(sessionInfo); CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE); - auto type = abilityRecord->GetAbilityInfo().type; - if (type != AppExecFwk::AbilityType::PAGE) { - HILOG_ERROR("failed, cannot minimize except page ability"); - return ERR_WRONG_INTERFACE_CALL; - } if (!IsAbilityControllerForeground(abilityRecord->GetAbilityInfo().bundleName)) { return ERR_WOULD_BLOCK; } diff --git a/services/abilitymgr/src/ability_manager_stub.cpp b/services/abilitymgr/src/ability_manager_stub.cpp index 9ff7fb9af76..fbe4e3b89de 100644 --- a/services/abilitymgr/src/ability_manager_stub.cpp +++ b/services/abilitymgr/src/ability_manager_stub.cpp @@ -84,6 +84,7 @@ void AbilityManagerStub::FirstStepInit() requestFuncMap_[ABILITY_RECOVERY] = &AbilityManagerStub::ScheduleRecoverAbilityInner; requestFuncMap_[ABILITY_RECOVERY_ENABLE] = &AbilityManagerStub::EnableRecoverAbilityInner; requestFuncMap_[MINIMIZE_UI_ABILITY_BY_SCB] = &AbilityManagerStub::MinimizeUIAbilityBySCBInner; + requestFuncMap_[CLOSE_UI_ABILITY_BY_SCB] = &AbilityManagerStub::CloseUIAbilityBySCBInner; } void AbilityManagerStub::SecondStepInit() @@ -758,6 +759,17 @@ int AbilityManagerStub::StartAbilityForOptionsInner(MessageParcel &data, Message return NO_ERROR; } +int AbilityManagerStub::CloseUIAbilityBySCBInner(MessageParcel &data, MessageParcel &reply) +{ + sptr sessionInfo = nullptr; + if (data.ReadBool()) { + sessionInfo = data.ReadParcelable(); + } + int32_t result = CloseUIAbilityBySCB(sessionInfo); + reply.WriteInt32(result); + return NO_ERROR; +} + int AbilityManagerStub::GetWantSenderInner(MessageParcel &data, MessageParcel &reply) { std::unique_ptr wantSenderInfo(data.ReadParcelable()); diff --git a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp index d03b30b7101..1aeacdd2e6e 100644 --- a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp +++ b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp @@ -30,6 +30,11 @@ constexpr char EVENT_KEY_PID[] = "PID"; constexpr char EVENT_KEY_MESSAGE[] = "MSG"; constexpr char EVENT_KEY_PACKAGE_NAME[] = "PACKAGE_NAME"; constexpr char EVENT_KEY_PROCESS_NAME[] = "PROCESS_NAME"; +#ifdef SUPPORT_ASAN +const int KILL_TIMEOUT_MULTIPLE = 45; +#else +const int KILL_TIMEOUT_MULTIPLE = 3; +#endif } int UIAbilityLifecycleManager::StartUIAbility(AbilityRequest &abilityRequest, sptr sessionInfo) { @@ -238,7 +243,21 @@ int UIAbilityLifecycleManager::DispatchBackground(const std::shared_ptr &abilityRecord) { - return 0; + CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE); + if (abilityRecord->GetAbilityState() != AbilityState::TERMINATING) { + HILOG_ERROR("DispatchTerminate error, ability state is %{public}d", abilityRecord->GetAbilityState()); + return INNER_ERR; + } + + // remove terminate timeout task. + auto handler = DelayedSingleton::GetInstance()->GetEventHandler(); + CHECK_POINTER_AND_RETURN_LOG(handler, ERR_INVALID_VALUE, "Fail to get AbilityEventHandler."); + handler->RemoveTask("terminate_" + std::to_string(abilityRecord->GetAbilityRecordId())); + auto self(shared_from_this()); + auto task = [self, abilityRecord]() { self->CompleteTerminate(abilityRecord); }; + handler->PostTask(task); + + return ERR_OK; } void UIAbilityLifecycleManager::CompleteForegroundSuccess(const std::shared_ptr &abilityRecord) @@ -335,6 +354,12 @@ std::shared_ptr UIAbilityLifecycleManager::GetAbilityRecordByToke } std::lock_guard guard(sessionLock_); + for (auto ability : terminateAbilityList_) { + if (ability && token == ability->GetToken()->AsObject()) { + return ability; + } + } + for (auto iter = sessionAbilityMap_.begin(); iter != sessionAbilityMap_.end(); iter++) { if (iter->second != nullptr && iter->second->GetToken()->AsObject() == token) { return iter->second; @@ -522,5 +547,65 @@ void UIAbilityLifecycleManager::CompleteBackground(const std::shared_ptr &abilityRecord) +{ + HILOG_DEBUG("call"); + std::lock_guard guard(sessionLock_); + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE); + std::string element = abilityRecord->GetWant().GetElement().GetURI(); + HILOG_INFO("call, from ability: %{public}s", element.c_str()); + if (abilityRecord->IsTerminating() && !abilityRecord->IsForeground()) { + HILOG_INFO("ability is on terminating"); + return ERR_OK; + } + terminateAbilityList_.push_back(abilityRecord); + EraseAbilityRecord(abilityRecord); + abilityRecord->SetTerminatingState(); + + auto self(shared_from_this()); + auto task = [abilityRecord, self]() { + HILOG_WARN("close ability by scb timeout"); + self->DelayCompleteTerminate(abilityRecord); + }; + abilityRecord->Terminate(task); + return ERR_OK; +} + +void UIAbilityLifecycleManager::DelayCompleteTerminate(const std::shared_ptr &abilityRecord) +{ + auto handler = DelayedSingleton::GetInstance()->GetEventHandler(); + CHECK_POINTER(handler); + + PrintTimeOutLog(abilityRecord, AbilityManagerService::TERMINATE_TIMEOUT_MSG); + + auto timeoutTask = [self = shared_from_this(), abilityRecord]() { + HILOG_INFO("emit delay complete terminate task."); + self->CompleteTerminate(abilityRecord); + }; + int killTimeout = AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * KILL_TIMEOUT_MULTIPLE; + handler->PostTask(timeoutTask, "DELAY_KILL_PROCESS", killTimeout); +} + +void UIAbilityLifecycleManager::CompleteTerminate(const std::shared_ptr &abilityRecord) +{ + CHECK_POINTER(abilityRecord); + std::lock_guard guard(sessionLock_); + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + + if (abilityRecord->GetAbilityState() != AbilityState::TERMINATING) { + HILOG_ERROR("failed, %{public}s, ability is not terminating.", __func__); + return; + } + abilityRecord->RemoveAbilityDeathRecipient(); + + // notify AppMS terminate + if (abilityRecord->TerminateAbility() != ERR_OK) { + // Don't return here + HILOG_ERROR("AppMS fail to terminate ability."); + } + terminateAbilityList_.remove(abilityRecord); +} + } // namespace AAFwk } // namespace OHOS \ No newline at end of file diff --git a/services/common/include/event_report.h b/services/common/include/event_report.h index dc4790e5617..1d096f5eb42 100644 --- a/services/common/include/event_report.h +++ b/services/common/include/event_report.h @@ -53,11 +53,13 @@ enum class EventName { STOP_EXTENSION_ERROR, CONNECT_SERVICE_ERROR, DISCONNECT_SERVICE_ERROR, + CLOSE_UI_ABILITY_BY_SCB_ERROR, // ability behavior event START_ABILITY, TERMINATE_ABILITY, CLOSE_ABILITY, + CLOSE_UI_ABILITY_BY_SCB, ABILITY_ONFOREGROUND, ABILITY_ONBACKGROUND, ABILITY_ONACTIVE, -- Gitee