From c5844a6467464e3b2435b54ee407aab306e3d060 Mon Sep 17 00:00:00 2001 From: Grady Date: Mon, 17 Jan 2022 21:30:59 +0800 Subject: [PATCH] add screen system testcase Signed-off-by: Grady Change-Id: I1fae58fa89ff8e20c76baf30dd2e3a57a1a0f3f4 --- dm/test/systemtest/BUILD.gn | 15 ++ dm/test/systemtest/display_test_utils.cpp | 92 ++++++++++- dm/test/systemtest/display_test_utils.h | 41 +++++ dm/test/systemtest/screen_manager_test.cpp | 176 +++++++++++++++++++++ dmserver/src/display_manager_service.cpp | 12 +- 5 files changed, 331 insertions(+), 5 deletions(-) create mode 100644 dm/test/systemtest/screen_manager_test.cpp diff --git a/dm/test/systemtest/BUILD.gn b/dm/test/systemtest/BUILD.gn index 65ebd6218f..fa19dfafcf 100644 --- a/dm/test/systemtest/BUILD.gn +++ b/dm/test/systemtest/BUILD.gn @@ -21,6 +21,7 @@ group("systemtest") { deps = [ ":dm_display_minimal_test", ":dm_display_power_test", + ":dm_screen_manager_test", ":dm_screenshot_cmd_test", ":dm_screenshot_test", ] @@ -68,6 +69,17 @@ ohos_systemtest("dm_screenshot_cmd_test") { ## SystemTest dm_screenshot_cmd_test }}} +## SystemTest dm_screen_manager_test {{{ +ohos_systemtest("dm_screen_manager_test") { + module_out_path = module_out_path + + sources = [ "screen_manager_test.cpp" ] + + deps = [ ":dm_systemtest_common" ] +} + +## SystemTest dm_screen_manager_test }}} + ## Build dm_systemtest_common.a {{{ config("dm_systemtest_common_public_config") { include_dirs = [ @@ -75,6 +87,9 @@ config("dm_systemtest_common_public_config") { "//foundation/windowmanager/dmserver/include", "//foundation/windowmanager/interfaces/innerkits/dm", "//foundation/windowmanager/utils/include", + + # RSSurface + "//foundation/graphic/standard/rosen/modules/render_service_client", ] } diff --git a/dm/test/systemtest/display_test_utils.cpp b/dm/test/systemtest/display_test_utils.cpp index fa3b46aa30..9d85305b89 100644 --- a/dm/test/systemtest/display_test_utils.cpp +++ b/dm/test/systemtest/display_test_utils.cpp @@ -21,6 +21,23 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "DisplayTestUtils"}; } +DisplayTestUtils::~DisplayTestUtils() +{ + if (prevBuffer_ != nullptr) { + SurfaceError ret = csurface_->ReleaseBuffer(prevBuffer_, -1); + if (ret != SURFACE_ERROR_OK) { + WLOGFE("buffer release failed"); + return; + } + WLOGFI("prevBuffer_ release success"); + } + csurface_ = nullptr; + psurface_ = nullptr; + listener_ = nullptr; + prevBuffer_ = nullptr; + bufferHandle_ = nullptr; +} + bool DisplayTestUtils::SizeEqualToDisplay(const sptr& display, const Media::Size cur) { int32_t dWidth = display->GetWidth(); @@ -28,7 +45,7 @@ bool DisplayTestUtils::SizeEqualToDisplay(const sptr& display, const Me bool res = ((cur.width == dWidth) && (cur.height == dHeight)); if (!res) { - WLOGFI("DisplaySize: %d %d, CurrentSize: %d %d\n", dWidth, dHeight, cur.width, cur.height); + WLOGFE("DisplaySize: %d %d, CurrentSize: %d %d", dWidth, dHeight, cur.width, cur.height); } return res; } @@ -37,9 +54,80 @@ bool DisplayTestUtils::SizeEqual(const Media::Size dst, const Media::Size cur) { bool res = ((cur.width == dst.width) && (cur.height == dst.height)); if (!res) { - WLOGFI("Desired Size: %d %d, Current Size: %d %d\n", dst.width, dst.height, cur.width, cur.height); + WLOGFE("Desired Size: %d %d, Current Size: %d %d", dst.width, dst.height, cur.width, cur.height); } return res; } + +bool DisplayTestUtils::CreateSurface() +{ + csurface_ = Surface::CreateSurfaceAsConsumer(); + if (csurface_ == nullptr) { + WLOGFE("csurface create failed"); + return false; + } + + auto producer = csurface_->GetProducer(); + psurface_ = Surface::CreateSurfaceAsProducer(producer); + if (psurface_ == nullptr) { + WLOGFE("csurface create failed"); + return false; + } + + listener_ = new BufferListener(*this); + SurfaceError ret = csurface_->RegisterConsumerListener(listener_); + if (ret != SURFACE_ERROR_OK) { + WLOGFE("listener register failed"); + return false; + } + return true; +} + +void DisplayTestUtils::OnVsync() +{ + std::lock_guard lock(mutex_); + WLOGFI("DisplayTestUtils::OnVsyn"); + sptr cbuffer = nullptr; + int32_t fence = -1; + int64_t timestamp = 0; + OHOS::Rect damage; + if (csurface_ == nullptr) { + WLOGFE("csurface_ is null"); + } + auto sret = csurface_->AcquireBuffer(cbuffer, fence, timestamp, damage); + UniqueFd fenceFd(fence); + if (cbuffer == nullptr || sret != OHOS::SURFACE_ERROR_OK) { + WLOGFE("acquire buffer failed"); + return; + } + bufferHandle_ = cbuffer->GetBufferHandle(); + if (bufferHandle_ == nullptr) { + WLOGFE("get bufferHandle failed"); + return; + } + if (defaultWidth_ == static_cast(bufferHandle_->width) && + defaultHeight_ == static_cast(bufferHandle_->height)) { + successCount_++; + WLOGFI("success count in OnVsync: %d", successCount_); + } else { + failCount_++; + } + if (cbuffer != prevBuffer_) { + if (prevBuffer_ != nullptr) { + SurfaceError ret = csurface_->ReleaseBuffer(prevBuffer_, -1); + if (ret != SURFACE_ERROR_OK) { + WLOGFE("buffer release failed"); + return; + } + } + prevBuffer_ = cbuffer; + } +} + +void DisplayTestUtils::SetDefaultWH(const sptr& display) +{ + defaultWidth_ = display->GetWidth(); + defaultHeight_ = display->GetHeight(); +} } // namespace ROSEN } // namespace OHOS \ No newline at end of file diff --git a/dm/test/systemtest/display_test_utils.h b/dm/test/systemtest/display_test_utils.h index d30204be0e..e78d255ad7 100644 --- a/dm/test/systemtest/display_test_utils.h +++ b/dm/test/systemtest/display_test_utils.h @@ -16,19 +16,60 @@ #ifndef FRAMEWORKS_DM_TEST_ST_DISPLAY_TEST_UTILS_H #define FRAMEWORKS_DM_TEST_ST_DISPLAY_TEST_UTILS_H +#include + #include "display_manager.h" +#include "screen_manager.h" #include "display_property.h" #include "display.h" +#include "screen.h" #include "display_info.h" #include "wm_common.h" +#include "dm_common.h" #include "window_manager_hilog.h" +#include "unique_fd.h" +#include "core/ui/rs_surface_node.h" +#include "core/ui/rs_display_node.h" namespace OHOS { namespace Rosen { class DisplayTestUtils { public: + ~DisplayTestUtils(); static bool SizeEqualToDisplay(const sptr& display, const Media::Size cur); static bool SizeEqual(const Media::Size dst, const Media::Size cur); + void init(); + bool CreateSurface(); + void SetDefaultWH(const sptr& display); + class BufferListener : public IBufferConsumerListener { + public: + explicit BufferListener(DisplayTestUtils &displayTestUtils): utils_(displayTestUtils) + { + } + ~BufferListener() noexcept override = default; + void OnBufferAvailable() override + { + utils_.OnVsync(); + } + + private: + DisplayTestUtils &utils_; + }; + friend class BufferListener; + + void OnVsync(); + uint32_t successCount_ = 0; + uint32_t failCount_ = 0; + uint32_t defaultWidth_ = 0; + uint32_t defaultHeight_ = 0; + sptr listener_ = nullptr; + sptr csurface_ = nullptr; // cosumer surface + sptr psurface_ = nullptr; // producer surface + sptr prevBuffer_ = nullptr; + BufferHandle *bufferHandle_ = nullptr; + +private: + std::mutex mutex_; }; } // namespace ROSEN } // namespace OHOS diff --git a/dm/test/systemtest/screen_manager_test.cpp b/dm/test/systemtest/screen_manager_test.cpp new file mode 100644 index 0000000000..fb163ce869 --- /dev/null +++ b/dm/test/systemtest/screen_manager_test.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2022 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. + */ + +// gtest +#include +#include "display_test_utils.h" +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace Rosen { +class ScreenManagerTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp() override; + virtual void TearDown() override; + static sptr defaultDisplay_; + static DisplayId defaultDisplayId_; + static std::string defaultName_; + static uint32_t defaultWidth_; + static uint32_t defaultHeight_; + static float defaultDensity_; + static int32_t defaultFlags_; + static VirtualScreenOption defaultoption_; + static uint32_t waitCount_; + const uint32_t sleepUs_ = 10 * 1000; + const uint32_t maxWaitCount_ = 2000; + const uint32_t execTimes_ = 10; +}; + +sptr ScreenManagerTest::defaultDisplay_ = nullptr; +DisplayId ScreenManagerTest::defaultDisplayId_ = DISPLAY_ID_INVALD; +std::string ScreenManagerTest::defaultName_ = "virtualScreen01"; +uint32_t ScreenManagerTest::defaultWidth_ = 480; +uint32_t ScreenManagerTest::defaultHeight_ = 320; +float ScreenManagerTest::defaultDensity_ = 2.0; +int32_t ScreenManagerTest::defaultFlags_ = 0; +VirtualScreenOption ScreenManagerTest::defaultoption_ = { + defaultName_, defaultWidth_, defaultHeight_, defaultDensity_, nullptr, defaultFlags_ +}; +uint32_t ScreenManagerTest::waitCount_ = 0; + +void ScreenManagerTest::SetUpTestCase() +{ + defaultDisplay_ = DisplayManager::GetInstance().GetDefaultDisplay(); + defaultDisplayId_ = defaultDisplay_->GetId(); + defaultWidth_ = defaultDisplay_->GetWidth(); + defaultHeight_ = defaultDisplay_->GetHeight(); + defaultoption_.width_ = defaultWidth_; + defaultoption_.height_ = defaultHeight_; +} + +void ScreenManagerTest::TearDownTestCase() +{ +} + +void ScreenManagerTest::SetUp() +{ +} + +void ScreenManagerTest::TearDown() +{ +} + +namespace { +/** + * @tc.name: ScreenManager01 + * @tc.desc: Create a virtual screen and destroy it + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager01, Function | MediumTest | Level1) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultoption_.surface_ = utils.psurface_; + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + ASSERT_NE(SCREEN_ID_INVALD, virtualScreenId); + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); +} + +/** + * @tc.name: ScreenManager02 + * @tc.desc: Create a virtual screen as mirror of default screen, and destroy virtual screen + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager02, Function | MediumTest | Level1) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultoption_.surface_ = utils.psurface_; + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + ScreenManager::GetInstance().AddMirror(defaultDisplayId_, virtualScreenId); + ASSERT_NE(SCREEN_ID_INVALD, virtualScreenId); + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); +} + +/** + * @tc.name: ScreenManager03 + * @tc.desc: Create a virtual screen and destroy it for 10 times + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager03, Function | MediumTest | Level1) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultoption_.surface_ = utils.psurface_; + for (uint32_t i = 0; i < execTimes_; i++) { + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + ASSERT_NE(SCREEN_ID_INVALD, virtualScreenId); + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + } +} + +/** + * @tc.name: ScreenManager04 + * @tc.desc: Create a virtual screen as mirror of default screen, and destroy virtual screen for 10 times + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager04, Function | MediumTest | Level1) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultoption_.surface_ = utils.psurface_; + for (uint32_t i = 0; i < execTimes_; i++) { + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + ScreenManager::GetInstance().AddMirror(static_cast(defaultDisplayId_), virtualScreenId); + ASSERT_NE(SCREEN_ID_INVALD, virtualScreenId); + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + } +} + +/** + * @tc.name: ScreenManager05 + * @tc.desc: Compare the length and width for recording screen + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager05, Function | MediumTest | Level1) +{ + DisplayTestUtils utils; + utils.SetDefaultWH(defaultDisplay_); + ASSERT_TRUE(utils.CreateSurface()); + defaultoption_.surface_ = utils.psurface_; + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + + ASSERT_NE(SCREEN_ID_INVALD, virtualScreenId); + uint32_t lastCount = -1u; + ScreenManager::GetInstance().AddMirror(static_cast(defaultDisplayId_), virtualScreenId); + while (utils.successCount_ <= execTimes_ && waitCount_ <= maxWaitCount_) { + if (lastCount != utils.successCount_) { + lastCount = utils.successCount_; + } + ASSERT_EQ(0, utils.failCount_); + waitCount_++; + usleep(sleepUs_); + } + ASSERT_GT(utils.successCount_, 0); + ASSERT_GT(maxWaitCount_, waitCount_); + + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); +} +} +} // namespace Rosen +} // namespace OHOS diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index 54a82468fe..f9bcf6ba9d 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -102,7 +102,7 @@ ScreenId DisplayManagerService::CreateVirtualScreen(VirtualScreenOption option) DMError DisplayManagerService::DestroyVirtualScreen(ScreenId screenId) { - WLOGFI("DisplayManagerService::DestroyVirtualScreen"); + WLOGFI("DestroyVirtualScreen::ScreenId: %{public}" PRIu64 "", screenId); if (screenId == SCREEN_ID_INVALID) { WLOGFE("DisplayManagerService: virtualScreenId is invalid"); return DMError::DM_ERROR_INVALID_PARAM; @@ -114,7 +114,12 @@ DMError DisplayManagerService::DestroyVirtualScreen(ScreenId screenId) return abstractScreenController_->DestroyVirtualScreen(screenId); } displayNodeMap_[screenId]->RemoveFromTree(); + WLOGFE("DisplayManagerService: displayNode remove from tree"); displayNodeMap_.erase(screenId); + auto transactionProxy = RSTransactionProxy::GetInstance(); + if (transactionProxy != nullptr) { + transactionProxy->FlushImplicitTransaction(); + } return abstractScreenController_->DestroyVirtualScreen(screenId); } @@ -209,10 +214,11 @@ sptr DisplayManagerService::GetAbstractScreenControlle DMError DisplayManagerService::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) { - if (mainScreenId == SCREEN_ID_INVALID) { + if (mainScreenId == SCREEN_ID_INVALID || mirrorScreenId == SCREEN_ID_INVALID) { return DMError::DM_ERROR_INVALID_PARAM; } WM_SCOPED_TRACE("dms:AddMirror"); + WLOGFI("AddMirror::ScreenId: %{public}" PRIu64 "", mirrorScreenId); std::shared_ptr displayNode = SingletonContainer::Get().GetDisplayNode(mainScreenId); if (displayNode == nullptr) { @@ -222,7 +228,7 @@ DMError DisplayManagerService::AddMirror(ScreenId mainScreenId, ScreenId mirrorS NodeId nodeId = displayNode->GetId(); struct RSDisplayNodeConfig config = {mirrorScreenId, true, nodeId}; - displayNodeMap_[mainScreenId] = RSDisplayNode::Create(config); + displayNodeMap_[mirrorScreenId] = RSDisplayNode::Create(config); auto transactionProxy = RSTransactionProxy::GetInstance(); transactionProxy->FlushImplicitTransaction(); WLOGFI("DisplayManagerService::AddMirror: NodeId: %{public}" PRIu64 "", nodeId >> 32); -- Gitee