blob: 63e5697488afdf69772d239d959f9be30f3b94a1 [file] [log] [blame]
// 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