From 206edb44a9a6f3ab0f4d469d5b706421c02a1c83 Mon Sep 17 00:00:00 2001 From: hubijie Date: Wed, 21 Aug 2024 19:27:23 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E5=BA=94=E7=94=A8=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E6=89=80=E6=9C=89=E7=AA=97=E5=8F=A3=E6=98=BE=E9=9A=90=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8F=98=E5=8C=96=E9=80=9A=E7=9F=A5=20Signed-off-by:?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interfaces/innerkits/wm/window_manager.h | 33 ++++++++ utils/BUILD.gn | 1 + utils/include/window_pid_visibility_info.h | 54 +++++++++++++ utils/src/window_pid_visibility_info.cpp | 42 ++++++++++ window_scene/session/host/include/session.h | 4 + window_scene/session/host/src/session.cpp | 11 +++ .../include/scene_session_manager.h | 4 + .../session_manager_agent_controller.h | 2 + .../src/scene_session_manager.cpp | 57 ++++++++++++++ .../src/session_manager_agent_controller.cpp | 11 +++ .../scene_session_manager_lifecycle_test.cpp | 47 +++++++++++ .../test/unittest/session_lifecycle_test.cpp | 21 +++++ wm/include/window_manager_agent.h | 1 + wm/include/window_manager_agent_lite.h | 1 + .../zidl/window_manager_agent_interface.h | 3 + wm/include/zidl/window_manager_agent_proxy.h | 1 + wm/src/window_manager.cpp | 78 +++++++++++++++++++ wm/src/window_manager_agent.cpp | 5 ++ wm/src/zidl/window_manager_agent_proxy.cpp | 31 ++++++++ wm/src/zidl/window_manager_agent_stub.cpp | 9 +++ .../window_manager_agent_proxy_test.cpp | 26 +++++++ wm/test/unittest/window_manager_test.cpp | 53 +++++++++++++ 22 files changed, 495 insertions(+) create mode 100644 utils/include/window_pid_visibility_info.h create mode 100644 utils/src/window_pid_visibility_info.cpp diff --git a/interfaces/innerkits/wm/window_manager.h b/interfaces/innerkits/wm/window_manager.h index 0154d9398b..7021779fa5 100644 --- a/interfaces/innerkits/wm/window_manager.h +++ b/interfaces/innerkits/wm/window_manager.h @@ -28,6 +28,7 @@ #include "window_visibility_info.h" #include "window_drawing_content_info.h" #include "window.h" +#include "window_pid_visibility_info.h" namespace OHOS { namespace Rosen { @@ -191,6 +192,21 @@ public: virtual void OnWindowStyleUpdate(WindowStyleType styleType) = 0; }; +/** + * @class IWindowPidVisibilityChangedListener + * + * @brief Listener to observe window visibility that in same pid. + */ +class IWindowPidVisibilityChangedListener : virtual public RefBase { +public: + /** + * @brief Notify caller when window style changed. + * + * @param info + */ + virtual void NotifyWindowPidVisibilityChanged(const sptr& info) = 0; +}; + /** * @class AccessibilityWindowInfo * @@ -562,6 +578,22 @@ public: */ WMError UnregisterDisplayInfoChangedListener(const sptr& token, const sptr& listener); + + /** + * @brief Register window in same pid visibility changed listener. + * + * @param listener IWindowPidVisibilityChangedListener. + * @return WM_OK means register success, others means register failed. + */ + WMError RegisterWindowPidVisibilityChangedListener(const sptr& listener); + + /** + * @brief Unregister window in same pid visibility changed listener. + * + * @param listener IWindowPidVisibilityChangedListener. + * @return WM_OK means unregister success, others means unregister failed. + */ + WMError UnregisterWindowPidVisibilityChangedListener(const sptr& listener); /** * @brief notify display information change. @@ -758,6 +790,7 @@ private: void NotifyGestureNavigationEnabledResult(bool enable) const; void UpdateVisibleWindowNum(const std::vector& visibleWindowNumInfo); WMError NotifyWindowStyleChange(WindowStyleType type); + void NotifyWindowPidVisibilityChanged(const sptr& info) const; }; } // namespace Rosen } // namespace OHOS diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 21bb4eeeb6..1dd0e32c3a 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -126,6 +126,7 @@ ohos_shared_library("libwmutil_base") { "src/string_util.cpp", "src/unreliable_window_info.cpp", "src/window_drawing_content_info.cpp", + "src/window_pid_visibility_info.cpp", "src/window_visibility_info.cpp", "src/wm_math.cpp", "src/wm_occlusion_region.cpp", diff --git a/utils/include/window_pid_visibility_info.h b/utils/include/window_pid_visibility_info.h new file mode 100644 index 0000000000..7a6dec9c99 --- /dev/null +++ b/utils/include/window_pid_visibility_info.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ROSEN_WINDOW_PID_VISIBILITY_INFO_H +#define OHOS_ROSEN_WINDOW_PID_VISIBILITY_INFO_H + +#include "wm_common.h" + +namespace OHOS::Rosen { +/** + * @enum WindowVisibilityState + * + * @brief Visibility state of a window + */ +enum WindowPidVisibilityState : uint32_t { + VISIBILITY_STATE, + INVISIBILITY_STATE, +}; + +class WindowPidVisibilityInfo : public Parcelable { +public: + WindowPidVisibilityInfo() = default; + /** + * @brief Construct of WindowPidVisibilityInfo. + * + * @param pid Process id. + * @param visibility True means window is visible, false means the opposite. + */ + WindowPidVisibilityInfo(int32_t pid, WindowPidVisibilityState visibilityState) : pid_(pid), + visibilityState_(visibilityState) {}; + + ~WindowPidVisibilityInfo() = default; + + virtual bool Marshalling(Parcel& parcel) const override; + + static sptr Unmarshalling(Parcel& parcel); + + int32_t pid_ { 0 }; + WindowPidVisibilityState visibilityState_ = INVISIBILITY_STATE; +}; +} // namespace OHOS::Rosen +#endif // OHOS_ROSEN_WINDOW_PID_VISIBILITY_INFO_H \ No newline at end of file diff --git a/utils/src/window_pid_visibility_info.cpp b/utils/src/window_pid_visibility_info.cpp new file mode 100644 index 0000000000..a39254f23a --- /dev/null +++ b/utils/src/window_pid_visibility_info.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "window_pid_visibility_info.h" +#include "window_manager_hilog.h" + +namespace OHOS::Rosen { + +bool WindowPidVisibilityInfo::Marshalling(Parcel& parcel) const +{ + return parcel.WriteInt32(pid_) && parcel.WriteUint32(static_cast(visibilityState_)); +} + +sptr WindowPidVisibilityInfo::Unmarshalling(Parcel& parcel) +{ + sptr windowPidVisibilityInfo = new (std::nothrow) WindowPidVisibilityInfo(); + if (windowPidVisibilityInfo == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "window pid visibility info is nullptr."); + return nullptr; + } + + uint32_t visibilityState = 0; + bool res = parcel.ReadInt32(windowPidVisibilityInfo->pid_) && parcel.ReadUint32(visibilityState); + if (!res) { + return nullptr; + } + windowPidVisibilityInfo->visibilityState_ = static_cast(visibilityState); + return windowPidVisibilityInfo; +} +} // namespace OHOS::Rosen diff --git a/window_scene/session/host/include/session.h b/window_scene/session/host/include/session.h index b7a0acd3f6..cd93f2e658 100644 --- a/window_scene/session/host/include/session.h +++ b/window_scene/session/host/include/session.h @@ -81,6 +81,8 @@ using NotifySystemSessionKeyEventFunc = std::function; using NotifyContextTransparentFunc = std::function; using NotifyFrameLayoutFinishFunc = std::function; +using VisibilityChangedDetectFunc = std::function; class ILifecycleListener { public: @@ -446,6 +448,7 @@ public: bool GetUIStateDirty() const; void ResetDirtyFlags(); static bool IsScbCoreEnabled(); + void SetVisibilityChangedDetectFunc(const VisibilityChangedDetectFunc& func); protected: class SessionLifeCycleTask : public virtual RefBase { @@ -615,6 +618,7 @@ private: std::shared_ptr handler_; std::shared_ptr exportHandler_; std::function isScreenLockedCallback_; + VisibilityChangedDetectFunc visibilityChangedDetectFunc_; mutable std::shared_mutex propertyMutex_; sptr property_; diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index 37050d5d23..1088c83273 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -427,6 +427,9 @@ void Session::SetSessionState(SessionState state) WLOGFD("Invalid session state: %{public}u", state); return; } + if (visibilityChangedDetectFunc_) { + visibilityChangedDetectFunc_(GetCallingPid(), state_, state); + } state_ = state; SetMainSessionUIStateDirty(true); } @@ -439,6 +442,9 @@ void Session::UpdateSessionState(SessionState state) state == SessionState::STATE_BACKGROUND) { RemoveWindowDetectTask(); } + if (visibilityChangedDetectFunc_) { + visibilityChangedDetectFunc_(GetCallingPid(), state_, state); + } state_ = state; SetMainSessionUIStateDirty(true); NotifySessionStateChange(state); @@ -3115,4 +3121,9 @@ bool Session::IsScbCoreEnabled() return system::GetParameter("const.product.devicetype", "unknown") == UI_TYPE_PHONE && system::GetParameter("persist.window.scbcore.enable", "1") == "1"; } + +void Session::SetVisibilityChangedDetectFunc(const VisibilityChangedDetectFunc& func) +{ + visibilityChangedDetectFunc_ = func; +} } // namespace OHOS::Rosen diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index d1912fb247..f111656fd9 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -525,6 +525,7 @@ private: void WindowDestroyNotifyVisibility(const sptr& sceneSession); void RegisterSessionExceptionFunc(const sptr& sceneSession); void RegisterSessionSnapshotFunc(const sptr& sceneSession); + void RegisterVisibilityChangedDetectFunc(const sptr& sceneSession); void NotifySessionForCallback(const sptr& scnSession, const bool needRemoveSession); void DumpSessionInfo(const sptr& session, std::ostringstream& oss); void DumpSessionElementInfo(const sptr& session, @@ -570,6 +571,8 @@ private: std::map> sceneSessionMap_; std::map> systemTopSceneSessionMap_; std::map> nonSystemFloatSceneSessionMap_; + mutable std::shared_mutex visibleWindowCountMapMutex_; + std::map visibleWindowCountMap_; sptr scbSessionHandler_; std::shared_ptr listenerController_; std::map, int32_t> remoteObjectMap_; @@ -753,6 +756,7 @@ private: WMError MakeScreenFoldData(const std::vector& screenFoldInfo, ScreenFoldData& screenFoldData); WMError CheckAndReportScreenFoldStatus(ScreenFoldData& data); WMError ReportScreenFoldStatus(const ScreenFoldData& data); + void RecoveryVisibilityPidCount(int32_t pid); RunnableFuture> dumpInfoFuture_; diff --git a/window_scene/session_manager/include/session_manager_agent_controller.h b/window_scene/session_manager/include/session_manager_agent_controller.h index a828060a83..cd48d4b7bb 100644 --- a/window_scene/session_manager/include/session_manager_agent_controller.h +++ b/window_scene/session_manager/include/session_manager_agent_controller.h @@ -23,6 +23,7 @@ #include "zidl/window_manager_agent_interface.h" #include "window_visibility_info.h" #include "window_drawing_content_info.h" +#include "window_pid_visibility_info.h" namespace OHOS { namespace Rosen { @@ -46,6 +47,7 @@ public: void UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing); void NotifyGestureNavigationEnabledResult(bool enable); void NotifyWindowStyleChange(WindowStyleType type); + void NotifyWindowPidVisibilityChanged(const sptr& info); private: SessionManagerAgentController() diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index cdb372003b..e2a57e9696 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -64,6 +64,7 @@ #include "res_type.h" #include "anomaly_detection.h" #include "hidump_controller.h" +#include "window_pid_visibility_info.h" #ifdef MEMMGR_WINDOW_ENABLE #include "mem_mgr_client.h" @@ -123,6 +124,15 @@ static const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait f static std::shared_ptr g_scbSubscriber(nullptr); +const std::map VISIBILITY_STATE_MAP = { + { SessionState::STATE_DISCONNECT, false }, + { SessionState::STATE_CONNECT, false }, + { SessionState::STATE_FOREGROUND, true }, + { SessionState::STATE_ACTIVE, true }, + { SessionState::STATE_INACTIVE, false }, + { SessionState::STATE_BACKGROUND, false }, +}; + std::string GetCurrentTime() { struct timespec tn; @@ -1536,6 +1546,7 @@ void SceneSessionManager::InitSceneSession(sptr& sceneSession, con sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str()); } RegisterSessionExceptionFunc(sceneSession); + RegisterVisibilityChangedDetectFunc(sceneSession); // Skip FillSessionInfo when atomicService free-install start. if (!IsAtomicServiceFreeInstall(sessionInfo)) { FillSessionInfo(sceneSession); @@ -3820,6 +3831,52 @@ void SceneSessionManager::RegisterSessionExceptionFunc(const sptr& TLOGD(WmsLogTag::WMS_LIFE, "RegisterSessionExceptionFunc success, id: %{public}d", sceneSession->GetPersistentId()); } +void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr& sceneSession) +{ + if (sceneSession == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr"); + return; + } + VisibilityChangedDetectFunc func = [this](const int32_t pid, SessionState oldState, SessionState newState) { + if (VISIBILITY_STATE_MAP.at(oldState) == VISIBILITY_STATE_MAP.at(newState)) { + return; + } + sptr windowPidVisibilityInfo = new WindowPidVisibilityInfo(); + windowPidVisibilityInfo->pid_ = pid; + std::shared_lock lock(visibleWindowCountMapMutex_); + if (VISIBILITY_STATE_MAP.at(oldState) && !VISIBILITY_STATE_MAP.at(newState)) { + visibleWindowCountMap_[pid]--; + if (visibleWindowCountMap_[pid] == 0) { + TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid); + windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE; + SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo); + } else if (visibleWindowCountMap_[pid] < 0) { + RecoveryVisibilityPidCount(pid); + } + }else if (!VISIBILITY_STATE_MAP.at(oldState) && VISIBILITY_STATE_MAP.at(newState)) { + visibleWindowCountMap_[pid]++; + if (visibleWindowCountMap_[pid] == 1) { + TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid); + windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE; + SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo); + } + } + }; + sceneSession->SetVisibilityChangedDetectFunc(func); +} + +void SceneSessionManager::RecoveryVisibilityPidCount(int32_t pid) +{ + std::shared_lock lock(sceneSessionMapMutex_); + visibleWindowCountMap_.erase(pid); + for (auto iter : sceneSessionMap_) { + auto& session = iter.second; + if (session && session->GetCallingPid() == pid && VISIBILITY_STATE_MAP.at(session->GetSessionState())) { + visibleWindowCountMap_[pid]++; + } + } +} + void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr& sceneSession) { if (sceneSession == nullptr) { diff --git a/window_scene/session_manager/src/session_manager_agent_controller.cpp b/window_scene/session_manager/src/session_manager_agent_controller.cpp index deca47a17a..e6a93c67d1 100644 --- a/window_scene/session_manager/src/session_manager_agent_controller.cpp +++ b/window_scene/session_manager/src/session_manager_agent_controller.cpp @@ -219,5 +219,16 @@ void SessionManagerAgentController::NotifyWindowStyleChange(WindowStyleType type } } +void SessionManagerAgentController::NotifyWindowPidVisibilityChanged( + const sptr& info) +{ + for (auto& agent : smAgentContainer_.GetAgentsByType( + WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY)) { + if (agent != nullptr) { + agent->NotifyWindowPidVisibilityChanged(info); + } + } +} + } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/window_scene/test/unittest/scene_session_manager_lifecycle_test.cpp b/window_scene/test/unittest/scene_session_manager_lifecycle_test.cpp index 6de49560e9..4af4dbc987 100644 --- a/window_scene/test/unittest/scene_session_manager_lifecycle_test.cpp +++ b/window_scene/test/unittest/scene_session_manager_lifecycle_test.cpp @@ -878,6 +878,53 @@ HWTEST_F(SceneSessionManagerLifecycleTest, ClearSession, Function | SmallTest | EXPECT_EQ(WSError::WS_ERROR_INVALID_SESSION, ssm_->ClearSession(nullptr)); EXPECT_EQ(WSError::WS_ERROR_INVALID_SESSION, ssm_->ClearSession(sceneSession)); } + +/** + * @tc.name: RegisterVisibilityChangedDetectFunc + * @tc.desc: RegisterVisibilityChangedDetectFunc + * @tc.type: FUNC +*/ +HWTEST_F(SceneSessionManagerLifecycleTest, RegisterVisibilityChangedDetectFunc, Function | SmallTest | Level3) +{ + ASSERT_NE(nullptr, ssm_); + SessionInfo info; + info.abilityName_ = "VisibilityChanged"; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(sceneSession, nullptr); + + ssm_->RegisterVisibilityChangedDetectFunc(nullptr); + + ssm_->RegisterVisibilityChangedDetectFunc(sceneSession); + EXPECT_NE(nullptr, sceneSession->visibilityChangedDetectFunc_); +} + +/** + * @tc.name: RecoveryVisibilityPidCount + * @tc.desc: RecoveryVisibilityPidCount + * @tc.type: FUNC +*/ +HWTEST_F(SceneSessionManagerLifecycleTest, RecoveryVisibilityPidCount, Function | SmallTest | Level3) +{ + ASSERT_NE(nullptr, ssm_); + int32_t pid = 10; + SessionInfo info; + info.abilityName_ = "VisibilityChanged"; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(sceneSession, nullptr); + ssm_->sceneSessionMap_.insert({1, sceneSession}); + sceneSession->SetCallingPid(pid); + sceneSession->SetSessionState(SessionState::STATE_BACKGROUND); + + sptr sceneSession2 = sptr::MakeSptr(info, nullptr); + ASSERT_NE(sceneSession2, nullptr); + ssm_->sceneSessionMap_.insert({2, sceneSession2}); + + sceneSession2->SetCallingPid(pid); + sceneSession2->SetSessionState(SessionState::STATE_FOREGROUND); + + ssm_->RecoveryVisibilityPidCount(pid); + EXPECT_EQ(1, ssm_->visibleWindowCountMap_[pid]); +} } } // namespace Rosen } // namespace OHOS diff --git a/window_scene/test/unittest/session_lifecycle_test.cpp b/window_scene/test/unittest/session_lifecycle_test.cpp index 8173f9a92b..f5536ef04a 100644 --- a/window_scene/test/unittest/session_lifecycle_test.cpp +++ b/window_scene/test/unittest/session_lifecycle_test.cpp @@ -637,6 +637,27 @@ HWTEST_F(WindowSessionLifecycleTest, UpdateSessionState32, Function | SmallTest ASSERT_EQ(session_->state_, SessionState::STATE_CONNECT); } +/** + * @tc.name: UpdateSessionState01 + * @tc.desc: UpdateSessionState01 + * @tc.type: FUNC + */ +HWTEST_F(WindowSessionLifecycleTest, UpdateSessionState01, Function | SmallTest | Level2) +{ + ASSERT_NE(session_, nullptr); + session_->SetSessionState(SessionState::STATE_CONNECT); + session_->UpdateSessionState(SessionState::STATE_CONNECT); + ASSERT_EQ(session_->state_, SessionState::STATE_CONNECT); + + session_->SetSessionState(SessionState::STATE_CONNECT); + session_->UpdateSessionState(SessionState::STATE_FOREGROUND); + ASSERT_EQ(session_->state_, SessionState::STATE_FOREGROUND); + + session_->SetSessionState(SessionState::STATE_ACTIVE); + session_->UpdateSessionState(SessionState::STATE_INACTIVE); + ASSERT_EQ(session_->state_, SessionState::STATE_INACTIVE); +} + /** * @tc.name: IsSystemSession44 * @tc.desc: IsSystemSession diff --git a/wm/include/window_manager_agent.h b/wm/include/window_manager_agent.h index 682709520e..ac9643df9b 100644 --- a/wm/include/window_manager_agent.h +++ b/wm/include/window_manager_agent.h @@ -40,6 +40,7 @@ public: void NotifyGestureNavigationEnabledResult(bool enable) override; void UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing) override {}; void NotifyWindowStyleChange(WindowStyleType type) override; + void NotifyWindowPidVisibilityChanged(const sptr& info) override; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_manager_agent_lite.h b/wm/include/window_manager_agent_lite.h index bf0a916f02..dbc95d9e1e 100644 --- a/wm/include/window_manager_agent_lite.h +++ b/wm/include/window_manager_agent_lite.h @@ -40,6 +40,7 @@ public: void NotifyGestureNavigationEnabledResult(bool enable) override {}; void UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing) override; void NotifyWindowStyleChange(WindowStyleType type) override; + void NotifyWindowPidVisibilityChanged(const sptr& info) override {}; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/zidl/window_manager_agent_interface.h b/wm/include/zidl/window_manager_agent_interface.h index dc0df1ed97..7fe302ce73 100644 --- a/wm/include/zidl/window_manager_agent_interface.h +++ b/wm/include/zidl/window_manager_agent_interface.h @@ -35,6 +35,7 @@ enum class WindowManagerAgentType : uint32_t { WINDOW_MANAGER_AGENT_TYPE_CAMERA_WINDOW, WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE, WINDOW_MANAGER_AGENT_TYPE_WINDOW_STYLE, + WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY, }; class IWindowManagerAgent : public IRemoteBroker { @@ -54,6 +55,7 @@ public: TRANS_ID_UPDATE_CAMERA_WINDOW_STATUS, TRANS_ID_UPDATE_WINDOW_MODE_TYPE, TRANS_ID_UPDATE_WINDOW_STYLE_TYPE, + TRANS_ID_NOTIFY_WINDOW_PID_VISIBILITY, }; virtual void UpdateFocusChangeInfo(const sptr& focusChangeInfo, bool focused) = 0; @@ -70,6 +72,7 @@ public: virtual void NotifyGestureNavigationEnabledResult(bool enable) = 0; virtual void UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing) = 0; virtual void NotifyWindowStyleChange(WindowStyleType type) = 0; + virtual void NotifyWindowPidVisibilityChanged(const sptr& info) = 0; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/zidl/window_manager_agent_proxy.h b/wm/include/zidl/window_manager_agent_proxy.h index f89ddac8b1..071ffe8d4f 100644 --- a/wm/include/zidl/window_manager_agent_proxy.h +++ b/wm/include/zidl/window_manager_agent_proxy.h @@ -41,6 +41,7 @@ public: void NotifyGestureNavigationEnabledResult(bool enable) override; void UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing) override; void NotifyWindowStyleChange(WindowStyleType type) override; + void NotifyWindowPidVisibilityChanged(const sptr& info) override; private: static inline BrokerDelegator delegator_; diff --git a/wm/src/window_manager.cpp b/wm/src/window_manager.cpp index 830695c631..e5e45a4ae8 100644 --- a/wm/src/window_manager.cpp +++ b/wm/src/window_manager.cpp @@ -65,6 +65,7 @@ public: void NotifyDisplayInfoChanged(const sptr& token, DisplayId displayId, float density, DisplayOrientation orientation); void NotifyWindowStyleChange(WindowStyleType type); + void NotifyWindowPidVisibilityChanged(const sptr& info); static inline SingletonDelegator delegator_; @@ -94,6 +95,8 @@ public: sptr windowStyleListenerAgent_; std::map, std::vector>> displayInfoChangedListeners_; + std::vector> windowPidVisibilityListeners_; + sptr windowPidVisibilityListenerAgent_; }; void WindowManager::Impl::NotifyWMSConnected(int32_t userId, int32_t screenId) @@ -340,6 +343,19 @@ void WindowManager::Impl::NotifyWindowStyleChange(WindowStyleType type) } } +void WindowManager::Impl::NotifyWindowPidVisibilityChanged( + const sptr& info) +{ + std::vector> windowPidVisibilityListeners; + { + std::unique_lock lock(listenerMutex_); + windowPidVisibilityListeners = windowPidVisibilityListeners_; + } + for (auto &listener : windowPidVisibilityListeners) { + listener->NotifyWindowPidVisibilityChanged(info); + } +} + WindowManager::WindowManager() : pImpl_(std::make_unique()) { } @@ -945,6 +961,63 @@ WMError WindowManager::UnregisterDisplayInfoChangedListener(const sptr& listener) +{ + if (listener == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "listener could not be null"); + return WMError::WM_ERROR_NULLPTR; + } + std::unique_lock lock(pImpl_->listenerMutex_); + WMError ret = WMError::WM_OK; + if (pImpl_->windowPidVisibilityListenerAgent_ == nullptr) { + pImpl_->windowPidVisibilityListenerAgent_ = new WindowManagerAgent(); + } + ret = SingletonContainer::Get().RegisterWindowManagerAgent( + WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY, + pImpl_->windowPidVisibilityListenerAgent_); + if (ret != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_LIFE, "RegisterWindowManagerAgent failed!"); + pImpl_->windowPidVisibilityListenerAgent_ = nullptr; + } else { + auto iter = std::find(pImpl_->windowPidVisibilityListeners_.begin(), + pImpl_->windowPidVisibilityListeners_.end(), listener); + if (iter != pImpl_->windowPidVisibilityListeners_.end()) { + WLOGI("Listener is already registered."); + return WMError::WM_OK; + } + pImpl_->windowPidVisibilityListeners_.emplace_back(listener); + } + return ret; +} + +WMError WindowManager::UnregisterWindowPidVisibilityChangedListener( + const sptr& listener) +{ + if (listener == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "listener could not be null"); + return WMError::WM_ERROR_NULLPTR; + } + std::unique_lock lock(pImpl_->listenerMutex_); + auto iter = std::find(pImpl_->windowPidVisibilityListeners_.begin(), + pImpl_->windowPidVisibilityListeners_.end(), listener); + if (iter == pImpl_->windowPidVisibilityListeners_.end()) { + WLOGFE("could not find this listener"); + return WMError::WM_OK; + } + pImpl_->windowPidVisibilityListeners_.erase(iter); + WMError ret = WMError::WM_OK; + if (pImpl_->windowPidVisibilityListeners_.empty() && pImpl_->windowPidVisibilityListenerAgent_ != nullptr) { + ret = SingletonContainer::Get().UnregisterWindowManagerAgent( + WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY, + pImpl_->windowPidVisibilityListenerAgent_); + if (ret == WMError::WM_OK) { + pImpl_->windowPidVisibilityListenerAgent_ = nullptr; + } + } + return ret; +} + WMError WindowManager::NotifyDisplayInfoChange(const sptr& token, DisplayId displayId, float density, DisplayOrientation orientation) { @@ -1114,6 +1187,11 @@ void WindowManager::NotifyGestureNavigationEnabledResult(bool enable) const pImpl_->NotifyGestureNavigationEnabledResult(enable); } +void WindowManager::NotifyWindowPidVisibilityChanged(const sptr& info) const +{ + pImpl_->NotifyWindowPidVisibilityChanged(info); +} + WMError WindowManager::RaiseWindowToTop(int32_t persistentId) { WMError ret = SingletonContainer::Get().RaiseWindowToTop(persistentId); diff --git a/wm/src/window_manager_agent.cpp b/wm/src/window_manager_agent.cpp index e8a7d159c5..80245531f6 100644 --- a/wm/src/window_manager_agent.cpp +++ b/wm/src/window_manager_agent.cpp @@ -78,5 +78,10 @@ void WindowManagerAgent::NotifyWindowStyleChange(WindowStyleType type) SingletonContainer::Get().NotifyWindowStyleChange(type); } +void WindowManagerAgent::NotifyWindowPidVisibilityChanged(const sptr& info) +{ + SingletonContainer::Get().NotifyWindowPidVisibilityChanged(info); +} + } // namespace Rosen } // namespace OHOS diff --git a/wm/src/zidl/window_manager_agent_proxy.cpp b/wm/src/zidl/window_manager_agent_proxy.cpp index 150c88e86f..0a0e325166 100644 --- a/wm/src/zidl/window_manager_agent_proxy.cpp +++ b/wm/src/zidl/window_manager_agent_proxy.cpp @@ -381,6 +381,37 @@ void WindowManagerAgentProxy::NotifyWindowStyleChange(WindowStyleType type) } } +void WindowManagerAgentProxy::NotifyWindowPidVisibilityChanged(const sptr& info) +{ + MessageParcel data; + if (info == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "Invalid window pid visibility info."); + return; + } + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TLOGE(WmsLogTag::WMS_LIFE, "WriteInterfaceToken failed"); + return; + } + + if (!data.WriteParcelable(info)) { + TLOGE(WmsLogTag::WMS_LIFE, "Write windowPidVisibilityInfo failed"); + return; + } + + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + sptr remote = Remote(); + if (remote == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "remote is null"); + return; + } + if (remote->SendRequest(static_cast(WindowManagerAgentMsg::TRANS_ID_NOTIFY_WINDOW_PID_VISIBILITY), + data, reply, option) != ERR_NONE) { + TLOGE(WmsLogTag::WMS_LIFE, "SendRequest failed"); + } +} + } // namespace Rosen } // namespace OHOS diff --git a/wm/src/zidl/window_manager_agent_stub.cpp b/wm/src/zidl/window_manager_agent_stub.cpp index 5c0b24eeca..27e3670323 100644 --- a/wm/src/zidl/window_manager_agent_stub.cpp +++ b/wm/src/zidl/window_manager_agent_stub.cpp @@ -149,6 +149,15 @@ int WindowManagerAgentStub::OnRemoteRequest(uint32_t code, MessageParcel& data, NotifyWindowStyleChange(type); break; } + case WindowManagerAgentMsg::TRANS_ID_NOTIFY_WINDOW_PID_VISIBILITY: { + sptr info = data.ReadParcelable(); + if (info == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "windowPidVisibilityInfo is null."); + return ERR_INVALID_DATA; + } + NotifyWindowPidVisibilityChanged(info); + break; + } default: WLOGFW("unknown transaction code %{public}d", code); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/wm/test/unittest/window_manager_agent_proxy_test.cpp b/wm/test/unittest/window_manager_agent_proxy_test.cpp index bc92ff8e22..78f0ea06dd 100644 --- a/wm/test/unittest/window_manager_agent_proxy_test.cpp +++ b/wm/test/unittest/window_manager_agent_proxy_test.cpp @@ -380,6 +380,32 @@ HWTEST_F(WindowManagerAgentProxyTest, NotifyWindowStyleChange, Function | SmallT ASSERT_EQ(resultValue, 1); } +/** + * @tc.name: NotifyWindowPidVisibilityChanged + * @tc.desc: test NotifyWindowPidVisibilityChanged + * @tc.type: FUNC + */ +HWTEST_F(WindowManagerAgentProxyTest, NotifyWindowPidVisibilityChanged, Function | SmallTest | Level2) +{ + SingletonContainer::Get().InitDMSProxy(); + sptr impl = SingletonContainer::Get().displayManagerServiceProxy_->AsObject(); + ASSERT_TRUE(impl != nullptr); + + sptr windowManagerAgentProxy = new (std::nothrow) WindowManagerAgentProxy(impl); + ASSERT_TRUE(windowManagerAgentProxy != nullptr); + + sptr info = new WindowPidVisibilityInfo(); + + int resultValue = 0; + std::function func = [&]() + { + windowManagerAgentProxy->NotifyWindowPidVisibilityChanged(info); + resultValue = 1; + }; + func(); + ASSERT_EQ(resultValue, 1); +} + } // namespace } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wm/test/unittest/window_manager_test.cpp b/wm/test/unittest/window_manager_test.cpp index 864d556e96..98a2352d0e 100644 --- a/wm/test/unittest/window_manager_test.cpp +++ b/wm/test/unittest/window_manager_test.cpp @@ -131,6 +131,14 @@ public: } }; +class TestWindowPidVisibilityChangedListener : public IWindowPidVisibilityChangedListener { +public: + void NotifyWindowPidVisibilityChanged(const sptr& info) + { + TLOGI(WmsLogTag::DMS, "TestWindowPidVisibilityChangedListener"); + } +}; + class WindowManagerTest : public testing::Test { public: static void SetUpTestCase(); @@ -1352,6 +1360,51 @@ HWTEST_F(WindowManagerTest, NotifyVisibleWindowNumChanged01, Function | SmallTes WindowManager::GetInstance().pImpl_->visibleWindowNumChangedListeners_.push_back(listener); WindowManager::GetInstance().pImpl_->NotifyVisibleWindowNumChanged(visibleWindowNumInfo); } + +/** + * @tc.name: RegisterWindowPidVisibilityChangedListener + * @tc.desc: check RegisterWindowPidVisibilityChangedListener + * @tc.type: FUNC + */ +HWTEST_F(WindowManagerTest, RegisterWindowPidVisibilityChangedListener, Function | SmallTest | Level2) +{ + WMError ret; + sptr listener = new (std::nothrow) TestWindowPidVisibilityChangedListener(); + ASSERT_NE(nullptr, listener); + ret = WindowManager::GetInstance().RegisterWindowPidVisibilityChangedListener(listener); + ASSERT_EQ(WMError::WM_OK, ret); + + ret = WindowManager::GetInstance().RegisterWindowPidVisibilityChangedListener(nullptr); + ASSERT_EQ(WMError::WM_ERROR_NULLPTR, ret); +} + +/** + * @tc.name: UnregisterWindowPidVisibilityChangedListener + * @tc.desc: check UnregisterWindowPidVisibilityChangedListener + * @tc.type: FUNC + */ +HWTEST_F(WindowManagerTest, UnregisterWindowPidVisibilityChangedListener, Function | SmallTest | Level2) +{ + WMError ret; + sptr listener = new (std::nothrow) TestWindowPidVisibilityChangedListener(); + ret = WindowManager::GetInstance().UnregisterWindowPidVisibilityChangedListener(listener); + ASSERT_EQ(WMError::WM_OK, ret); + + ret = WindowManager::GetInstance().UnregisterWindowPidVisibilityChangedListener(nullptr); + ASSERT_EQ(WMError::WM_ERROR_NULLPTR, ret); +} + +/** + * @tc.name: NotifyWindowPidVisibilityChanged + * @tc.desc: NotifyWindowPidVisibilityChanged + * @tc.type: FUNC + */ +HWTEST_F(WindowManagerTest, NotifyWindowPidVisibilityChanged, Function | SmallTest | Level2) +{ + sptr info = new WindowPidVisibilityInfo(); + WindowManager::GetInstance().NotifyWindowPidVisibilityChanged(info); + ASSERT_NE(info, nullptr); +} } } // namespace Rosen } // namespace OHOS \ No newline at end of file -- Gitee From e7afbda4990fd758111351149f7e417eb88f966e Mon Sep 17 00:00:00 2001 From: hubijie Date: Fri, 23 Aug 2024 11:38:36 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=BA=94=E7=94=A8=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E6=89=80=E6=9C=89=E7=AA=97=E5=8F=A3=E6=98=BE=E9=9A=90=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8F=98=E5=8C=96=E9=80=9A=E7=9F=A5=20Signed-off-by:?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- window_scene/session_manager/src/scene_session_manager.cpp | 4 ++-- wm/src/window_manager.cpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index e2a57e9696..8f8632381c 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -3841,7 +3841,7 @@ void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr windowPidVisibilityInfo = new WindowPidVisibilityInfo(); + sptr windowPidVisibilityInfo = sptr::MakeSptr(); windowPidVisibilityInfo->pid_ = pid; std::shared_lock lock(visibleWindowCountMapMutex_); if (VISIBILITY_STATE_MAP.at(oldState) && !VISIBILITY_STATE_MAP.at(newState)) { @@ -3853,7 +3853,7 @@ void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptrNotifyWindowPidVisibilityChanged(info); + if (listener != nullptr) { + listener->NotifyWindowPidVisibilityChanged(info); + } } } -- Gitee From bf7d9dd1175c9fe26b258419d14ddc2833700625 Mon Sep 17 00:00:00 2001 From: hubijie Date: Fri, 23 Aug 2024 14:59:40 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=BA=94=E7=94=A8=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E6=89=80=E6=9C=89=E7=AA=97=E5=8F=A3=E6=98=BE=E9=9A=90=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8F=98=E5=8C=96=E9=80=9A=E7=9F=A5=20Signed-off-by:?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/include/window_pid_visibility_info.h | 2 +- utils/src/window_pid_visibility_info.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/include/window_pid_visibility_info.h b/utils/include/window_pid_visibility_info.h index 7a6dec9c99..cad12b5459 100644 --- a/utils/include/window_pid_visibility_info.h +++ b/utils/include/window_pid_visibility_info.h @@ -45,7 +45,7 @@ public: virtual bool Marshalling(Parcel& parcel) const override; - static sptr Unmarshalling(Parcel& parcel); + static WindowPidVisibilityInfo* Unmarshalling(Parcel& parcel); int32_t pid_ { 0 }; WindowPidVisibilityState visibilityState_ = INVISIBILITY_STATE; diff --git a/utils/src/window_pid_visibility_info.cpp b/utils/src/window_pid_visibility_info.cpp index a39254f23a..a754d19d29 100644 --- a/utils/src/window_pid_visibility_info.cpp +++ b/utils/src/window_pid_visibility_info.cpp @@ -23,9 +23,9 @@ bool WindowPidVisibilityInfo::Marshalling(Parcel& parcel) const return parcel.WriteInt32(pid_) && parcel.WriteUint32(static_cast(visibilityState_)); } -sptr WindowPidVisibilityInfo::Unmarshalling(Parcel& parcel) +WindowPidVisibilityInfo* WindowPidVisibilityInfo::Unmarshalling(Parcel& parcel) { - sptr windowPidVisibilityInfo = new (std::nothrow) WindowPidVisibilityInfo(); + auto windowPidVisibilityInfo = new (std::nothrow) WindowPidVisibilityInfo(); if (windowPidVisibilityInfo == nullptr) { TLOGE(WmsLogTag::WMS_LIFE, "window pid visibility info is nullptr."); return nullptr; -- Gitee From 01ae1c90d01eed757375881cf8e2fc674d1ef493 Mon Sep 17 00:00:00 2001 From: hubijie Date: Fri, 23 Aug 2024 18:34:26 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E5=BA=94=E7=94=A8=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E6=89=80=E6=9C=89=E7=AA=97=E5=8F=A3=E6=98=BE=E9=9A=90=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8F=98=E5=8C=96=E9=80=9A=E7=9F=A5=20Signed-off-by:?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/scene_session_manager.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 8f8632381c..66e3dc0fcd 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -3838,27 +3838,26 @@ void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr windowPidVisibilityInfo = sptr::MakeSptr(); - windowPidVisibilityInfo->pid_ = pid; - std::shared_lock lock(visibleWindowCountMapMutex_); - if (VISIBILITY_STATE_MAP.at(oldState) && !VISIBILITY_STATE_MAP.at(newState)) { - visibleWindowCountMap_[pid]--; - if (visibleWindowCountMap_[pid] == 0) { + if (VISIBILITY_STATE_MAP.at(oldState) != VISIBILITY_STATE_MAP.at(newState)) { + sptr windowPidVisibilityInfo = sptr::MakeSptr(); + windowPidVisibilityInfo->pid_ = pid; + { + std::unique_lock lock(visibleWindowCountMapMutex_); + visibleWindowCountMap_[pid] = VISIBILITY_STATE_MAP.at(newState) ? + visibleWindowCountMap_[pid] + 1 : visibleWindowCountMap_[pid] - 1; + int32_t count = visibleWindowCountMap_[pid]; + } + if (count == 0) { TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid); windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE; SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo); - } else if (visibleWindowCountMap_[pid] < 0) { - RecoveryVisibilityPidCount(pid); - } - } else if (!VISIBILITY_STATE_MAP.at(oldState) && VISIBILITY_STATE_MAP.at(newState)) { - visibleWindowCountMap_[pid]++; - if (visibleWindowCountMap_[pid] == 1) { + } else if (count == 1) { TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid); windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE; SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo); + } else if (count < 0) { + TLOGE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid); + RecoveryVisibilityPidCount(pid); } } }; @@ -3868,8 +3867,9 @@ void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr lock(sceneSessionMapMutex_); - visibleWindowCountMap_.erase(pid); - for (auto iter : sceneSessionMap_) { + std::unique_lock lock(visibleWindowCountMapMutex_); + visibleWindowCountMap_[pid] = 0; + for (const auto& iter : sceneSessionMap_) { auto& session = iter.second; if (session && session->GetCallingPid() == pid && VISIBILITY_STATE_MAP.at(session->GetSessionState())) { visibleWindowCountMap_[pid]++; -- Gitee From fc75f6dc0060610ff0248823a07f0baffa76aa77 Mon Sep 17 00:00:00 2001 From: hubijie Date: Fri, 23 Aug 2024 18:41:09 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E5=BA=94=E7=94=A8=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E6=89=80=E6=9C=89=E7=AA=97=E5=8F=A3=E6=98=BE=E9=9A=90=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8F=98=E5=8C=96=E9=80=9A=E7=9F=A5=20Signed-off-by:?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/host/include/scene_session.h | 2 + window_scene/session/host/include/session.h | 8 +-- .../session/host/src/scene_session.cpp | 11 ++++ window_scene/session/host/src/session.cpp | 21 +++---- .../include/scene_session_manager.h | 2 +- .../src/scene_session_manager.cpp | 60 +++++++++---------- .../scene_session_manager_lifecycle_test.cpp | 3 +- .../test/unittest/session_lifecycle_test.cpp | 21 ------- 8 files changed, 54 insertions(+), 74 deletions(-) diff --git a/window_scene/session/host/include/scene_session.h b/window_scene/session/host/include/scene_session.h index d0e0a824ea..5b173bd411 100644 --- a/window_scene/session/host/include/scene_session.h +++ b/window_scene/session/host/include/scene_session.h @@ -80,6 +80,7 @@ using NotifyLayoutFullScreenChangeFunc = std::function; using NotifyForceSplitFunc = std::function; using UpdatePrivateStateAndNotifyFunc = std::function; + class SceneSession : public Session { public: friend class HidumpController; @@ -391,6 +392,7 @@ public: void SetMinimizedFlagByUserSwitch(bool isMinimized); bool IsMinimizedByUserSwitch() const; void UnregisterSessionChangeListeners() override; + void SetVisibilityChangedDetectFunc(const VisibilityChangedDetectFunc& func); protected: void NotifySessionRectChange(const WSRect& rect, const SizeChangeReason& reason = SizeChangeReason::UNDEFINED); diff --git a/window_scene/session/host/include/session.h b/window_scene/session/host/include/session.h index cd93f2e658..b31eb596c7 100644 --- a/window_scene/session/host/include/session.h +++ b/window_scene/session/host/include/session.h @@ -81,8 +81,8 @@ using NotifySystemSessionKeyEventFunc = std::function; using NotifyContextTransparentFunc = std::function; using NotifyFrameLayoutFinishFunc = std::function; -using VisibilityChangedDetectFunc = std::function; +using VisibilityChangedDetectFunc = std::function; class ILifecycleListener { public: @@ -448,7 +448,6 @@ public: bool GetUIStateDirty() const; void ResetDirtyFlags(); static bool IsScbCoreEnabled(); - void SetVisibilityChangedDetectFunc(const VisibilityChangedDetectFunc& func); protected: class SessionLifeCycleTask : public virtual RefBase { @@ -553,6 +552,8 @@ protected: NotifySystemSessionKeyEventFunc systemSessionKeyEventFunc_; NotifyContextTransparentFunc contextTransparentFunc_; NotifyFrameLayoutFinishFunc frameLayoutFinishFunc_; + VisibilityChangedDetectFunc visibilityChangedDetectFunc_; + SystemSessionConfig systemConfig_; bool needSnapshot_ = false; float snapshotScale_ = 0.5; @@ -618,7 +619,6 @@ private: std::shared_ptr handler_; std::shared_ptr exportHandler_; std::function isScreenLockedCallback_; - VisibilityChangedDetectFunc visibilityChangedDetectFunc_; mutable std::shared_mutex propertyMutex_; sptr property_; diff --git a/window_scene/session/host/src/scene_session.cpp b/window_scene/session/host/src/scene_session.cpp index 24034247b8..a131f9f93a 100644 --- a/window_scene/session/host/src/scene_session.cpp +++ b/window_scene/session/host/src/scene_session.cpp @@ -2344,6 +2344,9 @@ void SceneSession::UpdateNativeVisibility(bool visible) int32_t persistentId = session->GetPersistentId(); WLOGFI("[WMSSCB] name: %{public}s, id: %{public}u, visible: %{public}u", session->sessionInfo_.bundleName_.c_str(), persistentId, visible); + if (visibilityChangedDetectFunc_) { + visibilityChangedDetectFunc_(GetCallingPid(), session->isVisible_, visible); + } session->isVisible_ = visible; if (session->specificCallback_ == nullptr) { WLOGFW("specific callback is null."); @@ -4277,6 +4280,9 @@ bool SceneSession::UpdateVisibilityInner(bool visibility) if (isVisible_ == visibility) { return false; } + if (visibilityChangedDetectFunc_) { + visibilityChangedDetectFunc_(GetCallingPid(), isVisible_, visible); + } isVisible_ = visibility; return true; } @@ -4473,4 +4479,9 @@ void SceneSession::UnregisterSessionChangeListeners() }; PostTask(task, "UnregisterSessionChangeListeners"); } + +void SceneSession::SetVisibilityChangedDetectFunc(const VisibilityChangedDetectFunc& func) +{ + visibilityChangedDetectFunc_ = func; +} } // namespace OHOS::Rosen diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index 1088c83273..13d537002f 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -427,9 +427,6 @@ void Session::SetSessionState(SessionState state) WLOGFD("Invalid session state: %{public}u", state); return; } - if (visibilityChangedDetectFunc_) { - visibilityChangedDetectFunc_(GetCallingPid(), state_, state); - } state_ = state; SetMainSessionUIStateDirty(true); } @@ -442,9 +439,6 @@ void Session::UpdateSessionState(SessionState state) state == SessionState::STATE_BACKGROUND) { RemoveWindowDetectTask(); } - if (visibilityChangedDetectFunc_) { - visibilityChangedDetectFunc_(GetCallingPid(), state_, state); - } state_ = state; SetMainSessionUIStateDirty(true); NotifySessionStateChange(state); @@ -625,6 +619,9 @@ void Session::SetCallingPid(int32_t id) { TLOGI(WmsLogTag::WMS_EVENT, "id:%{public}d, callingPid:%{public}u", persistentId_, id); callingPid_ = id; + if (isVisible_) { + visibilityChangedDetectFunc_(callingPid_, false, isVisible_); + } } void Session::SetCallingUid(int32_t id) @@ -899,7 +896,7 @@ __attribute__((no_sanitize("cfi"))) WSError Session::ConnectInner(const sptr& sessionStage, const sptrGetPersistentId(); - callingPid_ = pid; + SetCallingPid(pid); callingUid_ = uid; bufferAvailable_ = true; UpdateSessionState(SessionState::STATE_CONNECT); @@ -1099,6 +1096,9 @@ WSError Session::Disconnect(bool isFromClient) UpdateSessionState(SessionState::STATE_BACKGROUND); UpdateSessionState(SessionState::STATE_DISCONNECT); NotifyDisconnect(); + if (visibilityChangedDetectFunc_) { + visibilityChangedDetectFunc_(GetCallingPid(), isVisible_, false); + } DelayedSingleton::GetInstance()->OnSessionLost(persistentId_); return WSError::WS_OK; } @@ -3121,9 +3121,4 @@ bool Session::IsScbCoreEnabled() return system::GetParameter("const.product.devicetype", "unknown") == UI_TYPE_PHONE && system::GetParameter("persist.window.scbcore.enable", "1") == "1"; } - -void Session::SetVisibilityChangedDetectFunc(const VisibilityChangedDetectFunc& func) -{ - visibilityChangedDetectFunc_ = func; -} } // namespace OHOS::Rosen diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index f111656fd9..21216440ad 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -571,7 +571,7 @@ private: std::map> sceneSessionMap_; std::map> systemTopSceneSessionMap_; std::map> nonSystemFloatSceneSessionMap_; - mutable std::shared_mutex visibleWindowCountMapMutex_; + std::mutex visibleWindowCountMapMutex_; std::map visibleWindowCountMap_; sptr scbSessionHandler_; std::shared_ptr listenerController_; diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 66e3dc0fcd..9f40dd1df1 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -124,15 +124,6 @@ static const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait f static std::shared_ptr g_scbSubscriber(nullptr); -const std::map VISIBILITY_STATE_MAP = { - { SessionState::STATE_DISCONNECT, false }, - { SessionState::STATE_CONNECT, false }, - { SessionState::STATE_FOREGROUND, true }, - { SessionState::STATE_ACTIVE, true }, - { SessionState::STATE_INACTIVE, false }, - { SessionState::STATE_BACKGROUND, false }, -}; - std::string GetCurrentTime() { struct timespec tn; @@ -3837,28 +3828,32 @@ void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr windowPidVisibilityInfo = sptr::MakeSptr(); - windowPidVisibilityInfo->pid_ = pid; - { - std::unique_lock lock(visibleWindowCountMapMutex_); - visibleWindowCountMap_[pid] = VISIBILITY_STATE_MAP.at(newState) ? - visibleWindowCountMap_[pid] + 1 : visibleWindowCountMap_[pid] - 1; - int32_t count = visibleWindowCountMap_[pid]; - } - if (count == 0) { - TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid); - windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE; - SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo); - } else if (count == 1) { - TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid); - windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE; - SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo); - } else if (count < 0) { - TLOGE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid); - RecoveryVisibilityPidCount(pid); - } + VisibilityChangedDetectFunc func = [this](const int32_t pid, const bool isVisible, const bool newIsVisible) { + if (isVisible == newIsVisible || pid == -1) { + return; + } + sptr windowPidVisibilityInfo = sptr::MakeSptr(); + windowPidVisibilityInfo->pid_ = pid; + int32_t count = 0; + int beforeCount = 0; + { + std::unique_lock lock(visibleWindowCountMapMutex_); + beforeCount = visibleWindowCountMap_[pid]; + visibleWindowCountMap_[pid] = newIsVisible ? visibleWindowCountMap_[pid] + 1 : + visibleWindowCountMap_[pid] - 1; + count = visibleWindowCountMap_[pid]; + } + if (beforeCount > 0 && count == 0) { + TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid); + windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE; + SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo); + } else if (beforeCount == 0 && count == 1) { + TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid); + windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE; + SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo); + } else if (count < 0) { + TLOGE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid); + RecoveryVisibilityPidCount(pid); } }; sceneSession->SetVisibilityChangedDetectFunc(func); @@ -3867,11 +3862,10 @@ void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr lock(sceneSessionMapMutex_); - std::unique_lock lock(visibleWindowCountMapMutex_); visibleWindowCountMap_[pid] = 0; for (const auto& iter : sceneSessionMap_) { auto& session = iter.second; - if (session && session->GetCallingPid() == pid && VISIBILITY_STATE_MAP.at(session->GetSessionState())) { + if (session && session->GetCallingPid() == pid && session->isVisible_) { visibleWindowCountMap_[pid]++; } } diff --git a/window_scene/test/unittest/scene_session_manager_lifecycle_test.cpp b/window_scene/test/unittest/scene_session_manager_lifecycle_test.cpp index 4af4dbc987..ded885f9a5 100644 --- a/window_scene/test/unittest/scene_session_manager_lifecycle_test.cpp +++ b/window_scene/test/unittest/scene_session_manager_lifecycle_test.cpp @@ -913,14 +913,13 @@ HWTEST_F(SceneSessionManagerLifecycleTest, RecoveryVisibilityPidCount, Function ASSERT_NE(sceneSession, nullptr); ssm_->sceneSessionMap_.insert({1, sceneSession}); sceneSession->SetCallingPid(pid); - sceneSession->SetSessionState(SessionState::STATE_BACKGROUND); sptr sceneSession2 = sptr::MakeSptr(info, nullptr); ASSERT_NE(sceneSession2, nullptr); ssm_->sceneSessionMap_.insert({2, sceneSession2}); sceneSession2->SetCallingPid(pid); - sceneSession2->SetSessionState(SessionState::STATE_FOREGROUND); + sceneSession2->isVisible_ = true; ssm_->RecoveryVisibilityPidCount(pid); EXPECT_EQ(1, ssm_->visibleWindowCountMap_[pid]); diff --git a/window_scene/test/unittest/session_lifecycle_test.cpp b/window_scene/test/unittest/session_lifecycle_test.cpp index f5536ef04a..8173f9a92b 100644 --- a/window_scene/test/unittest/session_lifecycle_test.cpp +++ b/window_scene/test/unittest/session_lifecycle_test.cpp @@ -637,27 +637,6 @@ HWTEST_F(WindowSessionLifecycleTest, UpdateSessionState32, Function | SmallTest ASSERT_EQ(session_->state_, SessionState::STATE_CONNECT); } -/** - * @tc.name: UpdateSessionState01 - * @tc.desc: UpdateSessionState01 - * @tc.type: FUNC - */ -HWTEST_F(WindowSessionLifecycleTest, UpdateSessionState01, Function | SmallTest | Level2) -{ - ASSERT_NE(session_, nullptr); - session_->SetSessionState(SessionState::STATE_CONNECT); - session_->UpdateSessionState(SessionState::STATE_CONNECT); - ASSERT_EQ(session_->state_, SessionState::STATE_CONNECT); - - session_->SetSessionState(SessionState::STATE_CONNECT); - session_->UpdateSessionState(SessionState::STATE_FOREGROUND); - ASSERT_EQ(session_->state_, SessionState::STATE_FOREGROUND); - - session_->SetSessionState(SessionState::STATE_ACTIVE); - session_->UpdateSessionState(SessionState::STATE_INACTIVE); - ASSERT_EQ(session_->state_, SessionState::STATE_INACTIVE); -} - /** * @tc.name: IsSystemSession44 * @tc.desc: IsSystemSession -- Gitee From ae124fb6c08c24b38069467cf448cd381ef05c16 Mon Sep 17 00:00:00 2001 From: hubijie Date: Fri, 30 Aug 2024 12:55:40 +0000 Subject: [PATCH 6/7] update window_scene/session/host/include/session.h. Signed-off-by: hubijie --- window_scene/session/host/include/session.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/window_scene/session/host/include/session.h b/window_scene/session/host/include/session.h index ec55dfe891..e8e9825953 100644 --- a/window_scene/session/host/include/session.h +++ b/window_scene/session/host/include/session.h @@ -453,7 +453,7 @@ public: bool GetUIStateDirty() const; void ResetDirtyFlags(); static bool IsScbCoreEnabled(); - bool IsVisible(); + bool IsVisible() const; protected: class SessionLifeCycleTask : public virtual RefBase { -- Gitee From f1d9f752f58053d25e317d954b2da72f702c140f Mon Sep 17 00:00:00 2001 From: hubijie Date: Fri, 30 Aug 2024 12:57:03 +0000 Subject: [PATCH 7/7] update window_scene/session/host/src/session.cpp. Signed-off-by: hubijie --- window_scene/session/host/src/session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index b29f9c627e..1255e7e8c3 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -3158,7 +3158,7 @@ bool Session::IsScbCoreEnabled() return system::GetParameter("persist.window.scbcore.enable", "1") == "1"; } -bool Session::IsVisible() +bool Session::IsVisible() const { return isVisible_; } -- Gitee