// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/display/chromeos/display_configurator.h"

#include <stddef.h>
#include <stdint.h>

#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/chromeos/test/action_logger_util.h"
#include "ui/display/chromeos/test/test_display_snapshot.h"
#include "ui/display/chromeos/test/test_native_display_delegate.h"
#include "ui/display/util/display_util.h"

namespace ui {
namespace test {

namespace {

class TestObserver : public DisplayConfigurator::Observer {
 public:
  explicit TestObserver(DisplayConfigurator* configurator)
      : configurator_(configurator) {
    Reset();
    configurator_->AddObserver(this);
  }
  ~TestObserver() override { configurator_->RemoveObserver(this); }

  int num_changes() const { return num_changes_; }
  int num_failures() const { return num_failures_; }
  const DisplayConfigurator::DisplayStateList& latest_outputs() const {
    return latest_outputs_;
  }
  MultipleDisplayState latest_failed_state() const {
    return latest_failed_state_;
  }

  void Reset() {
    num_changes_ = 0;
    num_failures_ = 0;
    latest_outputs_.clear();
    latest_failed_state_ = MULTIPLE_DISPLAY_STATE_INVALID;
  }

  // DisplayConfigurator::Observer overrides:
  void OnDisplayModeChanged(
      const DisplayConfigurator::DisplayStateList& outputs) override {
    num_changes_++;
    latest_outputs_ = outputs;
  }

  void OnDisplayModeChangeFailed(
      const DisplayConfigurator::DisplayStateList& outputs,
      MultipleDisplayState failed_new_state) override {
    num_failures_++;
    latest_failed_state_ = failed_new_state;
  }

 private:
  DisplayConfigurator* configurator_;  // Not owned.

  // Number of times that OnDisplayMode*() has been called.
  int num_changes_;
  int num_failures_;

  // Parameters most recently passed to OnDisplayMode*().
  DisplayConfigurator::DisplayStateList latest_outputs_;
  MultipleDisplayState latest_failed_state_;

  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

class TestStateController : public DisplayConfigurator::StateController {
 public:
  TestStateController() : state_(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {}
  ~TestStateController() override {}

  void set_state(MultipleDisplayState state) { state_ = state; }

  // DisplayConfigurator::StateController overrides:
  MultipleDisplayState GetStateForDisplayIds(
      const DisplayConfigurator::DisplayStateList& outputs) const override {
    return state_;
  }
  bool GetResolutionForDisplayId(int64_t display_id,
                                 gfx::Size* size) const override {
    return false;
  }

 private:
  MultipleDisplayState state_;

  DISALLOW_COPY_AND_ASSIGN(TestStateController);
};

class TestMirroringController
    : public DisplayConfigurator::SoftwareMirroringController {
 public:
  TestMirroringController() : software_mirroring_enabled_(false) {}
  ~TestMirroringController() override {}

  void SetSoftwareMirroring(bool enabled) override {
    software_mirroring_enabled_ = enabled;
  }

  bool SoftwareMirroringEnabled() const override {
    return software_mirroring_enabled_;
  }

 private:
  bool software_mirroring_enabled_;

  DISALLOW_COPY_AND_ASSIGN(TestMirroringController);
};

class DisplayConfiguratorTest : public testing::Test {
 public:
  enum CallbackResult {
    CALLBACK_FAILURE,
    CALLBACK_SUCCESS,
    CALLBACK_NOT_CALLED,
  };

  DisplayConfiguratorTest()
      : small_mode_(gfx::Size(1366, 768), false, 60.0f),
        big_mode_(gfx::Size(2560, 1600), false, 60.0f),
        observer_(&configurator_),
        test_api_(&configurator_),
        enable_content_protection_status_(0),
        enable_content_protection_call_count_(0),
        query_content_protection_call_count_(0),
        callback_result_(CALLBACK_NOT_CALLED),
        display_control_result_(CALLBACK_NOT_CALLED) {}
  ~DisplayConfiguratorTest() override {}

  void SetUp() override {
    log_.reset(new ActionLogger());

    native_display_delegate_ = new TestNativeDisplayDelegate(log_.get());
    configurator_.SetDelegateForTesting(
        std::unique_ptr<NativeDisplayDelegate>(native_display_delegate_));

    configurator_.set_state_controller(&state_controller_);
    configurator_.set_mirroring_controller(&mirroring_controller_);

    std::vector<std::unique_ptr<const DisplayMode>> modes;
    modes.push_back(small_mode_.Clone());

    TestDisplaySnapshot* o = &outputs_[0];
    o->set_current_mode(modes.front().get());
    o->set_native_mode(modes.front().get());
    o->set_modes(std::move(modes));
    o->set_type(DISPLAY_CONNECTION_TYPE_INTERNAL);
    o->set_is_aspect_preserving_scaling(true);
    o->set_display_id(123);

    modes.clear();
    modes.push_back(small_mode_.Clone());
    modes.push_back(big_mode_.Clone());
    o = &outputs_[1];
    o->set_current_mode(modes.back().get());
    o->set_native_mode(modes.back().get());
    o->set_modes(std::move(modes));
    o->set_type(DISPLAY_CONNECTION_TYPE_HDMI);
    o->set_is_aspect_preserving_scaling(true);
    o->set_display_id(456);

    modes.clear();
    modes.push_back(small_mode_.Clone());
    o = &outputs_[2];
    o->set_current_mode(modes.back().get());
    o->set_native_mode(modes.back().get());
    o->set_modes(std::move(modes));
    o->set_type(DISPLAY_CONNECTION_TYPE_HDMI);
    o->set_is_aspect_preserving_scaling(true);
    o->set_display_id(789);

    UpdateOutputs(2, false);
  }

  void OnConfiguredCallback(bool status) {
    callback_result_ = (status ? CALLBACK_SUCCESS : CALLBACK_FAILURE);
  }

  void OnDisplayControlUpdated(bool status) {
    display_control_result_ = (status ? CALLBACK_SUCCESS : CALLBACK_FAILURE);
  }

  void EnableContentProtectionCallback(bool status) {
    enable_content_protection_status_ = status;
    enable_content_protection_call_count_++;
  }

  void QueryContentProtectionCallback(
      const DisplayConfigurator::QueryProtectionResponse& response) {
    query_content_protection_response_ = response;
    query_content_protection_call_count_++;
  }

  // Predefined modes that can be used by outputs.
  const DisplayMode small_mode_;
  const DisplayMode big_mode_;

 protected:
  // Configures |native_display_delegate_| to return the first |num_outputs|
  // entries from
  // |outputs_|. If |send_events| is true, also sends screen-change and
  // output-change events to |configurator_| and triggers the configure
  // timeout if one was scheduled.
  void UpdateOutputs(size_t num_outputs, bool send_events) {
    ASSERT_LE(num_outputs, arraysize(outputs_));
    std::vector<DisplaySnapshot*> outputs;
    for (size_t i = 0; i < num_outputs; ++i)
      outputs.push_back(&outputs_[i]);
    native_display_delegate_->set_outputs(outputs);

    if (send_events) {
      configurator_.OnConfigurationChanged();
      EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
    }
  }

  void Init(bool panel_fitting_enabled) {
    configurator_.Init(nullptr, panel_fitting_enabled);
  }

  // Initializes |configurator_| with a single internal display.
  void InitWithSingleOutput() {
    UpdateOutputs(1, false);
    EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    configurator_.Init(nullptr, false);

    EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    configurator_.ForceInitialConfigure(0);
    EXPECT_EQ(JoinActions(kInitXRandR, kGrab,
                          GetFramebufferAction(small_mode_.size(), &outputs_[0],
                                               NULL).c_str(),
                          GetCrtcAction(outputs_[0], &small_mode_,
                                        gfx::Point(0, 0)).c_str(),
                          kForceDPMS, kUngrab, NULL),
              log_->GetActionsAndClear());
  }

  CallbackResult PopCallbackResult() {
    CallbackResult result = callback_result_;
    callback_result_ = CALLBACK_NOT_CALLED;
    return result;
  }

  CallbackResult PopDisplayControlResult() {
    CallbackResult result = display_control_result_;
    display_control_result_ = CALLBACK_NOT_CALLED;
    return result;
  }

  base::MessageLoop message_loop_;
  TestStateController state_controller_;
  TestMirroringController mirroring_controller_;
  DisplayConfigurator configurator_;
  TestObserver observer_;
  std::unique_ptr<ActionLogger> log_;
  TestNativeDisplayDelegate* native_display_delegate_;  // not owned
  DisplayConfigurator::TestApi test_api_;

  bool enable_content_protection_status_;
  int enable_content_protection_call_count_;
  DisplayConfigurator::QueryProtectionResponse
      query_content_protection_response_;
  int query_content_protection_call_count_;

  TestDisplaySnapshot outputs_[3];

  CallbackResult callback_result_;
  CallbackResult display_control_result_;

 private:
  DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorTest);
};

}  // namespace

TEST_F(DisplayConfiguratorTest, FindDisplayModeMatchingSize) {
  std::vector<const DisplayMode*> modes;

  // Fields are width, height, interlaced, refresh rate.
  modes.push_back(new DisplayMode(gfx::Size(1920, 1200), false, 60.0));
  DisplayMode* native_mode =
      new DisplayMode(gfx::Size(1920, 1200), false, 50.0);
  modes.push_back(native_mode);
  // Different rates.
  modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 30.0));
  modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 50.0));
  modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
  modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 0.0));
  // Interlaced vs non-interlaced.
  modes.push_back(new DisplayMode(gfx::Size(1280, 720), true, 60.0));
  modes.push_back(new DisplayMode(gfx::Size(1280, 720), false, 40.0));
  // Interlaced only.
  modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 0.0));
  modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 40.0));
  modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 60.0));
  // Mixed.
  modes.push_back(new DisplayMode(gfx::Size(1024, 600), true, 60.0));
  modes.push_back(new DisplayMode(gfx::Size(1024, 600), false, 40.0));
  modes.push_back(new DisplayMode(gfx::Size(1024, 600), false, 50.0));
  // Just one interlaced mode.
  modes.push_back(new DisplayMode(gfx::Size(640, 480), true, 60.0));
  // Refresh rate not available.
  modes.push_back(new DisplayMode(gfx::Size(320, 200), false, 0.0));

  TestDisplaySnapshot output;
  std::vector<std::unique_ptr<const DisplayMode>> tmp_modes;
  for (const DisplayMode* mode : modes)
    tmp_modes.push_back(base::WrapUnique(mode));
  output.set_modes(std::move(tmp_modes));
  output.set_native_mode(native_mode);

  // Should pick native over highest refresh rate.
  EXPECT_EQ(modes[1],
            DisplayConfigurator::FindDisplayModeMatchingSize(
                output, gfx::Size(1920, 1200)));

  // Should pick highest refresh rate.
  EXPECT_EQ(modes[3],
            DisplayConfigurator::FindDisplayModeMatchingSize(
                output, gfx::Size(1920, 1080)));

  // Should pick non-interlaced mode.
  EXPECT_EQ(modes[7],
            DisplayConfigurator::FindDisplayModeMatchingSize(
                output, gfx::Size(1280, 720)));

  // Interlaced only. Should pick one with the highest refresh rate in
  // interlaced mode.
  EXPECT_EQ(modes[10],
            DisplayConfigurator::FindDisplayModeMatchingSize(
                output, gfx::Size(1024, 768)));

  // Mixed: Should pick one with the highest refresh rate in
  // interlaced mode.
  EXPECT_EQ(modes[13],
            DisplayConfigurator::FindDisplayModeMatchingSize(
                output, gfx::Size(1024, 600)));

  // Just one interlaced mode.
  EXPECT_EQ(modes[14],
            DisplayConfigurator::FindDisplayModeMatchingSize(
                output, gfx::Size(640, 480)));

  // Refresh rate not available.
  EXPECT_EQ(modes[15],
            DisplayConfigurator::FindDisplayModeMatchingSize(
                output, gfx::Size(320, 200)));

  // No mode found.
  EXPECT_EQ(NULL,
            DisplayConfigurator::FindDisplayModeMatchingSize(
                output, gfx::Size(1440, 900)));
}

TEST_F(DisplayConfiguratorTest, EnableVirtualDisplay) {
  InitWithSingleOutput();

  observer_.Reset();
  const DisplayConfigurator::DisplayStateList& cached =
      configurator_.cached_displays();
  ASSERT_EQ(static_cast<size_t>(1u), cached.size());
  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());

  // Add virtual display.
  int64_t virtual_display_id =
      configurator_.AddVirtualDisplay(big_mode_.size());
  EXPECT_EQ(display::GenerateDisplayID(0x8000, 0x0, 1), virtual_display_id);
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
            configurator_.display_state());

  // Virtual should not trigger addition of added crtc but does change FB
  // height.
  const int kVirtualHeight = small_mode_.size().height() +
                             DisplayConfigurator::kVerticalGap +
                             big_mode_.size().height();
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(
                     gfx::Size(big_mode_.size().width(), kVirtualHeight),
                     &outputs_[0], nullptr)
                     .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab, nullptr),
      log_->GetActionsAndClear());
  EXPECT_EQ(1, observer_.num_changes());
  ASSERT_EQ(static_cast<size_t>(2u), cached.size());
  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
  EXPECT_EQ(big_mode_.size(), cached[1]->current_mode()->size());
  EXPECT_EQ(virtual_display_id, cached[1]->display_id());

  // Remove virtual display.
  observer_.Reset();
  EXPECT_TRUE(configurator_.RemoveVirtualDisplay(virtual_display_id));
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(small_mode_.size(), &outputs_[0], nullptr)
                     .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab, nullptr),
      log_->GetActionsAndClear());
  EXPECT_EQ(1, observer_.num_changes());
  ASSERT_EQ(static_cast<size_t>(1u), cached.size());
  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
}

TEST_F(DisplayConfiguratorTest, EnableTwoVirtualDisplays) {
  InitWithSingleOutput();

  observer_.Reset();
  const DisplayConfigurator::DisplayStateList& cached =
      configurator_.cached_displays();
  ASSERT_EQ(static_cast<size_t>(1u), cached.size());
  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());

  // Add 1st virtual display.
  int64_t virtual_display_id_1 =
      configurator_.AddVirtualDisplay(big_mode_.size());
  EXPECT_EQ(display::GenerateDisplayID(0x8000, 0x0, 1), virtual_display_id_1);
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
            configurator_.display_state());

  // Virtual should not trigger addition of added crtc but does change FB
  // height.
  const int kSingleVirtualHeight = small_mode_.size().height() +
                                   DisplayConfigurator::kVerticalGap +
                                   big_mode_.size().height();
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(
                     gfx::Size(big_mode_.size().width(), kSingleVirtualHeight),
                     &outputs_[0], nullptr)
                     .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab, nullptr),
      log_->GetActionsAndClear());
  EXPECT_EQ(1, observer_.num_changes());
  ASSERT_EQ(static_cast<size_t>(2), cached.size());
  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
  EXPECT_EQ(big_mode_.size(), cached[1]->current_mode()->size());
  EXPECT_EQ(virtual_display_id_1, cached[1]->display_id());

  // Add 2nd virtual display
  int64_t virtual_display_id_2 =
      configurator_.AddVirtualDisplay(big_mode_.size());
  EXPECT_EQ(display::GenerateDisplayID(0x8000, 0x0, 2), virtual_display_id_2);
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED,
            configurator_.display_state());

  const int kDualVirtualHeight =
      small_mode_.size().height() +
      (DisplayConfigurator::kVerticalGap + big_mode_.size().height()) * 2;
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(
                     gfx::Size(big_mode_.size().width(), kDualVirtualHeight),
                     &outputs_[0], nullptr)
                     .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab, nullptr),
      log_->GetActionsAndClear());
  EXPECT_EQ(2, observer_.num_changes());
  ASSERT_EQ(static_cast<size_t>(3u), cached.size());
  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
  EXPECT_EQ(big_mode_.size(), cached[1]->current_mode()->size());
  EXPECT_EQ(big_mode_.size(), cached[2]->current_mode()->size());
  EXPECT_EQ(virtual_display_id_1, cached[1]->display_id());
  EXPECT_EQ(virtual_display_id_2, cached[2]->display_id());

  // Remove 1st virtual display.
  observer_.Reset();
  EXPECT_TRUE(configurator_.RemoveVirtualDisplay(virtual_display_id_1));
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(
                     gfx::Size(big_mode_.size().width(), kSingleVirtualHeight),
                     &outputs_[0], nullptr)
                     .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab, nullptr),
      log_->GetActionsAndClear());
  EXPECT_EQ(1, observer_.num_changes());
  ASSERT_EQ(static_cast<size_t>(2u), cached.size());
  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
  EXPECT_EQ(big_mode_.size(), cached[1]->current_mode()->size());
  EXPECT_EQ(virtual_display_id_2, cached[1]->display_id());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
            configurator_.display_state());

  // Remove 2nd virtual display.
  observer_.Reset();
  EXPECT_TRUE(configurator_.RemoveVirtualDisplay(virtual_display_id_2));
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(small_mode_.size(), &outputs_[0], nullptr)
                     .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab, nullptr),
      log_->GetActionsAndClear());
  EXPECT_EQ(1, observer_.num_changes());
  ASSERT_EQ(static_cast<size_t>(1), cached.size());
  EXPECT_EQ(small_mode_.size(), cached[0]->current_mode()->size());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
}

TEST_F(DisplayConfiguratorTest, ConnectSecondOutput) {
  InitWithSingleOutput();

  // Connect a second output and check that the configurator enters
  // extended mode.
  observer_.Reset();
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  UpdateOutputs(2, true);
  const int kDualHeight = small_mode_.size().height() +
                          DisplayConfigurator::kVerticalGap +
                          big_mode_.size().height();
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0],
                               &outputs_[1]).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1],
                        &big_mode_,
                        gfx::Point(0,
                                   small_mode_.size().height() +
                                       DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  observer_.Reset();
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Disconnect the second output.
  observer_.Reset();
  UpdateOutputs(1, true);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Get rid of shared modes to force software mirroring.
  std::vector<std::unique_ptr<const DisplayMode>> modes;
  modes.push_back(big_mode_.Clone());
  outputs_[1].set_current_mode(modes.front().get());
  outputs_[1].set_native_mode(modes.front().get());
  outputs_[1].set_modes(std::move(modes));
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  UpdateOutputs(2, true);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0],
                               &outputs_[1]).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1],
                        &big_mode_,
                        gfx::Point(0,
                                   small_mode_.size().height() +
                                       DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  const gfx::Size framebuffer_size = configurator_.framebuffer_size();
  DCHECK(!framebuffer_size.IsEmpty());

  observer_.Reset();
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
            configurator_.display_state());
  EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(framebuffer_size.ToString(),
            configurator_.framebuffer_size().ToString());

  EXPECT_EQ(1, observer_.num_changes());

  // Setting MULTIPLE_DISPLAY_STATE_DUAL_MIRROR should try to reconfigure.
  observer_.Reset();
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  EXPECT_EQ(JoinActions(NULL), log_->GetActionsAndClear());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Set back to software mirror mode.
  observer_.Reset();
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
            configurator_.display_state());
  EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Disconnect the second output.
  observer_.Reset();
  UpdateOutputs(1, true);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());
}

TEST_F(DisplayConfiguratorTest, SetDisplayPower) {
  InitWithSingleOutput();

  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  observer_.Reset();
  UpdateOutputs(2, true);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Turning off the internal display should switch the external display to
  // its native mode.
  observer_.Reset();
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
  EXPECT_EQ(1, observer_.num_changes());

  // When all displays are turned off, the framebuffer should switch back
  // to the mirrored size.
  observer_.Reset();
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(kGrab,
                  GetFramebufferAction(
                      small_mode_.size(), &outputs_[0], &outputs_[1]).c_str(),
                  GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
                  GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(),
                  kUngrab,
                  NULL),
      log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Turn all displays on and check that mirroring is still used.
  observer_.Reset();
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Get rid of shared modes to force software mirroring.
  std::vector<std::unique_ptr<const DisplayMode>> modes;
  modes.push_back(big_mode_.Clone());
  outputs_[1].set_current_mode(modes.front().get());
  outputs_[1].set_native_mode(modes.front().get());
  outputs_[1].set_modes(std::move(modes));
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  observer_.Reset();
  UpdateOutputs(2, true);
  const int kDualHeight = small_mode_.size().height() +
                          DisplayConfigurator::kVerticalGap +
                          big_mode_.size().height();
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0],
                               &outputs_[1]).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1],
                        &big_mode_,
                        gfx::Point(0,
                                   small_mode_.size().height() +
                                       DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
            configurator_.display_state());
  EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Turning off the internal display should switch the external display to
  // its native mode.
  observer_.Reset();
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
  EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // When all displays are turned off, the framebuffer should switch back
  // to the extended + software mirroring.
  observer_.Reset();
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0],
                               &outputs_[1]).c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1],
                        NULL,
                        gfx::Point(0,
                                   small_mode_.size().height() +
                                       DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
            configurator_.display_state());
  EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());

  // Turn all displays on and check that mirroring is still used.
  observer_.Reset();
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0],
                               &outputs_[1]).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1],
                        &big_mode_,
                        gfx::Point(0,
                                   small_mode_.size().height() +
                                       DisplayConfigurator::kVerticalGap))
              .c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
            configurator_.display_state());
  EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
  EXPECT_EQ(1, observer_.num_changes());
}

TEST_F(DisplayConfiguratorTest, SuspendAndResume) {
  InitWithSingleOutput();

  // No preparation is needed before suspending when the display is already
  // on.  The configurator should still reprobe on resume in case a display
  // was connected while suspended.
  const gfx::Size framebuffer_size = configurator_.framebuffer_size();
  DCHECK(!framebuffer_size.IsEmpty());
  configurator_.SuspendDisplays(base::Bind(
      &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(framebuffer_size.ToString(),
            configurator_.framebuffer_size().ToString());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          kUngrab,
          kSync,
          NULL),
      log_->GetActionsAndClear());
  configurator_.ResumeDisplays();
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  // Now turn the display off before suspending and check that the
  // configurator turns it back on and syncs with the server.
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  configurator_.SuspendDisplays(base::Bind(
      &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(kSync, log_->GetActionsAndClear());

  configurator_.ResumeDisplays();
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  UpdateOutputs(2, true);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  configurator_.SuspendDisplays(base::Bind(
      &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(kSync, log_->GetActionsAndClear());

  // If a display is disconnected while suspended, the configurator should
  // pick up the change and only turn on the internal display.
  UpdateOutputs(1, false);
  configurator_.ResumeDisplays();
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest, Headless) {
  UpdateOutputs(0, false);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
  Init(false);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
  configurator_.ForceInitialConfigure(0);
  EXPECT_EQ(JoinActions(kInitXRandR, kGrab, kForceDPMS, kUngrab, NULL),
            log_->GetActionsAndClear());

  // Not much should happen when the display power state is changed while
  // no displays are connected.
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(JoinActions(kGrab, kForceDPMS, kUngrab, NULL),
            log_->GetActionsAndClear());

  // Connect an external display and check that it's configured correctly.
  std::vector<std::unique_ptr<const DisplayMode>> modes;
  for (const std::unique_ptr<const DisplayMode>& mode : outputs_[1].modes()) {
    modes.push_back(mode->Clone());
    if (mode.get() == outputs_[1].current_mode())
      outputs_[0].set_current_mode(modes.back().get());
    if (mode.get() == outputs_[1].native_mode())
      outputs_[0].set_native_mode(modes.back().get());
  }
  outputs_[0].set_modes(std::move(modes));
  outputs_[0].set_type(outputs_[1].type());

  UpdateOutputs(1, true);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], &big_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
  const gfx::Size framebuffer_size = configurator_.framebuffer_size();
  DCHECK(!framebuffer_size.IsEmpty());

  UpdateOutputs(0, true);
  EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
  EXPECT_EQ(framebuffer_size.ToString(),
            configurator_.framebuffer_size().ToString());
}

TEST_F(DisplayConfiguratorTest, StartWithTwoOutputs) {
  UpdateOutputs(2, false);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
  Init(false);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  configurator_.ForceInitialConfigure(0);
  EXPECT_EQ(
      JoinActions(
          kInitXRandR, kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS, kUngrab, NULL),
      log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest, InvalidMultipleDisplayStates) {
  UpdateOutputs(0, false);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
  Init(false);
  configurator_.ForceInitialConfigure(0);
  observer_.Reset();
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS);
  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(0, observer_.num_failures());
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE);
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(3, observer_.num_failures());

  UpdateOutputs(1, true);
  observer_.Reset();
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS);
  EXPECT_EQ(0, observer_.num_changes());
  EXPECT_EQ(1, observer_.num_failures());
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE);
  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(1, observer_.num_failures());
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(3, observer_.num_failures());

  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  UpdateOutputs(2, true);
  observer_.Reset();
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS);
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE);
  EXPECT_EQ(0, observer_.num_changes());
  EXPECT_EQ(2, observer_.num_failures());
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  EXPECT_EQ(2, observer_.num_changes());
  EXPECT_EQ(2, observer_.num_failures());
}

TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForMirroredDisplays) {
  UpdateOutputs(2, false);
  Init(false);
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  configurator_.ForceInitialConfigure(0);
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
}

TEST_F(DisplayConfiguratorTest, UpdateCachedOutputsEvenAfterFailure) {
  InitWithSingleOutput();
  const DisplayConfigurator::DisplayStateList& cached =
      configurator_.cached_displays();
  ASSERT_EQ(static_cast<size_t>(1), cached.size());
  EXPECT_EQ(outputs_[0].current_mode(), cached[0]->current_mode());

  // After connecting a second output, check that it shows up in
  // |cached_displays_| even if an invalid state is requested.
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
  UpdateOutputs(2, true);
  ASSERT_EQ(static_cast<size_t>(2), cached.size());
  EXPECT_EQ(outputs_[0].current_mode(), cached[0]->current_mode());
  EXPECT_EQ(outputs_[1].current_mode(), cached[1]->current_mode());
}

TEST_F(DisplayConfiguratorTest, PanelFitting) {
  // Configure the internal display to support only the big mode and the
  // external display to support only the small mode.
  std::unique_ptr<const DisplayMode> tmp_mode = big_mode_.Clone();
  const DisplayMode* mode = tmp_mode.get();
  std::vector<std::unique_ptr<const DisplayMode>> modes;
  modes.push_back(std::move(tmp_mode));
  outputs_[0].set_modes(std::move(modes));
  outputs_[0].set_current_mode(mode);
  outputs_[0].set_native_mode(mode);

  modes.clear();
  tmp_mode = small_mode_.Clone();
  mode = tmp_mode.get();
  modes.push_back(std::move(tmp_mode));
  outputs_[1].set_modes(std::move(modes));
  outputs_[1].set_current_mode(mode);
  outputs_[1].set_native_mode(mode);

  // The small mode should be added to the internal output when requesting
  // mirrored mode.
  UpdateOutputs(2, false);
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  Init(true /* is_panel_fitting_enabled */);
  configurator_.ForceInitialConfigure(0);
  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
  EXPECT_EQ(
      JoinActions(
          kInitXRandR, kGrab,
          GetAddOutputModeAction(outputs_[0], &small_mode_).c_str(),
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS, kUngrab, NULL),
      log_->GetActionsAndClear());

  // Both outputs should be using the small mode.
  ASSERT_EQ(1, observer_.num_changes());
  ASSERT_EQ(static_cast<size_t>(2), observer_.latest_outputs().size());
  EXPECT_EQ(small_mode_.size(),
            observer_.latest_outputs()[0]->current_mode()->size());
  EXPECT_EQ(small_mode_.size(),
            observer_.latest_outputs()[1]->current_mode()->size());

  // Also test that there are 2 modes (instead of the initial one) in the
  // snapshot that was passed to the observer (http://crbug.com/289159).
  DisplaySnapshot* state = observer_.latest_outputs()[0];
  ASSERT_EQ(2UL, state->modes().size());
}

TEST_F(DisplayConfiguratorTest, ContentProtection) {
  Init(false);
  configurator_.ForceInitialConfigure(0);
  EXPECT_NE(kNoActions, log_->GetActionsAndClear());

  DisplayConfigurator::ContentProtectionClientId id =
      configurator_.RegisterContentProtectionClient();
  EXPECT_NE(0u, id);

  // One output.
  UpdateOutputs(1, true);
  EXPECT_NE(kNoActions, log_->GetActionsAndClear());
  configurator_.QueryContentProtectionStatus(
      id, outputs_[0].display_id(),
      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(1, query_content_protection_call_count_);
  EXPECT_TRUE(query_content_protection_response_.success);
  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL),
            query_content_protection_response_.link_mask);
  EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
            query_content_protection_response_.protection_mask);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  // Two outputs.
  UpdateOutputs(2, true);
  EXPECT_NE(kNoActions, log_->GetActionsAndClear());
  configurator_.QueryContentProtectionStatus(
      id, outputs_[1].display_id(),
      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(2, query_content_protection_call_count_);
  EXPECT_TRUE(query_content_protection_response_.success);
  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
            query_content_protection_response_.link_mask);
  EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
            query_content_protection_response_.protection_mask);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  configurator_.EnableContentProtection(
      id, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(1, enable_content_protection_call_count_);
  EXPECT_TRUE(enable_content_protection_status_);
  EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED),
            log_->GetActionsAndClear());

  // Enable protection.
  native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
  configurator_.QueryContentProtectionStatus(
      id, outputs_[1].display_id(),
      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(3, query_content_protection_call_count_);
  EXPECT_TRUE(query_content_protection_response_.success);
  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
            query_content_protection_response_.link_mask);
  EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP),
            query_content_protection_response_.protection_mask);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  // Protections should be disabled after unregister.
  configurator_.UnregisterContentProtectionClient(id);
  EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED),
            log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) {
  InitWithSingleOutput();

  // The DisplayConfigurator may occasionally receive OnConfigurationChanged()
  // after the displays have been suspended.  This event should be ignored since
  // the DisplayConfigurator will force a probe and reconfiguration of displays
  // at resume time.
  configurator_.SuspendDisplays(base::Bind(
      &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          kUngrab,
          kSync,
          NULL),
      log_->GetActionsAndClear());

  // The configuration timer should not be started when the displays
  // are suspended.
  configurator_.OnConfigurationChanged();
  EXPECT_FALSE(test_api_.TriggerConfigureTimeout());
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  // Calls to SetDisplayPower should do nothing if the power state doesn't
  // change.
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  UpdateOutputs(2, false);
  configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  // The DisplayConfigurator should do nothing at resume time if there is no
  // state change.
  UpdateOutputs(1, false);
  configurator_.ResumeDisplays();
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  // If a configuration task is pending when the displays are suspended, that
  // task should not run either and the timer should be stopped. The displays
  // should be turned off by suspend.
  configurator_.OnConfigurationChanged();
  configurator_.SuspendDisplays(base::Bind(
      &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          kUngrab,
          kSync,
          NULL),
      log_->GetActionsAndClear());

  EXPECT_FALSE(test_api_.TriggerConfigureTimeout());
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  configurator_.ResumeDisplays();
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClients) {
  DisplayConfigurator::ContentProtectionClientId client1 =
      configurator_.RegisterContentProtectionClient();
  DisplayConfigurator::ContentProtectionClientId client2 =
      configurator_.RegisterContentProtectionClient();
  EXPECT_NE(client1, client2);

  Init(false);
  configurator_.ForceInitialConfigure(0);
  UpdateOutputs(2, true);
  EXPECT_NE(kNoActions, log_->GetActionsAndClear());

  // Clients never know state enableness for methods that they didn't request.
  configurator_.EnableContentProtection(
      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(1, enable_content_protection_call_count_);
  EXPECT_TRUE(enable_content_protection_status_);
  EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
            log_->GetActionsAndClear());
  native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);

  configurator_.QueryContentProtectionStatus(
      client1, outputs_[1].display_id(),
      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(1, query_content_protection_call_count_);
  EXPECT_TRUE(query_content_protection_response_.success);
  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
            query_content_protection_response_.link_mask);
  EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP,
            query_content_protection_response_.protection_mask);

  configurator_.QueryContentProtectionStatus(
      client2, outputs_[1].display_id(),
      base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(2, query_content_protection_call_count_);
  EXPECT_TRUE(query_content_protection_response_.success);
  EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
            query_content_protection_response_.link_mask);
  EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE,
            query_content_protection_response_.protection_mask);

  // Protections will be disabled only if no more clients request them.
  configurator_.EnableContentProtection(
      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE,
      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(2, enable_content_protection_call_count_);
  EXPECT_TRUE(enable_content_protection_status_);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());

  configurator_.EnableContentProtection(
      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE,
      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(3, enable_content_protection_call_count_);
  EXPECT_TRUE(enable_content_protection_status_);
  EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED).c_str(),
            log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClientsEnable) {
  DisplayConfigurator::ContentProtectionClientId client1 =
      configurator_.RegisterContentProtectionClient();
  DisplayConfigurator::ContentProtectionClientId client2 =
      configurator_.RegisterContentProtectionClient();
  EXPECT_NE(client1, client2);

  Init(false);
  configurator_.ForceInitialConfigure(0);
  UpdateOutputs(2, true);
  log_->GetActionsAndClear();

  // Only enable once if HDCP is enabling.
  configurator_.EnableContentProtection(
      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(1, enable_content_protection_call_count_);
  EXPECT_TRUE(enable_content_protection_status_);
  native_display_delegate_->set_hdcp_state(HDCP_STATE_DESIRED);
  configurator_.EnableContentProtection(
      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(2, enable_content_protection_call_count_);
  EXPECT_TRUE(enable_content_protection_status_);
  EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
            log_->GetActionsAndClear());
  native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);

  // Don't enable again if HDCP is already active.
  configurator_.EnableContentProtection(
      client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(3, enable_content_protection_call_count_);
  EXPECT_TRUE(enable_content_protection_status_);
  configurator_.EnableContentProtection(
      client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
      base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
                 base::Unretained(this)));
  EXPECT_EQ(4, enable_content_protection_call_count_);
  EXPECT_TRUE(enable_content_protection_status_);
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest, HandleConfigureCrtcFailure) {
  InitWithSingleOutput();

  ScopedVector<const DisplayMode> modes;
  // The first mode is the mode we are requesting DisplayConfigurator to choose.
  // The test will be setup so that this mode will fail and it will have to
  // choose the next best option.
  modes.push_back(new DisplayMode(gfx::Size(2560, 1600), false, 60.0));
  modes.push_back(new DisplayMode(gfx::Size(1024, 768), false, 60.0));
  modes.push_back(new DisplayMode(gfx::Size(1280, 720), false, 60.0));
  modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 60.0));
  modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));

  for (unsigned int i = 0; i < arraysize(outputs_); i++) {
    std::vector<std::unique_ptr<const DisplayMode>> tmp_modes;
    for (const DisplayMode* mode : modes)
      tmp_modes.push_back(mode->Clone());
    outputs_[i].set_current_mode(tmp_modes[0].get());
    outputs_[i].set_native_mode(tmp_modes[0].get());
    outputs_[i].set_modes(std::move(tmp_modes));
  }

  // First test simply fails in MULTIPLE_DISPLAY_STATE_SINGLE mode. This is
  // probably unrealistic but we want to make sure any assumptions don't creep
  // in.
  native_display_delegate_->set_max_configurable_pixels(
      modes[2]->size().GetArea());
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
  UpdateOutputs(1, true);

  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(),
          GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[0], modes[2], gfx::Point(0, 0)).c_str(),
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  // This test should attempt to configure a mirror mode that will not succeed
  // and should end up in extended mode.
  native_display_delegate_->set_max_configurable_pixels(
      modes[3]->size().GetArea());
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  UpdateOutputs(2, true);

  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(modes[0]->size(), &outputs_[0],
                                      &outputs_[1]).c_str(),
          GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
          // Then attempt to configure crtc1 with the first mode.
          GetCrtcAction(outputs_[1], modes[0], gfx::Point(0, 0)).c_str(),
          // First mode tried is expected to fail and it will
          // retry wil the 4th mode in the list.
          GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], modes[3], gfx::Point(0, 0)).c_str(),
          // Since it was requested to go into mirror mode
          // and the configured modes were different, it
          // should now try and setup a valid configurable
          // extended mode.
          GetFramebufferAction(
              gfx::Size(modes[0]->size().width(),
                        modes[0]->size().height() + modes[0]->size().height() +
                            DisplayConfigurator::kVerticalGap),
              &outputs_[0], &outputs_[1]).c_str(),
          GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], modes[0],
                        gfx::Point(0, modes[0]->size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], modes[3],
                        gfx::Point(0, modes[0]->size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab, NULL),
      log_->GetActionsAndClear());
}

// Tests that power state requests are saved after failed configuration attempts
// so they can be reused later: http://crosbug.com/p/31571
TEST_F(DisplayConfiguratorTest, SaveDisplayPowerStateOnConfigFailure) {
  // Start out with two displays in extended mode.
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  Init(false);
  configurator_.ForceInitialConfigure(0);
  log_->GetActionsAndClear();
  observer_.Reset();

  // Turn off the internal display, simulating docked mode.
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(0, observer_.num_failures());
  log_->GetActionsAndClear();

  // Make all subsequent configuration requests fail and try to turn the
  // internal display back on.
  native_display_delegate_->set_max_configurable_pixels(1);
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_FAILURE, PopCallbackResult());
  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(1, observer_.num_failures());
  log_->GetActionsAndClear();

  // Simulate the external display getting disconnected and check that the
  // internal display is turned on (i.e. DISPLAY_POWER_ALL_ON is used) rather
  // than the earlier DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON state.
  native_display_delegate_->set_max_configurable_pixels(0);
  UpdateOutputs(1, true);
  EXPECT_EQ(JoinActions(kGrab, GetFramebufferAction(small_mode_.size(),
                                                    &outputs_[0], NULL).c_str(),
                        GetCrtcAction(outputs_[0], &small_mode_,
                                      gfx::Point(0, 0)).c_str(),
                        kForceDPMS, kUngrab, NULL),
            log_->GetActionsAndClear());
}

// Tests that the SetDisplayPowerState() task posted by HandleResume() doesn't
// use a stale state if a new state is requested before it runs:
// http://crosbug.com/p/32393
TEST_F(DisplayConfiguratorTest, DontRestoreStalePowerStateAfterResume) {
  // Start out with two displays in mirrored mode.
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
  Init(false);
  configurator_.ForceInitialConfigure(0);
  log_->GetActionsAndClear();
  observer_.Reset();

  // Turn off the internal display, simulating docked mode.
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(0, observer_.num_failures());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  // Suspend and resume the system. Resuming should restore the previous power
  // state and force a probe. Suspend should turn off the displays since an
  // external monitor is connected.
  configurator_.SuspendDisplays(base::Bind(
      &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(2, observer_.num_changes());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0],
              &outputs_[1]).c_str(),
          GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(),
          kUngrab,
          kSync,
          NULL),
      log_->GetActionsAndClear());

  // Before the task runs, exit docked mode.
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(3, observer_.num_changes());
  EXPECT_EQ(0, observer_.num_failures());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
          kForceDPMS,
          kUngrab,
          NULL),
      log_->GetActionsAndClear());

  // Check that the display states are not changed after resuming.
  configurator_.ResumeDisplays();
  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest, ExternalControl) {
  InitWithSingleOutput();
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
  configurator_.RelinquishControl(
      base::Bind(&DisplayConfiguratorTest::OnDisplayControlUpdated,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopDisplayControlResult());
  EXPECT_EQ(
      JoinActions(
          kRelinquishDisplayControl,
          NULL),
      log_->GetActionsAndClear());
  configurator_.TakeControl(
      base::Bind(&DisplayConfiguratorTest::OnDisplayControlUpdated,
                 base::Unretained(this)));
  EXPECT_EQ(CALLBACK_SUCCESS, PopDisplayControlResult());
  EXPECT_EQ(JoinActions(kTakeDisplayControl, kGrab,
                        GetFramebufferAction(small_mode_.size(), &outputs_[0],
                                             nullptr).c_str(),
                        GetCrtcAction(outputs_[0], &small_mode_,
                                      gfx::Point(0, 0)).c_str(),
                        kUngrab, NULL),
            log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest,
       SetDisplayPowerWhilePendingConfigurationTaskRunning) {
  // Start out with two displays in extended mode.
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  Init(false);
  configurator_.ForceInitialConfigure(0);
  log_->GetActionsAndClear();
  observer_.Reset();

  native_display_delegate_->set_run_async(true);

  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));

  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));

  EXPECT_EQ(CALLBACK_NOT_CALLED, PopCallbackResult());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(0, observer_.num_failures());

  const int kDualHeight = small_mode_.size().height() +
                          DisplayConfigurator::kVerticalGap +
                          big_mode_.size().height();
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], nullptr, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], nullptr,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab, NULL),
      log_->GetActionsAndClear());

  EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(2, observer_.num_changes());
  EXPECT_EQ(0, observer_.num_failures());

  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          kForceDPMS, kUngrab, NULL),
      log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest,
       SetDisplayPowerAfterFailedDisplayConfiguration) {
  // Start out with two displays in extended mode.
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  Init(false);
  configurator_.ForceInitialConfigure(0);
  log_->GetActionsAndClear();
  observer_.Reset();

  // Fail display configuration.
  native_display_delegate_->set_max_configurable_pixels(-1);

  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));

  EXPECT_EQ(CALLBACK_FAILURE, PopCallbackResult());
  EXPECT_EQ(0, observer_.num_changes());
  EXPECT_EQ(1, observer_.num_failures());

  const int kDualHeight = small_mode_.size().height() +
                          DisplayConfigurator::kVerticalGap +
                          big_mode_.size().height();

  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], nullptr, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], nullptr,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab, NULL),
      log_->GetActionsAndClear());

  // This configuration should trigger a display configuration since the
  // previous configuration failed.
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));

  EXPECT_EQ(0, observer_.num_changes());
  EXPECT_EQ(2, observer_.num_failures());
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          GetCrtcAction(outputs_[1], &small_mode_,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab, NULL),
      log_->GetActionsAndClear());

  // Allow configuration to succeed.
  native_display_delegate_->set_max_configurable_pixels(0);

  // Validate that a configuration event has the proper power state (displays
  // should be on).
  configurator_.OnConfigurationChanged();
  EXPECT_TRUE(test_api_.TriggerConfigureTimeout());

  EXPECT_EQ(1, observer_.num_changes());
  EXPECT_EQ(2, observer_.num_failures());

  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab, NULL),
      log_->GetActionsAndClear());
}

TEST_F(DisplayConfiguratorTest, TestWithThreeDisplays) {
  // Start out with two displays in extended mode.
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  Init(false);
  configurator_.ForceInitialConfigure(0);
  log_->GetActionsAndClear();
  observer_.Reset();

  UpdateOutputs(3, true);
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED);

  const int kDualHeight = small_mode_.size().height() +
                          DisplayConfigurator::kVerticalGap +
                          big_mode_.size().height();
  const int kTripleHeight = 2 * small_mode_.size().height() +
                            2 * DisplayConfigurator::kVerticalGap +
                            big_mode_.size().height();
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(
                     gfx::Size(big_mode_.size().width(), kTripleHeight),
                     &outputs_[0], &outputs_[1])
                     .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          GetCrtcAction(
              outputs_[2], &small_mode_,
              gfx::Point(0, small_mode_.size().height() +
                                big_mode_.size().height() +
                                2 * DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab, NULL),
      log_->GetActionsAndClear());

  // Verify that turning the power off works.
  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_OFF,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));

  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(
                     gfx::Size(big_mode_.size().width(), kTripleHeight),
                     &outputs_[0], &outputs_[1])
                     .c_str(),
          GetCrtcAction(outputs_[0], nullptr, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], nullptr,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          GetCrtcAction(
              outputs_[2], nullptr,
              gfx::Point(0, small_mode_.size().height() +
                                big_mode_.size().height() +
                                2 * DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab, NULL),
      log_->GetActionsAndClear());

  configurator_.SetDisplayPower(
      chromeos::DISPLAY_POWER_ALL_ON,
      DisplayConfigurator::kSetDisplayPowerNoFlags,
      base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
                 base::Unretained(this)));

  EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
  EXPECT_EQ(
      JoinActions(
          kGrab, GetFramebufferAction(
                     gfx::Size(big_mode_.size().width(), kTripleHeight),
                     &outputs_[0], &outputs_[1])
                     .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          GetCrtcAction(
              outputs_[2], &small_mode_,
              gfx::Point(0, small_mode_.size().height() +
                                big_mode_.size().height() +
                                2 * DisplayConfigurator::kVerticalGap))
              .c_str(),
          kForceDPMS, kUngrab, NULL),
      log_->GetActionsAndClear());

  // Disconnect the third output.
  observer_.Reset();
  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
  UpdateOutputs(2, true);
  EXPECT_EQ(
      JoinActions(
          kGrab,
          GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
                               &outputs_[0], &outputs_[1])
              .c_str(),
          GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
          GetCrtcAction(outputs_[1], &big_mode_,
                        gfx::Point(0, small_mode_.size().height() +
                                          DisplayConfigurator::kVerticalGap))
              .c_str(),
          kUngrab, NULL),
      log_->GetActionsAndClear());
}

}  // namespace test
}  // namespace ui
