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 2aba4fb3401800d7386dac7e6920271d7e03c72e..7256b924b9ea2a40248288713d817c57f4ba6817 100644 --- a/window_scene/session/container/include/zidl/session_stage_interface.h +++ b/window_scene/session/container/include/zidl/session_stage_interface.h @@ -68,6 +68,7 @@ public: virtual WSError NotifyDialogStateChange(bool isForeground) = 0; virtual WSError SetPipActionEvent(const std::string& action, int32_t status) = 0; virtual WSError UpdateDisplayId(uint64_t displayId) = 0; + virtual void NotifyDisplayMove(DisplayId from, DisplayId to) = 0; // **Non** IPC interface virtual void NotifyBackpressedEvent(bool& isConsumed) {} 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 5bf2f72710cf8173acd4c576fcffa156121f8d7a..c0dcf88cad37eff09ad88519eac2a1ee63cabb83 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 @@ -47,6 +47,7 @@ enum class SessionStageInterfaceCode { TRANS_ID_NOTIFY_DIALOG_STATE_CHANGE, TRANS_ID_SET_PIP_ACTION_EVENT, TRANS_ID_NOTIFY_DISPLAYID_CHANGE, + TRANS_ID_NOTIFY_DISPLAY_MOVE, }; } // 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 3efe0d072efbe6c6a7bcf649fa6116a3118c9ebc..ac2cb8c6fef9827892836a71a55e888d3cb2e1ae 100644 --- a/window_scene/session/container/include/zidl/session_stage_proxy.h +++ b/window_scene/session/container/include/zidl/session_stage_proxy.h @@ -57,6 +57,7 @@ public: WSError NotifyDialogStateChange(bool isForeground) override; WSError SetPipActionEvent(const std::string& action, int32_t status) override; WSError UpdateDisplayId(uint64_t displayId) override; + void NotifyDisplayMove(DisplayId from, DisplayId to) 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 75a51ac92fb3ad2e8213e6005cbe5ddfaa9d8220..6638c0270d1ff838047083c45d8ec0547b9167e1 100644 --- a/window_scene/session/container/include/zidl/session_stage_stub.h +++ b/window_scene/session/container/include/zidl/session_stage_stub.h @@ -62,6 +62,7 @@ private: int HandleNotifyDialogStateChange(MessageParcel& data, MessageParcel& reply); int HandleSetPipActionEvent(MessageParcel& data, MessageParcel& reply); int HandleUpdateDisplayId(MessageParcel& data, MessageParcel& reply); + int HandleNotifyDisplayMove(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 0dbeffa261e7d1cd235727f075dfaedfa056994c..e8fa024daf9c04d38485e53f7feeee2dc85c1e71 100644 --- a/window_scene/session/container/src/zidl/session_stage_proxy.cpp +++ b/window_scene/session/container/src/zidl/session_stage_proxy.cpp @@ -631,4 +631,31 @@ WSError SessionStageProxy::SetPipActionEvent(const std::string& action, int32_t } return WSError::WS_OK; } + +void SessionStageProxy::NotifyDisplayMove(DisplayId from, DisplayId to) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + + if (!data.WriteUint64(from)) { + WLOGFE("Write from id failed"); + return; + } + + if (!data.WriteUint64(to)) { + WLOGFE("Write to id failed"); + return; + } + + if (Remote()->SendRequest(static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_DISPLAY_MOVE), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest notify display move failed"); + return; + } +} } // 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 540687e0e5a641958a23e896cef4d1dc077c616c..619aa6122d9c1a16fb3cce72da2a033230213c8e 100644 --- a/window_scene/session/container/src/zidl/session_stage_stub.cpp +++ b/window_scene/session/container/src/zidl/session_stage_stub.cpp @@ -77,6 +77,8 @@ const std::map SessionStageStub::stubFuncMap_{ &SessionStageStub::HandleSetPipActionEvent), std::make_pair(static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_DISPLAYID_CHANGE), &SessionStageStub::HandleUpdateDisplayId), + std::make_pair(static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_DISPLAY_MOVE), + &SessionStageStub::HandleNotifyDisplayMove), }; int SessionStageStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) @@ -356,4 +358,13 @@ int SessionStageStub::HandleUpdateDisplayId(MessageParcel& data, MessageParcel& reply.WriteInt32(static_cast(errCode)); return ERR_NONE; } + +int SessionStageStub::HandleNotifyDisplayMove(MessageParcel& data, MessageParcel& reply) +{ + WLOGD("HandleNotifyDisplayMove!"); + DisplayId from = static_cast(data.ReadUint64()); + DisplayId to = static_cast(data.ReadUint64()); + NotifyDisplayMove(from, to); + 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 53908688c2850bdf15578b120011bdaac1c199ef..9b3f4a60207def6aa645f747b243de0f64fb6b7b 100644 --- a/window_scene/session/host/include/scene_session.h +++ b/window_scene/session/host/include/scene_session.h @@ -225,6 +225,7 @@ public: bool IsExtWindowHasWaterMarkFlag(); void RomoveExtWindowFlags(int32_t extPersistentId); void ClearExtWindowFlags(); + void NotifyDisplayMove(DisplayId from, DisplayId to); void SetSessionState(SessionState state) override; void UpdateSessionState(SessionState state) override; diff --git a/window_scene/session/host/src/scene_session.cpp b/window_scene/session/host/src/scene_session.cpp index 1fd834691a18e9a20bdab157997e568fc35e5b26..58995f73177276eaf573548821294e68072460dc 100644 --- a/window_scene/session/host/src/scene_session.cpp +++ b/window_scene/session/host/src/scene_session.cpp @@ -2370,6 +2370,14 @@ bool SceneSession::IsExtWindowHasWaterMarkFlag() } return isExtWindowHasWaterMarkFlag; } + +void SceneSession::NotifyDisplayMove(DisplayId from, DisplayId to) +{ + if (sessionStage_) { + sessionStage_->NotifyDisplayMove(from, to); + } +} + void SceneSession::RomoveExtWindowFlags(int32_t extPersistentId) { std::shared_lock lock(extWindowFlagsMapMutex_); diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index d0ba599a04d908442bf1def5142ef28a84671ac4..b8443cc6766f9f85afdf4eee6ddff06871ad3ffc 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -1208,6 +1208,10 @@ sptr SceneSessionManager::SetAbilitySessionInfo(const sptruserId = currentUserId_; abilitySessionInfo->isClearSession = sessionInfo.isClearSession; abilitySessionInfo->processOptions = sessionInfo.processOptions; + if (scnSession->GetSessionProperty()) { + abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, + static_cast(scnSession->GetSessionProperty()->GetDisplayId())); + } if (sessionInfo.want != nullptr) { abilitySessionInfo->want = *sessionInfo.want; } else { @@ -6847,6 +6851,8 @@ WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64 scnSession->GetSessionProperty()->SetDisplayId(screenId); WLOGFD("Session move display %{public}" PRIu64" from %{public}" PRIu64"", screenId, fromScreenId); NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId); + scnSession->NotifyDisplayMove(fromScreenId, screenId); + scnSession->UpdateDensity(); return WSError::WS_OK; } diff --git a/window_scene/test/mock/mock_session_stage.h b/window_scene/test/mock/mock_session_stage.h index f782bf6d7ff78100924b8088b339843b35b3789d..28d3d5a292b0a1db8da07b3a172075848131190d 100644 --- a/window_scene/test/mock/mock_session_stage.h +++ b/window_scene/test/mock/mock_session_stage.h @@ -55,6 +55,7 @@ public: MOCK_METHOD1(NotifyDialogStateChange, WSError(bool isForeground)); MOCK_METHOD2(SetPipActionEvent, WSError(const std::string& action, int32_t status)); MOCK_METHOD1(UpdateDisplayId, WSError(uint64_t displayId)); + MOCK_METHOD2(NotifyDisplayMove, void(DisplayId from, DisplayId to)); }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index 3a4977448554e7e3e4021890304d43af15684f0a..e4ce3cd6729549a7bb0d91eaebce61c6318975a9 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -118,9 +118,12 @@ public: bool notifyInputMethod = true) override; void NotifyOccupiedAreaChangeInfo(sptr info) override; void NotifyForegroundInteractiveStatus(bool interactive) override; + void NotifyDisplayMove(DisplayId from, DisplayId to) override; WMError RegisterLifeCycleListener(const sptr& listener) override; WMError UnregisterLifeCycleListener(const sptr& listener) override; + WMError RegisterDisplayMoveListener(sptr& listener) override; + WMError UnregisterDisplayMoveListener(sptr& listener) override; WMError RegisterWindowChangeListener(const sptr& listener) override; WMError UnregisterWindowChangeListener(const sptr& listener) override; WMError RegisterAvoidAreaChangeListener(sptr& listener) override; @@ -265,6 +268,7 @@ private: template WMError RegisterListener(std::vector>& holder, const sptr& listener); template WMError UnregisterListener(std::vector>& holder, const sptr& listener); template EnableIfSame>> GetListeners(); + template EnableIfSame>> GetListeners(); template EnableIfSame>> GetListeners(); template @@ -314,7 +318,9 @@ private: static std::recursive_mutex windowVisibilityChangeListenerMutex_; static std::recursive_mutex windowStatusChangeListenerMutex_; static std::recursive_mutex windowTitleButtonRectChangeListenerMutex_; + static std::recursive_mutex displayMoveListenerMutex_; static std::map>> lifecycleListeners_; + static std::map>> displayMoveListeners_; static std::map>> windowChangeListeners_; static std::map>> avoidAreaChangeListeners_; static std::map>> dialogDeathRecipientListeners_; diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index 542e2474ccd2950ec75d005d0e80ea6870b5e754..69c3f528fb6dd7189c4d9c4a59e7a3afce28a7d9 100644 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -62,6 +62,7 @@ constexpr int32_t ANIMATION_TIME = 400; } std::map>> WindowSessionImpl::lifecycleListeners_; +std::map>> WindowSessionImpl::displayMoveListeners_; std::map>> WindowSessionImpl::windowChangeListeners_; std::map>> WindowSessionImpl::avoidAreaChangeListeners_; std::map>> WindowSessionImpl::dialogDeathRecipientListeners_; @@ -83,6 +84,7 @@ std::recursive_mutex WindowSessionImpl::touchOutsideListenerMutex_; std::recursive_mutex WindowSessionImpl::windowVisibilityChangeListenerMutex_; std::recursive_mutex WindowSessionImpl::windowStatusChangeListenerMutex_; std::recursive_mutex WindowSessionImpl::windowTitleButtonRectChangeListenerMutex_; +std::recursive_mutex WindowSessionImpl::displayMoveListenerMutex_; std::map>> WindowSessionImpl::windowSessionMap_; std::shared_mutex WindowSessionImpl::windowSessionMutex_; std::map>> WindowSessionImpl::subWindowSessionMap_; @@ -1127,6 +1129,20 @@ WMError WindowSessionImpl::RegisterLifeCycleListener(const sptr& listener) +{ + WLOGFD("RegisterDisplayMoveListener"); + std::lock_guard lockListener(displayMoveListenerMutex_); + return RegisterListener(displayMoveListeners_[GetPersistentId()], listener); +} + +WMError WindowSessionImpl::UnregisterDisplayMoveListener(sptr& listener) +{ + WLOGFD("UnregisterDisplayMoveListener"); + std::lock_guard lockListener(displayMoveListenerMutex_); + return UnregisterListener(displayMoveListeners_[GetPersistentId()], listener); +} + WMError WindowSessionImpl::RegisterOccupiedAreaChangeListener(const sptr& listener) { WLOGFD("Start register"); @@ -1440,6 +1456,10 @@ EnableIfSame lockListener(displayMoveListenerMutex_); + ClearUselessListeners(displayMoveListeners_, persistentId); + } { std::lock_guard lockListener(lifeCycleListenerMutex_); ClearUselessListeners(lifecycleListeners_, persistentId); @@ -1766,6 +1786,27 @@ WSError WindowSessionImpl::NotifyDestroy() return WSError::WS_OK; } +template +EnableIfSame>> WindowSessionImpl::GetListeners() +{ + std::vector> displayMoveListeners; + for (auto& listener : displayMoveListeners_[GetPersistentId()]) { + displayMoveListeners.push_back(listener); + } + return displayMoveListeners; +} + +void WindowSessionImpl::NotifyDisplayMove(DisplayId from, DisplayId to) +{ + std::lock_guard lockListener(displayMoveListenerMutex_); + auto displayMoveListeners = GetListeners(); + for (auto& listener : displayMoveListeners) { + if (listener != nullptr) { + listener->OnDisplayMove(from, to); + } + } +} + WSError WindowSessionImpl::NotifyCloseExistPipWindow() { TLOGD(WmsLogTag::WMS_PIP, "WindowSessionImpl::NotifyCloseExistPipWindow"); diff --git a/wm/test/unittest/window_session_impl_test.cpp b/wm/test/unittest/window_session_impl_test.cpp index 834fa4f6afa99d190ee122a903bab1510508348a..b105caa271cac3d1289a6fcbbca88d793601b8ae 100644 --- a/wm/test/unittest/window_session_impl_test.cpp +++ b/wm/test/unittest/window_session_impl_test.cpp @@ -863,6 +863,12 @@ HWTEST_F(WindowSessionImplTest, RegisterListener01, Function | SmallTest | Level res = window->UnregisterWindowStatusChangeListener(listener5); ASSERT_EQ(res, WMError::WM_ERROR_NULLPTR); + sptr listener6 = nullptr; + res = window->RegisterDisplayMoveListener(listener6); + ASSERT_EQ(res, WMError::WM_ERROR_NULLPTR); + res = window->UnregisterDisplayMoveListener(listener6); + ASSERT_EQ(res, WMError::WM_ERROR_NULLPTR); + GTEST_LOG_(INFO) << "WindowSessionImplTest: RegisterListener01 end"; } @@ -917,6 +923,33 @@ HWTEST_F(WindowSessionImplTest, RegisterListener02, Function | SmallTest | Level GTEST_LOG_(INFO) << "WindowSessionImplTest: RegisterListener02 end"; } +/** + * @tc.name: NotifyDisplayMove + * @tc.desc: NotifyDisplayMove + * @tc.type: FUNC + */ +HWTEST_F(WindowSessionImplTest, NotifyDisplayMove, Function | SmallTest | Level2) +{ + GTEST_LOG_(INFO) << "WindowSessionImplTest: NotifyDisplayMove start"; + sptr option = new WindowOption(); + option->SetWindowName("NotifyDisplayMove"); + sptr window = new WindowSessionImpl(option); + + SessionInfo sessionInfo = {"CreateTestBundle", "CreateTestModule", + "CreateTestAbility"}; + sptr session = new (std::nothrow) SessionMocker(sessionInfo); + ASSERT_NE(nullptr, session); + ASSERT_EQ(WMError::WM_OK, window->Create(nullptr, session)); + + int res = 0; + DisplayId from = 0; + DisplayId to = 2; + window->NotifyDisplayMove(from, to); + ASSERT_EQ(res, 0); + + GTEST_LOG_(INFO) << "WindowSessionImplTest: NotifyDisplayMove end"; +} + /** * @tc.name: NotifyAfterForeground * @tc.desc: NotifyAfterForeground