diff --git a/frameworks/native/ability/native/extension_impl.cpp b/frameworks/native/ability/native/extension_impl.cpp index e4fd47f0b9e27e67d6439311c99256cf7e7fc3c1..2fb558fd5418f3c8c60c001e6ed88e9c3541c54b 100644 --- a/frameworks/native/ability/native/extension_impl.cpp +++ b/frameworks/native/ability/native/extension_impl.cpp @@ -79,7 +79,7 @@ void ExtensionImpl::HandleExtensionTransaction(const Want &want, const AAFwk::Li case AAFwk::ABILITY_STATE_INITIAL: { bool isAsyncCallback = false; if (lifecycleState_ != AAFwk::ABILITY_STATE_INITIAL) { - Stop(isAsyncCallback); + Stop(isAsyncCallback, want, sessionInfo); } if (isAsyncCallback) { ret = false; @@ -100,7 +100,7 @@ void ExtensionImpl::HandleExtensionTransaction(const Want &want, const AAFwk::Li break; } case AAFwk::ABILITY_STATE_BACKGROUND_NEW: { - Background(); + Background(want, sessionInfo); break; } default: { @@ -192,7 +192,7 @@ void ExtensionImpl::Stop() HILOG_INFO("ok"); } -void ExtensionImpl::Stop(bool &isAsyncCallback) +void ExtensionImpl::Stop(bool &isAsyncCallback, const Want &want, sptr sessionInfo) { HILOG_INFO("call"); if (extension_ == nullptr) { @@ -201,6 +201,10 @@ void ExtensionImpl::Stop(bool &isAsyncCallback) return; } + if (AAFwk::UIExtensionUtils::IsUIExtension(extensionType_) && sessionInfo != nullptr) { + CommandExtensionWindow(want, sessionInfo, AAFwk::WIN_CMD_DESTROY); + } + auto *callbackInfo = AppExecFwk::AbilityTransactionCallbackInfo<>::Create(); if (callbackInfo == nullptr) { extension_->OnStop(); @@ -412,7 +416,8 @@ bool ExtensionImpl::HandleInsightIntent(const Want &want) void ExtensionImpl::CommandExtensionWindow(const Want &want, const sptr &sessionInfo, AAFwk::WindowCommand winCmd) { - HILOG_INFO("call"); + HILOG_INFO("persistentId: %{private}d, componentId: %{public}" PRId64 ", winCmd: %{public}d", + sessionInfo->persistentId, sessionInfo->uiExtensionComponentId, winCmd); if (extension_ == nullptr) { HILOG_ERROR("extension_ is nullptr"); return; @@ -446,13 +451,18 @@ void ExtensionImpl::Foreground(const Want &want, sptr sessio lifecycleState_ = AAFwk::ABILITY_STATE_FOREGROUND_NEW; } -void ExtensionImpl::Background() +void ExtensionImpl::Background(const Want &want, sptr sessionInfo) { HILOG_DEBUG("ExtensionImpl::Background begin"); if (extension_ == nullptr) { HILOG_ERROR("ExtensionImpl::Background ability is nullptr"); return; } + + if (AAFwk::UIExtensionUtils::IsUIExtension(extensionType_) && sessionInfo != nullptr) { + CommandExtensionWindow(want, sessionInfo, AAFwk::WIN_CMD_BACKGROUND); + } + extension_->OnBackground(); lifecycleState_ = AAFwk::ABILITY_STATE_BACKGROUND_NEW; } diff --git a/interfaces/kits/native/ability/native/extension_impl.h b/interfaces/kits/native/ability/native/extension_impl.h index 25cac3b129e7534a1b973fd51af4019792d21b32..309399e30e2ae2dc55f3c2eb83e7fe71ce9ee6d3 100644 --- a/interfaces/kits/native/ability/native/extension_impl.h +++ b/interfaces/kits/native/ability/native/extension_impl.h @@ -173,8 +173,10 @@ protected: * @brief Toggles the lifecycle status of Extension to AAFwk::ABILITY_STATE_INITIAL. And notifies the application * that it belongs to of the lifecycle status. * @param isAsyncCallback Indicates whether it is an asynchronous lifecycle callback + * @param want Indicates want. + * @param sessionInfo Indicates the sessionInfo, nullptr when not uiextension. */ - void Stop(bool &isAsyncCallback); + void Stop(bool &isAsyncCallback, const Want &want, sptr sessionInfo); void AbilityTransactionCallback(const AAFwk::AbilityLifeCycleState &state); /** @@ -188,9 +190,10 @@ protected: /** * @brief Toggles the lifecycle status of Extension to AAFwk::ABILITY_STATE_BACKGROUND. And notifies the * application that it belongs to of the lifecycle status. - * + * @param want Indicates want. + * @param sessionInfo Indicates the sessionInfo, nullptr when not uiextension. */ - void Background(); + void Background(const Want &want, sptr sessionInfo); private: inline bool UIExtensionAbilityExecuteInsightIntent(const Want &want); diff --git a/services/abilitymgr/include/ability_connect_manager.h b/services/abilitymgr/include/ability_connect_manager.h index 55f9d78008692e558da7e199ac78005ad3c9356e..e60fae11a7e220d1d0dab0799d85df49f8fa5be0 100644 --- a/services/abilitymgr/include/ability_connect_manager.h +++ b/services/abilitymgr/include/ability_connect_manager.h @@ -469,6 +469,7 @@ private: void SaveUIExtRequestSessionInfo(std::shared_ptr abilityRecord, sptr sessionInfo); void DoBackgroundAbilityWindow(const std::shared_ptr &abilityRecord, const sptr &sessionInfo); + void DoTerminateUIExtensionAbility(std::shared_ptr abilityRecord, sptr sessionInfo); /** * When a service is under starting, enque the request and handle it after the service starting completes diff --git a/services/abilitymgr/include/lifecycle_deal.h b/services/abilitymgr/include/lifecycle_deal.h index d2b860d47b386e5ba20e67c79ccc3360bfd4af75..b9e4077fcc3c29ba4f8cf318a31300bd9373f25b 100644 --- a/services/abilitymgr/include/lifecycle_deal.h +++ b/services/abilitymgr/include/lifecycle_deal.h @@ -50,7 +50,7 @@ public: void MoveToBackground(const Want &want, LifeCycleStateInfo &stateInfo); void ConnectAbility(const Want &want); void DisconnectAbility(const Want &want); - void Terminate(const Want &want, LifeCycleStateInfo &stateInfo); + void Terminate(const Want &want, LifeCycleStateInfo &stateInfo, sptr sessionInfo = nullptr); void CommandAbility(const Want &want, bool reStart, int startId); void CommandAbilityWindow(const Want &want, const sptr &sessionInfo, WindowCommand winCmd); void SaveAbilityState(); diff --git a/services/abilitymgr/src/ability_connect_manager.cpp b/services/abilitymgr/src/ability_connect_manager.cpp index ff4edc0f4117fff9346f01fb48b4f99e505aabf3..6eff223c566adf4c3883ab8364995645a1f901a4 100644 --- a/services/abilitymgr/src/ability_connect_manager.cpp +++ b/services/abilitymgr/src/ability_connect_manager.cpp @@ -200,6 +200,8 @@ void AbilityConnectManager::DoForegroundUIExtension(std::shared_ptrGetURI().c_str(), + abilityRequest.sessionInfo->persistentId); if (abilityRecord->IsReady() && !abilityRecord->IsAbilityState(AbilityState::INACTIVATING) && !abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING) && !abilityRecord->IsAbilityState(AbilityState::BACKGROUNDING) && @@ -890,7 +892,8 @@ int AbilityConnectManager::ScheduleCommandAbilityWindowDone( HILOG_DEBUG("Ability: %{public}s, persistentId: %{private}d, winCmd: %{public}d, abilityCmd: %{public}d", element.c_str(), sessionInfo->persistentId, winCmd, abilityCmd); - if (taskHandler_) { + // Only foreground mode need cancel, cause only foreground CommandAbilityWindow post timeout task. + if (taskHandler_ && winCmd == WIN_CMD_FOREGROUND) { int recordId = abilityRecord->GetRecordId(); std::string taskName = std::string("CommandWindowTimeout_") + std::to_string(recordId) + std::string("_") + std::to_string(sessionInfo->persistentId) + std::string("_") + std::to_string(winCmd); @@ -901,31 +904,6 @@ int AbilityConnectManager::ScheduleCommandAbilityWindowDone( HandleCommandDestroy(sessionInfo); } - switch (abilityCmd) { - case ABILITY_CMD_BACKGROUND: { - if (abilityRecord->IsAbilityState(AbilityState::INACTIVE) || - abilityRecord->IsAbilityState(AbilityState::ACTIVE) || - abilityRecord->IsAbilityState(AbilityState::FOREGROUND) || - abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) { - MoveToBackground(abilityRecord); - } - break; - } - case ABILITY_CMD_DESTROY: { - EventInfo eventInfo; - eventInfo.bundleName = abilityRecord->GetAbilityInfo().bundleName; - eventInfo.abilityName = abilityRecord->GetAbilityInfo().name; - EventReport::SendAbilityEvent(EventName::TERMINATE_ABILITY, HiSysEventType::BEHAVIOR, eventInfo); - eventInfo.errCode = TerminateAbilityInner(token); - if (eventInfo.errCode != ERR_OK) { - EventReport::SendAbilityEvent(EventName::TERMINATE_ABILITY_ERROR, HiSysEventType::FAULT, eventInfo); - } - break; - } - default: - HILOG_WARN("not supported ability cmd"); - break;; - } abilityRecord->SetAbilityWindowState(sessionInfo, winCmd, true); CompleteStartServiceReq(element); @@ -990,7 +968,7 @@ void AbilityConnectManager::CompleteStartServiceReq(const std::string &serviceUr } if (reqList) { - HILOG_INFO("Target service is already activating : %{public}zu", reqList->size()); + HILOG_INFO("Target service is activating : %{public}zu, uri: %{public}s", reqList->size(), serviceUri.c_str()); for (const auto &req: *reqList) { StartAbilityLocked(req); } @@ -1454,7 +1432,7 @@ void AbilityConnectManager::CommandAbilityWindow(const std::shared_ptrGetAbilityInfo().name.c_str(), sessionInfo->persistentId, winCmd); + abilityRecord->GetURI().c_str(), sessionInfo->persistentId, winCmd); abilityRecord->SetAbilityWindowState(sessionInfo, winCmd, false); if (taskHandler_ != nullptr) { int recordId = abilityRecord->GetRecordId(); @@ -1508,6 +1486,8 @@ void AbilityConnectManager::DoBackgroundAbilityWindow(const std::shared_ptrGetURI().c_str(), + sessionInfo->persistentId); std::vector metaData = abilityRecord->GetAbilityInfo().metadata; bool isSingleton = std::any_of(metaData.begin(), metaData.end(), [](const auto &metaDataItem) { @@ -1516,7 +1496,7 @@ void AbilityConnectManager::DoBackgroundAbilityWindow(const std::shared_ptrIsAbilityState(AbilityState::FOREGROUND) || isSingleton) { - CommandAbilityWindow(abilityRecord, sessionInfo, WIN_CMD_BACKGROUND); + MoveToBackground(abilityRecord); } else if (abilityRecord->IsAbilityState(AbilityState::INITIAL) || abilityRecord->IsAbilityState(AbilityState::FOREGROUNDING)) { HILOG_INFO("There exist initial or foregrounding task."); @@ -1538,7 +1518,26 @@ void AbilityConnectManager::TerminateAbilityWindowLocked(const std::shared_ptr abilityRecord, + sptr sessionInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + CHECK_POINTER(abilityRecord); + CHECK_POINTER(sessionInfo); + HILOG_INFO("Terminate ability: %{public}s, persistentId: %{private}d", abilityRecord->GetURI().c_str(), + sessionInfo->persistentId); + + EventInfo eventInfo; + eventInfo.bundleName = abilityRecord->GetAbilityInfo().bundleName; + eventInfo.abilityName = abilityRecord->GetAbilityInfo().name; + EventReport::SendAbilityEvent(EventName::TERMINATE_ABILITY, HiSysEventType::BEHAVIOR, eventInfo); + eventInfo.errCode = TerminateAbilityInner(abilityRecord->GetToken()); + if (eventInfo.errCode != ERR_OK) { + EventReport::SendAbilityEvent(EventName::TERMINATE_ABILITY_ERROR, HiSysEventType::FAULT, eventInfo); + } } void AbilityConnectManager::TerminateDone(const std::shared_ptr &abilityRecord) @@ -2373,7 +2372,7 @@ void AbilityConnectManager::HandleUIExtWindowDiedTask(const sptr if (it != uiExtensionMap_.end()) { auto abilityRecord = it->second.first.lock(); if (abilityRecord) { - CommandAbilityWindow(abilityRecord, it->second.second, WIN_CMD_DESTROY); + DoTerminateUIExtensionAbility(abilityRecord, it->second.second); } else { HILOG_INFO("abilityRecord is nullptr"); } diff --git a/services/abilitymgr/src/ability_record.cpp b/services/abilitymgr/src/ability_record.cpp index c4ddc284ddb99589d143b1edd53990bcd98e8a7c..9a37aea0a8f0f55b9b6eb1ce891681d403acfb7b 100644 --- a/services/abilitymgr/src/ability_record.cpp +++ b/services/abilitymgr/src/ability_record.cpp @@ -441,7 +441,7 @@ void AbilityRecord::ForegroundAbility(uint32_t sceneFlag) void AbilityRecord::ForegroundAbility(const Closure &task, sptr sessionInfo, uint32_t sceneFlag) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - HILOG_INFO("name:%{public}s.", abilityInfo_.name.c_str()); + HILOG_INFO("ability: %{public}s.", GetURI().c_str()); CHECK_POINTER(lifecycleDeal_); // grant uri permission { @@ -1163,8 +1163,7 @@ bool AbilityRecord::IsCompleteFirstFrameDrawing() const void AbilityRecord::BackgroundAbility(const Closure &task) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - HILOG_INFO("BackgroundLifecycle: begin, bundle: %{public}s, ability: %{public}s.", abilityInfo_.bundleName.c_str(), - abilityInfo_.name.c_str()); + HILOG_INFO("BackgroundLifecycle: ability: %{public}s.", GetURI().c_str()); if (lifecycleDeal_ == nullptr) { HILOG_ERROR("Move the ability to background fail, lifecycleDeal_ is null."); return; @@ -1491,7 +1490,7 @@ void AbilityRecord::Inactivate() void AbilityRecord::Terminate(const Closure &task) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - HILOG_INFO("ability:%{public}s.", abilityInfo_.name.c_str()); + HILOG_INFO("ability: %{public}s.", GetURI().c_str()); CHECK_POINTER(lifecycleDeal_); if (!IsDebug()) { auto handler = DelayedSingleton::GetInstance()->GetTaskHandler(); @@ -1512,7 +1511,7 @@ void AbilityRecord::Terminate(const Closure &task) // schedule background after updating AbilityState and sending timeout message to avoid ability async callback // earlier than above actions. SetAbilityStateInner(AbilityState::TERMINATING); - lifecycleDeal_->Terminate(GetWant(), lifeCycleStateInfo_); + lifecycleDeal_->Terminate(GetWant(), lifeCycleStateInfo_, GetSessionInfo()); } void AbilityRecord::ShareData(const int32_t &uniqueId) diff --git a/services/abilitymgr/src/lifecycle_deal.cpp b/services/abilitymgr/src/lifecycle_deal.cpp index 8bf008b63bbdb9e26ed3d4f5a200aaedf9b63427..a3f096b7b767f57caca60862760ee762541f4a50 100644 --- a/services/abilitymgr/src/lifecycle_deal.cpp +++ b/services/abilitymgr/src/lifecycle_deal.cpp @@ -86,13 +86,13 @@ void LifecycleDeal::DisconnectAbility(const Want &want) abilityScheduler->ScheduleDisconnectAbility(want); } -void LifecycleDeal::Terminate(const Want &want, LifeCycleStateInfo &stateInfo) +void LifecycleDeal::Terminate(const Want &want, LifeCycleStateInfo &stateInfo, sptr sessionInfo) { HILOG_INFO("call"); auto abilityScheduler = GetScheduler(); CHECK_POINTER(abilityScheduler); stateInfo.state = AbilityLifeCycleState::ABILITY_STATE_INITIAL; - abilityScheduler->ScheduleAbilityTransaction(want, stateInfo); + abilityScheduler->ScheduleAbilityTransaction(want, stateInfo, sessionInfo); } void LifecycleDeal::CommandAbility(const Want &want, bool reStart, int startId) diff --git a/test/moduletest/ui_extension_ability_test/ui_extension_stability_test/ui_extension_stability_test.cpp b/test/moduletest/ui_extension_ability_test/ui_extension_stability_test/ui_extension_stability_test.cpp index 3a6f0624fc927851ed0cbfdf6cf86f4115ac3c6f..68f14563633ae0ed61403480a3cf8a659e67cd3b 100644 --- a/test/moduletest/ui_extension_ability_test/ui_extension_stability_test/ui_extension_stability_test.cpp +++ b/test/moduletest/ui_extension_ability_test/ui_extension_stability_test/ui_extension_stability_test.cpp @@ -207,6 +207,39 @@ void UIExtensionStabilityTest::WaitUntilAbilityBackground( EXPECT_EQ(observer->processBackgrounded_, true); } +/** + * @tc.name: TerminateUIExtensionAbility_0100 + * @tc.desc: basic function test. + * @tc.type: FUNC + * @tc.require: issueI8TYNB + */ +HWTEST_F(UIExtensionStabilityTest, TerminateUIExtensionAbility_0100, TestSize.Level1) +{ + HILOG_INFO("start."); + auto currentId = GetSelfTokenID(); + SetNativeToken(); + + auto observer = sptr::MakeSptr(); + RegisterApplicationStateObserver(observer); + + // start uiextension user firstly. + Want userWant; + AppExecFwk::ElementName userElement("0", USER_BUNDLE_NAME, USER_ABILITY_NAME, USER_MODULE_NAME); + userWant.SetElement(userElement); + EXPECT_EQ(AbilityManagerClient::GetInstance()->StartAbility(userWant), ERR_OK); + WaitUntilAbilityForeground(observer); + + sptr token = nullptr; + auto ret = AbilityManagerClient::GetInstance()->GetTopAbility(token); + int resultCode = 0; + Want resultWant; + ret = AbilityManagerClient::GetInstance()->TerminateAbility(token, resultCode, &resultWant); + WaitUntilProcessDied(observer); + + UnregisterApplicationStateObserver(observer); + HILOG_INFO("finish."); +} + /** * @tc.name: MinimizeUIExtensionAbility_0100 * @tc.desc: basic function test.