blob: 63dd271bf847e167fe4fb152745102e81a27185f [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/linux/gnome_display_config.h"
#include <string_view>
#include <vector>
#include "base/no_destructor.h"
#include "remoting/host/linux/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
namespace remoting {
TEST(GnomeDisplayConfigTest, GetScreenId) {
ASSERT_EQ(GnomeDisplayConfig::GetScreenId("Meta-0"), 0);
ASSERT_EQ(GnomeDisplayConfig::GetScreenId("Meta-123"), 123);
ASSERT_EQ(GnomeDisplayConfig::GetScreenId("Meta-123"),
GnomeDisplayConfig::GetScreenId("Meta-123"));
ASSERT_NE(GnomeDisplayConfig::GetScreenId("Meta-123"),
GnomeDisplayConfig::GetScreenId("SomeMonitor"));
ASSERT_EQ(GnomeDisplayConfig::GetScreenId("SomeMonitor"),
GnomeDisplayConfig::GetScreenId("SomeMonitor"));
ASSERT_NE(GnomeDisplayConfig::GetScreenId("SomeMonitor"),
GnomeDisplayConfig::GetScreenId("SomeOtherMonitor"));
}
TEST(GnomeDisplayConfigTest, FindMonitor) {
GnomeDisplayConfig config;
config.monitors["Meta-0"] = GnomeDisplayConfig::MonitorInfo();
config.monitors["Other-1"] = GnomeDisplayConfig::MonitorInfo();
auto it = config.FindMonitor(0);
ASSERT_NE(it, config.monitors.end());
EXPECT_EQ(it->first, "Meta-0");
webrtc::ScreenId other_1_id = GnomeDisplayConfig::GetScreenId("Other-1");
it = config.FindMonitor(other_1_id);
ASSERT_NE(it, config.monitors.end());
EXPECT_EQ(it->first, "Other-1");
// Try to find a monitor that doesn't exist.
it = config.FindMonitor(12345);
EXPECT_EQ(it, config.monitors.end());
}
TEST(GnomeDisplayConfigTest, RemoveInvalidMonitors) {
GnomeDisplayConfig config;
config.monitors["valid-monitor"] = CreateMonitorInfo(0, 0, 100, 100, 1.0);
config.monitors["invalid-monitor"] = GnomeDisplayConfig::MonitorInfo();
config.RemoveInvalidMonitors();
EXPECT_EQ(config.monitors.size(), 1u);
EXPECT_TRUE(config.monitors.contains("valid-monitor"));
EXPECT_FALSE(config.monitors.contains("invalid-monitor"));
}
// Layout tests:
namespace {
struct LayoutInfoTestCase {
const std::map<std::string, GnomeDisplayConfig::MonitorInfo>&
GetMonitorsForLayoutMode(GnomeDisplayConfig::LayoutMode layout_mode) const {
return layout_mode == GnomeDisplayConfig::LayoutMode::kPhysical
? physical_layout_monitors
: logical_layout_monitors;
}
std::string_view name;
std::map<std::string, GnomeDisplayConfig::MonitorInfo>
physical_layout_monitors;
std::map<std::string, GnomeDisplayConfig::MonitorInfo>
logical_layout_monitors;
GnomeDisplayConfig::LayoutDirection direction;
GnomeDisplayConfig::LayoutAlignment alignment;
};
const std::vector<LayoutInfoTestCase>& GetLayoutInfoTestCases() {
static const base::NoDestructor<std::vector<LayoutInfoTestCase>> test_cases({
{.name = "horizontal_start_aligned",
.physical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(100, 0, 100, 100, 2.0)}},
.logical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(50, 0, 100, 100, 2.0)}},
.direction = GnomeDisplayConfig::LayoutDirection::kHorizontal,
.alignment = GnomeDisplayConfig::LayoutAlignment::kStart},
{.name = "horizontal_center_aligned",
.physical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 200, 2.0)},
{"Meta-1", CreateMonitorInfo(100, 50, 100, 100, 2.0)}},
.logical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 200, 2.0)},
{"Meta-1", CreateMonitorInfo(50, 25, 100, 100, 2.0)}},
.direction = GnomeDisplayConfig::LayoutDirection::kHorizontal,
.alignment = GnomeDisplayConfig::LayoutAlignment::kCenter},
{.name = "horizontal_end_aligned",
.physical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(100, 50, 100, 50, 2.0)}},
.logical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(50, 25, 100, 50, 2.0)}},
.direction = GnomeDisplayConfig::LayoutDirection::kHorizontal,
.alignment = GnomeDisplayConfig::LayoutAlignment::kEnd},
{.name = "vertical_start_aligned",
.physical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(0, 100, 100, 100, 2.0)}},
.logical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(0, 50, 100, 100, 2.0)}},
.direction = GnomeDisplayConfig::LayoutDirection::kVertical,
.alignment = GnomeDisplayConfig::LayoutAlignment::kStart},
{.name = "vertical_center_aligned",
.physical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 200, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(50, 100, 100, 100, 2.0)}},
.logical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 200, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(25, 50, 100, 100, 2.0)}},
.direction = GnomeDisplayConfig::LayoutDirection::kVertical,
.alignment = GnomeDisplayConfig::LayoutAlignment::kCenter},
{.name = "vertical_end_aligned",
.physical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(50, 100, 50, 100, 2.0)}},
.logical_layout_monitors =
{{"Meta-0", CreateMonitorInfo(0, 0, 100, 100, 2.0)},
{"Meta-1", CreateMonitorInfo(25, 50, 50, 100, 2.0)}},
.direction = GnomeDisplayConfig::LayoutDirection::kVertical,
.alignment = GnomeDisplayConfig::LayoutAlignment::kEnd},
});
return *test_cases;
}
} // namespace
class GnomeDisplayConfigTest
: public ::testing::TestWithParam<
std::tuple<GnomeDisplayConfig::LayoutMode, LayoutInfoTestCase>> {};
TEST_P(GnomeDisplayConfigTest, GetLayoutInfo) {
const auto& [layout_mode, test_case] = GetParam();
const auto& monitors = test_case.GetMonitorsForLayoutMode(layout_mode);
GnomeDisplayConfig config;
config.layout_mode = layout_mode;
config.monitors = monitors;
auto actual_layout_info = config.GetLayoutInfo();
EXPECT_EQ(actual_layout_info.layout_mode, layout_mode);
EXPECT_EQ(actual_layout_info.direction, test_case.direction);
EXPECT_EQ(actual_layout_info.alignment, test_case.alignment);
}
TEST_P(GnomeDisplayConfigTest, SwitchLayoutMode) {
const auto& [to_layout_mode, test_case] = GetParam();
GnomeDisplayConfig::LayoutMode from_layout_mode =
to_layout_mode == GnomeDisplayConfig::LayoutMode::kPhysical
? GnomeDisplayConfig::LayoutMode::kLogical
: GnomeDisplayConfig::LayoutMode::kPhysical;
const auto& from_monitors =
test_case.GetMonitorsForLayoutMode(from_layout_mode);
const auto& to_monitors = test_case.GetMonitorsForLayoutMode(to_layout_mode);
GnomeDisplayConfig config;
config.layout_mode = from_layout_mode;
config.monitors = from_monitors;
config.SwitchLayoutMode(to_layout_mode);
auto new_layout_info = config.GetLayoutInfo();
EXPECT_EQ(config.monitors, to_monitors);
EXPECT_EQ(new_layout_info.layout_mode, to_layout_mode);
EXPECT_EQ(new_layout_info.direction, test_case.direction);
EXPECT_EQ(new_layout_info.alignment, test_case.alignment);
}
TEST_P(GnomeDisplayConfigTest, Relayout_ClosesGaps) {
const auto& [layout_mode, test_case] = GetParam();
const auto& monitors = test_case.GetMonitorsForLayoutMode(layout_mode);
GnomeDisplayConfig config;
config.layout_mode = layout_mode;
config.monitors = monitors;
auto layout_info = config.GetLayoutInfo();
config.monitors["Meta-1"].x += 10;
config.monitors["Meta-1"].y += 10;
config.Relayout(layout_info);
EXPECT_EQ(config.monitors, monitors);
}
TEST_P(GnomeDisplayConfigTest, Relayout_RemovesOverlaps) {
const auto& [layout_mode, test_case] = GetParam();
const auto& monitors = test_case.GetMonitorsForLayoutMode(layout_mode);
GnomeDisplayConfig config;
config.layout_mode = layout_mode;
config.monitors = monitors;
auto layout_info = config.GetLayoutInfo();
config.monitors["Meta-1"].x -= 10;
config.monitors["Meta-1"].y -= 10;
config.Relayout(layout_info);
EXPECT_EQ(config.monitors, monitors);
}
TEST_P(GnomeDisplayConfigTest, Relayout_RestoresLayout) {
const auto& [layout_mode, test_case] = GetParam();
const auto& monitors = test_case.GetMonitorsForLayoutMode(layout_mode);
GnomeDisplayConfig config;
config.layout_mode = layout_mode;
config.monitors = monitors;
auto layout_info = config.GetLayoutInfo();
config.monitors["Meta-1"].x = 0;
config.monitors["Meta-1"].y = 0;
config.Relayout(layout_info);
EXPECT_EQ(config.monitors, monitors);
}
INSTANTIATE_TEST_SUITE_P(
All,
GnomeDisplayConfigTest,
testing::Combine(testing::Values(GnomeDisplayConfig::LayoutMode::kLogical,
GnomeDisplayConfig::LayoutMode::kPhysical),
testing::ValuesIn(GetLayoutInfoTestCases())),
[](const auto& info) {
const auto& layout_mode = std::get<0>(info.param);
const auto& test_case = std::get<1>(info.param);
return std::string(test_case.name) +
(layout_mode == GnomeDisplayConfig::LayoutMode::kPhysical
? "_physical"
: "_logical");
});
} // namespace remoting