#include <stddef.h>
#include <vector>
#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/manager/configure_displays_task.h"
#include "ui/display/manager/test/action_logger_util.h"
#include "ui/display/manager/test/fake_display_snapshot.h"
#include "ui/display/manager/test/test_native_display_delegate.h"
#include "ui/display/types/display_constants.h"
#include "ui/display/types/display_mode.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
namespace display::test {
namespace {
constexpr uint64_t kEdpConnectorId = 71u;
constexpr uint64_t kSecondConnectorId = kEdpConnectorId + 10u;
constexpr uint64_t kThirdConnectorId = kEdpConnectorId + 20u;
constexpr uint64_t kInvalidConnectorId = 0u;
std::string GetDisableCrtcAction(
const std::unique_ptr<DisplaySnapshot>& display) {
return GetCrtcAction({display->display_id(), gfx::Point(), nullptr});
}
class ConfigureDisplaysTaskTest : public testing::Test {
public:
ConfigureDisplaysTaskTest()
: delegate_(&log_),
small_mode_60hz_({1366, 768}, false, 60.0f),
small_mode_30hz_({1366, 768}, false, 30.0f),
medium_mode_60hz_({1920, 1080}, false, 60.0f),
medium_mode_29_98hz_({1920, 1080}, false, 29.98f),
medium_interlaced_mode_60hz_({1920, 1080}, true, 60.0f),
big_mode_60hz_({2560, 1600}, false, 60.0f),
big_mode_29_97hz_({2560, 1600}, false, 29.97f) {}
ConfigureDisplaysTaskTest(const ConfigureDisplaysTaskTest&) = delete;
ConfigureDisplaysTaskTest& operator=(const ConfigureDisplaysTaskTest&) =
delete;
~ConfigureDisplaysTaskTest() override = default;
void SetUp() override {
displays_.push_back(
FakeDisplaySnapshot::Builder()
.SetId(123)
.SetNativeMode(medium_mode_60hz_.Clone())
.SetCurrentMode(medium_mode_60hz_.Clone())
.AddMode(medium_mode_29_98hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.AddMode(small_mode_30hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_INTERNAL)
.SetBaseConnectorId(kEdpConnectorId)
.SetVariableRefreshRateState(VariableRefreshRateState::kVrrDisabled)
.Build());
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(big_mode_29_97hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.AddMode(small_mode_30hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.SetVariableRefreshRateState(
VariableRefreshRateState::kVrrNotCapable)
.Build());
}
void ConfigureCallback(ConfigureDisplaysTask::Status status) {
callback_called_ = true;
status_ = status;
}
protected:
base::test::SingleThreadTaskEnvironment task_environment_;
ActionLogger log_;
TestNativeDisplayDelegate delegate_;
bool callback_called_ = false;
ConfigureDisplaysTask::Status status_ = ConfigureDisplaysTask::ERROR;
const DisplayMode small_mode_60hz_;
const DisplayMode small_mode_30hz_;
const DisplayMode medium_mode_60hz_;
const DisplayMode medium_mode_29_98hz_;
const DisplayMode medium_interlaced_mode_60hz_;
const DisplayMode big_mode_60hz_;
const DisplayMode big_mode_29_97hz_;
std::vector<std::unique_ptr<DisplaySnapshot>> displays_;
};
}
* Cases that report ConfigureDisplaysTask::SUCCESS
**************************************************/
TEST_F(ConfigureDisplaysTaskTest, ConfigureInternalDisplay) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
std::vector<DisplayConfigureRequest> requests(
1, DisplayConfigureRequest(displays_[0].get(),
displays_[0]->native_mode(), gfx::Point()));
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::SUCCESS, status_);
EXPECT_EQ(JoinActions(kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureInternalAndOneExternalDisplays) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::SUCCESS, status_);
EXPECT_EQ(JoinActions(kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureOneExternalDisplay) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
std::vector<DisplayConfigureRequest> requests(
1, DisplayConfigureRequest(displays_[1].get(),
displays_[1]->native_mode(), gfx::Point()));
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::SUCCESS, status_);
EXPECT_EQ(JoinActions(kTestModesetStr,
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
displays_[1]->native_mode()})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
displays_[1]->native_mode()})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureTwoMstDisplays) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_[0] = FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
displays_[1] = FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::SUCCESS, status_);
EXPECT_EQ(JoinActions(kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureInternalAndTwoMstAndHdmiDisplays) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(101112)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_HDMI)
.SetBaseConnectorId(kThirdConnectorId)
.Build());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::SUCCESS, status_);
EXPECT_EQ(JoinActions(kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({displays_[2]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({displays_[3]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({displays_[2]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({displays_[3]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
* Cases that report ConfigureDisplaysTask::ERROR
************************************************/
TEST_F(ConfigureDisplaysTaskTest, DisableInternalDisplayFails) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
delegate_.set_max_configurable_pixels(-1);
std::vector<DisplayConfigureRequest> requests(
1, DisplayConfigureRequest(displays_[0].get(), nullptr, gfx::Point()));
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
kModesetOutcomeFailure, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, NoModeChangeAttemptWhenInternalDisplayFails) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
delegate_.set_max_configurable_pixels(1);
std::vector<DisplayConfigureRequest> requests(
1, DisplayConfigureRequest(displays_[0].get(),
displays_[0]->native_mode(), gfx::Point()));
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
kModesetOutcomeFailure, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureOneExternalNoInternalDisplayFails) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
delegate_.set_max_configurable_pixels(1);
std::vector<DisplayConfigureRequest> requests(
1, DisplayConfigureRequest(displays_[1].get(), &big_mode_60hz_,
gfx::Point()));
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_30hz_})
.c_str(),
kModesetOutcomeFailure, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureTwoNoneMstDisplaysNoInternalFail) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_[0] = FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
displays_[1] = FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kThirdConnectorId)
.Build();
delegate_.set_max_configurable_pixels(small_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kCommitModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(), kModesetOutcomeSuccess,
nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureTwoMstDisplaysNoInternalFail) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_[0] = FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
displays_[1] = FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
delegate_.set_max_configurable_pixels(1);
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndOneExternalDisplaysFailsDueToInternal) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
delegate_.set_max_configurable_pixels(1);
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(), kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_30hz_})
.c_str(),
kModesetOutcomeFailure, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndOneExternalDisplaysFailsDueToExternal) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_[0] = FakeDisplaySnapshot::Builder()
.SetId(123)
.SetNativeMode(small_mode_60hz_.Clone())
.SetCurrentMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_INTERNAL)
.SetBaseConnectorId(kEdpConnectorId)
.Build();
displays_[1] = FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
delegate_.set_max_configurable_pixels(small_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(), kModesetOutcomeSuccess,
nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndTwoMstExternalDisplaysFailsDueToInternal) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
delegate_.set_max_configurable_pixels(1);
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_30hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndTwoMstExternalDisplaysFailsDueToExternals) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_[0] = FakeDisplaySnapshot::Builder()
.SetId(123)
.SetNativeMode(small_mode_60hz_.Clone())
.SetCurrentMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_INTERNAL)
.SetBaseConnectorId(kEdpConnectorId)
.Build();
displays_[1] = FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
delegate_.set_max_configurable_pixels(small_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeSuccess,
nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndTwoMstAndHdmiDisplaysFailsDueToInternal) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(101112)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(big_mode_29_97hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.AddMode(medium_mode_29_98hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.AddMode(small_mode_30hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_HDMI)
.SetBaseConnectorId(kThirdConnectorId)
.Build());
delegate_.set_max_configurable_pixels(1);
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_30hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr, GetDisableCrtcAction(displays_[0]).c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &medium_mode_29_98hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetDisableCrtcAction(displays_[0]).c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &small_mode_30hz_})
.c_str(),
kModesetOutcomeFailure, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndTwoMstAndHdmiDisplaysFailsDueToMst) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(101112)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(big_mode_29_97hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.AddMode(medium_mode_29_98hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.AddMode(small_mode_30hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_HDMI)
.SetBaseConnectorId(kThirdConnectorId)
.Build());
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_30hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndTwoMstAndHdmiDisplaysFailsDueToHDMI) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_[1] = FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(medium_mode_60hz_.Clone())
.SetCurrentMode(medium_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(medium_mode_60hz_.Clone())
.SetCurrentMode(medium_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(101112)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_HDMI)
.SetBaseConnectorId(kThirdConnectorId)
.Build());
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeSuccess,
nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndOneBadMstHubWithTwoDisplaysFails) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_[1] = FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kInvalidConnectorId)
.Build();
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kInvalidConnectorId)
.Build());
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeSuccess,
nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndTwoBadMstHubsWithFourDisplaysFails) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_[1] = FakeDisplaySnapshot::Builder()
.SetId(456)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kInvalidConnectorId)
.Build();
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kInvalidConnectorId)
.Build());
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(101112)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kInvalidConnectorId)
.Build());
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(131415)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kInvalidConnectorId)
.Build());
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::ERROR, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[4]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetDisableCrtcAction(displays_[3]).c_str(),
GetDisableCrtcAction(displays_[4]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[4]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[4]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[4]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[4]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[4]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetDisableCrtcAction(displays_[3]).c_str(),
GetDisableCrtcAction(displays_[4]).c_str(), kModesetOutcomeSuccess,
nullptr),
log_.GetActionsAndClear());
}
* Cases that report ConfigureDisplaysTask::PARTIAL_SUCCESS
**********************************************************/
TEST_F(ConfigureDisplaysTaskTest, ConfigureLastDisplayPartialSuccess) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureMiddleDisplayPartialSuccess) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(small_mode_60hz_.Clone())
.SetCurrentMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_HDMI)
.SetBaseConnectorId(kThirdConnectorId)
.Build());
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureTwoMstDisplaysPartialSuccess) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndTwoMstAndHdmiDisplaysPartialSuccess) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(101112)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_HDMI)
.SetBaseConnectorId(kThirdConnectorId)
.Build());
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &medium_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest,
ConfigureInternalAndMstThenNestAnotherMstForThreeExternalDisplays) {
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(789)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
{
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(),
gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::SUCCESS, status_);
EXPECT_EQ(
JoinActions(kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({displays_[2]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({displays_[2]->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
displays_.push_back(FakeDisplaySnapshot::Builder()
.SetId(101112)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build());
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
{
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(),
gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(),
GetDisableCrtcAction(displays_[2]).c_str(),
GetDisableCrtcAction(displays_[3]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[2]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
GetCrtcAction(
{displays_[3]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
}
TEST_F(ConfigureDisplaysTaskTest, AsyncConfigureWithTwoDisplaysPartialSuccess) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
delegate_.set_run_async(true);
delegate_.set_max_configurable_pixels(medium_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point());
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_FALSE(callback_called_);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetDisableCrtcAction(displays_[1]).c_str(), kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &big_mode_29_97hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess,
kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
GetCrtcAction(
{displays_[1]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, CloseLidThenOpenLid) {
std::unique_ptr<DisplaySnapshot> internal_display =
FakeDisplaySnapshot::Builder()
.SetId(100)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_INTERNAL)
.SetBaseConnectorId(kEdpConnectorId)
.Build();
std::unique_ptr<DisplaySnapshot> external_display1 =
FakeDisplaySnapshot::Builder()
.SetId(200)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
std::unique_ptr<DisplaySnapshot> external_display2 =
FakeDisplaySnapshot::Builder()
.SetId(external_display1->display_id() + 1)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
std::vector<DisplayConfigureRequest> requests;
requests.emplace_back(internal_display.get(), internal_display->native_mode(),
gfx::Point());
requests.emplace_back(external_display1.get(),
external_display1->native_mode(), gfx::Point());
requests.emplace_back(external_display2.get(),
external_display2->native_mode(), gfx::Point());
int supported_option_1 = big_mode_60hz_.size().GetArea() * 2;
int supported_option_2 =
big_mode_60hz_.size().GetArea() + small_mode_60hz_.size().GetArea() * 2;
int supported_bw = std::max(supported_option_1, supported_option_2);
ASSERT_LT(supported_bw, big_mode_60hz_.size().GetArea() * 3);
delegate_.set_system_bandwidth_limit(supported_bw);
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
ConfigureDisplaysTask turn_on_all_displays_task(&delegate_, requests,
std::move(callback));
turn_on_all_displays_task.Run();
ASSERT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
log_.GetActionsAndClear();
requests.clear();
requests.emplace_back(internal_display.get(), nullptr, gfx::Point());
requests.emplace_back(external_display1.get(),
external_display1->native_mode(), gfx::Point());
requests.emplace_back(external_display2.get(),
external_display2->native_mode(), gfx::Point());
callback = base::BindOnce(&ConfigureDisplaysTaskTest::ConfigureCallback,
base::Unretained(this));
ConfigureDisplaysTask close_lid(&delegate_, requests, std::move(callback));
close_lid.Run();
EXPECT_EQ(ConfigureDisplaysTask::SUCCESS, status_);
EXPECT_EQ(JoinActions(kTestModesetStr,
GetDisableCrtcAction(internal_display).c_str(),
GetCrtcAction({external_display1->display_id(),
gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display2->display_id(),
gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetDisableCrtcAction(internal_display).c_str(),
GetCrtcAction({external_display1->display_id(),
gfx::Point(), &big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display2->display_id(),
gfx::Point(), &big_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
requests.clear();
requests.emplace_back(internal_display.get(), internal_display->native_mode(),
gfx::Point());
requests.emplace_back(external_display1.get(),
external_display1->native_mode(), gfx::Point());
requests.emplace_back(external_display2.get(),
external_display2->native_mode(), gfx::Point());
callback = base::BindOnce(&ConfigureDisplaysTaskTest::ConfigureCallback,
base::Unretained(this));
ConfigureDisplaysTask open_lid(&delegate_, requests, std::move(callback));
open_lid.Run();
ASSERT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
EXPECT_EQ(JoinActions(
kTestModesetStr,
GetCrtcAction({internal_display->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display1->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display2->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({internal_display->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetDisableCrtcAction(external_display1).c_str(),
GetDisableCrtcAction(external_display2).c_str(),
kModesetOutcomeSuccess,
kTestModesetStr,
GetCrtcAction({internal_display->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display1->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display2->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({internal_display->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display1->display_id(), gfx::Point(),
&small_mode_60hz_})
.c_str(),
GetCrtcAction({external_display2->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
kModesetOutcomeFailure, kTestModesetStr,
GetCrtcAction({internal_display->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display1->display_id(), gfx::Point(),
&small_mode_60hz_})
.c_str(),
GetCrtcAction({external_display2->display_id(), gfx::Point(),
&small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess,
kCommitModesetStr,
GetCrtcAction({internal_display->display_id(), gfx::Point(),
&big_mode_60hz_})
.c_str(),
GetCrtcAction({external_display1->display_id(), gfx::Point(),
&small_mode_60hz_})
.c_str(),
GetCrtcAction({external_display2->display_id(), gfx::Point(),
&small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, ConfigureVrr) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
std::vector<DisplayConfigureRequest> requests;
for (const auto& display : displays_) {
requests.emplace_back(display.get(), display->native_mode(), gfx::Point(),
true);
}
ConfigureDisplaysTask task(&delegate_, requests, std::move(callback));
task.Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::SUCCESS, status_);
EXPECT_EQ(displays_[0]->variable_refresh_rate_state(),
VariableRefreshRateState::kVrrEnabled);
EXPECT_EQ(displays_[1]->variable_refresh_rate_state(),
VariableRefreshRateState::kVrrNotCapable);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode(), true})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_, true})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode(), true})
.c_str(),
GetCrtcAction({displays_[1]->display_id(), gfx::Point(),
&big_mode_60hz_, true})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
TEST_F(ConfigureDisplaysTaskTest, TestPrioritizeProgressiveOverInterlaced) {
ConfigureDisplaysTask::ResponseCallback callback = base::BindOnce(
&ConfigureDisplaysTaskTest::ConfigureCallback, base::Unretained(this));
displays_.pop_back();
displays_[0] = FakeDisplaySnapshot::Builder()
.SetId(0xBADC0FFEE)
.SetNativeMode(big_mode_60hz_.Clone())
.SetCurrentMode(big_mode_60hz_.Clone())
.AddMode(medium_interlaced_mode_60hz_.Clone())
.AddMode(small_mode_60hz_.Clone())
.SetType(DISPLAY_CONNECTION_TYPE_DISPLAYPORT)
.SetBaseConnectorId(kSecondConnectorId)
.Build();
delegate_.set_max_configurable_pixels(
medium_interlaced_mode_60hz_.size().GetArea());
std::vector<DisplayConfigureRequest> requests;
requests.emplace_back(displays_[0].get(), displays_[0]->native_mode(),
gfx::Point(), false);
ConfigureDisplaysTask(&delegate_, requests, std::move(callback)).Run();
EXPECT_TRUE(callback_called_);
EXPECT_EQ(ConfigureDisplaysTask::PARTIAL_SUCCESS, status_);
EXPECT_EQ(
JoinActions(
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction({displays_[0]->display_id(), gfx::Point(),
displays_[0]->native_mode()})
.c_str(),
kModesetOutcomeFailure,
kTestModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, kCommitModesetStr,
GetCrtcAction(
{displays_[0]->display_id(), gfx::Point(), &small_mode_60hz_})
.c_str(),
kModesetOutcomeSuccess, nullptr),
log_.GetActionsAndClear());
}
}