diff --git a/interfaces/innerkits/wm/window.h b/interfaces/innerkits/wm/window.h index 735b6bf3fa2f9c3620057b40cbabcd7fda65f74b..4922ce9d1299c28acdc08b94c447361a9017a866 100644 --- a/interfaces/innerkits/wm/window.h +++ b/interfaces/innerkits/wm/window.h @@ -142,6 +142,16 @@ public: * @brief Notify caller that window is destroyed. */ virtual void AfterDestroyed() {} + + /** + * @brief Notify caller that window is already foreground. + */ + virtual void AfterDidForeground() {} + + /** + * @brief Notify caller that window is already background. + */ + virtual void AfterDidBackground() {} }; /** @@ -1051,6 +1061,11 @@ public: virtual WMError Show(uint32_t reason = 0, bool withAnimation = false, bool withFocus = true) { return WMError::WM_OK; } + /** + * @brief resume window + */ + virtual void Resume() {} + /** * @brief Hide window * diff --git a/interfaces/innerkits/wm/window_scene.h b/interfaces/innerkits/wm/window_scene.h index 2933899c71b04ea5ea85a7fdd6fe02fdfd79a066..837827b964e643dbeac31c25dfc4cb305a49d3c8 100644 --- a/interfaces/innerkits/wm/window_scene.h +++ b/interfaces/innerkits/wm/window_scene.h @@ -115,6 +115,13 @@ public: */ WMError GoDestroy(); + /** + * Window go resume. + * + * @return the error code of window + */ + WMError GoResume(); + /** * Window handle new want. * diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index ba1f8b3ee0f204fabdc424da443c1040ea0c115a..b55acf37a42dc94da9ecf0c3067fd9f4bfd23e26 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -37,6 +37,7 @@ enum class WindowStateChangeReason : uint32_t { KEYGUARD, TOGGLING, USER_SWITCH, + ABILITY_CALL, }; enum class WindowUpdateReason : uint32_t { diff --git a/window_scene/common/include/window_session_property.h b/window_scene/common/include/window_session_property.h index cf75e50a69d606353242aa6fa53bb35175cf81e9..cb2efafdeb713fcd6a1db56deb38068df2ba75f9 100755 --- a/window_scene/common/include/window_session_property.h +++ b/window_scene/common/include/window_session_property.h @@ -206,6 +206,8 @@ public: void Read(Parcel& parcel, WSPropertyChangeAction action); void SetFullScreenStart(bool fullScreenStart); bool GetFullScreenStart() const; + void SetApiVersion(uint32_t version); + uint32_t GetApiVersion() const; /* * Sub Window @@ -416,6 +418,7 @@ private: uint8_t backgroundAlpha_ = 0xff; // default alpha is opaque. mutable std::mutex atomicServiceMutex_; bool isAtomicService_ = false; + uint32_t apiVersion_ = 0; /* * Sub Window diff --git a/window_scene/common/src/window_session_property.cpp b/window_scene/common/src/window_session_property.cpp index 65606b688c63c4eed16f909b2b1575a5375872fb..d81efc71519ec880805fe1defebd642d8abe4d63 100755 --- a/window_scene/common/src/window_session_property.cpp +++ b/window_scene/common/src/window_session_property.cpp @@ -1211,7 +1211,7 @@ bool WindowSessionProperty::Marshalling(Parcel& parcel) const parcel.WriteUint32(avoidAreaOption_) && parcel.WriteBool(isWindowDelayRaiseEnabled_) && parcel.WriteUint8(backgroundAlpha_) && parcel.WriteUint32(static_cast(keyboardViewMode_)) && parcel.WriteFloat(cornerRadius_) && parcel.WriteBool(isExclusivelyHighlighted_) && - parcel.WriteBool(isAtomicService_); + parcel.WriteBool(isAtomicService_) && parcel.WriteUint32(apiVersion_); } WindowSessionProperty* WindowSessionProperty::Unmarshalling(Parcel& parcel) @@ -1299,6 +1299,7 @@ WindowSessionProperty* WindowSessionProperty::Unmarshalling(Parcel& parcel) property->SetWindowCornerRadius(parcel.ReadFloat()); property->SetExclusivelyHighlighted(parcel.ReadBool()); property->SetIsAtomicService(parcel.ReadBool()); + property->SetApiVersion(parcel.ReadUint32()); return property; } @@ -1388,6 +1389,7 @@ void WindowSessionProperty::CopyFrom(const sptr& property isExclusivelyHighlighted_ = property->isExclusivelyHighlighted_; cornerRadius_ = property->cornerRadius_; isAtomicService_ = property->isAtomicService_; + apiVersion_ = property->apiVersion_; } bool WindowSessionProperty::Write(Parcel& parcel, WSPropertyChangeAction action) @@ -1933,5 +1935,15 @@ bool WindowSessionProperty::IsConstrainedModal() const { return isConstrainedModal_; } + +void WindowSessionProperty::SetApiVersion(uint32_t version) +{ + apiVersion_ = version; +} + +uint32_t WindowSessionProperty::GetApiVersion() const +{ + return apiVersion_; +} } // namespace Rosen } // namespace OHOS diff --git a/window_scene/session/container/src/zidl/session_stage_stub.cpp b/window_scene/session/container/src/zidl/session_stage_stub.cpp index 881fd73409ddfd3579ef927dca572543c79304ae..44c3fbb583a8f829b68251f55205e63ca1ede099 100644 --- a/window_scene/session/container/src/zidl/session_stage_stub.cpp +++ b/window_scene/session/container/src/zidl/session_stage_stub.cpp @@ -839,5 +839,4 @@ int SessionStageStub::HandleNotifyWindowAttachStateChange(MessageParcel& data, M NotifyWindowAttachStateChange(isAttach); return ERR_NONE; } - } // namespace OHOS::Rosen diff --git a/window_scene/session/host/include/scene_session.h b/window_scene/session/host/include/scene_session.h index e7b5d262b07188ee23cd3be09145586652cf0e8e..53112942c6a97ee79dc6abe83cb66cda37cb8f62 100644 --- a/window_scene/session/host/include/scene_session.h +++ b/window_scene/session/host/include/scene_session.h @@ -488,6 +488,7 @@ public: virtual void RegisterSessionLockStateChangeCallback(NotifySessionLockStateChangeCallback&& callback) {} virtual void NotifySessionLockStateChange(bool isLockedState) {} virtual void SetUpdateSessionLabelAndIconListener(NofitySessionLabelAndIconUpdatedFunc&& func) {} + bool UpdateInteractiveInner(bool interactive); void SendPointerEventToUI(std::shared_ptr pointerEvent); bool SendKeyEventToUI(std::shared_ptr keyEvent, bool isPreImeEvent = false); @@ -674,7 +675,6 @@ protected: * Window Pipeline */ bool UpdateVisibilityInner(bool visibility) REQUIRES(SCENE_GUARD); - bool UpdateInteractiveInner(bool interactive); virtual void NotifyClientToUpdateInteractive(bool interactive) {} bool PipelineNeedNotifyClientToUpdateRect() const; bool UpdateRectInner(const SessionUIParam& uiParam, SizeChangeReason reason); diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 1045875755135b50cfe983b06f2e003ad5a5263f..ae9b8b62cd097e8e4cc7921f2565fcd72c0a8270 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -134,6 +134,7 @@ constexpr int32_t MAX_LOCK_STATUS_CACHE_SIZE = 1000; constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PC = 24; constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PAD = 8; constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PHONE = 3; +constexpr uint32_t LIFECYCLE_ISOLATE_VERSION = 16; const std::map STRING_TO_DISPLAY_ORIENTATION_MAP = { {"unspecified", OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED}, @@ -2379,7 +2380,8 @@ int32_t SceneSessionManager::StartUIAbilityBySCB(sptr& sceneSessio int32_t SceneSessionManager::StartUIAbilityBySCB(sptr& abilitySessionInfo) { bool isColdStart = false; - return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart); + return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart, + static_cast(WindowStateChangeReason::ABILITY_CALL)); } int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(const sptr& sceneSession, @@ -2442,7 +2444,8 @@ WSError SceneSessionManager::RequestSceneSessionActivationInner( if (!systemConfig_.backgroundswitch || sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc()) { TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId, static_cast(sceneSession->GetSessionInfo().isSystem_)); - errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(sceneSessionInfo, isColdStart); + errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(sceneSessionInfo, isColdStart, + static_cast(WindowStateChangeReason::ABILITY_CALL)); } else { TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u", isNewActive, sceneSession->GetSessionState()); @@ -2450,7 +2453,8 @@ WSError SceneSessionManager::RequestSceneSessionActivationInner( sceneSession->GetSessionState() == SessionState::STATE_END) { TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId, static_cast(sceneSession->GetSessionInfo().isSystem_)); - errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(sceneSessionInfo, isColdStart); + errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(sceneSessionInfo, isColdStart, + static_cast(WindowStateChangeReason::ABILITY_CALL)); } else { TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId); sceneSession->NotifySessionForeground(1, true); @@ -2562,6 +2566,13 @@ WSError SceneSessionManager::RequestSceneSessionBackground(const sptrGetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) { + TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId); + if (!sceneSession->UpdateInteractiveInner(false)) { + TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId); + } + } sceneSession->SetActive(false); if (isToDesktop) { @@ -2590,9 +2601,11 @@ WSError SceneSessionManager::RequestSceneSessionBackground(const sptr(sceneSession->GetSessionInfo().isSystem_)); auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession); if (!isDelegator) { - AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo); + AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, false, + static_cast(WindowStateChangeReason::ABILITY_CALL)); } else { - AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, true); + AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, true, + static_cast(WindowStateChangeReason::ABILITY_CALL)); } } @@ -2811,6 +2824,12 @@ WSError SceneSessionManager::RequestSceneSessionDestruction(const sptrSetRemoveSnapshotCallback([this, persistentId]() { this->RemoveSnapshotFromCache(persistentId); }); + if (sceneSession->GetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) { + TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId); + if (!sceneSession->UpdateInteractiveInner(false)) { + TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId); + } + } sceneSession->DisconnectTask(false, isSaveSnapshot); if (!GetSceneSession(persistentId)) { TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId); @@ -2866,9 +2885,11 @@ WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptrGetSessionInfo().isSystem_); if (isForceClean) { - AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit); + AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit, + static_cast(WindowStateChangeReason::ABILITY_CALL)); } else { - AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit); + AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit, + static_cast(WindowStateChangeReason::ABILITY_CALL)); } sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE); if (needRemoveSession) { @@ -4055,6 +4076,12 @@ WSError SceneSessionManager::StartOrMinimizeUIAbilityBySCB(const sptrGetWindowType(), sceneSession->GetSessionState()); bool isFromUser = false; + if (sceneSession->GetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) { + TLOGI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId); + if (!sceneSession->UpdateInteractiveInner(false)) { + TLOGI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId); + } + } int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB( abilitySessionInfo, isFromUser, static_cast(WindowStateChangeReason::USER_SWITCH)); if (errCode == ERR_OK) { diff --git a/wm/include/window_scene_session_impl.h b/wm/include/window_scene_session_impl.h index 4cce9ecc1e5c14f1aed83bd7fbdfc215a2cae6c2..f5505fff86ee700affce78f2315716c128094374 100644 --- a/wm/include/window_scene_session_impl.h +++ b/wm/include/window_scene_session_impl.h @@ -39,6 +39,7 @@ public: void StartMove() override; bool IsStartMoving() override; WindowMode GetWindowMode() const override; + void Resume() override; /* * Window Layout @@ -412,6 +413,12 @@ private: static std::mutex windowAttachStateChangeListenerMutex_; sptr windowAttachStateChangeListener_; WSError NotifyWindowAttachStateChange(bool isAttach) override; + + /* + * Window Lifecycle + */ + bool isColdStart_ = true; + void NotifyFreeMultiWindowModeResume(); }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index f68aba7c09eb015331b235c3fd3c949810e455be..344109c1fba3d25735113b1f0ee80875f174571b 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -39,6 +39,7 @@ #include "window_helper.h" #include "window_option.h" #include "wm_common.h" +#include "wm_common_inner.h" namespace OHOS { namespace Rosen { @@ -221,6 +222,8 @@ public: int32_t GetFloatingWindowParentId(); void NotifyAfterForeground(bool needNotifyListeners = true, bool needNotifyUiContent = true); void NotifyAfterBackground(bool needNotifyListeners = true, bool needNotifyUiContent = true); + void NotifyAfterDidForeground(uint32_t reason = static_cast(WindowStateChangeReason::NORMAL)); + void NotifyAfterDidBackground(uint32_t reason = static_cast(WindowStateChangeReason::NORMAL)); void NotifyForegroundFailed(WMError ret); void NotifyBackgroundFailed(WMError ret); WSError MarkProcessed(int32_t eventId) override; @@ -510,6 +513,7 @@ protected: */ bool hasFirstNotifyInteractive_ = false; bool interactive_ = true; + bool isDidForeground_ = false; /* * Window Layout diff --git a/wm/src/window_scene.cpp b/wm/src/window_scene.cpp index ada362d55a896ae66922afeb872d0896bb3c3ae4..514f3d8cffa5fd165c8a0796ef40fedf35915899 100644 --- a/wm/src/window_scene.cpp +++ b/wm/src/window_scene.cpp @@ -159,6 +159,18 @@ WMError WindowScene::GoForeground(uint32_t reason) return mainWindow->Show(reason); } +WMError WindowScene::GoResume() +{ + TLOGI(WmsLogTag::WMS_MAIN, "in"); + auto mainWindow = GetMainWindow(); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::WMS_MAIN, "failed, because main window is null"); + return WMError::WM_ERROR_NULLPTR; + } + mainWindow->Resume(); + return WMError::WM_OK; +} + WMError WindowScene::GoBackground(uint32_t reason) { TLOGI(WmsLogTag::WMS_MAIN, "reason: %{public}u", reason); diff --git a/wm/src/window_scene_session_impl.cpp b/wm/src/window_scene_session_impl.cpp index 89c23cc2bb92185d657674c9407061d692b34403..f3c8988d4d638669edfa6a379a035a39be7922e1 100644 --- a/wm/src/window_scene_session_impl.cpp +++ b/wm/src/window_scene_session_impl.cpp @@ -128,6 +128,7 @@ constexpr float INVALID_DEFAULT_DENSITY = 1.0f; constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_WIDTH = 40; constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_HEIGHT = 40; constexpr int32_t API_VERSION_16 = 16; +constexpr uint32_t LIFECYCLE_ISOLATE_VERSION = 16; } uint32_t WindowSceneSessionImpl::maxFloatingWindowSize_ = 1920; std::mutex WindowSceneSessionImpl::keyboardPanelInfoChangeListenerMutex_; @@ -1125,6 +1126,7 @@ WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation, bool w if (reason == static_cast(WindowStateChangeReason::USER_SWITCH)) { TLOGI(WmsLogTag::WMS_MULTI_USER, "Switch to current user, NotifyAfterForeground"); NotifyAfterForeground(true, false); + NotifyAfterDidForeground(reason); return WMError::WM_OK; } const auto type = GetType(); @@ -1144,12 +1146,13 @@ WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation, bool w property_->SetDecorEnable(isDecorEnable); if (state_ == WindowState::STATE_SHOWN) { - TLOGD(WmsLogTag::WMS_LIFE, "window is already shown [name:%{public}s, id:%{public}d, type: %{public}u]", + TLOGI(WmsLogTag::WMS_LIFE, "window is already shown [name:%{public}s, id:%{public}d, type: %{public}u]", property_->GetWindowName().c_str(), property_->GetPersistentId(), type); if (WindowHelper::IsMainWindow(type)) { hostSession->RaiseAppMainWindowToTop(); } NotifyAfterForeground(true, false); + NotifyAfterDidForeground(reason); RefreshNoInteractionTimeoutMonitor(); return WMError::WM_OK; } @@ -1203,6 +1206,8 @@ WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation, bool w state_ = WindowState::STATE_SHOWN; requestState_ = WindowState::STATE_SHOWN; NotifyAfterForeground(true, true); + NotifyAfterDidForeground(reason); + NotifyFreeMultiWindowModeResume(); RefreshNoInteractionTimeoutMonitor(); TLOGI(WmsLogTag::WMS_LIFE, "Window show success [name:%{public}s, id:%{public}d, type:%{public}u]", property_->GetWindowName().c_str(), GetPersistentId(), type); @@ -1228,11 +1233,32 @@ WMError WindowSceneSessionImpl::ShowKeyboard(KeyboardViewMode mode) return Show(); } +void WindowSceneSessionImpl::NotifyFreeMultiWindowModeResume() +{ + TLOGI(WmsLogTag::WMS_MAIN, "api version %{public}u, IsPcMode %{public}d, isColdStart %{public}d", + GetTargetAPIVersion(), IsPcOrPadCapabilityEnabled(), isColdStart_); + if (GetTargetAPIVersion() >= LIFECYCLE_ISOLATE_VERSION && IsPcOrPadCapabilityEnabled() && !isColdStart_) { + isDidForeground_ = true; + NotifyForegroundInteractiveStatus(true); + } +} + +void WindowSceneSessionImpl::Resume() +{ + if (GetTargetAPIVersion() >= LIFECYCLE_ISOLATE_VERSION) { + isDidForeground_ = true; + isColdStart_ = false; + TLOGI(WmsLogTag::WMS_LIFE, "in"); + NotifyForegroundInteractiveStatus(true); + } +} + WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits) { if (reason == static_cast(WindowStateChangeReason::USER_SWITCH)) { TLOGI(WmsLogTag::WMS_MULTI_USER, "Switch to another user, NotifyAfterBackground"); NotifyAfterBackground(true, false); + NotifyAfterDidBackground(reason); return WMError::WM_OK; } @@ -1283,8 +1309,10 @@ WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool i if (res == WMError::WM_OK) { // update sub window state if this is main window UpdateSubWindowState(type); + NotifyAfterDidBackground(reason); state_ = WindowState::STATE_HIDDEN; requestState_ = WindowState::STATE_HIDDEN; + isDidForeground_ = false; if (!interactive_) { hasFirstNotifyInteractive_ = false; } diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index 41fccbe5bd0d9fd813901d790c723b141662c062..09f8feee2b9bd828513261a82b15a6d30d992c43 100644 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -61,6 +61,7 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowSessionImpl"}; constexpr int32_t FORCE_SPLIT_MODE = 5; constexpr int32_t API_VERSION_15 = 15; +constexpr uint32_t LIFECYCLE_ISOLATE_VERSION = 16; /* * DFX @@ -1173,12 +1174,19 @@ void WindowSessionImpl::NotifyForegroundInteractiveStatus(bool interactive) if (IsNotifyInteractiveDuplicative(interactive)) { return; } - if (state_ == WindowState::STATE_SHOWN) { - if (interactive) { - NotifyAfterResumed(); - } else { - NotifyAfterPaused(); + if (state_ != WindowState::STATE_SHOWN) { + TLOGI(WmsLogTag::WMS_LIFE, "window state %{public}d, is not shown", state_); + return; + } + if (interactive) { + if (GetTargetAPIVersion() >= LIFECYCLE_ISOLATE_VERSION && !isDidForeground_) { + TLOGI(WmsLogTag::WMS_LIFE, "api version %{public}u, isDidForeground %{public}d", GetTargetAPIVersion(), + isDidForeground_); + return; } + NotifyAfterResumed(); + } else { + NotifyAfterPaused(); } } @@ -3235,6 +3243,31 @@ void WindowSessionImpl::NotifyAfterForeground(bool needNotifyListeners, bool nee } } +void WindowSessionImpl::NotifyAfterDidForeground(uint32_t reason) +{ + TLOGI(WmsLogTag::WMS_LIFE, "reason: %{public}d", reason); + if (reason != static_cast(WindowStateChangeReason::USER_SWITCH) && + reason != static_cast(WindowStateChangeReason::ABILITY_CALL)) { + TLOGI(WmsLogTag::WMS_LIFE, "reason: %{public}d no need notify did foreground", reason); + return; + } + if (handler_ == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "handler is nullptr"); + return; + } + const char* const where = __func__; + handler_->PostTask([weak = wptr(this), where] { + auto window = weak.promote(); + if (window == nullptr) { + TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s window is nullptr", where); + return; + } + TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s execute", where); + auto lifecycleListeners = window->GetListeners(); + CALL_LIFECYCLE_LISTENER(AfterDidForeground, lifecycleListeners); + }, where, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); +} + void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool needNotifyUiContent) { if (needNotifyListeners) { @@ -3259,6 +3292,31 @@ void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool nee } } +void WindowSessionImpl::NotifyAfterDidBackground(uint32_t reason) +{ + TLOGI(WmsLogTag::WMS_LIFE, "reason: %{public}d", reason); + if (reason != static_cast(WindowStateChangeReason::USER_SWITCH) && + reason != static_cast(WindowStateChangeReason::ABILITY_CALL)) { + TLOGI(WmsLogTag::WMS_LIFE, "reason: %{public}d no need notify did background", reason); + return; + } + if (handler_ == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "handler is nullptr"); + return; + } + const char* const where = __func__; + handler_->PostTask([weak = wptr(this), where] { + auto window = weak.promote(); + if (window == nullptr) { + TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s window is nullptr", where); + return; + } + TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s execute", where); + auto lifecycleListeners = window->GetListeners(); + CALL_LIFECYCLE_LISTENER(AfterDidBackground, lifecycleListeners); + }, where, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); +} + static void RequestInputMethodCloseKeyboard(bool isNeedKeyboard, bool keepKeyboardFlag) { if (!isNeedKeyboard && !keepKeyboardFlag) { diff --git a/wm/test/mock/mock_window.h b/wm/test/mock/mock_window.h index e9848a324c7c8a6a0bf868a10d6dc102ca0fdfdd..ef4a1de96e6c4551d07759a635fa243068df487f 100644 --- a/wm/test/mock/mock_window.h +++ b/wm/test/mock/mock_window.h @@ -41,6 +41,8 @@ public: MOCK_METHOD0(AfterResumed, void(void)); MOCK_METHOD0(AfterPaused, void(void)); MOCK_METHOD0(AfterDestroyed, void(void)); + MOCK_METHOD0(AfterDidForeground, void(void)); + MOCK_METHOD0(AfterDidBackground, void(void)); }; class MockAvoidAreaChangedListener : public IAvoidAreaChangedListener { diff --git a/wm/test/unittest/window_scene_session_impl_test5.cpp b/wm/test/unittest/window_scene_session_impl_test5.cpp index 9fd52e0a8270eaf949309fa3cfc5177957a8cbfd..826b38de5e1ce74adf4c1508121ffa09d0167829 100644 --- a/wm/test/unittest/window_scene_session_impl_test5.cpp +++ b/wm/test/unittest/window_scene_session_impl_test5.cpp @@ -20,9 +20,11 @@ #include "display_info.h" #include "mock_session.h" #include "mock_uicontent.h" +#include "mock_window.h" #include "mock_window_adapter.h" #include "pointer_event.h" #include "singleton_mocker.h" +#include "wm_common_inner.h" #include "window_scene_session_impl.h" #include "window_session_impl.h" using namespace testing; @@ -696,6 +698,85 @@ HWTEST_F(WindowSceneSessionImplTest5, UpdateSystemBarProperties, Function | Smal std::unordered_map systemBarPropertyFlags; ASSERT_EQ(WMError::WM_OK, window->UpdateSystemBarProperties(systemBarProperties, systemBarPropertyFlags)); } + +/** + * @tc.name: NotifyAfterDidForeground + * @tc.desc: NotifyAfterDidForeground + * @tc.type: FUNC + */ +HWTEST_F(WindowSceneSessionImplTest5, NotifyAfterDidForeground, Function | SmallTest | Level2) +{ + sptr mockListener = sptr::MakeSptr(); + sptr listener = static_cast>(mockListener); + + sptr option = sptr::MakeSptr(); + option->SetWindowName("Test"); + option->SetDisplayId(0); + + SessionInfo sessionInfo = { "CreateTestBundle", "CreateTestModule", "CreateTestAbility" }; + sptr session = sptr::MakeSptr(sessionInfo); + + sptr window = sptr::MakeSptr(option); + window->property_->SetPersistentId(1); + window->hostSession_ = session; + window->RegisterLifeCycleListener(listener); + + EXPECT_CALL(*mockListener, AfterDidForeground()).Times(1); + ASSERT_EQ(WMError::WM_OK, window->Show(static_cast(WindowStateChangeReason::ABILITY_CALL), false)); +} + +/** + * @tc.name: NotifyAfterDidBackground + * @tc.desc: NotifyAfterDidBackground + * @tc.type: FUNC + */ +HWTEST_F(WindowSceneSessionImplTest5, NotifyAfterDidBackground, Function | SmallTest | Level2) +{ + sptr mockListener = sptr::MakeSptr(); + sptr listener = static_cast>(mockListener); + + sptr option = sptr::MakeSptr(); + option->SetWindowName("Test"); + option->SetDisplayId(0); + + SessionInfo sessionInfo = { "CreateTestBundle", "CreateTestModule", "CreateTestAbility" }; + sptr session = sptr::MakeSptr(sessionInfo); + + sptr window = sptr::MakeSptr(option); + window->property_->SetPersistentId(1); + window->hostSession_ = session; + window->RegisterLifeCycleListener(listener); + + EXPECT_CALL(*mockListener, AfterDidBackground()).Times(1); + ASSERT_EQ(WMError::WM_OK, window->Hide(static_cast(WindowStateChangeReason::ABILITY_CALL), false, false)); +} + +/** + * @tc.name: Resume + * @tc.desc: Resume + * @tc.type: FUNC + */ +HWTEST_F(WindowSceneSessionImplTest5, Resume, Function | SmallTest | Level2) +{ + sptr mockListener = sptr::MakeSptr(); + sptr listener = static_cast>(mockListener); + + sptr option = sptr::MakeSptr(); + option->SetWindowName("Test"); + option->SetDisplayId(0); + + SessionInfo sessionInfo = { "CreateTestBundle", "CreateTestModule", "CreateTestAbility" }; + sptr session = sptr::MakeSptr(sessionInfo); + + sptr window = sptr::MakeSptr(option); + window->property_->SetPersistentId(1); + window->hostSession_ = session; + window->RegisterLifeCycleListener(listener); + window->SetTargetAPIVersion(16); + + EXPECT_CALL(*mockListener, AfterResumed()).Times(1); + window->Resume(); +} } } // namespace Rosen } // namespace OHOS \ No newline at end of file