Home | History | Annotate | Download | only in chromeos
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/display/chromeos/display_configurator.h"
      6 
      7 #include <stdint.h>
      8 
      9 #include <cmath>
     10 #include <cstdarg>
     11 #include <map>
     12 #include <string>
     13 #include <vector>
     14 
     15 #include "base/compiler_specific.h"
     16 #include "base/format_macros.h"
     17 #include "base/memory/scoped_vector.h"
     18 #include "base/message_loop/message_loop.h"
     19 #include "base/strings/stringprintf.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "ui/display/chromeos/test/test_display_snapshot.h"
     22 #include "ui/display/types/display_mode.h"
     23 #include "ui/display/types/native_display_delegate.h"
     24 
     25 namespace ui {
     26 
     27 namespace {
     28 
     29 // Strings returned by TestNativeDisplayDelegate::GetActionsAndClear() to
     30 // describe various actions that were performed.
     31 const char kInitXRandR[] = "init";
     32 const char kGrab[] = "grab";
     33 const char kUngrab[] = "ungrab";
     34 const char kSync[] = "sync";
     35 const char kForceDPMS[] = "dpms";
     36 
     37 // String returned by TestNativeDisplayDelegate::GetActionsAndClear() if no
     38 // actions were requested.
     39 const char kNoActions[] = "";
     40 
     41 std::string DisplaySnapshotToString(const DisplaySnapshot& output) {
     42   return base::StringPrintf("id=%" PRId64, output.display_id());
     43 }
     44 
     45 // Returns a string describing a TestNativeDisplayDelegate::SetBackgroundColor()
     46 // call.
     47 std::string GetBackgroundAction(uint32_t color_argb) {
     48   return base::StringPrintf("background(0x%x)", color_argb);
     49 }
     50 
     51 // Returns a string describing a TestNativeDisplayDelegate::AddOutputMode()
     52 // call.
     53 std::string GetAddOutputModeAction(const DisplaySnapshot& output,
     54                                    const DisplayMode* mode) {
     55   return base::StringPrintf("add_mode(output=%" PRId64 ",mode=%s)",
     56                             output.display_id(),
     57                             mode->ToString().c_str());
     58 }
     59 
     60 // Returns a string describing a TestNativeDisplayDelegate::Configure()
     61 // call.
     62 std::string GetCrtcAction(const DisplaySnapshot& output,
     63                           const DisplayMode* mode,
     64                           const gfx::Point& origin) {
     65   return base::StringPrintf("crtc(display=[%s],x=%d,y=%d,mode=[%s])",
     66                             DisplaySnapshotToString(output).c_str(),
     67                             origin.x(),
     68                             origin.y(),
     69                             mode ? mode->ToString().c_str() : "NULL");
     70 }
     71 
     72 // Returns a string describing a TestNativeDisplayDelegate::CreateFramebuffer()
     73 // call.
     74 std::string GetFramebufferAction(const gfx::Size& size,
     75                                  const DisplaySnapshot* out1,
     76                                  const DisplaySnapshot* out2) {
     77   return base::StringPrintf(
     78       "framebuffer(width=%d,height=%d,display1=%s,display2=%s)",
     79       size.width(),
     80       size.height(),
     81       out1 ? DisplaySnapshotToString(*out1).c_str() : "NULL",
     82       out2 ? DisplaySnapshotToString(*out2).c_str() : "NULL");
     83 }
     84 
     85 // Returns a string describing a TestNativeDisplayDelegate::SetHDCPState() call.
     86 std::string GetSetHDCPStateAction(const DisplaySnapshot& output,
     87                                   HDCPState state) {
     88   return base::StringPrintf(
     89       "set_hdcp(id=%" PRId64 ",state=%d)", output.display_id(), state);
     90 }
     91 
     92 // Joins a sequence of strings describing actions (e.g. kScreenDim) such
     93 // that they can be compared against a string returned by
     94 // ActionLogger::GetActionsAndClear().  The list of actions must be
     95 // terminated by a NULL pointer.
     96 std::string JoinActions(const char* action, ...) {
     97   std::string actions;
     98 
     99   va_list arg_list;
    100   va_start(arg_list, action);
    101   while (action) {
    102     if (!actions.empty())
    103       actions += ",";
    104     actions += action;
    105     action = va_arg(arg_list, const char*);
    106   }
    107   va_end(arg_list);
    108   return actions;
    109 }
    110 
    111 class ActionLogger {
    112  public:
    113   ActionLogger() {}
    114 
    115   void AppendAction(const std::string& action) {
    116     if (!actions_.empty())
    117       actions_ += ",";
    118     actions_ += action;
    119   }
    120 
    121   // Returns a comma-separated string describing the actions that were
    122   // requested since the previous call to GetActionsAndClear() (i.e.
    123   // results are non-repeatable).
    124   std::string GetActionsAndClear() {
    125     std::string actions = actions_;
    126     actions_.clear();
    127     return actions;
    128   }
    129 
    130  private:
    131   std::string actions_;
    132 
    133   DISALLOW_COPY_AND_ASSIGN(ActionLogger);
    134 };
    135 
    136 class TestNativeDisplayDelegate : public NativeDisplayDelegate {
    137  public:
    138   // Ownership of |log| remains with the caller.
    139   explicit TestNativeDisplayDelegate(ActionLogger* log)
    140       : max_configurable_pixels_(0),
    141         hdcp_state_(HDCP_STATE_UNDESIRED),
    142         log_(log) {}
    143   virtual ~TestNativeDisplayDelegate() {}
    144 
    145   const std::vector<DisplaySnapshot*>& outputs() const { return outputs_; }
    146   void set_outputs(const std::vector<DisplaySnapshot*>& outputs) {
    147     outputs_ = outputs;
    148   }
    149 
    150   void set_max_configurable_pixels(int pixels) {
    151     max_configurable_pixels_ = pixels;
    152   }
    153 
    154   void set_hdcp_state(HDCPState state) { hdcp_state_ = state; }
    155 
    156   // DisplayConfigurator::Delegate overrides:
    157   virtual void Initialize() OVERRIDE { log_->AppendAction(kInitXRandR); }
    158   virtual void GrabServer() OVERRIDE { log_->AppendAction(kGrab); }
    159   virtual void UngrabServer() OVERRIDE { log_->AppendAction(kUngrab); }
    160   virtual void SyncWithServer() OVERRIDE { log_->AppendAction(kSync); }
    161   virtual void SetBackgroundColor(uint32_t color_argb) OVERRIDE {
    162     log_->AppendAction(GetBackgroundAction(color_argb));
    163   }
    164   virtual void ForceDPMSOn() OVERRIDE { log_->AppendAction(kForceDPMS); }
    165   virtual std::vector<DisplaySnapshot*> GetDisplays() OVERRIDE {
    166     return outputs_;
    167   }
    168   virtual void AddMode(const DisplaySnapshot& output,
    169                        const DisplayMode* mode) OVERRIDE {
    170     log_->AppendAction(GetAddOutputModeAction(output, mode));
    171   }
    172   virtual bool Configure(const DisplaySnapshot& output,
    173                          const DisplayMode* mode,
    174                          const gfx::Point& origin) OVERRIDE {
    175     log_->AppendAction(GetCrtcAction(output, mode, origin));
    176 
    177     if (max_configurable_pixels_ == 0)
    178       return true;
    179 
    180     if (!mode)
    181       return false;
    182 
    183     return mode->size().GetArea() <= max_configurable_pixels_;
    184   }
    185   virtual void CreateFrameBuffer(const gfx::Size& size) OVERRIDE {
    186     log_->AppendAction(
    187         GetFramebufferAction(size,
    188                              outputs_.size() >= 1 ? outputs_[0] : NULL,
    189                              outputs_.size() >= 2 ? outputs_[1] : NULL));
    190   }
    191   virtual bool GetHDCPState(const DisplaySnapshot& output,
    192                             HDCPState* state) OVERRIDE {
    193     *state = hdcp_state_;
    194     return true;
    195   }
    196 
    197   virtual bool SetHDCPState(const DisplaySnapshot& output,
    198                             HDCPState state) OVERRIDE {
    199     log_->AppendAction(GetSetHDCPStateAction(output, state));
    200     return true;
    201   }
    202 
    203   virtual std::vector<ui::ColorCalibrationProfile>
    204   GetAvailableColorCalibrationProfiles(const DisplaySnapshot& output) OVERRIDE {
    205     return std::vector<ui::ColorCalibrationProfile>();
    206   }
    207 
    208   virtual bool SetColorCalibrationProfile(
    209       const DisplaySnapshot& output,
    210       ui::ColorCalibrationProfile new_profile) OVERRIDE {
    211     return false;
    212   }
    213 
    214   virtual void AddObserver(NativeDisplayObserver* observer) OVERRIDE {}
    215 
    216   virtual void RemoveObserver(NativeDisplayObserver* observer) OVERRIDE {}
    217 
    218  private:
    219   // Outputs to be returned by GetDisplays().
    220   std::vector<DisplaySnapshot*> outputs_;
    221 
    222   // |max_configurable_pixels_| represents the maximum number of pixels that
    223   // Configure will support.  Tests can use this to force Configure
    224   // to fail if attempting to set a resolution that is higher than what
    225   // a device might support under a given circumstance.
    226   // A value of 0 means that no limit is enforced and Configure will
    227   // return success regardless of the resolution.
    228   int max_configurable_pixels_;
    229 
    230   // Result value of GetHDCPState().
    231   HDCPState hdcp_state_;
    232 
    233   ActionLogger* log_;  // Not owned.
    234 
    235   DISALLOW_COPY_AND_ASSIGN(TestNativeDisplayDelegate);
    236 };
    237 
    238 class TestObserver : public DisplayConfigurator::Observer {
    239  public:
    240   explicit TestObserver(DisplayConfigurator* configurator)
    241       : configurator_(configurator) {
    242     Reset();
    243     configurator_->AddObserver(this);
    244   }
    245   virtual ~TestObserver() { configurator_->RemoveObserver(this); }
    246 
    247   int num_changes() const { return num_changes_; }
    248   int num_failures() const { return num_failures_; }
    249   const DisplayConfigurator::DisplayStateList& latest_outputs() const {
    250     return latest_outputs_;
    251   }
    252   MultipleDisplayState latest_failed_state() const {
    253     return latest_failed_state_;
    254   }
    255 
    256   void Reset() {
    257     num_changes_ = 0;
    258     num_failures_ = 0;
    259     latest_outputs_.clear();
    260     latest_failed_state_ = MULTIPLE_DISPLAY_STATE_INVALID;
    261   }
    262 
    263   // DisplayConfigurator::Observer overrides:
    264   virtual void OnDisplayModeChanged(
    265       const DisplayConfigurator::DisplayStateList& outputs) OVERRIDE {
    266     num_changes_++;
    267     latest_outputs_ = outputs;
    268   }
    269 
    270   virtual void OnDisplayModeChangeFailed(MultipleDisplayState failed_new_state)
    271       OVERRIDE {
    272     num_failures_++;
    273     latest_failed_state_ = failed_new_state;
    274   }
    275 
    276  private:
    277   DisplayConfigurator* configurator_;  // Not owned.
    278 
    279   // Number of times that OnDisplayMode*() has been called.
    280   int num_changes_;
    281   int num_failures_;
    282 
    283   // Parameters most recently passed to OnDisplayMode*().
    284   DisplayConfigurator::DisplayStateList latest_outputs_;
    285   MultipleDisplayState latest_failed_state_;
    286 
    287   DISALLOW_COPY_AND_ASSIGN(TestObserver);
    288 };
    289 
    290 class TestStateController : public DisplayConfigurator::StateController {
    291  public:
    292   TestStateController() : state_(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {}
    293   virtual ~TestStateController() {}
    294 
    295   void set_state(MultipleDisplayState state) { state_ = state; }
    296 
    297   // DisplayConfigurator::StateController overrides:
    298   virtual MultipleDisplayState GetStateForDisplayIds(
    299       const std::vector<int64_t>& outputs) const OVERRIDE {
    300     return state_;
    301   }
    302   virtual bool GetResolutionForDisplayId(int64_t display_id,
    303                                          gfx::Size* size) const OVERRIDE {
    304     return false;
    305   }
    306 
    307  private:
    308   MultipleDisplayState state_;
    309 
    310   DISALLOW_COPY_AND_ASSIGN(TestStateController);
    311 };
    312 
    313 class TestMirroringController
    314     : public DisplayConfigurator::SoftwareMirroringController {
    315  public:
    316   TestMirroringController() : software_mirroring_enabled_(false) {}
    317   virtual ~TestMirroringController() {}
    318 
    319   virtual void SetSoftwareMirroring(bool enabled) OVERRIDE {
    320     software_mirroring_enabled_ = enabled;
    321   }
    322 
    323   virtual bool SoftwareMirroringEnabled() const OVERRIDE {
    324     return software_mirroring_enabled_;
    325   }
    326 
    327  private:
    328   bool software_mirroring_enabled_;
    329 
    330   DISALLOW_COPY_AND_ASSIGN(TestMirroringController);
    331 };
    332 
    333 class DisplayConfiguratorTest : public testing::Test {
    334  public:
    335   DisplayConfiguratorTest()
    336       : small_mode_(gfx::Size(1366, 768), false, 60.0f),
    337         big_mode_(gfx::Size(2560, 1600), false, 60.0f),
    338         observer_(&configurator_),
    339         test_api_(&configurator_) {}
    340   virtual ~DisplayConfiguratorTest() {}
    341 
    342   virtual void SetUp() OVERRIDE {
    343     log_.reset(new ActionLogger());
    344 
    345     native_display_delegate_ = new TestNativeDisplayDelegate(log_.get());
    346     configurator_.SetDelegateForTesting(
    347         scoped_ptr<NativeDisplayDelegate>(native_display_delegate_));
    348 
    349     configurator_.set_state_controller(&state_controller_);
    350     configurator_.set_mirroring_controller(&mirroring_controller_);
    351 
    352     std::vector<const DisplayMode*> modes;
    353     modes.push_back(&small_mode_);
    354 
    355     TestDisplaySnapshot* o = &outputs_[0];
    356     o->set_current_mode(&small_mode_);
    357     o->set_native_mode(&small_mode_);
    358     o->set_modes(modes);
    359     o->set_type(DISPLAY_CONNECTION_TYPE_INTERNAL);
    360     o->set_is_aspect_preserving_scaling(true);
    361     o->set_display_id(123);
    362     o->set_has_proper_display_id(true);
    363 
    364     o = &outputs_[1];
    365     o->set_current_mode(&big_mode_);
    366     o->set_native_mode(&big_mode_);
    367     modes.push_back(&big_mode_);
    368     o->set_modes(modes);
    369     o->set_type(DISPLAY_CONNECTION_TYPE_HDMI);
    370     o->set_is_aspect_preserving_scaling(true);
    371     o->set_display_id(456);
    372     o->set_has_proper_display_id(true);
    373 
    374     UpdateOutputs(2, false);
    375   }
    376 
    377   // Predefined modes that can be used by outputs.
    378   const DisplayMode small_mode_;
    379   const DisplayMode big_mode_;
    380 
    381  protected:
    382   // Configures |native_display_delegate_| to return the first |num_outputs|
    383   // entries from
    384   // |outputs_|. If |send_events| is true, also sends screen-change and
    385   // output-change events to |configurator_| and triggers the configure
    386   // timeout if one was scheduled.
    387   void UpdateOutputs(size_t num_outputs, bool send_events) {
    388     ASSERT_LE(num_outputs, arraysize(outputs_));
    389     std::vector<DisplaySnapshot*> outputs;
    390     for (size_t i = 0; i < num_outputs; ++i)
    391       outputs.push_back(&outputs_[i]);
    392     native_display_delegate_->set_outputs(outputs);
    393 
    394     if (send_events) {
    395       configurator_.OnConfigurationChanged();
    396       EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
    397     }
    398   }
    399 
    400   // Initializes |configurator_| with a single internal display.
    401   void InitWithSingleOutput() {
    402     UpdateOutputs(1, false);
    403     EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    404     configurator_.Init(false);
    405     EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    406     configurator_.ForceInitialConfigure(0);
    407     EXPECT_EQ(
    408         JoinActions(
    409             kGrab,
    410             kInitXRandR,
    411             GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL)
    412                 .c_str(),
    413             GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    414             kForceDPMS,
    415             kUngrab,
    416             NULL),
    417         log_->GetActionsAndClear());
    418   }
    419 
    420   base::MessageLoop message_loop_;
    421   TestStateController state_controller_;
    422   TestMirroringController mirroring_controller_;
    423   DisplayConfigurator configurator_;
    424   TestObserver observer_;
    425   scoped_ptr<ActionLogger> log_;
    426   TestNativeDisplayDelegate* native_display_delegate_;  // not owned
    427   DisplayConfigurator::TestApi test_api_;
    428 
    429   TestDisplaySnapshot outputs_[2];
    430 
    431  private:
    432   DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorTest);
    433 };
    434 
    435 }  // namespace
    436 
    437 TEST_F(DisplayConfiguratorTest, FindDisplayModeMatchingSize) {
    438   ScopedVector<const DisplayMode> modes;
    439 
    440   // Fields are width, height, interlaced, refresh rate.
    441   modes.push_back(new DisplayMode(gfx::Size(1920, 1200), false, 60.0));
    442   // Different rates.
    443   modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 30.0));
    444   modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 50.0));
    445   modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
    446   modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 0.0));
    447   // Interlaced vs non-interlaced.
    448   modes.push_back(new DisplayMode(gfx::Size(1280, 720), true, 60.0));
    449   modes.push_back(new DisplayMode(gfx::Size(1280, 720), false, 40.0));
    450   // Interlaced only.
    451   modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 0.0));
    452   modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 40.0));
    453   modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 60.0));
    454   // Mixed.
    455   modes.push_back(new DisplayMode(gfx::Size(1024, 600), true, 60.0));
    456   modes.push_back(new DisplayMode(gfx::Size(1024, 600), false, 40.0));
    457   modes.push_back(new DisplayMode(gfx::Size(1024, 600), false, 50.0));
    458   // Just one interlaced mode.
    459   modes.push_back(new DisplayMode(gfx::Size(640, 480), true, 60.0));
    460   // Refresh rate not available.
    461   modes.push_back(new DisplayMode(gfx::Size(320, 200), false, 0.0));
    462 
    463   TestDisplaySnapshot output;
    464   output.set_modes(modes.get());
    465 
    466   EXPECT_EQ(modes[0],
    467             DisplayConfigurator::FindDisplayModeMatchingSize(
    468                 output, gfx::Size(1920, 1200)));
    469 
    470   // Should pick highest refresh rate.
    471   EXPECT_EQ(modes[2],
    472             DisplayConfigurator::FindDisplayModeMatchingSize(
    473                 output, gfx::Size(1920, 1080)));
    474 
    475   // Should pick non-interlaced mode.
    476   EXPECT_EQ(modes[6],
    477             DisplayConfigurator::FindDisplayModeMatchingSize(
    478                 output, gfx::Size(1280, 720)));
    479 
    480   // Interlaced only. Should pick one with the highest refresh rate in
    481   // interlaced mode.
    482   EXPECT_EQ(modes[9],
    483             DisplayConfigurator::FindDisplayModeMatchingSize(
    484                 output, gfx::Size(1024, 768)));
    485 
    486   // Mixed: Should pick one with the highest refresh rate in
    487   // interlaced mode.
    488   EXPECT_EQ(modes[12],
    489             DisplayConfigurator::FindDisplayModeMatchingSize(
    490                 output, gfx::Size(1024, 600)));
    491 
    492   // Just one interlaced mode.
    493   EXPECT_EQ(modes[13],
    494             DisplayConfigurator::FindDisplayModeMatchingSize(
    495                 output, gfx::Size(640, 480)));
    496 
    497   // Refresh rate not available.
    498   EXPECT_EQ(modes[14],
    499             DisplayConfigurator::FindDisplayModeMatchingSize(
    500                 output, gfx::Size(320, 200)));
    501 
    502   // No mode found.
    503   EXPECT_EQ(NULL,
    504             DisplayConfigurator::FindDisplayModeMatchingSize(
    505                 output, gfx::Size(1440, 900)));
    506 }
    507 
    508 TEST_F(DisplayConfiguratorTest, ConnectSecondOutput) {
    509   InitWithSingleOutput();
    510 
    511   // Connect a second output and check that the configurator enters
    512   // extended mode.
    513   observer_.Reset();
    514   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
    515   UpdateOutputs(2, true);
    516   const int kDualHeight = small_mode_.size().height() +
    517                           DisplayConfigurator::kVerticalGap +
    518                           big_mode_.size().height();
    519   EXPECT_EQ(
    520       JoinActions(
    521           kGrab,
    522           GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
    523                                &outputs_[0],
    524                                &outputs_[1]).c_str(),
    525           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    526           GetCrtcAction(outputs_[1],
    527                         &big_mode_,
    528                         gfx::Point(0,
    529                                    small_mode_.size().height() +
    530                                        DisplayConfigurator::kVerticalGap))
    531               .c_str(),
    532           kUngrab,
    533           NULL),
    534       log_->GetActionsAndClear());
    535   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    536   EXPECT_EQ(1, observer_.num_changes());
    537 
    538   observer_.Reset();
    539   EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
    540   EXPECT_EQ(
    541       JoinActions(
    542           kGrab,
    543           GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
    544               .c_str(),
    545           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    546           GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
    547           kUngrab,
    548           NULL),
    549       log_->GetActionsAndClear());
    550   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    551   EXPECT_EQ(1, observer_.num_changes());
    552 
    553   // Disconnect the second output.
    554   observer_.Reset();
    555   UpdateOutputs(1, true);
    556   EXPECT_EQ(
    557       JoinActions(
    558           kGrab,
    559           GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
    560           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    561           kUngrab,
    562           NULL),
    563       log_->GetActionsAndClear());
    564   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    565   EXPECT_EQ(1, observer_.num_changes());
    566 
    567   // Get rid of shared modes to force software mirroring.
    568   outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &big_mode_));
    569   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
    570   UpdateOutputs(2, true);
    571   EXPECT_EQ(
    572       JoinActions(
    573           kGrab,
    574           GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
    575                                &outputs_[0],
    576                                &outputs_[1]).c_str(),
    577           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    578           GetCrtcAction(outputs_[1],
    579                         &big_mode_,
    580                         gfx::Point(0,
    581                                    small_mode_.size().height() +
    582                                        DisplayConfigurator::kVerticalGap))
    583               .c_str(),
    584           kUngrab,
    585           NULL),
    586       log_->GetActionsAndClear());
    587   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    588 
    589   observer_.Reset();
    590   EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
    591   EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
    592   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
    593             configurator_.display_state());
    594   EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
    595   EXPECT_EQ(1, observer_.num_changes());
    596 
    597   // Setting MULTIPLE_DISPLAY_STATE_DUAL_MIRROR should try to reconfigure.
    598   observer_.Reset();
    599   EXPECT_TRUE(
    600       configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED));
    601   EXPECT_EQ(JoinActions(NULL), log_->GetActionsAndClear());
    602   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    603   EXPECT_EQ(1, observer_.num_changes());
    604 
    605   // Set back to software mirror mode.
    606   observer_.Reset();
    607   EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
    608   EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
    609   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
    610             configurator_.display_state());
    611   EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
    612   EXPECT_EQ(1, observer_.num_changes());
    613 
    614   // Disconnect the second output.
    615   observer_.Reset();
    616   UpdateOutputs(1, true);
    617   EXPECT_EQ(
    618       JoinActions(
    619           kGrab,
    620           GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
    621           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    622           kUngrab,
    623           NULL),
    624       log_->GetActionsAndClear());
    625   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    626   EXPECT_EQ(1, observer_.num_changes());
    627 }
    628 
    629 TEST_F(DisplayConfiguratorTest, SetDisplayPower) {
    630   InitWithSingleOutput();
    631 
    632   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
    633   observer_.Reset();
    634   UpdateOutputs(2, true);
    635   EXPECT_EQ(
    636       JoinActions(
    637           kGrab,
    638           GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
    639               .c_str(),
    640           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    641           GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
    642           kUngrab,
    643           NULL),
    644       log_->GetActionsAndClear());
    645   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    646   EXPECT_EQ(1, observer_.num_changes());
    647 
    648   // Turning off the internal display should switch the external display to
    649   // its native mode.
    650   observer_.Reset();
    651   configurator_.SetDisplayPower(
    652       chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
    653       DisplayConfigurator::kSetDisplayPowerNoFlags);
    654   EXPECT_EQ(
    655       JoinActions(
    656           kGrab,
    657           GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
    658               .c_str(),
    659           GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
    660           GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
    661           kForceDPMS,
    662           kUngrab,
    663           NULL),
    664       log_->GetActionsAndClear());
    665   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
    666   EXPECT_EQ(1, observer_.num_changes());
    667 
    668   // When all displays are turned off, the framebuffer should switch back
    669   // to the mirrored size.
    670   observer_.Reset();
    671   configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
    672                                 DisplayConfigurator::kSetDisplayPowerNoFlags);
    673   EXPECT_EQ(
    674       JoinActions(kGrab,
    675                   GetFramebufferAction(
    676                       small_mode_.size(), &outputs_[0], &outputs_[1]).c_str(),
    677                   GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
    678                   GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(),
    679                   kUngrab,
    680                   NULL),
    681       log_->GetActionsAndClear());
    682   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
    683   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    684   EXPECT_EQ(1, observer_.num_changes());
    685 
    686   // Turn all displays on and check that mirroring is still used.
    687   observer_.Reset();
    688   configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
    689                                 DisplayConfigurator::kSetDisplayPowerNoFlags);
    690   EXPECT_EQ(
    691       JoinActions(
    692           kGrab,
    693           GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
    694               .c_str(),
    695           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    696           GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
    697           kForceDPMS,
    698           kUngrab,
    699           NULL),
    700       log_->GetActionsAndClear());
    701   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
    702   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    703   EXPECT_EQ(1, observer_.num_changes());
    704 
    705   // Get rid of shared modes to force software mirroring.
    706   outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &big_mode_));
    707   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
    708   observer_.Reset();
    709   UpdateOutputs(2, true);
    710   const int kDualHeight = small_mode_.size().height() +
    711                           DisplayConfigurator::kVerticalGap +
    712                           big_mode_.size().height();
    713   EXPECT_EQ(
    714       JoinActions(
    715           kGrab,
    716           GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
    717                                &outputs_[0],
    718                                &outputs_[1]).c_str(),
    719           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    720           GetCrtcAction(outputs_[1],
    721                         &big_mode_,
    722                         gfx::Point(0,
    723                                    small_mode_.size().height() +
    724                                        DisplayConfigurator::kVerticalGap))
    725               .c_str(),
    726           kUngrab,
    727           NULL),
    728       log_->GetActionsAndClear());
    729   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
    730             configurator_.display_state());
    731   EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
    732   EXPECT_EQ(1, observer_.num_changes());
    733 
    734   // Turning off the internal display should switch the external display to
    735   // its native mode.
    736   observer_.Reset();
    737   configurator_.SetDisplayPower(
    738       chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
    739       DisplayConfigurator::kSetDisplayPowerNoFlags);
    740   EXPECT_EQ(
    741       JoinActions(
    742           kGrab,
    743           GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
    744               .c_str(),
    745           GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
    746           GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
    747           kForceDPMS,
    748           kUngrab,
    749           NULL),
    750       log_->GetActionsAndClear());
    751   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
    752   EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
    753   EXPECT_EQ(1, observer_.num_changes());
    754 
    755   // When all displays are turned off, the framebuffer should switch back
    756   // to the extended + software mirroring.
    757   observer_.Reset();
    758   configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
    759                                 DisplayConfigurator::kSetDisplayPowerNoFlags);
    760   EXPECT_EQ(
    761       JoinActions(
    762           kGrab,
    763           GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
    764                                &outputs_[0],
    765                                &outputs_[1]).c_str(),
    766           GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
    767           GetCrtcAction(outputs_[1],
    768                         NULL,
    769                         gfx::Point(0,
    770                                    small_mode_.size().height() +
    771                                        DisplayConfigurator::kVerticalGap))
    772               .c_str(),
    773           kUngrab,
    774           NULL),
    775       log_->GetActionsAndClear());
    776   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
    777             configurator_.display_state());
    778   EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
    779   EXPECT_EQ(1, observer_.num_changes());
    780 
    781   // Turn all displays on and check that mirroring is still used.
    782   observer_.Reset();
    783   configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
    784                                 DisplayConfigurator::kSetDisplayPowerNoFlags);
    785   EXPECT_EQ(
    786       JoinActions(
    787           kGrab,
    788           GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
    789                                &outputs_[0],
    790                                &outputs_[1]).c_str(),
    791           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    792           GetCrtcAction(outputs_[1],
    793                         &big_mode_,
    794                         gfx::Point(0,
    795                                    small_mode_.size().height() +
    796                                        DisplayConfigurator::kVerticalGap))
    797               .c_str(),
    798           kForceDPMS,
    799           kUngrab,
    800           NULL),
    801       log_->GetActionsAndClear());
    802   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
    803             configurator_.display_state());
    804   EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
    805   EXPECT_EQ(1, observer_.num_changes());
    806 }
    807 
    808 TEST_F(DisplayConfiguratorTest, SuspendAndResume) {
    809   InitWithSingleOutput();
    810 
    811   // No preparation is needed before suspending when the display is already
    812   // on.  The configurator should still reprobe on resume in case a display
    813   // was connected while suspended.
    814   configurator_.SuspendDisplays();
    815   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    816   configurator_.ResumeDisplays();
    817   EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
    818   EXPECT_EQ(
    819       JoinActions(
    820           kGrab,
    821           GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
    822           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    823           kForceDPMS,
    824           kUngrab,
    825           NULL),
    826       log_->GetActionsAndClear());
    827 
    828   // Now turn the display off before suspending and check that the
    829   // configurator turns it back on and syncs with the server.
    830   configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
    831                                 DisplayConfigurator::kSetDisplayPowerNoFlags);
    832   EXPECT_EQ(
    833       JoinActions(
    834           kGrab,
    835           GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
    836           GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
    837           kUngrab,
    838           NULL),
    839       log_->GetActionsAndClear());
    840 
    841   configurator_.SuspendDisplays();
    842   EXPECT_EQ(
    843       JoinActions(
    844           kGrab,
    845           GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
    846           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    847           kForceDPMS,
    848           kUngrab,
    849           kSync,
    850           NULL),
    851       log_->GetActionsAndClear());
    852 
    853   configurator_.ResumeDisplays();
    854   EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
    855   EXPECT_EQ(
    856       JoinActions(
    857           kGrab,
    858           GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
    859           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    860           kForceDPMS,
    861           kUngrab,
    862           NULL),
    863       log_->GetActionsAndClear());
    864 
    865   // If a second, external display is connected, the displays shouldn't be
    866   // powered back on before suspending.
    867   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
    868   UpdateOutputs(2, true);
    869   EXPECT_EQ(
    870       JoinActions(
    871           kGrab,
    872           GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
    873               .c_str(),
    874           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    875           GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
    876           kUngrab,
    877           NULL),
    878       log_->GetActionsAndClear());
    879 
    880   configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
    881                                 DisplayConfigurator::kSetDisplayPowerNoFlags);
    882   EXPECT_EQ(
    883       JoinActions(kGrab,
    884                   GetFramebufferAction(
    885                       small_mode_.size(), &outputs_[0], &outputs_[1]).c_str(),
    886                   GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
    887                   GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(),
    888                   kUngrab,
    889                   NULL),
    890       log_->GetActionsAndClear());
    891 
    892   configurator_.SuspendDisplays();
    893   EXPECT_EQ(JoinActions(kGrab, kUngrab, kSync, NULL),
    894             log_->GetActionsAndClear());
    895 
    896   // If a display is disconnected while suspended, the configurator should
    897   // pick up the change.
    898   UpdateOutputs(1, false);
    899   configurator_.ResumeDisplays();
    900   EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
    901   EXPECT_EQ(
    902       JoinActions(
    903           kGrab,
    904           GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
    905           GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
    906           kUngrab,
    907           NULL),
    908       log_->GetActionsAndClear());
    909 }
    910 
    911 TEST_F(DisplayConfiguratorTest, Headless) {
    912   UpdateOutputs(0, false);
    913   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    914   configurator_.Init(false);
    915   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    916   configurator_.ForceInitialConfigure(0);
    917   EXPECT_EQ(JoinActions(kGrab, kInitXRandR, kForceDPMS, kUngrab, NULL),
    918             log_->GetActionsAndClear());
    919 
    920   // Not much should happen when the display power state is changed while
    921   // no displays are connected.
    922   configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
    923                                 DisplayConfigurator::kSetDisplayPowerNoFlags);
    924   EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
    925   configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
    926                                 DisplayConfigurator::kSetDisplayPowerNoFlags);
    927   EXPECT_EQ(JoinActions(kGrab, kForceDPMS, kUngrab, NULL),
    928             log_->GetActionsAndClear());
    929 
    930   // Connect an external display and check that it's configured correctly.
    931   outputs_[0].set_current_mode(outputs_[1].current_mode());
    932   outputs_[0].set_native_mode(outputs_[1].native_mode());
    933   outputs_[0].set_modes(outputs_[1].modes());
    934   outputs_[0].set_type(outputs_[1].type());
    935 
    936   UpdateOutputs(1, true);
    937   EXPECT_EQ(
    938       JoinActions(
    939           kGrab,
    940           GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(),
    941           GetCrtcAction(outputs_[0], &big_mode_, gfx::Point(0, 0)).c_str(),
    942           kUngrab,
    943           NULL),
    944       log_->GetActionsAndClear());
    945 }
    946 
    947 TEST_F(DisplayConfiguratorTest, StartWithTwoOutputs) {
    948   UpdateOutputs(2, false);
    949   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    950   configurator_.Init(false);
    951   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    952 
    953   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
    954   configurator_.ForceInitialConfigure(0);
    955   EXPECT_EQ(
    956       JoinActions(
    957           kGrab,
    958           kInitXRandR,
    959           GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
    960               .c_str(),
    961           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
    962           GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
    963           kForceDPMS,
    964           kUngrab,
    965           NULL),
    966       log_->GetActionsAndClear());
    967 }
    968 
    969 TEST_F(DisplayConfiguratorTest, InvalidMultipleDisplayStates) {
    970   UpdateOutputs(0, false);
    971   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
    972   configurator_.Init(false);
    973   configurator_.ForceInitialConfigure(0);
    974   observer_.Reset();
    975   EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS));
    976   EXPECT_FALSE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE));
    977   EXPECT_FALSE(
    978       configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
    979   EXPECT_FALSE(
    980       configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED));
    981   EXPECT_EQ(1, observer_.num_changes());
    982   EXPECT_EQ(3, observer_.num_failures());
    983 
    984   UpdateOutputs(1, true);
    985   observer_.Reset();
    986   EXPECT_FALSE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS));
    987   EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE));
    988   EXPECT_FALSE(
    989       configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
    990   EXPECT_FALSE(
    991       configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED));
    992   EXPECT_EQ(1, observer_.num_changes());
    993   EXPECT_EQ(3, observer_.num_failures());
    994 
    995   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
    996   UpdateOutputs(2, true);
    997   observer_.Reset();
    998   EXPECT_FALSE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS));
    999   EXPECT_FALSE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE));
   1000   EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
   1001   EXPECT_TRUE(
   1002       configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED));
   1003   EXPECT_EQ(2, observer_.num_changes());
   1004   EXPECT_EQ(2, observer_.num_failures());
   1005 }
   1006 
   1007 TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForDisplaysWithoutId) {
   1008   outputs_[0].set_has_proper_display_id(false);
   1009   UpdateOutputs(2, false);
   1010   configurator_.Init(false);
   1011   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
   1012   configurator_.ForceInitialConfigure(0);
   1013   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
   1014             configurator_.display_state());
   1015 }
   1016 
   1017 TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForDisplaysWithId) {
   1018   outputs_[0].set_has_proper_display_id(true);
   1019   UpdateOutputs(2, false);
   1020   configurator_.Init(false);
   1021   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
   1022   configurator_.ForceInitialConfigure(0);
   1023   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
   1024 }
   1025 
   1026 TEST_F(DisplayConfiguratorTest, UpdateCachedOutputsEvenAfterFailure) {
   1027   InitWithSingleOutput();
   1028   const DisplayConfigurator::DisplayStateList* cached =
   1029       &configurator_.cached_displays();
   1030   ASSERT_EQ(static_cast<size_t>(1), cached->size());
   1031   EXPECT_EQ(outputs_[0].current_mode(), (*cached)[0].display->current_mode());
   1032 
   1033   // After connecting a second output, check that it shows up in
   1034   // |cached_displays_| even if an invalid state is requested.
   1035   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
   1036   UpdateOutputs(2, true);
   1037   cached = &configurator_.cached_displays();
   1038   ASSERT_EQ(static_cast<size_t>(2), cached->size());
   1039   EXPECT_EQ(outputs_[0].current_mode(), (*cached)[0].display->current_mode());
   1040   EXPECT_EQ(outputs_[1].current_mode(), (*cached)[1].display->current_mode());
   1041 }
   1042 
   1043 TEST_F(DisplayConfiguratorTest, PanelFitting) {
   1044   // Configure the internal display to support only the big mode and the
   1045   // external display to support only the small mode.
   1046   outputs_[0].set_current_mode(&big_mode_);
   1047   outputs_[0].set_native_mode(&big_mode_);
   1048   outputs_[0].set_modes(std::vector<const DisplayMode*>(1, &big_mode_));
   1049 
   1050   outputs_[1].set_current_mode(&small_mode_);
   1051   outputs_[1].set_native_mode(&small_mode_);
   1052   outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &small_mode_));
   1053 
   1054   // The small mode should be added to the internal output when requesting
   1055   // mirrored mode.
   1056   UpdateOutputs(2, false);
   1057   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
   1058   configurator_.Init(true /* is_panel_fitting_enabled */);
   1059   configurator_.ForceInitialConfigure(0);
   1060   EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
   1061   EXPECT_EQ(
   1062       JoinActions(
   1063           kGrab,
   1064           kInitXRandR,
   1065           GetAddOutputModeAction(outputs_[0], &small_mode_).c_str(),
   1066           GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
   1067               .c_str(),
   1068           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
   1069           GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
   1070           kForceDPMS,
   1071           kUngrab,
   1072           NULL),
   1073       log_->GetActionsAndClear());
   1074 
   1075   // Both outputs should be using the small mode.
   1076   ASSERT_EQ(1, observer_.num_changes());
   1077   ASSERT_EQ(static_cast<size_t>(2), observer_.latest_outputs().size());
   1078   EXPECT_EQ(&small_mode_, observer_.latest_outputs()[0].mirror_mode);
   1079   EXPECT_EQ(&small_mode_,
   1080             observer_.latest_outputs()[0].display->current_mode());
   1081   EXPECT_EQ(&small_mode_, observer_.latest_outputs()[1].mirror_mode);
   1082   EXPECT_EQ(&small_mode_,
   1083             observer_.latest_outputs()[1].display->current_mode());
   1084 
   1085   // Also check that the newly-added small mode is present in the internal
   1086   // snapshot that was passed to the observer (http://crbug.com/289159).
   1087   const DisplayConfigurator::DisplayState& state =
   1088       observer_.latest_outputs()[0];
   1089   ASSERT_NE(state.display->modes().end(),
   1090             std::find(state.display->modes().begin(),
   1091                       state.display->modes().end(),
   1092                       &small_mode_));
   1093 }
   1094 
   1095 TEST_F(DisplayConfiguratorTest, ContentProtection) {
   1096   configurator_.Init(false);
   1097   configurator_.ForceInitialConfigure(0);
   1098   EXPECT_NE(kNoActions, log_->GetActionsAndClear());
   1099 
   1100   DisplayConfigurator::ContentProtectionClientId id =
   1101       configurator_.RegisterContentProtectionClient();
   1102   EXPECT_NE(0u, id);
   1103 
   1104   // One output.
   1105   UpdateOutputs(1, true);
   1106   EXPECT_NE(kNoActions, log_->GetActionsAndClear());
   1107   uint32_t link_mask = 0;
   1108   uint32_t protection_mask = 0;
   1109   EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
   1110       id, outputs_[0].display_id(), &link_mask, &protection_mask));
   1111   EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL), link_mask);
   1112   EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
   1113             protection_mask);
   1114   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
   1115 
   1116   // Two outputs.
   1117   UpdateOutputs(2, true);
   1118   EXPECT_NE(kNoActions, log_->GetActionsAndClear());
   1119   EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
   1120       id, outputs_[1].display_id(), &link_mask, &protection_mask));
   1121   EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
   1122   EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
   1123             protection_mask);
   1124   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
   1125 
   1126   EXPECT_TRUE(configurator_.EnableContentProtection(
   1127       id, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
   1128   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED),
   1129             log_->GetActionsAndClear());
   1130 
   1131   // Enable protection.
   1132   native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
   1133   EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
   1134       id, outputs_[1].display_id(), &link_mask, &protection_mask));
   1135   EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
   1136   EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP),
   1137             protection_mask);
   1138   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
   1139 
   1140   // Protections should be disabled after unregister.
   1141   configurator_.UnregisterContentProtectionClient(id);
   1142   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED),
   1143             log_->GetActionsAndClear());
   1144 }
   1145 
   1146 TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClients) {
   1147   DisplayConfigurator::ContentProtectionClientId client1 =
   1148       configurator_.RegisterContentProtectionClient();
   1149   DisplayConfigurator::ContentProtectionClientId client2 =
   1150       configurator_.RegisterContentProtectionClient();
   1151   EXPECT_NE(client1, client2);
   1152 
   1153   configurator_.Init(false);
   1154   configurator_.ForceInitialConfigure(0);
   1155   UpdateOutputs(2, true);
   1156   EXPECT_NE(kNoActions, log_->GetActionsAndClear());
   1157 
   1158   // Clients never know state enableness for methods that they didn't request.
   1159   EXPECT_TRUE(configurator_.EnableContentProtection(
   1160       client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
   1161   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
   1162             log_->GetActionsAndClear());
   1163   native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
   1164 
   1165   uint32_t link_mask = 0;
   1166   uint32_t protection_mask = 0;
   1167   EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
   1168       client1, outputs_[1].display_id(), &link_mask, &protection_mask));
   1169   EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
   1170   EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask);
   1171 
   1172   EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
   1173       client2, outputs_[1].display_id(), &link_mask, &protection_mask));
   1174   EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
   1175   EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask);
   1176 
   1177   // Protections will be disabled only if no more clients request them.
   1178   EXPECT_TRUE(configurator_.EnableContentProtection(
   1179       client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE));
   1180   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
   1181   EXPECT_TRUE(configurator_.EnableContentProtection(
   1182       client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE));
   1183   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED).c_str(),
   1184             log_->GetActionsAndClear());
   1185 }
   1186 
   1187 TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClientsEnable) {
   1188   DisplayConfigurator::ContentProtectionClientId client1 =
   1189       configurator_.RegisterContentProtectionClient();
   1190   DisplayConfigurator::ContentProtectionClientId client2 =
   1191       configurator_.RegisterContentProtectionClient();
   1192   EXPECT_NE(client1, client2);
   1193 
   1194   configurator_.Init(false);
   1195   configurator_.ForceInitialConfigure(0);
   1196   UpdateOutputs(2, true);
   1197   log_->GetActionsAndClear();
   1198 
   1199   // Only enable once if HDCP is enabling.
   1200   EXPECT_TRUE(configurator_.EnableContentProtection(
   1201       client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
   1202   native_display_delegate_->set_hdcp_state(HDCP_STATE_DESIRED);
   1203   EXPECT_TRUE(configurator_.EnableContentProtection(
   1204       client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
   1205   EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
   1206             log_->GetActionsAndClear());
   1207   native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
   1208 
   1209   // Don't enable again if HDCP is already active.
   1210   EXPECT_TRUE(configurator_.EnableContentProtection(
   1211       client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
   1212   EXPECT_TRUE(configurator_.EnableContentProtection(
   1213       client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
   1214   EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
   1215 }
   1216 
   1217 TEST_F(DisplayConfiguratorTest, HandleConfigureCrtcFailure) {
   1218   InitWithSingleOutput();
   1219 
   1220   ScopedVector<const DisplayMode> modes;
   1221   // The first mode is the mode we are requesting DisplayConfigurator to choose.
   1222   // The test will be setup so that this mode will fail and it will have to
   1223   // choose the next best option.
   1224   modes.push_back(new DisplayMode(gfx::Size(2560, 1600), false, 60.0));
   1225   modes.push_back(new DisplayMode(gfx::Size(1024, 768), false, 60.0));
   1226   modes.push_back(new DisplayMode(gfx::Size(1280, 720), false, 60.0));
   1227   modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 60.0));
   1228   modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
   1229 
   1230   for (unsigned int i = 0; i < arraysize(outputs_); i++) {
   1231     outputs_[i].set_modes(modes.get());
   1232     outputs_[i].set_current_mode(modes[0]);
   1233     outputs_[i].set_native_mode(modes[0]);
   1234   }
   1235 
   1236   // First test simply fails in MULTIPLE_DISPLAY_STATE_SINGLE mode. This is
   1237   // probably unrealistic but we want to make sure any assumptions don't creep
   1238   // in.
   1239   native_display_delegate_->set_max_configurable_pixels(
   1240       modes[2]->size().GetArea());
   1241   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
   1242   UpdateOutputs(1, true);
   1243 
   1244   EXPECT_EQ(
   1245       JoinActions(
   1246           kGrab,
   1247           GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(),
   1248           GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
   1249           GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
   1250           GetCrtcAction(outputs_[0], modes[2], gfx::Point(0, 0)).c_str(),
   1251           kUngrab,
   1252           NULL),
   1253       log_->GetActionsAndClear());
   1254 
   1255   // This test should attempt to configure a mirror mode that will not succeed
   1256   // and should end up in extended mode.
   1257   native_display_delegate_->set_max_configurable_pixels(
   1258       modes[3]->size().GetArea());
   1259   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
   1260   UpdateOutputs(2, true);
   1261 
   1262   EXPECT_EQ(
   1263       JoinActions(
   1264           kGrab,
   1265           GetFramebufferAction(modes[0]->size(), &outputs_[0], &outputs_[1])
   1266               .c_str(),
   1267           GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
   1268           // First mode tried is expected to fail and it will
   1269           // retry wil the 4th mode in the list.
   1270           GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
   1271           // Then attempt to configure crtc1 with the first mode.
   1272           GetCrtcAction(outputs_[1], modes[0], gfx::Point(0, 0)).c_str(),
   1273           GetCrtcAction(outputs_[1], modes[3], gfx::Point(0, 0)).c_str(),
   1274           // Since it was requested to go into mirror mode
   1275           // and the configured modes were different, it
   1276           // should now try and setup a valid configurable
   1277           // extended mode.
   1278           GetFramebufferAction(
   1279               gfx::Size(modes[0]->size().width(),
   1280                         modes[0]->size().height() + modes[0]->size().height() +
   1281                             DisplayConfigurator::kVerticalGap),
   1282               &outputs_[0],
   1283               &outputs_[1]).c_str(),
   1284           GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
   1285           GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
   1286           GetCrtcAction(outputs_[1],
   1287                         modes[0],
   1288                         gfx::Point(0,
   1289                                    modes[0]->size().height() +
   1290                                        DisplayConfigurator::kVerticalGap))
   1291               .c_str(),
   1292           GetCrtcAction(outputs_[1],
   1293                         modes[3],
   1294                         gfx::Point(0,
   1295                                    modes[0]->size().height() +
   1296                                        DisplayConfigurator::kVerticalGap))
   1297               .c_str(),
   1298           kUngrab,
   1299           NULL),
   1300       log_->GetActionsAndClear());
   1301 }
   1302 
   1303 // Tests that power state requests are saved after failed configuration attempts
   1304 // so they can be reused later: http://crosbug.com/p/31571
   1305 TEST_F(DisplayConfiguratorTest, SaveDisplayPowerStateOnConfigFailure) {
   1306   // Start out with two displays in extended mode.
   1307   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
   1308   configurator_.Init(false);
   1309   configurator_.ForceInitialConfigure(0);
   1310   log_->GetActionsAndClear();
   1311 
   1312   // Turn off the internal display, simulating docked mode.
   1313   EXPECT_TRUE(configurator_.SetDisplayPower(
   1314       chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
   1315       DisplayConfigurator::kSetDisplayPowerNoFlags));
   1316   log_->GetActionsAndClear();
   1317 
   1318   // Make all subsequent configuration requests fail and try to turn the
   1319   // internal display back on.
   1320   native_display_delegate_->set_max_configurable_pixels(1);
   1321   EXPECT_FALSE(configurator_.SetDisplayPower(
   1322       chromeos::DISPLAY_POWER_ALL_ON,
   1323       DisplayConfigurator::kSetDisplayPowerNoFlags));
   1324   log_->GetActionsAndClear();
   1325 
   1326   // Simulate the external display getting disconnected and check that the
   1327   // internal display is turned on (i.e. DISPLAY_POWER_ALL_ON is used) rather
   1328   // than the earlier DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON state.
   1329   native_display_delegate_->set_max_configurable_pixels(0);
   1330   UpdateOutputs(1, true);
   1331   EXPECT_EQ(
   1332       JoinActions(
   1333           kGrab,
   1334           GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
   1335           GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
   1336           kUngrab,
   1337           NULL),
   1338       log_->GetActionsAndClear());
   1339 }
   1340 
   1341 }  // namespace ui
   1342