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