| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "extensions/browser/api/system_display/display_info_provider.h" |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "ash/constants/ash_switches.h" |
| #include "ash/display/cros_display_config.h" |
| #include "ash/display/screen_orientation_controller.h" |
| #include "ash/display/screen_orientation_controller_test_api.h" |
| #include "ash/public/cpp/test/shell_test_api.h" |
| #include "ash/shell.h" |
| #include "base/command_line.h" |
| #include "base/functional/bind.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/stringprintf.h" |
| #include "chrome/browser/extensions/system_display/display_info_provider_chromeos.h" |
| #include "chrome/test/base/chrome_ash_test_base.h" |
| #include "extensions/common/api/system_display.h" |
| #include "mojo/public/cpp/bindings/pending_receiver.h" |
| #include "ui/display/display.h" |
| #include "ui/display/display_layout.h" |
| #include "ui/display/display_switches.h" |
| #include "ui/display/manager/display_manager.h" |
| #include "ui/display/manager/test/touch_transform_controller_test_api.h" |
| #include "ui/display/manager/touch_transform_setter.h" |
| #include "ui/display/screen.h" |
| #include "ui/display/test/display_manager_test_api.h" |
| #include "ui/display/types/display_constants.h" |
| #include "ui/gfx/geometry/rect.h" |
| |
| namespace extensions { |
| namespace { |
| |
| using DisplayUnitInfoList = DisplayInfoProvider::DisplayUnitInfoList; |
| using DisplayLayoutList = DisplayInfoProvider::DisplayLayoutList; |
| |
| void ErrorCallback(std::string* result, |
| base::OnceClosure callback, |
| std::optional<std::string> error) { |
| *result = error ? *error : ""; |
| std::move(callback).Run(); |
| } |
| |
| class DisplayInfoProviderChromeosTest : public ChromeAshTestBase { |
| public: |
| DisplayInfoProviderChromeosTest() = default; |
| |
| DisplayInfoProviderChromeosTest(const DisplayInfoProviderChromeosTest&) = |
| delete; |
| DisplayInfoProviderChromeosTest& operator=( |
| const DisplayInfoProviderChromeosTest&) = delete; |
| |
| ~DisplayInfoProviderChromeosTest() override = default; |
| |
| void SetUp() override { |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kUseFirstDisplayAsInternal); |
| |
| ChromeAshTestBase::SetUp(); |
| |
| // Note: for now we have two instances of CrosDisplayConfig, one owned by |
| // ash::Shell and this one. Since CrosDisplayConfig just provides an |
| // interface and doesn't own any classes this should be fine. |
| cros_display_config_ = std::make_unique<ash::CrosDisplayConfig>(); |
| |
| // Initialize the DisplayInfoProviderChromeOS with a remote connected to our |
| // local implementation. |
| mojo::PendingRemote<crosapi::mojom::CrosDisplayConfigController> |
| display_config; |
| cros_display_config_->BindReceiver( |
| display_config.InitWithNewPipeAndPassReceiver()); |
| DisplayInfoProvider::InitializeForTesting( |
| new DisplayInfoProviderChromeOS(std::move(display_config))); |
| |
| provider_ = DisplayInfoProvider::Get(); |
| ASSERT_TRUE(provider_); |
| |
| // Wait for TabletModeController to take its initial state from the power |
| // manager. |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_FALSE(display::Screen::GetScreen()->InTabletMode()); |
| } |
| |
| void TearDown() override { |
| // Destroy CrosDisplayConfig before the ash::Shell is destroyed, since it |
| // depends on the TabletModeController and the ScreenOrientationController. |
| cros_display_config_.reset(); |
| |
| ChromeAshTestBase::TearDown(); |
| } |
| |
| float GetDisplayZoom(int64_t display_id) { |
| return display_manager()->GetDisplayInfo(display_id).zoom_factor(); |
| } |
| |
| protected: |
| bool CallSetDisplayUnitInfo( |
| const std::string& display_id, |
| const api::system_display::DisplayProperties& info) { |
| std::string result; |
| base::RunLoop run_loop; |
| provider_->SetDisplayProperties( |
| display_id, info, |
| base::BindOnce(&ErrorCallback, &result, run_loop.QuitClosure())); |
| run_loop.Run(); |
| return result.empty(); |
| } |
| |
| bool DisplayExists(int64_t display_id) const { |
| const display::Display& display = |
| GetDisplayManager()->GetDisplayForId(display_id); |
| return display.id() != display::kInvalidDisplayId; |
| } |
| |
| void EnableTabletMode(bool enable) { |
| ash::ShellTestApi().SetTabletModeEnabledForTest(enable); |
| } |
| |
| display::DisplayManager* GetDisplayManager() const { |
| return ash::Shell::Get()->display_manager(); |
| } |
| |
| std::string SystemInfoDisplayInsetsToString( |
| const api::system_display::Insets& insets) const { |
| // Order to match gfx::Insets::ToString(). |
| return base::StringPrintf("%d,%d,%d,%d", insets.top, insets.left, |
| insets.bottom, insets.right); |
| } |
| |
| std::string SystemInfoDisplayBoundsToString( |
| const api::system_display::Bounds& bounds) const { |
| // Order to match gfx::Rect::ToString(). |
| return base::StringPrintf("%d,%d %dx%d", bounds.left, bounds.top, |
| bounds.width, bounds.height); |
| } |
| |
| DisplayUnitInfoList GetAllDisplaysInfoSetSingleUnified(bool single_unified) { |
| DisplayUnitInfoList result; |
| base::RunLoop run_loop; |
| provider_->GetAllDisplaysInfo( |
| single_unified, |
| base::BindOnce( |
| [](DisplayUnitInfoList* result_ptr, base::OnceClosure callback, |
| DisplayUnitInfoList result) { |
| *result_ptr = std::move(result); |
| std::move(callback).Run(); |
| }, |
| &result, run_loop.QuitClosure())); |
| run_loop.Run(); |
| return result; |
| } |
| |
| DisplayUnitInfoList GetAllDisplaysInfo() { |
| return GetAllDisplaysInfoSetSingleUnified(false); |
| } |
| |
| DisplayLayoutList GetDisplayLayout() { |
| DisplayLayoutList result; |
| base::RunLoop run_loop; |
| provider_->GetDisplayLayout(base::BindOnce( |
| [](DisplayLayoutList* result_ptr, base::OnceClosure callback, |
| DisplayLayoutList result) { |
| *result_ptr = std::move(result); |
| std::move(callback).Run(); |
| }, |
| &result, run_loop.QuitClosure())); |
| run_loop.Run(); |
| return result; |
| } |
| |
| bool SetDisplayLayout(const DisplayLayoutList& layouts) { |
| std::string result; |
| base::RunLoop run_loop; |
| provider_->SetDisplayLayout( |
| layouts, |
| base::BindOnce(&ErrorCallback, &result, run_loop.QuitClosure())); |
| run_loop.Run(); |
| return result.empty(); |
| } |
| |
| bool SetMirrorMode(const api::system_display::MirrorModeInfo& info) { |
| std::string result; |
| base::RunLoop run_loop; |
| provider_->SetMirrorMode( |
| info, base::BindOnce(&ErrorCallback, &result, run_loop.QuitClosure())); |
| run_loop.Run(); |
| return result.empty(); |
| } |
| |
| private: |
| std::unique_ptr<ash::CrosDisplayConfig> cros_display_config_; |
| |
| protected: |
| raw_ptr<DisplayInfoProvider> provider_; |
| }; |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetBasic) { |
| UpdateDisplay("500x600,400x520"); |
| DisplayUnitInfoList result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| int64_t display_id; |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| EXPECT_EQ(0, result[0].rotation); |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[0].is_enabled); |
| EXPECT_EQ(api::system_display::ActiveState::kActive, result[0].active_state); |
| |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ(GetDisplayManager()->GetDisplayNameForId(display_id), |
| result[1].name); |
| // The second display is positioned left of the primary display, whose width |
| // is 500. |
| EXPECT_EQ("500,0 400x520", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[1].overscan)); |
| EXPECT_EQ(0, result[1].rotation); |
| EXPECT_FALSE(result[1].is_primary); |
| EXPECT_EQ(96, result[1].dpi_x); |
| EXPECT_EQ(96, result[1].dpi_y); |
| EXPECT_TRUE(result[1].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[1].is_enabled); |
| EXPECT_EQ(api::system_display::ActiveState::kActive, result[1].active_state); |
| |
| // Disconnect all displays. |
| UpdateDisplay(""); |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_EQ(api::system_display::ActiveState::kInactive, |
| result[0].active_state); |
| |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ("500,0 400x520", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_FALSE(result[1].is_primary); |
| EXPECT_EQ(api::system_display::ActiveState::kInactive, |
| result[1].active_state); |
| |
| // Reconnect first display. |
| UpdateDisplay("500x600"); |
| result = GetAllDisplaysInfo(); |
| ASSERT_EQ(1u, result.size()); |
| |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_EQ(api::system_display::ActiveState::kActive, result[0].active_state); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetWithUnifiedDesktop) { |
| UpdateDisplay("500x600,400x520"); |
| |
| // Check initial state. |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| DisplayUnitInfoList result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| int64_t display_id; |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| EXPECT_EQ(0, result[0].rotation); |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_FALSE(result[0].is_unified); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[0].is_enabled); |
| |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ(GetDisplayManager()->GetDisplayNameForId(display_id), |
| result[1].name); |
| |
| // Initial multiple display configuration. |
| EXPECT_EQ("500,0 400x520", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[1].overscan)); |
| EXPECT_EQ(0, result[1].rotation); |
| EXPECT_FALSE(result[1].is_primary); |
| EXPECT_FALSE(result[0].is_unified); |
| EXPECT_EQ(96, result[1].dpi_x); |
| EXPECT_EQ(96, result[1].dpi_y); |
| EXPECT_TRUE(result[1].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[1].is_enabled); |
| |
| // Enable unified. |
| GetDisplayManager()->SetUnifiedDesktopEnabled(true); |
| EXPECT_TRUE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| EXPECT_EQ(0, result[0].rotation); |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_TRUE(result[0].is_unified); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[0].is_enabled); |
| |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| EXPECT_EQ(GetDisplayManager()->GetDisplayNameForId(display_id), |
| result[1].name); |
| |
| // After enabling unified the second display is scaled to meet the height for |
| // the first. Which also affects the DPI below. |
| EXPECT_EQ("500,0 461x600", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[1].overscan)); |
| EXPECT_EQ(0, result[1].rotation); |
| EXPECT_FALSE(result[1].is_primary); |
| EXPECT_TRUE(result[1].is_unified); |
| EXPECT_FLOAT_EQ(111, round(result[1].dpi_x)); |
| EXPECT_FLOAT_EQ(111, round(result[1].dpi_y)); |
| EXPECT_TRUE(result[1].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[1].is_enabled); |
| |
| // Disable unified and check that once again it matches initial situation. |
| GetDisplayManager()->SetUnifiedDesktopEnabled(false); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| EXPECT_EQ(0, result[0].rotation); |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_FALSE(result[0].is_unified); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[0].is_enabled); |
| |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ(GetDisplayManager()->GetDisplayNameForId(display_id), |
| result[1].name); |
| EXPECT_EQ("500,0 400x520", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[1].overscan)); |
| EXPECT_EQ(0, result[1].rotation); |
| EXPECT_FALSE(result[1].is_primary); |
| EXPECT_FALSE(result[1].is_unified); |
| EXPECT_EQ(96, result[1].dpi_x); |
| EXPECT_EQ(96, result[1].dpi_y); |
| EXPECT_TRUE(result[1].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[1].is_enabled); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetWithUnifiedDesktopForSettings) { |
| UpdateDisplay("500x600,400x520"); |
| |
| // Check initial state. |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| DisplayUnitInfoList result = GetAllDisplaysInfoSetSingleUnified(true); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| int64_t display_id; |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| EXPECT_EQ(0, result[0].rotation); |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_FALSE(result[0].is_unified); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[0].is_enabled); |
| |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ(GetDisplayManager()->GetDisplayNameForId(display_id), |
| result[1].name); |
| |
| // Initial multiple display configuration. |
| EXPECT_EQ("500,0 400x520", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[1].overscan)); |
| EXPECT_EQ(0, result[1].rotation); |
| EXPECT_FALSE(result[1].is_primary); |
| EXPECT_FALSE(result[0].is_unified); |
| EXPECT_EQ(96, result[1].dpi_x); |
| EXPECT_EQ(96, result[1].dpi_y); |
| EXPECT_TRUE(result[1].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[1].is_enabled); |
| |
| // Enable unified. |
| GetDisplayManager()->SetUnifiedDesktopEnabled(true); |
| EXPECT_TRUE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // For settings, GetAllDisplaysInfo will return a single unified display. The |
| // second display will be scaled to match the height of the first, so the |
| // height will be 600 and the new width will be 500 + [400 * 600/520 = 461] = |
| // 961. |
| result = GetAllDisplaysInfoSetSingleUnified(true); |
| |
| ASSERT_EQ(1u, result.size()); |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| EXPECT_EQ("0,0 961x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| EXPECT_EQ(0, result[0].rotation); |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_TRUE(result[0].is_unified); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[0].is_enabled); |
| |
| // Disable unified and check that once again it matches initial situation. |
| GetDisplayManager()->SetUnifiedDesktopEnabled(false); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| EXPECT_EQ(0, result[0].rotation); |
| EXPECT_TRUE(result[0].is_primary); |
| EXPECT_FALSE(result[0].is_unified); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[0].is_enabled); |
| |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ(GetDisplayManager()->GetDisplayNameForId(display_id), |
| result[1].name); |
| EXPECT_EQ("500,0 400x520", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ("0,0,0,0", SystemInfoDisplayInsetsToString(result[1].overscan)); |
| EXPECT_EQ(0, result[1].rotation); |
| EXPECT_FALSE(result[1].is_primary); |
| EXPECT_FALSE(result[1].is_unified); |
| EXPECT_EQ(96, result[1].dpi_x); |
| EXPECT_EQ(96, result[1].dpi_y); |
| EXPECT_TRUE(result[1].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[1].is_enabled); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetRotation) { |
| UpdateDisplay("500x600/r"); |
| DisplayUnitInfoList result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(1u, result.size()); |
| |
| int64_t display_id; |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ(90, result[0].rotation); |
| |
| GetDisplayManager()->SetDisplayRotation( |
| display_id, display::Display::ROTATE_270, |
| display::Display::RotationSource::ACTIVE); |
| |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(1u, result.size()); |
| |
| EXPECT_EQ(base::NumberToString(display_id), result[0].id); |
| EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ(270, result[0].rotation); |
| |
| GetDisplayManager()->SetDisplayRotation( |
| display_id, display::Display::ROTATE_180, |
| display::Display::RotationSource::ACTIVE); |
| |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(1u, result.size()); |
| |
| EXPECT_EQ(base::NumberToString(display_id), result[0].id); |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ(180, result[0].rotation); |
| |
| GetDisplayManager()->SetDisplayRotation( |
| display_id, display::Display::ROTATE_0, |
| display::Display::RotationSource::ACTIVE); |
| |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(1u, result.size()); |
| |
| EXPECT_EQ(base::NumberToString(display_id), result[0].id); |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ(0, result[0].rotation); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetDPI) { |
| UpdateDisplay("500x600,400x520*2"); |
| DisplayUnitInfoList result; |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| |
| EXPECT_EQ("500,0 200x260", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| // DPI should be 96 (native dpi) * 200 (display) / 400 (native) when ui scale |
| // is 2. |
| EXPECT_EQ(96 / 2, result[1].dpi_x); |
| EXPECT_EQ(96 / 2, result[1].dpi_y); |
| |
| SwapPrimaryDisplay(); |
| |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| EXPECT_EQ("-500,0 500x600", |
| SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ(96, result[0].dpi_x); |
| EXPECT_EQ(96, result[0].dpi_y); |
| |
| EXPECT_EQ("0,0 200x260", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ(96 / 2, result[1].dpi_x); |
| EXPECT_EQ(96 / 2, result[1].dpi_y); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetVisibleArea) { |
| UpdateDisplay("640x720*2/o, 400x520/o"); |
| DisplayUnitInfoList result; |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| int64_t display_id; |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[1].id; |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| |
| // Default overscan is 5%. |
| EXPECT_EQ("304,0 380x494", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ("13,10,13,10", SystemInfoDisplayInsetsToString(result[1].overscan)); |
| |
| GetDisplayManager()->SetOverscanInsets(display_id, |
| gfx::Insets::TLBR(20, 30, 50, 60)); |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| EXPECT_EQ(base::NumberToString(display_id), result[1].id); |
| EXPECT_EQ("304,0 310x450", SystemInfoDisplayBoundsToString(result[1].bounds)); |
| EXPECT_EQ("20,30,50,60", SystemInfoDisplayInsetsToString(result[1].overscan)); |
| |
| // Set insets for the primary screen. Note that it has 2x scale. |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| ASSERT_TRUE(DisplayExists(display_id)) << display_id << " not found"; |
| |
| EXPECT_EQ("0,0 304x342", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("9,8,9,8", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| |
| GetDisplayManager()->SetOverscanInsets(display_id, |
| gfx::Insets::TLBR(10, 20, 30, 40)); |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| EXPECT_EQ(base::NumberToString(display_id), result[0].id); |
| EXPECT_EQ("0,0 260x320", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("10,20,30,40", SystemInfoDisplayInsetsToString(result[0].overscan)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetMirroring) { |
| UpdateDisplay("600x500, 400x520/o"); |
| DisplayUnitInfoList result; |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| |
| int64_t display_id_primary; |
| ASSERT_TRUE(base::StringToInt64(result[0].id, &display_id_primary)) |
| << "Display id must be convertible to integer: " << result[0].id; |
| ASSERT_TRUE(DisplayExists(display_id_primary)) |
| << display_id_primary << " not found"; |
| |
| int64_t display_id_secondary; |
| ASSERT_TRUE(base::StringToInt64(result[1].id, &display_id_secondary)) |
| << "Display id must be convertible to integer: " << result[1].id; |
| ASSERT_TRUE(DisplayExists(display_id_secondary)) |
| << display_id_secondary << " not found"; |
| |
| ASSERT_FALSE(GetDisplayManager()->IsInMirrorMode()); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_TRUE(result[1].mirroring_source_id.empty()); |
| |
| GetDisplayManager()->SetMirrorMode(display::MirrorMode::kNormal, |
| std::nullopt); |
| ASSERT_TRUE(GetDisplayManager()->IsInMirrorMode()); |
| |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_EQ(base::NumberToString(display_id_primary), result[0].id); |
| EXPECT_EQ(base::NumberToString(display_id_primary), |
| result[0].mirroring_source_id); |
| |
| GetDisplayManager()->SetMirrorMode(display::MirrorMode::kOff, std::nullopt); |
| ASSERT_FALSE(GetDisplayManager()->IsInMirrorMode()); |
| |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| EXPECT_EQ(base::NumberToString(display_id_primary), result[0].id); |
| EXPECT_TRUE(result[0].mirroring_source_id.empty()); |
| EXPECT_EQ(base::NumberToString(display_id_secondary), result[1].id); |
| EXPECT_TRUE(result[1].mirroring_source_id.empty()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetBounds) { |
| UpdateDisplay("600x500, 400x520"); |
| GetDisplayManager()->SetLayoutForCurrentDisplays( |
| display::test::CreateDisplayLayout(display_manager(), |
| display::DisplayPlacement::LEFT, -40)); |
| |
| DisplayUnitInfoList result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("-400,-40 400x520", |
| SystemInfoDisplayBoundsToString(result[1].bounds)); |
| |
| GetDisplayManager()->SetLayoutForCurrentDisplays( |
| display::test::CreateDisplayLayout(display_manager(), |
| display::DisplayPlacement::TOP, 40)); |
| |
| result = GetAllDisplaysInfo(); |
| |
| ASSERT_EQ(2u, result.size()); |
| EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("40,-520 400x520", |
| SystemInfoDisplayBoundsToString(result[1].bounds)); |
| |
| GetDisplayManager()->SetLayoutForCurrentDisplays( |
| display::test::CreateDisplayLayout( |
| display_manager(), display::DisplayPlacement::BOTTOM, 80)); |
| |
| result = GetAllDisplaysInfo(); |
| ASSERT_EQ(2u, result.size()); |
| EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0].bounds)); |
| EXPECT_EQ("80,500 400x520", |
| SystemInfoDisplayBoundsToString(result[1].bounds)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, Layout) { |
| UpdateDisplay("500x400,500x400,500x400"); |
| |
| DisplayUnitInfoList displays = GetAllDisplaysInfo(); |
| std::string primary_id = displays[0].id; |
| ASSERT_EQ(3u, displays.size()); |
| |
| DisplayLayoutList layout = GetDisplayLayout(); |
| |
| ASSERT_EQ(2u, layout.size()); |
| |
| // Confirm layout. |
| EXPECT_EQ(displays[1].id, layout[0].id); |
| EXPECT_EQ(primary_id, layout[0].parent_id); |
| EXPECT_EQ(api::system_display::LayoutPosition::kRight, layout[0].position); |
| EXPECT_EQ(0, layout[0].offset); |
| |
| EXPECT_EQ(displays[2].id, layout[1].id); |
| EXPECT_EQ(layout[0].id, layout[1].parent_id); |
| EXPECT_EQ(api::system_display::LayoutPosition::kRight, layout[1].position); |
| EXPECT_EQ(0, layout[1].offset); |
| |
| // Modify layout. |
| layout[0].offset = 100; |
| layout[1].parent_id = primary_id; |
| layout[1].position = api::system_display::LayoutPosition::kBottom; |
| layout[1].offset = -100; |
| |
| // Update with modified layout. |
| EXPECT_TRUE(SetDisplayLayout(layout)); |
| |
| // Get updated layout. |
| layout = GetDisplayLayout(); |
| |
| // Confirm modified layout. |
| EXPECT_EQ(displays[1].id, layout[0].id); |
| EXPECT_EQ(primary_id, layout[0].parent_id); |
| EXPECT_EQ(api::system_display::LayoutPosition::kRight, layout[0].position); |
| EXPECT_EQ(100, layout[0].offset); |
| |
| EXPECT_EQ(displays[2].id, layout[1].id); |
| EXPECT_EQ(primary_id, layout[1].parent_id); |
| EXPECT_EQ(api::system_display::LayoutPosition::kBottom, layout[1].position); |
| EXPECT_EQ(-100, layout[1].offset); |
| |
| // TODO(stevenjb/oshima): Implement and test illegal layout prevention. |
| |
| // Test setting invalid layout fails. |
| layout[0].parent_id = displays[2].id; |
| layout[1].parent_id = displays[1].id; |
| EXPECT_FALSE(SetDisplayLayout(layout)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, UnifiedModeLayout) { |
| UpdateDisplay("500x300,400x500,300x600,200x300"); |
| GetDisplayManager()->SetUnifiedDesktopEnabled(true); |
| EXPECT_TRUE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| DisplayUnitInfoList displays = GetAllDisplaysInfo(); |
| ASSERT_EQ(4u, displays.size()); |
| |
| // Get the default layout, which should be a horizontal layout. |
| DisplayLayoutList default_layout = GetDisplayLayout(); |
| |
| // There is no placement for the primary display. |
| ASSERT_EQ(3u, default_layout.size()); |
| |
| // Confirm the horizontal layout. |
| EXPECT_EQ(displays[1].id, default_layout[0].id); |
| EXPECT_EQ(displays[0].id, default_layout[0].parent_id); |
| EXPECT_EQ(api::system_display::LayoutPosition::kRight, |
| default_layout[0].position); |
| EXPECT_EQ(0, default_layout[0].offset); |
| EXPECT_EQ(displays[2].id, default_layout[1].id); |
| EXPECT_EQ(displays[1].id, default_layout[1].parent_id); |
| EXPECT_EQ(api::system_display::LayoutPosition::kRight, |
| default_layout[1].position); |
| EXPECT_EQ(0, default_layout[1].offset); |
| EXPECT_EQ(displays[3].id, default_layout[2].id); |
| EXPECT_EQ(displays[2].id, default_layout[2].parent_id); |
| EXPECT_EQ(api::system_display::LayoutPosition::kRight, |
| default_layout[2].position); |
| EXPECT_EQ(0, default_layout[2].offset); |
| |
| // Create a 2x2 matrix layout. |
| // [3][200 x 300] [1][400 x 500] |
| // [2][300 x 600] [0][500 x 300] |
| DisplayLayoutList layout; |
| layout.resize(3u); |
| layout[0].id = displays[1].id; |
| layout[0].parent_id = displays[3].id; |
| layout[0].position = api::system_display::LayoutPosition::kRight; |
| layout[1].id = displays[2].id; |
| layout[1].parent_id = displays[3].id; |
| layout[1].position = api::system_display::LayoutPosition::kBottom; |
| layout[2].id = displays[0].id; |
| layout[2].parent_id = displays[2].id; |
| layout[2].position = api::system_display::LayoutPosition::kRight; |
| |
| EXPECT_TRUE(SetDisplayLayout(layout)); |
| EXPECT_EQ(gfx::Size(650, 743), |
| display::Screen::GetScreen()->GetPrimaryDisplay().size()); |
| EXPECT_EQ(displays[2].id, |
| std::to_string(ash::Shell::Get() |
| ->display_configuration_controller() |
| ->GetPrimaryMirroringDisplayForUnifiedDesktop() |
| .id())); |
| |
| // Confirm the new layout. |
| DisplayLayoutList new_layout = GetDisplayLayout(); |
| ASSERT_EQ(3u, new_layout.size()); |
| |
| EXPECT_EQ(layout[0].id, new_layout[0].id); |
| EXPECT_EQ(layout[0].parent_id, new_layout[0].parent_id); |
| EXPECT_EQ(layout[0].position, new_layout[0].position); |
| EXPECT_EQ(0, new_layout[0].offset); |
| EXPECT_EQ(layout[1].id, new_layout[1].id); |
| EXPECT_EQ(layout[1].parent_id, new_layout[1].parent_id); |
| EXPECT_EQ(layout[1].position, new_layout[1].position); |
| EXPECT_EQ(0, new_layout[1].offset); |
| EXPECT_EQ(layout[2].id, new_layout[2].id); |
| EXPECT_EQ(layout[2].parent_id, new_layout[2].parent_id); |
| EXPECT_EQ(layout[2].position, new_layout[2].position); |
| EXPECT_EQ(0, new_layout[2].offset); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetUnified) { |
| UpdateDisplay("500x400,500x400"); |
| EXPECT_FALSE(GetDisplayManager()->unified_desktop_enabled()); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| api::system_display::DisplayProperties info; |
| |
| // Test that setting is_unified to true fails unless EnableUnifiedDesktop is |
| // called first. |
| info.is_unified = true; |
| EXPECT_FALSE(CallSetDisplayUnitInfo( |
| base::NumberToString( |
| display::Screen::GetScreen()->GetPrimaryDisplay().id()), |
| info)); |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // Test that enabling unified desktop succeeds and sets the desktop mode to |
| // unified. |
| provider_->EnableUnifiedDesktop(true); |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_TRUE(GetDisplayManager()->unified_desktop_enabled()); |
| EXPECT_TRUE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // Test that setting is_unified to false turns off unified mode but leaves it |
| // enabled. |
| info.is_unified = false; |
| EXPECT_TRUE(CallSetDisplayUnitInfo( |
| base::NumberToString( |
| display::Screen::GetScreen()->GetPrimaryDisplay().id()), |
| info)); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // Test that setting is_unified to true succeeds without an additional call to |
| // EnableUnifiedDesktop. |
| info.is_unified = true; |
| EXPECT_TRUE(CallSetDisplayUnitInfo( |
| base::NumberToString( |
| display::Screen::GetScreen()->GetPrimaryDisplay().id()), |
| info)); |
| EXPECT_TRUE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // Restore extended mode. |
| provider_->EnableUnifiedDesktop(false); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetUnifiedOneDisplay) { |
| UpdateDisplay("500x400"); |
| EXPECT_FALSE(GetDisplayManager()->unified_desktop_enabled()); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| api::system_display::DisplayProperties info; |
| |
| // Enabling unified desktop with one display should succeed, but desktop mode |
| // will not be unified. |
| provider_->EnableUnifiedDesktop(true); |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_TRUE(GetDisplayManager()->unified_desktop_enabled()); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // Adding another display should set unified mode. |
| UpdateDisplay("500x400,500x400"); |
| EXPECT_TRUE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // Restore extended mode. |
| provider_->EnableUnifiedDesktop(false); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetUnifiedMirrored) { |
| UpdateDisplay("500x400,500x400"); |
| |
| GetDisplayManager()->SetMirrorMode(display::MirrorMode::kNormal, |
| std::nullopt); |
| EXPECT_TRUE(GetDisplayManager()->IsInMirrorMode()); |
| |
| EXPECT_FALSE(GetDisplayManager()->unified_desktop_enabled()); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| api::system_display::DisplayProperties info; |
| |
| // Enabling unified desktop while mirroring should succeed, but desktop mode |
| // will not be unified. |
| provider_->EnableUnifiedDesktop(true); |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_FALSE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // Turning off mirroring should set unified mode. |
| GetDisplayManager()->SetMirrorMode(display::MirrorMode::kOff, std::nullopt); |
| EXPECT_TRUE(GetDisplayManager()->IsInUnifiedMode()); |
| |
| // Restore extended mode. |
| provider_->EnableUnifiedDesktop(false); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftExact) { |
| UpdateDisplay("1200x600,520x400"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = -520; |
| info.bounds_origin_y = 50; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("-520,50 520x400", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginRightExact) { |
| UpdateDisplay("1200x600,520x400"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 1200; |
| info.bounds_origin_y = 100; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopExact) { |
| UpdateDisplay("1200x600,520x400"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 1100; |
| info.bounds_origin_y = -400; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1100,-400 520x400", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginBottomExact) { |
| UpdateDisplay("1200x600,520x400"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = -350; |
| info.bounds_origin_y = 600; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("-350,600 520x400", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSameCenter) { |
| UpdateDisplay("1200x600,520x400"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 340; |
| info.bounds_origin_y = 100; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftOutside) { |
| UpdateDisplay("1200x600,520x400"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = -1040; |
| info.bounds_origin_y = 100; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("-520,100 520x400", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopOutside) { |
| UpdateDisplay("1200x600,520x400"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = -360; |
| info.bounds_origin_y = -301; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("-360,-400 520x400", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, |
| SetBoundsOriginLeftButSharesBottomSide) { |
| UpdateDisplay("1200x600,1000x100"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = -650; |
| info.bounds_origin_y = 700; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("-650,600 1000x100", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginRightButSharesTopSide) { |
| UpdateDisplay("1200x600,1000x100"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 850; |
| info.bounds_origin_y = -150; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("850,-100 1000x100", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopButSharesLeftSide) { |
| UpdateDisplay("1200x600,1000x100/l"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = -150; |
| info.bounds_origin_y = -650; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("-100,-650 100x1000", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, |
| SetBoundsOriginBottomButSharesRightSide) { |
| UpdateDisplay("1200x600,1000x100/l"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 1350; |
| info.bounds_origin_y = 450; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,450 100x1000", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginPrimaryHiDPI) { |
| UpdateDisplay("1200x600*2,500x400"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 250; |
| info.bounds_origin_y = -100; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("600,-100 500x400", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSecondaryHiDPI) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 450; |
| info.bounds_origin_y = -100; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("450,-500 300x500", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOutOfBounds) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 0x200001; |
| info.bounds_origin_y = -100; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOutOfBoundsNegative) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 300; |
| info.bounds_origin_y = -0x200001; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginMaxValues) { |
| UpdateDisplay("1200x4600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 200000; |
| info.bounds_origin_y = 10; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,10 300x500", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOnPrimary) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 300; |
| info.is_primary = true; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString()); |
| // The operation failed because the primary property would be set before |
| // setting bounds. The primary display shouldn't have been changed, though. |
| EXPECT_NE(display::Screen::GetScreen()->GetPrimaryDisplay().id(), |
| secondary.id()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginWithMirroring) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| const display::Display& primary = |
| display::Screen::GetScreen()->GetPrimaryDisplay(); |
| |
| api::system_display::DisplayProperties info; |
| info.bounds_origin_x = 300; |
| info.mirroring_source_id = base::NumberToString(primary.id()); |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetRotation) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.rotation = 90; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString()); |
| EXPECT_EQ(display::Display::ROTATE_90, secondary.rotation()); |
| |
| info.rotation = 270; |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString()); |
| EXPECT_EQ(display::Display::ROTATE_270, secondary.rotation()); |
| |
| info.rotation = 180; |
| // Switch primary display. |
| info.is_primary = true; |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("0,0 300x500", secondary.bounds().ToString()); |
| EXPECT_EQ(display::Display::ROTATE_180, secondary.rotation()); |
| EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().id(), |
| secondary.id()); |
| |
| info.rotation = 0; |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("0,0 300x500", secondary.bounds().ToString()); |
| EXPECT_EQ(display::Display::ROTATE_0, secondary.rotation()); |
| EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().id(), |
| secondary.id()); |
| } |
| |
| // Tests that rotation changes made before entering tablet mode are restored |
| // upon exiting tablet mode, and that a rotation lock is not set. |
| TEST_F(DisplayInfoProviderChromeosTest, SetRotationBeforeTabletMode) { |
| ash::ScreenOrientationController* screen_orientation_controller = |
| ash::Shell::Get()->screen_orientation_controller(); |
| api::system_display::DisplayProperties info; |
| info.rotation = 90; |
| |
| EXPECT_TRUE(CallSetDisplayUnitInfo( |
| base::NumberToString(display::Display::InternalDisplayId()), info)); |
| EXPECT_FALSE(screen_orientation_controller->rotation_locked()); |
| |
| // Entering tablet mode enables accelerometer screen rotations. |
| EnableTabletMode(true); |
| // Rotation lock should not activate because DisplayInfoProvider::SetInfo() |
| // was called when not in tablet mode. |
| EXPECT_FALSE(screen_orientation_controller->rotation_locked()); |
| |
| // ScreenOrientationController rotations override display info. |
| ash::ScreenOrientationControllerTestApi test_api( |
| screen_orientation_controller); |
| test_api.SetDisplayRotation(display::Display::ROTATE_0, |
| display::Display::RotationSource::ACTIVE); |
| EXPECT_EQ(display::Display::ROTATE_0, GetCurrentInternalDisplayRotation()); |
| |
| // Exiting tablet mode should restore the initial rotation |
| EnableTabletMode(false); |
| EXPECT_EQ(display::Display::ROTATE_90, GetCurrentInternalDisplayRotation()); |
| } |
| |
| // Tests that rotation changes made during tablet mode lock the display |
| // against accelerometer rotations, and is set as user rotation locked. |
| TEST_F(DisplayInfoProviderChromeosTest, SetRotationDuringTabletMode) { |
| // Entering tablet mode enables accelerometer screen rotations. |
| EnableTabletMode(true); |
| |
| ASSERT_FALSE( |
| ash::Shell::Get()->screen_orientation_controller()->rotation_locked()); |
| ASSERT_FALSE(ash::Shell::Get() |
| ->screen_orientation_controller() |
| ->user_rotation_locked()); |
| |
| api::system_display::DisplayProperties info; |
| info.rotation = 90; |
| |
| EXPECT_TRUE(CallSetDisplayUnitInfo( |
| base::NumberToString(display::Display::InternalDisplayId()), info)); |
| EXPECT_TRUE( |
| ash::Shell::Get()->screen_orientation_controller()->rotation_locked()); |
| EXPECT_TRUE(ash::Shell::Get() |
| ->screen_orientation_controller() |
| ->user_rotation_locked()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetInvalidRotation) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.rotation = 91; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetNegativeOverscan) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.overscan.emplace(); |
| info.overscan->left = -10; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString()); |
| |
| info.overscan->left = 0; |
| info.overscan->right = -200; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString()); |
| |
| info.overscan->right = 0; |
| info.overscan->top = -300; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString()); |
| |
| info.overscan->right = 0; |
| info.overscan->top = -1000; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString()); |
| |
| info.overscan->right = 0; |
| info.overscan->top = 0; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetOverscanLargerThanHorizontalBounds) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.overscan.emplace(); |
| // Horizontal overscan is 151, which would make the bounds width 149. |
| info.overscan->left = 50; |
| info.overscan->top = 10; |
| info.overscan->right = 101; |
| info.overscan->bottom = 20; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetOverscanLargerThanVerticalBounds) { |
| UpdateDisplay("1200x600,600x1000"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.overscan.emplace(); |
| // Vertical overscan is 501, which would make the bounds height 499. |
| info.overscan->left = 20; |
| info.overscan->top = 250; |
| info.overscan->right = 101; |
| info.overscan->bottom = 251; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetOverscan) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| |
| const display::Display& secondary = |
| display::test::DisplayManagerTestApi(display_manager()) |
| .GetSecondaryDisplay(); |
| api::system_display::DisplayProperties info; |
| info.overscan.emplace(); |
| info.overscan->left = 20; |
| info.overscan->top = 199; |
| info.overscan->right = 130; |
| info.overscan->bottom = 51; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(secondary.id()), info)); |
| |
| EXPECT_EQ("1200,0 150x250", secondary.bounds().ToString()); |
| const gfx::Insets overscan = |
| GetDisplayManager()->GetOverscanInsets(secondary.id()); |
| |
| EXPECT_EQ(20, overscan.left()); |
| EXPECT_EQ(199, overscan.top()); |
| EXPECT_EQ(130, overscan.right()); |
| EXPECT_EQ(51, overscan.bottom()); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetOverscanForInternal) { |
| UpdateDisplay("1200x600,600x1000*2"); |
| const int64_t internal_display_id = |
| display::test::DisplayManagerTestApi(ash::Shell::Get()->display_manager()) |
| .SetFirstDisplayAsInternalDisplay(); |
| |
| api::system_display::DisplayProperties info; |
| info.overscan.emplace(); |
| // Vertical overscan is 501, which would make the bounds height 499. |
| info.overscan->left = 20; |
| info.overscan->top = 20; |
| info.overscan->right = 20; |
| info.overscan->bottom = 20; |
| |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(internal_display_id), info)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, DisplayMode) { |
| UpdateDisplay("1200x600,600x1000#500x900|400x800|300x700"); |
| |
| DisplayUnitInfoList result = GetAllDisplaysInfo(); |
| ASSERT_GE(result.size(), 1u); |
| const api::system_display::DisplayUnitInfo& secondary_info = result[1]; |
| // Ensure that we have two modes for the primary display so that we can |
| // test changing modes. |
| ASSERT_GE(secondary_info.modes.size(), 2u); |
| |
| // Get the currently active mode and one other mode to switch to. |
| int64_t id; |
| base::StringToInt64(secondary_info.id, &id); |
| display::ManagedDisplayMode active_mode; |
| EXPECT_TRUE(GetDisplayManager()->GetActiveModeForDisplayId(id, &active_mode)); |
| const api::system_display::DisplayMode* cur_mode = nullptr; |
| const api::system_display::DisplayMode* other_mode = nullptr; |
| for (const auto& mode : secondary_info.modes) { |
| if (mode.is_selected) { |
| cur_mode = &mode; |
| } else if (!other_mode) { |
| other_mode = &mode; |
| } |
| if (cur_mode && other_mode) { |
| break; |
| } |
| } |
| ASSERT_TRUE(cur_mode); |
| ASSERT_TRUE(other_mode); |
| ASSERT_NE(other_mode, cur_mode); |
| |
| // Verify that other_mode differs from the active mode. |
| display::ManagedDisplayMode other_mode_ash( |
| gfx::Size(other_mode->width_in_native_pixels, |
| other_mode->height_in_native_pixels), |
| active_mode.refresh_rate(), active_mode.is_interlaced(), |
| other_mode->is_native, other_mode->device_scale_factor); |
| EXPECT_FALSE(active_mode.IsEquivalent(other_mode_ash)); |
| |
| // Switch modes. |
| api::system_display::DisplayProperties info; |
| info.display_mode = |
| api::system_display::DisplayMode::FromValue(other_mode->ToValue()); |
| |
| EXPECT_TRUE(CallSetDisplayUnitInfo(base::NumberToString(id), info)); |
| |
| // Verify that other_mode now matches the active mode. |
| EXPECT_TRUE(GetDisplayManager()->GetActiveModeForDisplayId(id, &active_mode)); |
| EXPECT_TRUE(active_mode.IsEquivalent(other_mode_ash)); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetDisplayZoomFactor) { |
| UpdateDisplay("1200x600,1600x1000*2"); |
| display::DisplayIdList display_id_list = |
| display_manager()->GetConnectedDisplayIdList(); |
| |
| float zoom_factor_1 = 1.23f; |
| float zoom_factor_2 = 2.34f; |
| display_manager()->UpdateZoomFactor(display_id_list[0], zoom_factor_1); |
| display_manager()->UpdateZoomFactor(display_id_list[1], zoom_factor_2); |
| |
| DisplayUnitInfoList displays = GetAllDisplaysInfo(); |
| |
| for (const auto& display : displays) { |
| if (display.id == base::NumberToString(display_id_list[0])) { |
| EXPECT_EQ(display.display_zoom_factor, zoom_factor_1); |
| } |
| if (display.id == base::NumberToString(display_id_list[1])) { |
| EXPECT_EQ(display.display_zoom_factor, zoom_factor_2); |
| } |
| } |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetDisplayZoomFactor) { |
| UpdateDisplay("1200x600, 1600x1000#1600x1000"); |
| display::DisplayIdList display_id_list = |
| display_manager()->GetConnectedDisplayIdList(); |
| |
| float zoom_factor_1 = 1.23f; |
| float zoom_factor_2 = 2.34f; |
| display_manager()->UpdateZoomFactor(display_id_list[0], zoom_factor_2); |
| display_manager()->UpdateZoomFactor(display_id_list[1], zoom_factor_1); |
| |
| EXPECT_EQ(GetDisplayZoom(display_id_list[0]), zoom_factor_2); |
| EXPECT_EQ(GetDisplayZoom(display_id_list[1]), zoom_factor_1); |
| |
| // After update, display 1 should have |final_zoom_factor_1| as its zoom |
| // factor and display 2 should have |final_zoom_factor_2| as its zoom factor. |
| float final_zoom_factor_1 = zoom_factor_1; |
| float final_zoom_factor_2 = zoom_factor_2; |
| |
| api::system_display::DisplayProperties info; |
| info.display_zoom_factor = zoom_factor_1; |
| |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(display_id_list[0]), info)); |
| |
| EXPECT_EQ(GetDisplayZoom(display_id_list[0]), final_zoom_factor_1); |
| // Display 2 has not been updated yet, so it will still have the old zoom |
| // factor. |
| EXPECT_EQ(GetDisplayZoom(display_id_list[1]), zoom_factor_1); |
| |
| info.display_zoom_factor = zoom_factor_2; |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(display_id_list[1]), info)); |
| |
| // Both displays should now have the correct zoom factor set. |
| EXPECT_EQ(GetDisplayZoom(display_id_list[0]), final_zoom_factor_1); |
| EXPECT_EQ(GetDisplayZoom(display_id_list[1]), final_zoom_factor_2); |
| |
| // This zoom factor when applied to the display with width 1200, will result |
| // in an effective width greater than 4096, which is out of range. |
| float invalid_zoom_factor_1 = 0.285f; |
| info.display_zoom_factor = invalid_zoom_factor_1; |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(display_id_list[0]), info)); |
| |
| // This zoom factor when applied to the display with width 1200, will result |
| // in an effective width greater less than 640, which is out of range. |
| float invalid_zoom_factor_2 = 1.88f; |
| info.display_zoom_factor = invalid_zoom_factor_2; |
| EXPECT_FALSE( |
| CallSetDisplayUnitInfo(base::NumberToString(display_id_list[0]), info)); |
| |
| // Initialize displays that have bounds outside the valid width range of 640px |
| // to 4096px. |
| UpdateDisplay("400x350, 4500x1000#4500x1000"); |
| |
| display_id_list = display_manager()->GetConnectedDisplayIdList(); |
| |
| // Results in a logical width of 500px. This is below the 640px threshold but |
| // is valid because the initial width was 400px, so the logical width now |
| // allows a minimum width of 400px. |
| float valid_zoom_factor_1 = 0.8f; |
| info.display_zoom_factor = valid_zoom_factor_1; |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(display_id_list[0]), info)); |
| |
| // Results in a logical width of 4200px. This is above the 4096px threshold |
| // but is valid because the initial width was 4500px, so logical width of up |
| // to 4500px is allowed in this case. |
| float valid_zoom_factor_2 = 1.07f; |
| info.display_zoom_factor = valid_zoom_factor_2; |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(display_id_list[1]), info)); |
| |
| float valid_zoom_factor_3 = 0.5f; |
| info.display_zoom_factor = valid_zoom_factor_3; |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(display_id_list[0]), info)); |
| |
| float valid_zoom_factor_4 = 2.f; |
| info.display_zoom_factor = valid_zoom_factor_4; |
| EXPECT_TRUE( |
| CallSetDisplayUnitInfo(base::NumberToString(display_id_list[1]), info)); |
| } |
| |
| class DisplayInfoProviderChromeosTouchviewTest |
| : public DisplayInfoProviderChromeosTest { |
| public: |
| DisplayInfoProviderChromeosTouchviewTest() = default; |
| |
| DisplayInfoProviderChromeosTouchviewTest( |
| const DisplayInfoProviderChromeosTouchviewTest&) = delete; |
| DisplayInfoProviderChromeosTouchviewTest& operator=( |
| const DisplayInfoProviderChromeosTouchviewTest&) = delete; |
| |
| ~DisplayInfoProviderChromeosTouchviewTest() override = default; |
| |
| void SetUp() override { |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kUseFirstDisplayAsInternal); |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| ash::switches::kAshEnableTabletMode); |
| DisplayInfoProviderChromeosTest::SetUp(); |
| } |
| }; |
| |
| TEST_F(DisplayInfoProviderChromeosTouchviewTest, GetTabletMode) { |
| UpdateDisplay("500x600,400x520"); |
| |
| // Check initial state. Note: is_auto_rotation_allowed is always provided on |
| // CrOS. |
| DisplayUnitInfoList result = GetAllDisplaysInfo(); |
| ASSERT_EQ(2u, result.size()); |
| EXPECT_TRUE(result[0].has_accelerometer_support); |
| ASSERT_TRUE(result[0].is_auto_rotation_allowed); |
| EXPECT_FALSE(*result[0].is_auto_rotation_allowed); |
| EXPECT_FALSE(result[1].has_accelerometer_support); |
| ASSERT_TRUE(result[1].is_auto_rotation_allowed); |
| EXPECT_FALSE(*result[1].is_auto_rotation_allowed); |
| |
| // Entering tablet mode will cause DisplayConfigurationObserver to set |
| // forced mirror mode. https://crbug.com/733092. |
| EnableTabletMode(true); |
| // DisplayConfigurationObserver enables mirror mode asynchronously after |
| // tablet mode is enabled. |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_TRUE(display_manager()->IsInMirrorMode()); |
| result = GetAllDisplaysInfo(); |
| ASSERT_EQ(1u, result.size()); |
| EXPECT_TRUE(result[0].has_accelerometer_support); |
| ASSERT_TRUE(result[0].is_auto_rotation_allowed); |
| EXPECT_TRUE(*result[0].is_auto_rotation_allowed); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, SetMIXEDMode) { |
| { |
| // Mirroring source id not specified fails. |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| { |
| // Mirroring destination ids not specified fails. |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = "1000000"; |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| { |
| // Mirroring source id in bad format fails. |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = "bad_format_id"; |
| info.mirroring_destination_ids.emplace(); |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| { |
| // Mirroring destination id in bad format fails. |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = "1000000"; |
| info.mirroring_destination_ids.emplace(); |
| info.mirroring_destination_ids->emplace_back("bad_format_id"); |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| { |
| // Single display fails. |
| EXPECT_EQ(1U, display_manager()->num_connected_displays()); |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = "1000000"; |
| info.mirroring_destination_ids.emplace(); |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| // Add more displays. |
| UpdateDisplay("200x150,600x550,700x650"); |
| display::DisplayIdList id_list = |
| display_manager()->GetConnectedDisplayIdList(); |
| EXPECT_EQ(3U, id_list.size()); |
| |
| { |
| // Mirroring source id not found fails. |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = "1000000"; |
| info.mirroring_destination_ids.emplace(); |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| { |
| // Mirroring destination ids empty fails. |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = base::NumberToString(id_list[0]); |
| info.mirroring_destination_ids.emplace(); |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| { |
| // Mirroring destination ids not found fails. |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = base::NumberToString(id_list[0]); |
| info.mirroring_destination_ids.emplace(); |
| info.mirroring_destination_ids->emplace_back( |
| base::NumberToString(display::kInvalidDisplayId)); |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| { |
| // Duplicate display id fails. |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = base::NumberToString(id_list[0]); |
| info.mirroring_destination_ids.emplace(); |
| info.mirroring_destination_ids->emplace_back( |
| base::NumberToString(id_list[0])); |
| EXPECT_FALSE(SetMirrorMode(info)); |
| } |
| |
| { |
| // Turn on mixed mirror mode (mirroring from the first display to the second |
| // one). |
| api::system_display::MirrorModeInfo info; |
| info.mode = api::system_display::MirrorMode::kMixed; |
| info.mirroring_source_id = base::NumberToString(id_list[0]); |
| info.mirroring_destination_ids.emplace(); |
| info.mirroring_destination_ids->emplace_back( |
| base::NumberToString(id_list[1])); |
| EXPECT_TRUE(SetMirrorMode(info)); |
| EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode()); |
| EXPECT_EQ(id_list[0], display_manager()->mirroring_source_id()); |
| const display::Displays software_mirroring_display_list = |
| display_manager()->software_mirroring_display_list(); |
| EXPECT_EQ(1U, software_mirroring_display_list.size()); |
| EXPECT_EQ(id_list[1], software_mirroring_display_list[0].id()); |
| |
| // Turn off mixed mirror mode. |
| info.mode = api::system_display::MirrorMode::kOff; |
| EXPECT_TRUE(SetMirrorMode(info)); |
| EXPECT_FALSE(display_manager()->IsInMirrorMode()); |
| } |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTest, GetEdid) { |
| UpdateDisplay("500x600, 400x200"); |
| const char* kManufacturerId = "GOO"; |
| const char* kProductId = "GL"; |
| constexpr int32_t kYearOfManufacture = 2018; |
| |
| display::ManagedDisplayInfo info( |
| GetDisplayManager()->active_display_list()[0].id(), "", |
| false /* has_overscan */); |
| info.SetBounds(gfx::Rect(0, 0, 500, 600)); |
| info.set_manufacturer_id(kManufacturerId); |
| info.set_product_id(kProductId); |
| info.set_year_of_manufacture(kYearOfManufacture); |
| GetDisplayManager()->OnNativeDisplaysChanged({info}); |
| |
| DisplayUnitInfoList result = GetAllDisplaysInfo(); |
| ASSERT_EQ(1u, result.size()); |
| ASSERT_TRUE(result[0].edid); |
| EXPECT_EQ(kManufacturerId, result[0].edid->manufacturer_id); |
| EXPECT_EQ(kProductId, result[0].edid->product_id); |
| EXPECT_EQ(kYearOfManufacture, result[0].edid->year_of_manufacture); |
| } |
| |
| TEST_F(DisplayInfoProviderChromeosTouchviewTest, AutoRotation) { |
| EnableTabletMode(true); |
| |
| using DisplayUnitInfo = api::system_display::DisplayUnitInfo; |
| auto is_auto_rotation_allowed = [](const DisplayUnitInfo& info) { |
| return info.is_auto_rotation_allowed && *info.is_auto_rotation_allowed; |
| }; |
| auto is_auto_rotate = [](const DisplayUnitInfo& info) { |
| return info.rotation == -1; |
| }; |
| auto set_rotation_options = [&](int rotation) { |
| api::system_display::DisplayProperties info; |
| info.rotation = rotation; |
| EXPECT_TRUE(CallSetDisplayUnitInfo( |
| base::NumberToString(display::Display::InternalDisplayId()), info)); |
| }; |
| |
| DisplayUnitInfoList result = GetAllDisplaysInfo(); |
| EXPECT_TRUE(is_auto_rotation_allowed(result[0])); |
| EXPECT_TRUE(is_auto_rotate(result[0])); |
| |
| set_rotation_options(90); |
| result = GetAllDisplaysInfo(); |
| EXPECT_TRUE(is_auto_rotation_allowed(result[0])); |
| EXPECT_FALSE(is_auto_rotate(result[0])); |
| EXPECT_EQ(90, result[0].rotation); |
| auto* screen_orientation_controller = |
| ash::Shell::Get()->screen_orientation_controller(); |
| EXPECT_TRUE(screen_orientation_controller->user_rotation_locked()); |
| |
| // -1 means auto-rotate. |
| set_rotation_options(-1); |
| result = GetAllDisplaysInfo(); |
| EXPECT_TRUE(is_auto_rotation_allowed(result[0])); |
| EXPECT_TRUE(is_auto_rotate(result[0])); |
| EXPECT_FALSE(screen_orientation_controller->user_rotation_locked()); |
| |
| EnableTabletMode(false); |
| result = GetAllDisplaysInfo(); |
| EXPECT_FALSE(is_auto_rotation_allowed(result[0])); |
| EXPECT_FALSE(is_auto_rotate(result[0])); |
| EXPECT_EQ(0, result[0].rotation); |
| } |
| |
| } // namespace |
| } // namespace extensions |