diff --git a/interfaces/innerkits/wm/window.h b/interfaces/innerkits/wm/window.h index f79ee593945ebf5784ed262a7744a268fdc82b50..1003076e02c960d3d5db175d9d834bd3c436cfbb 100644 --- a/interfaces/innerkits/wm/window.h +++ b/interfaces/innerkits/wm/window.h @@ -144,6 +144,17 @@ public: virtual void AfterDestroyed() {} }; +/** + * @class IWindowAttachStateChangeListner + * + * @brief IWindowAttachStateChangeListner is used to observe the window attach or detach state changed. + */ +class IWindowAttachStateChangeListner : virtual public RefBase { +public: + virtual void AfterAttached() {} + virtual void AfterDetached() {} +}; + /** * @class IWindowChangeListener * @@ -3176,6 +3187,27 @@ public: * @param want the want to update param. */ virtual void UpdateExtensionConfig(const std::shared_ptr& want) {} + + /** + * @brief Register window scene attach or detach framenode listener. + * + * @param listener IWindowAttachStateChangeListner. + * @return WM_OK means register success, others means register failed. + */ + virtual WMError RegisterWindowAttachStateChangeListener(const sptr& listener) + { + return WMError::WM_OK; + } + + /** + * @brief Unregister window scene attach or detach framenode listener. + * + * @return WM_OK means unregister success + */ + virtual WMError UnregisterWindowAttachStateChangeListener() + { + return WMError::WM_OK; + } }; } } diff --git a/window_scene/session/container/include/zidl/session_stage_interface.h b/window_scene/session/container/include/zidl/session_stage_interface.h index 2a450d4a5d281dfe4da904e70a7a464588a38b77..b5308fdd7b20bf5c3b40652065bb5b5bf9f457dd 100644 --- a/window_scene/session/container/include/zidl/session_stage_interface.h +++ b/window_scene/session/container/include/zidl/session_stage_interface.h @@ -242,6 +242,7 @@ public: virtual WSError SetSupportEnterWaterfallMode(bool isSupportEnter) { return WSError::WS_DO_NOTHING; } virtual WSError SendContainerModalEvent(const std::string& eventName, const std::string& eventValue) = 0; virtual void NotifyWindowCrossAxisChange(CrossAxisState state) = 0; + virtual WSError NotifyWindowAttachStateChange(bool isAttach) { return WSError::WS_DO_NOTHING; } }; } // namespace OHOS::Rosen #endif // OHOS_WINDOW_SCENE_SESSION_STAGE_INTERFACE_H diff --git a/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h b/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h index 261ca3faad4355097b1b8d49f0f6d3b62f46667e..3f1e7f6aca1a9af0e70ef67b386eacd20d91f220 100644 --- a/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h +++ b/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h @@ -75,6 +75,7 @@ enum class SessionStageInterfaceCode { TRANS_ID_NOTIFY_HIGHLIGHT_CHANGE, TRANS_ID_NOTIFY_CROSS_AXIS, TRANS_ID_NOTIFY_PIPSIZE_CHANGE, + TRANS_ID_NOTIFY_WINDOW_ATTACH_STATE_CHANGE, }; } // namespace Rosen } // namespace OHOS diff --git a/window_scene/session/container/include/zidl/session_stage_proxy.h b/window_scene/session/container/include/zidl/session_stage_proxy.h index 71662c3c4676691f2b1799e2bb148cab888bb507..5f20185a5a3bee7d8a245fa331250cf09778e81c 100644 --- a/window_scene/session/container/include/zidl/session_stage_proxy.h +++ b/window_scene/session/container/include/zidl/session_stage_proxy.h @@ -89,6 +89,7 @@ public: WSError SendContainerModalEvent(const std::string& eventName, const std::string& eventValue) override; WSError NotifyHighlightChange(bool isHighlight) override; void NotifyWindowCrossAxisChange(CrossAxisState state) override; + WSError NotifyWindowAttachStateChange(bool isAttach) override; private: static inline BrokerDelegator delegator_; diff --git a/window_scene/session/container/include/zidl/session_stage_stub.h b/window_scene/session/container/include/zidl/session_stage_stub.h index ac5f19c3ee804baeaf79c12311953c049e85a2bf..c6e53da46085b046c6a87214459845cbd44217ab 100644 --- a/window_scene/session/container/include/zidl/session_stage_stub.h +++ b/window_scene/session/container/include/zidl/session_stage_stub.h @@ -85,6 +85,7 @@ private: int HandleNotifyHighlightChange(MessageParcel& data, MessageParcel& reply); int HandleNotifyWindowCrossAxisChange(MessageParcel& data, MessageParcel& reply); int HandleNotifyPipSizeChange(MessageParcel& data, MessageParcel& reply); + int HandleNotifyWindowAttachStateChange(MessageParcel& data, MessageParcel& reply); }; } // namespace OHOS::Rosen #endif // OHOS_WINDOW_SCENE_SESSION_STAGE_STUB_H diff --git a/window_scene/session/container/src/zidl/session_stage_proxy.cpp b/window_scene/session/container/src/zidl/session_stage_proxy.cpp index 90758fc8e4f36e823be8135acd6d9abb50756c9d..f498e0df59b210e29c0b562a96f6f13d459da1f7 100644 --- a/window_scene/session/container/src/zidl/session_stage_proxy.cpp +++ b/window_scene/session/container/src/zidl/session_stage_proxy.cpp @@ -1638,4 +1638,31 @@ void SessionStageProxy::NotifyWindowCrossAxisChange(CrossAxisState state) return; } } + +WSError SessionStageProxy::NotifyWindowAttachStateChange(bool isAttach) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + TLOGE(WmsLogTag::WMS_SUB, "WriteInterfaceToken failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (!data.WriteBool(isAttach)) { + TLOGE(WmsLogTag::WMS_SUB, "Write params failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + sptr remote = Remote(); + if (remote == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "remote is null"); + return WSError::WS_ERROR_IPC_FAILED; + } + if (remote->SendRequest( + static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_WINDOW_ATTACH_STATE_CHANGE), + data, reply, option) != ERR_NONE) { + TLOGE(WmsLogTag::WMS_SUB, "SendRequest failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + return WSError::WS_OK; +} } // namespace OHOS::Rosen 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 5e549e0fceb921daeb603b69150a208443b35650..881fd73409ddfd3579ef927dca572543c79304ae 100644 --- a/window_scene/session/container/src/zidl/session_stage_stub.cpp +++ b/window_scene/session/container/src/zidl/session_stage_stub.cpp @@ -198,6 +198,8 @@ int SessionStageStub::OnRemoteRequest(uint32_t code, MessageParcel& data, Messag return HandleNotifyWindowCrossAxisChange(data, reply); case static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_PIPSIZE_CHANGE): return HandleNotifyPipSizeChange(data, reply); + case static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_WINDOW_ATTACH_STATE_CHANGE): + return HandleNotifyWindowAttachStateChange(data, reply); default: WLOGFE("Failed to find function handler!"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -826,4 +828,16 @@ int SessionStageStub::HandleNotifyPipSizeChange(MessageParcel& data, MessageParc NotifyPipWindowSizeChange(width, height, scale); return ERR_NONE; } + +int SessionStageStub::HandleNotifyWindowAttachStateChange(MessageParcel& data, MessageParcel& reply) +{ + TLOGD(WmsLogTag::WMS_SUB, "in"); + bool isAttach = false; + if (!data.ReadBool(isAttach)) { + return ERR_INVALID_DATA; + } + NotifyWindowAttachStateChange(isAttach); + return ERR_NONE; +} + } // namespace OHOS::Rosen diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index a9c091ec539121f1f069c09f6e536e93745cd86d..ba9813b0ffd698117e4141405d8e05aad6743160 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -1576,6 +1576,9 @@ void Session::SetAttachState(bool isAttach, WindowMode windowMode) TLOGND(WmsLogTag::WMS_LIFE, "session is null"); return; } + if (session->sessionStage_) { + session->sessionStage_->NotifyWindowAttachStateChange(isAttach); + } TLOGND(WmsLogTag::WMS_LIFE, "isAttach:%{public}d persistentId:%{public}d", isAttach, session->GetPersistentId()); if (!isAttach && session->detachCallback_ != nullptr) { diff --git a/wm/include/window_scene_session_impl.h b/wm/include/window_scene_session_impl.h index 3d616a6aca6f8135ba5a98d26fd929ed84331360..90265d146a47fe1a997a1040e2d8f0bed0ca7fab 100644 --- a/wm/include/window_scene_session_impl.h +++ b/wm/include/window_scene_session_impl.h @@ -231,6 +231,13 @@ public: */ WMError NotifyRemoveStartingWindow() override; + /* + * Window Scene + */ + WMError RegisterWindowAttachStateChangeListener( + const sptr& listener) override; + WMError UnregisterWindowAttachStateChangeListener() override; + protected: WMError CreateAndConnectSpecificSession(); WMError CreateSystemWindow(WindowType type); @@ -386,6 +393,13 @@ private: * Window Input Event */ int32_t superFoldOffsetY_ = -1; // calculate the total height of the display_B area and crease area. + + /* + * Window Scene + */ + static std::mutex windowAttachStateChangeListenerMutex_; + sptr windowAttachStateChangeListener_; + WSError NotifyWindowAttachStateChange(bool isAttach) override; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index af9bd75df12c982184a8d61fcaeacd133c0f6b6d..e6d7308818093cab73721ec15f28bdbee024d52d 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -748,6 +748,11 @@ private: MouseEventFilterFunc mouseEventFilter_; std::mutex touchEventFilterMutex_; TouchEventFilterFunc touchEventFilter_; + + /* + * Window Scene + */ + WSError NotifyWindowAttachStateChange(bool isAttach) override { return WSError::WS_OK; } }; } // namespace Rosen } // namespace OHOS diff --git a/wm/src/window_scene_session_impl.cpp b/wm/src/window_scene_session_impl.cpp index a562c8289b4c3eae1259ef3539727f040de3522b..045d78e3bf8d9b59a6321a7871208679ce43c3f1 100644 --- a/wm/src/window_scene_session_impl.cpp +++ b/wm/src/window_scene_session_impl.cpp @@ -129,6 +129,7 @@ constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_HEIGHT = 40; uint32_t WindowSceneSessionImpl::maxFloatingWindowSize_ = 1920; std::mutex WindowSceneSessionImpl::keyboardPanelInfoChangeListenerMutex_; using WindowSessionImplMap = std::map>>; +std::mutex WindowSceneSessionImpl::windowAttachStateChangeListenerMutex_; WindowSceneSessionImpl::WindowSceneSessionImpl(const sptr& option) : WindowSessionImpl(option) { @@ -4549,6 +4550,43 @@ WMError WindowSceneSessionImpl::RegisterKeyboardPanelInfoChangeListener( return WMError::WM_OK; } +WMError WindowSceneSessionImpl::RegisterWindowAttachStateChangeListener( + const sptr& listener) +{ + std::lock_guard lockListener(windowAttachStateChangeListenerMutex_); + if (listener == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "id: %{public}d, listener is null", GetPersistentId()); + return WMError::WM_ERROR_NULLPTR; + } + windowAttachStateChangeListener_ = listener; + TLOGD(WmsLogTag::WMS_SUB, "id: %{public}d listener registered", GetPersistentId()); + return WMError::WM_OK; +} + +WMError WindowSceneSessionImpl::UnregisterWindowAttachStateChangeListener() +{ + std::lock_guard lockListener(windowAttachStateChangeListenerMutex_); + windowAttachStateChangeListener_ = nullptr; + TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", GetPersistentId()); + return WMError::WM_OK; +} + +WSError WindowSceneSessionImpl::NotifyWindowAttachStateChange(bool isAttach) +{ + TLOGD(WmsLogTag::WMS_SUB, "id: %{public}d", GetPersistentId()); + if (!windowAttachStateChangeListener_) { + TLOGW(WmsLogTag::WMS_SUB, "listener is null"); + return WSError::WS_ERROR_NULLPTR; + } + + if (isAttach) { + windowAttachStateChangeListener_->AfterAttached(); + } else { + windowAttachStateChangeListener_->AfterDetached(); + } + return WSError::WS_OK; +} + WMError WindowSceneSessionImpl::UnregisterKeyboardPanelInfoChangeListener( const sptr& listener) {