diff --git a/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp b/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp index 27998b4db258a72991652a94bfde07f3cc2f3979..f27e1c67e3c774d00a61bfefc6c3af1ff1cde7b9 100644 --- a/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp +++ b/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp @@ -253,12 +253,15 @@ void ScreenSessionManagerClient::OnPropertyChanged(ScreenId screenId, void ScreenSessionManagerClient::OnPowerStatusChanged(DisplayPowerEvent event, EventStatus status, PowerStateChangeReason reason) { - std::lock_guard lock(screenSessionMapMutex_); - if (screenSessionMap_.empty()) { - TLOGE(WmsLogTag::DMS, "[UL_POWER]screenSessionMap_ is nullptr"); - return; + sptr screenSession; + { + std::lock_guard lock(screenSessionMapMutex_); + if (screenSessionMap_.empty()) { + TLOGE(WmsLogTag::DMS, "[UL_POWER]screenSessionMap_ is empty"); + return; + } + screenSession = screenSessionMap_.begin()->second; } - auto screenSession = screenSessionMap_.begin()->second; if (!screenSession) { TLOGE(WmsLogTag::DMS, "[UL_POWER]screenSession is null"); return; diff --git a/window_scene/session/screen/include/screen_session.h b/window_scene/session/screen/include/screen_session.h index 5f1cb39c652d5597dac2f792557b31821fb41b6a..e6737f63c82be66d353ee6944574a3e757a780ff 100644 --- a/window_scene/session/screen/include/screen_session.h +++ b/window_scene/session/screen/include/screen_session.h @@ -41,6 +41,7 @@ using DestroyScreenSceneFunc = std::function; class IScreenChangeListener { public: + virtual ~IScreenChangeListener() = default; virtual void OnConnect(ScreenId screenId) {} virtual void OnDisconnect(ScreenId screenId) {} virtual void OnPropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason, @@ -390,12 +391,14 @@ public: private: bool IsVertical(Rotation rotation) const; Orientation CalcDisplayOrientationToOrientation(DisplayOrientation displayOrientation) const; + std::vector GetScreenChangeListenerList() const; + ScreenProperty property_; mutable std::mutex propertyMutex_; // above guarded by clientProxyMutex_ std::shared_ptr displayNode_; ScreenState screenState_ { ScreenState::INIT }; std::vector screenChangeListenerList_; - std::mutex screenChangeListenerListMutex_; + mutable std::mutex screenChangeListenerListMutex_; ScreenCombination combination_ { ScreenCombination::SCREEN_ALONE }; mutable std::mutex combinationMutex_; // above guarded by clientProxyMutex_ VirtualScreenFlag screenFlag_ { VirtualScreenFlag::DEFAULT }; diff --git a/window_scene/session/screen/src/screen_session.cpp b/window_scene/session/screen/src/screen_session.cpp index 1b17b3f61f5818ef412bee0a08ce6ed46c39deeb..be8885e4f9a6d534b14f4426fd6cfbceb36258de 100644 --- a/window_scene/session/screen/src/screen_session.cpp +++ b/window_scene/session/screen/src/screen_session.cpp @@ -781,16 +781,16 @@ void ScreenSession::Disconnect() void ScreenSession::PropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason) { - std::lock_guard lock(screenChangeListenerListMutex_); - property_ = newProperty; + SetScreenProperty(newProperty); if (reason == ScreenPropertyChangeReason::VIRTUAL_PIXEL_RATIO_CHANGE) { return; } - if (screenChangeListenerList_.empty()) { + auto listeners = GetScreenChangeListenerList(); + if (listeners.empty()) { TLOGE(WmsLogTag::DMS, "screenChangeListenerList is empty."); return; } - for (auto& listener : screenChangeListenerList_) { + for (auto* listener : listeners) { if (!listener) { TLOGE(WmsLogTag::DMS, "screenChangeListener is null."); continue; @@ -2782,4 +2782,10 @@ uint32_t ScreenSession::GetScreenAreaHeight() const { return property_.GetScreenAreaHeight(); } + +std::vector ScreenSession::GetScreenChangeListenerList() const +{ + std::lock_guard lock(screenChangeListenerListMutex_); + return screenChangeListenerList_; +} } // namespace OHOS::Rosen diff --git a/window_scene/test/dms_unittest/screen_session_test.cpp b/window_scene/test/dms_unittest/screen_session_test.cpp index 88a887886a34dcd06b74cec9f1e35f7645ad4933..ef30eaf21be32e55e0d941d83b33722d077ec3ff 100644 --- a/window_scene/test/dms_unittest/screen_session_test.cpp +++ b/window_scene/test/dms_unittest/screen_session_test.cpp @@ -14,10 +14,13 @@ */ #include "screen_session.h" + #include -#include "screen_session_manager/include/screen_session_manager.h" -#include "scene_board_judgement.h" +#include + #include "fold_screen_state_internel.h" +#include "scene_board_judgement.h" +#include "screen_session_manager/include/screen_session_manager.h" #include "window_manager_hilog.h" // using namespace FRAME_TRACE; @@ -34,28 +37,31 @@ namespace { g_errLog = msg; } } + class MockScreenChangeListener : public IScreenChangeListener { public: - void OnConnect(ScreenId screenId) override {} - void OnDisconnect(ScreenId screenId) override {} - void OnPropertyChange(const ScreenProperty& newProperty, ScreenPropertyChangeReason reason, - ScreenId screenId) override {} - void OnPowerStatusChange(DisplayPowerEvent event, EventStatus status, - PowerStateChangeReason reason) override {} - void OnSensorRotationChange(float sensorRotation, ScreenId screenId) override {} - void OnScreenOrientationChange(float screenOrientation, ScreenId screenId) override {} - void OnScreenRotationLockedChange(bool isLocked, ScreenId screenId) override {} - void OnScreenExtendChange(ScreenId mainScreenId, ScreenId extendScreenId) override {} - void OnHoverStatusChange(int32_t hoverStatus, bool needRotate, ScreenId screenId) override {} - void OnScreenCaptureNotify(ScreenId mainScreenId, int32_t uid, const std::string& clientName) override {} - void OnCameraBackSelfieChange(bool isCameraBackSelfie, ScreenId screenId) override {} - void OnSuperFoldStatusChange(ScreenId screenId, SuperFoldStatus superFoldStatus) override {} - void OnSecondaryReflexionChange(ScreenId screenId, bool isSecondaryReflexion) override {} - void OnExtendScreenConnectStatusChange(ScreenId screenId, - ExtendScreenConnectStatus extendScreenConnectStatus) override {} - void OnBeforeScreenPropertyChange(FoldStatus foldStatus) override {} - void OnScreenModeChange(ScreenModeChangeEvent screenModeChangeEvent) override {} + MOCK_METHOD(void, OnConnect, (ScreenId screenId), (override)); + MOCK_METHOD(void, OnDisconnect, (ScreenId screenId), (override)); + MOCK_METHOD(void, OnPropertyChange, + (const ScreenProperty& newProperty, ScreenPropertyChangeReason reason, ScreenId screenId), (override)); + MOCK_METHOD(void, OnPowerStatusChange, + (DisplayPowerEvent event, EventStatus status, PowerStateChangeReason reason), (override)); + MOCK_METHOD(void, OnSensorRotationChange, (float sensorRotation, ScreenId screenId), (override)); + MOCK_METHOD(void, OnScreenOrientationChange, (float screenOrientation, ScreenId screenId), (override)); + MOCK_METHOD(void, OnScreenRotationLockedChange, (bool isLocked, ScreenId screenId), (override)); + MOCK_METHOD(void, OnScreenExtendChange, (ScreenId mainScreenId, ScreenId extendScreenId), (override)); + MOCK_METHOD(void, OnHoverStatusChange, (int32_t hoverStatus, bool needRotate, ScreenId screenId), (override)); + MOCK_METHOD(void, OnScreenCaptureNotify, + (ScreenId mainScreenId, int32_t uid, const std::string& clientName), (override)); + MOCK_METHOD(void, OnCameraBackSelfieChange, (bool isCameraBackSelfie, ScreenId screenId), (override)); + MOCK_METHOD(void, OnSuperFoldStatusChange, (ScreenId screenId, SuperFoldStatus superFoldStatus), (override)); + MOCK_METHOD(void, OnSecondaryReflexionChange, (ScreenId screenId, bool isSecondaryReflexion), (override)); + MOCK_METHOD(void, OnExtendScreenConnectStatusChange, + (ScreenId screenId, ExtendScreenConnectStatus extendScreenConnectStatus), (override)); + MOCK_METHOD(void, OnBeforeScreenPropertyChange, (FoldStatus foldStatus), (override)); + MOCK_METHOD(void, OnScreenModeChange, (ScreenModeChangeEvent screenModeChangeEvent), (override)); }; + class ScreenSessionTest : public testing::Test { public: void TearDown() override; @@ -4592,6 +4598,60 @@ HWTEST_F(ScreenSessionTest, GetScreenSnapshotWithAllWindows02, TestSize.Level2) pixelMap = screenSession->GetScreenSnapshotWithAllWindows(scaleX, scaleY, isNeedCheckDrmAndSurfaceLock); EXPECT_EQ(pixelMap, nullptr); } + +/** + * @tc.name: TestPropertyChangeAllCases + * @tc.desc: Verify PropertyChange behavior for multiple scenarios + * @tc.type: FUNC + */ +HWTEST_F(ScreenSessionTest, TestPropertyChangeAllCases, TestSize.Level1) +{ + ScreenId screenId = 10000; + ScreenProperty screenProperty; + sptr session = sptr::MakeSptr(screenId, screenProperty, screenId); + + // Case 1: reason = VIRTUAL_PIXEL_RATIO_CHANGE -> no listener call + { + auto listener = std::make_unique(); + EXPECT_CALL(*listener, OnPropertyChange(_, _, _)).Times(0); + + session->screenChangeListenerList_.push_back(listener.get()); + session->PropertyChange(screenProperty, ScreenPropertyChangeReason::VIRTUAL_PIXEL_RATIO_CHANGE); + session->screenChangeListenerList_.clear(); + } + + // Case 2: listener list is empty -> early return + { + session->PropertyChange(screenProperty, ScreenPropertyChangeReason::UNDEFINED); + SUCCEED(); + } + + // Case 3: listener list contains nullptr -> skip safely + { + auto reason = ScreenPropertyChangeReason::UNDEFINED; + auto listener = std::make_unique(); + EXPECT_CALL(*listener, OnPropertyChange(_, reason, screenId)).Times(1); + + session->screenChangeListenerList_.push_back(nullptr); + session->screenChangeListenerList_.push_back(listener.get()); + session->PropertyChange(screenProperty, reason); + session->screenChangeListenerList_.clear(); + } + + // Case 4: normal case -> all valid listeners should be called + { + auto reason = ScreenPropertyChangeReason::UNDEFINED; + auto listener1 = std::make_unique(); + auto listener2 = std::make_unique(); + EXPECT_CALL(*listener1, OnPropertyChange(_, reason, screenId)).Times(1); + EXPECT_CALL(*listener2, OnPropertyChange(_, reason, screenId)).Times(1); + + session->screenChangeListenerList_.push_back(listener1.get()); + session->screenChangeListenerList_.push_back(listener2.get()); + session->PropertyChange(screenProperty, reason); + session->screenChangeListenerList_.clear(); + } +} } // namespace } // namespace Rosen } // namespace OHOS