blob: 79cfd7bfdd9075c0537c0e198b8984eca1df91db [file] [log] [blame]
[email protected]29957af2014-03-14 21:08:561// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]6d980bc2012-09-10 19:28:452// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]1e31cbd2014-04-07 20:06:115#include "ui/display/chromeos/display_configurator.h"
[email protected]6d980bc2012-09-10 19:28:456
[email protected]08b47ca2014-03-28 13:46:207#include <stdint.h>
8
[email protected]06b20fe2013-11-13 19:18:389#include <cmath>
[email protected]acb217ed2013-04-09 21:52:3610#include <cstdarg>
11#include <map>
[email protected]6d980bc2012-09-10 19:28:4512#include <string>
[email protected]acb217ed2013-04-09 21:52:3613#include <vector>
[email protected]6d980bc2012-09-10 19:28:4514
[email protected]acb217ed2013-04-09 21:52:3615#include "base/compiler_specific.h"
[email protected]a20ff0f2014-03-19 16:56:4916#include "base/format_macros.h"
[email protected]71da07e2014-03-18 21:16:0417#include "base/memory/scoped_vector.h"
[email protected]f129d2502013-07-17 22:45:5018#include "base/message_loop/message_loop.h"
[email protected]afa339d72013-06-11 06:32:5119#include "base/strings/stringprintf.h"
[email protected]6d980bc2012-09-10 19:28:4520#include "testing/gtest/include/gtest/gtest.h"
[email protected]71da07e2014-03-18 21:16:0421#include "ui/display/chromeos/test/test_display_snapshot.h"
spangcef10972014-09-18 15:47:1022#include "ui/display/types/display_mode.h"
23#include "ui/display/types/native_display_delegate.h"
[email protected]6d980bc2012-09-10 19:28:4524
[email protected]29957af2014-03-14 21:08:5625namespace ui {
[email protected]6d980bc2012-09-10 19:28:4526
[email protected]acb217ed2013-04-09 21:52:3627namespace {
28
[email protected]72bce522014-02-10 21:11:2629// Strings returned by TestNativeDisplayDelegate::GetActionsAndClear() to
30// describe various actions that were performed.
[email protected]acb217ed2013-04-09 21:52:3631const char kInitXRandR[] = "init";
[email protected]acb217ed2013-04-09 21:52:3632const char kGrab[] = "grab";
33const char kUngrab[] = "ungrab";
34const char kSync[] = "sync";
35const char kForceDPMS[] = "dpms";
[email protected]acb217ed2013-04-09 21:52:3636
[email protected]72bce522014-02-10 21:11:2637// String returned by TestNativeDisplayDelegate::GetActionsAndClear() if no
38// actions were requested.
[email protected]acb217ed2013-04-09 21:52:3639const char kNoActions[] = "";
40
[email protected]71da07e2014-03-18 21:16:0441std::string DisplaySnapshotToString(const DisplaySnapshot& output) {
[email protected]a20ff0f2014-03-19 16:56:4942 return base::StringPrintf("id=%" PRId64, output.display_id());
[email protected]71da07e2014-03-18 21:16:0443}
44
[email protected]72bce522014-02-10 21:11:2645// Returns a string describing a TestNativeDisplayDelegate::SetBackgroundColor()
46// call.
[email protected]08b47ca2014-03-28 13:46:2047std::string GetBackgroundAction(uint32_t color_argb) {
[email protected]acb217ed2013-04-09 21:52:3648 return base::StringPrintf("background(0x%x)", color_argb);
49}
50
[email protected]72bce522014-02-10 21:11:2651// Returns a string describing a TestNativeDisplayDelegate::AddOutputMode()
52// call.
[email protected]71da07e2014-03-18 21:16:0453std::string GetAddOutputModeAction(const DisplaySnapshot& output,
54 const DisplayMode* mode) {
[email protected]a20ff0f2014-03-19 16:56:4955 return base::StringPrintf("add_mode(output=%" PRId64 ",mode=%s)",
[email protected]71da07e2014-03-18 21:16:0456 output.display_id(),
[email protected]311063ab2014-03-19 22:10:0957 mode->ToString().c_str());
[email protected]6eebb90b2013-09-17 18:30:2758}
59
[email protected]3d1cd602014-02-26 23:39:1860// Returns a string describing a TestNativeDisplayDelegate::Configure()
[email protected]72bce522014-02-10 21:11:2661// call.
[email protected]71da07e2014-03-18 21:16:0462std::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(),
[email protected]311063ab2014-03-19 22:10:0969 mode ? mode->ToString().c_str() : "NULL");
[email protected]acb217ed2013-04-09 21:52:3670}
71
[email protected]72bce522014-02-10 21:11:2672// Returns a string describing a TestNativeDisplayDelegate::CreateFramebuffer()
73// call.
[email protected]71da07e2014-03-18 21:16:0474std::string GetFramebufferAction(const gfx::Size& size,
75 const DisplaySnapshot* out1,
76 const DisplaySnapshot* out2) {
[email protected]acb217ed2013-04-09 21:52:3677 return base::StringPrintf(
[email protected]71da07e2014-03-18 21:16:0478 "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");
[email protected]acb217ed2013-04-09 21:52:3683}
84
[email protected]72bce522014-02-10 21:11:2685// Returns a string describing a TestNativeDisplayDelegate::SetHDCPState() call.
[email protected]71da07e2014-03-18 21:16:0486std::string GetSetHDCPStateAction(const DisplaySnapshot& output,
87 HDCPState state) {
88 return base::StringPrintf(
[email protected]a20ff0f2014-03-19 16:56:4989 "set_hdcp(id=%" PRId64 ",state=%d)", output.display_id(), state);
[email protected]a9318842013-10-02 07:21:1390}
91
[email protected]acb217ed2013-04-09 21:52:3692// Joins a sequence of strings describing actions (e.g. kScreenDim) such
93// that they can be compared against a string returned by
[email protected]72bce522014-02-10 21:11:2694// ActionLogger::GetActionsAndClear(). The list of actions must be
[email protected]acb217ed2013-04-09 21:52:3695// terminated by a NULL pointer.
96std::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
[email protected]b036effd2014-02-05 16:24:54111class 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
[email protected]3d1cd602014-02-26 23:39:18136class TestNativeDisplayDelegate : public NativeDisplayDelegate {
[email protected]acb217ed2013-04-09 21:52:36137 public:
[email protected]b036effd2014-02-05 16:24:54138 // Ownership of |log| remains with the caller.
[email protected]72bce522014-02-10 21:11:26139 explicit TestNativeDisplayDelegate(ActionLogger* log)
[email protected]63da7fb2014-01-10 00:35:31140 : max_configurable_pixels_(0),
[email protected]29957af2014-03-14 21:08:56141 hdcp_state_(HDCP_STATE_UNDESIRED),
[email protected]b036effd2014-02-05 16:24:54142 log_(log) {}
[email protected]72bce522014-02-10 21:11:26143 virtual ~TestNativeDisplayDelegate() {}
[email protected]acb217ed2013-04-09 21:52:36144
[email protected]71da07e2014-03-18 21:16:04145 const std::vector<DisplaySnapshot*>& outputs() const { return outputs_; }
146 void set_outputs(const std::vector<DisplaySnapshot*>& outputs) {
[email protected]acb217ed2013-04-09 21:52:36147 outputs_ = outputs;
148 }
149
[email protected]63da7fb2014-01-10 00:35:31150 void set_max_configurable_pixels(int pixels) {
151 max_configurable_pixels_ = pixels;
[email protected]edc1c802013-08-14 03:55:04152 }
153
[email protected]29957af2014-03-14 21:08:56154 void set_hdcp_state(HDCPState state) { hdcp_state_ = state; }
[email protected]a9318842013-10-02 07:21:13155
[email protected]1e31cbd2014-04-07 20:06:11156 // DisplayConfigurator::Delegate overrides:
[email protected]29957af2014-03-14 21:08:56157 virtual void Initialize() OVERRIDE { log_->AppendAction(kInitXRandR); }
[email protected]b036effd2014-02-05 16:24:54158 virtual void GrabServer() OVERRIDE { log_->AppendAction(kGrab); }
159 virtual void UngrabServer() OVERRIDE { log_->AppendAction(kUngrab); }
160 virtual void SyncWithServer() OVERRIDE { log_->AppendAction(kSync); }
[email protected]08b47ca2014-03-28 13:46:20161 virtual void SetBackgroundColor(uint32_t color_argb) OVERRIDE {
[email protected]b036effd2014-02-05 16:24:54162 log_->AppendAction(GetBackgroundAction(color_argb));
163 }
164 virtual void ForceDPMSOn() OVERRIDE { log_->AppendAction(kForceDPMS); }
[email protected]bcec7fb2014-04-08 20:59:09165 virtual std::vector<DisplaySnapshot*> GetDisplays() OVERRIDE {
[email protected]acb217ed2013-04-09 21:52:36166 return outputs_;
167 }
[email protected]71da07e2014-03-18 21:16:04168 virtual void AddMode(const DisplaySnapshot& output,
169 const DisplayMode* mode) OVERRIDE {
170 log_->AppendAction(GetAddOutputModeAction(output, mode));
[email protected]6eebb90b2013-09-17 18:30:27171 }
[email protected]71da07e2014-03-18 21:16:04172 virtual bool Configure(const DisplaySnapshot& output,
173 const DisplayMode* mode,
174 const gfx::Point& origin) OVERRIDE {
175 log_->AppendAction(GetCrtcAction(output, mode, origin));
[email protected]63da7fb2014-01-10 00:35:31176
177 if (max_configurable_pixels_ == 0)
178 return true;
179
[email protected]71da07e2014-03-18 21:16:04180 if (!mode)
[email protected]63da7fb2014-01-10 00:35:31181 return false;
182
[email protected]71da07e2014-03-18 21:16:04183 return mode->size().GetArea() <= max_configurable_pixels_;
[email protected]acb217ed2013-04-09 21:52:36184 }
[email protected]71da07e2014-03-18 21:16:04185 virtual void CreateFrameBuffer(const gfx::Size& size) OVERRIDE {
[email protected]b036effd2014-02-05 16:24:54186 log_->AppendAction(
[email protected]71da07e2014-03-18 21:16:04187 GetFramebufferAction(size,
188 outputs_.size() >= 1 ? outputs_[0] : NULL,
189 outputs_.size() >= 2 ? outputs_[1] : NULL));
[email protected]acb217ed2013-04-09 21:52:36190 }
[email protected]71da07e2014-03-18 21:16:04191 virtual bool GetHDCPState(const DisplaySnapshot& output,
[email protected]29957af2014-03-14 21:08:56192 HDCPState* state) OVERRIDE {
[email protected]a9318842013-10-02 07:21:13193 *state = hdcp_state_;
[email protected]a1ab6d82013-09-28 13:49:54194 return true;
195 }
196
[email protected]71da07e2014-03-18 21:16:04197 virtual bool SetHDCPState(const DisplaySnapshot& output,
[email protected]29957af2014-03-14 21:08:56198 HDCPState state) OVERRIDE {
[email protected]71da07e2014-03-18 21:16:04199 log_->AppendAction(GetSetHDCPStateAction(output, state));
[email protected]a1ab6d82013-09-28 13:49:54200 return true;
201 }
202
[email protected]38472462014-03-22 07:01:50203 virtual std::vector<ui::ColorCalibrationProfile>
[email protected]1e31cbd2014-04-07 20:06:11204 GetAvailableColorCalibrationProfiles(const DisplaySnapshot& output) OVERRIDE {
[email protected]38472462014-03-22 07:01:50205 return std::vector<ui::ColorCalibrationProfile>();
206 }
207
[email protected]29fb7a272014-03-20 06:22:08208 virtual bool SetColorCalibrationProfile(
209 const DisplaySnapshot& output,
210 ui::ColorCalibrationProfile new_profile) OVERRIDE {
211 return false;
212 }
213
[email protected]3d1cd602014-02-26 23:39:18214 virtual void AddObserver(NativeDisplayObserver* observer) OVERRIDE {}
215
216 virtual void RemoveObserver(NativeDisplayObserver* observer) OVERRIDE {}
217
[email protected]acb217ed2013-04-09 21:52:36218 private:
[email protected]bcec7fb2014-04-08 20:59:09219 // Outputs to be returned by GetDisplays().
[email protected]71da07e2014-03-18 21:16:04220 std::vector<DisplaySnapshot*> outputs_;
[email protected]acb217ed2013-04-09 21:52:36221
[email protected]63da7fb2014-01-10 00:35:31222 // |max_configurable_pixels_| represents the maximum number of pixels that
[email protected]3d1cd602014-02-26 23:39:18223 // Configure will support. Tests can use this to force Configure
[email protected]63da7fb2014-01-10 00:35:31224 // to fail if attempting to set a resolution that is higher than what
225 // a device might support under a given circumstance.
[email protected]3d1cd602014-02-26 23:39:18226 // A value of 0 means that no limit is enforced and Configure will
[email protected]63da7fb2014-01-10 00:35:31227 // return success regardless of the resolution.
[email protected]29957af2014-03-14 21:08:56228 int max_configurable_pixels_;
[email protected]edc1c802013-08-14 03:55:04229
[email protected]a9318842013-10-02 07:21:13230 // Result value of GetHDCPState().
[email protected]29957af2014-03-14 21:08:56231 HDCPState hdcp_state_;
[email protected]a9318842013-10-02 07:21:13232
[email protected]b036effd2014-02-05 16:24:54233 ActionLogger* log_; // Not owned.
234
[email protected]72bce522014-02-10 21:11:26235 DISALLOW_COPY_AND_ASSIGN(TestNativeDisplayDelegate);
[email protected]acb217ed2013-04-09 21:52:36236};
237
[email protected]1e31cbd2014-04-07 20:06:11238class TestObserver : public DisplayConfigurator::Observer {
[email protected]0b1b283b2013-08-17 13:32:18239 public:
[email protected]1e31cbd2014-04-07 20:06:11240 explicit TestObserver(DisplayConfigurator* configurator)
[email protected]0b1b283b2013-08-17 13:32:18241 : configurator_(configurator) {
242 Reset();
243 configurator_->AddObserver(this);
244 }
[email protected]29957af2014-03-14 21:08:56245 virtual ~TestObserver() { configurator_->RemoveObserver(this); }
[email protected]0b1b283b2013-08-17 13:32:18246
247 int num_changes() const { return num_changes_; }
248 int num_failures() const { return num_failures_; }
[email protected]1e31cbd2014-04-07 20:06:11249 const DisplayConfigurator::DisplayStateList& latest_outputs() const {
[email protected]0b1b283b2013-08-17 13:32:18250 return latest_outputs_;
251 }
[email protected]bcec7fb2014-04-08 20:59:09252 MultipleDisplayState latest_failed_state() const {
253 return latest_failed_state_;
254 }
[email protected]0b1b283b2013-08-17 13:32:18255
256 void Reset() {
257 num_changes_ = 0;
258 num_failures_ = 0;
259 latest_outputs_.clear();
[email protected]bcec7fb2014-04-08 20:59:09260 latest_failed_state_ = MULTIPLE_DISPLAY_STATE_INVALID;
[email protected]0b1b283b2013-08-17 13:32:18261 }
262
[email protected]1e31cbd2014-04-07 20:06:11263 // DisplayConfigurator::Observer overrides:
[email protected]0b1b283b2013-08-17 13:32:18264 virtual void OnDisplayModeChanged(
[email protected]1e31cbd2014-04-07 20:06:11265 const DisplayConfigurator::DisplayStateList& outputs) OVERRIDE {
[email protected]0b1b283b2013-08-17 13:32:18266 num_changes_++;
267 latest_outputs_ = outputs;
268 }
269
[email protected]bcec7fb2014-04-08 20:59:09270 virtual void OnDisplayModeChangeFailed(MultipleDisplayState failed_new_state)
[email protected]0b1b283b2013-08-17 13:32:18271 OVERRIDE {
272 num_failures_++;
273 latest_failed_state_ = failed_new_state;
274 }
275
276 private:
[email protected]1e31cbd2014-04-07 20:06:11277 DisplayConfigurator* configurator_; // Not owned.
[email protected]0b1b283b2013-08-17 13:32:18278
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*().
[email protected]1e31cbd2014-04-07 20:06:11284 DisplayConfigurator::DisplayStateList latest_outputs_;
[email protected]bcec7fb2014-04-08 20:59:09285 MultipleDisplayState latest_failed_state_;
[email protected]0b1b283b2013-08-17 13:32:18286
287 DISALLOW_COPY_AND_ASSIGN(TestObserver);
288};
289
[email protected]1e31cbd2014-04-07 20:06:11290class TestStateController : public DisplayConfigurator::StateController {
[email protected]acb217ed2013-04-09 21:52:36291 public:
[email protected]bcec7fb2014-04-08 20:59:09292 TestStateController() : state_(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {}
[email protected]42091902013-05-02 02:24:12293 virtual ~TestStateController() {}
[email protected]acb217ed2013-04-09 21:52:36294
[email protected]bcec7fb2014-04-08 20:59:09295 void set_state(MultipleDisplayState state) { state_ = state; }
[email protected]acb217ed2013-04-09 21:52:36296
[email protected]1e31cbd2014-04-07 20:06:11297 // DisplayConfigurator::StateController overrides:
[email protected]bcec7fb2014-04-08 20:59:09298 virtual MultipleDisplayState GetStateForDisplayIds(
[email protected]08b47ca2014-03-28 13:46:20299 const std::vector<int64_t>& outputs) const OVERRIDE {
[email protected]c97505102014-02-12 14:50:26300 return state_;
301 }
[email protected]08b47ca2014-03-28 13:46:20302 virtual bool GetResolutionForDisplayId(int64_t display_id,
[email protected]71da07e2014-03-18 21:16:04303 gfx::Size* size) const OVERRIDE {
[email protected]a5792d32013-08-01 11:18:21304 return false;
305 }
[email protected]acb217ed2013-04-09 21:52:36306
307 private:
[email protected]bcec7fb2014-04-08 20:59:09308 MultipleDisplayState state_;
[email protected]acb217ed2013-04-09 21:52:36309
310 DISALLOW_COPY_AND_ASSIGN(TestStateController);
311};
312
[email protected]c1f30dc2013-05-22 17:27:45313class TestMirroringController
[email protected]1e31cbd2014-04-07 20:06:11314 : public DisplayConfigurator::SoftwareMirroringController {
[email protected]c1f30dc2013-05-22 17:27:45315 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
[email protected]857f47c2014-05-17 18:21:06323 virtual bool SoftwareMirroringEnabled() const OVERRIDE {
[email protected]c1f30dc2013-05-22 17:27:45324 return software_mirroring_enabled_;
325 }
326
327 private:
328 bool software_mirroring_enabled_;
329
330 DISALLOW_COPY_AND_ASSIGN(TestMirroringController);
331};
332
[email protected]1e31cbd2014-04-07 20:06:11333class DisplayConfiguratorTest : public testing::Test {
[email protected]acb217ed2013-04-09 21:52:36334 public:
[email protected]1e31cbd2014-04-07 20:06:11335 DisplayConfiguratorTest()
[email protected]71da07e2014-03-18 21:16:04336 : 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_) {}
[email protected]1e31cbd2014-04-07 20:06:11340 virtual ~DisplayConfiguratorTest() {}
[email protected]acb217ed2013-04-09 21:52:36341
342 virtual void SetUp() OVERRIDE {
[email protected]b036effd2014-02-05 16:24:54343 log_.reset(new ActionLogger());
344
[email protected]72bce522014-02-10 21:11:26345 native_display_delegate_ = new TestNativeDisplayDelegate(log_.get());
dnicoara67548022014-09-12 19:05:21346 configurator_.SetDelegateForTesting(
347 scoped_ptr<NativeDisplayDelegate>(native_display_delegate_));
[email protected]b036effd2014-02-05 16:24:54348
[email protected]acb217ed2013-04-09 21:52:36349 configurator_.set_state_controller(&state_controller_);
[email protected]c1f30dc2013-05-22 17:27:45350 configurator_.set_mirroring_controller(&mirroring_controller_);
[email protected]acb217ed2013-04-09 21:52:36351
[email protected]71da07e2014-03-18 21:16:04352 std::vector<const DisplayMode*> modes;
353 modes.push_back(&small_mode_);
[email protected]5d99ee62013-08-16 19:56:47354
[email protected]71da07e2014-03-18 21:16:04355 TestDisplaySnapshot* o = &outputs_[0];
356 o->set_current_mode(&small_mode_);
357 o->set_native_mode(&small_mode_);
358 o->set_modes(modes);
[email protected]bcec7fb2014-04-08 20:59:09359 o->set_type(DISPLAY_CONNECTION_TYPE_INTERNAL);
[email protected]71da07e2014-03-18 21:16:04360 o->set_is_aspect_preserving_scaling(true);
361 o->set_display_id(123);
362 o->set_has_proper_display_id(true);
[email protected]acb217ed2013-04-09 21:52:36363
364 o = &outputs_[1];
[email protected]71da07e2014-03-18 21:16:04365 o->set_current_mode(&big_mode_);
366 o->set_native_mode(&big_mode_);
367 modes.push_back(&big_mode_);
368 o->set_modes(modes);
[email protected]bcec7fb2014-04-08 20:59:09369 o->set_type(DISPLAY_CONNECTION_TYPE_HDMI);
[email protected]71da07e2014-03-18 21:16:04370 o->set_is_aspect_preserving_scaling(true);
371 o->set_display_id(456);
372 o->set_has_proper_display_id(true);
[email protected]acb217ed2013-04-09 21:52:36373
[email protected]edc1c802013-08-14 03:55:04374 UpdateOutputs(2, false);
[email protected]acb217ed2013-04-09 21:52:36375 }
376
[email protected]71da07e2014-03-18 21:16:04377 // Predefined modes that can be used by outputs.
378 const DisplayMode small_mode_;
379 const DisplayMode big_mode_;
380
[email protected]acb217ed2013-04-09 21:52:36381 protected:
[email protected]72bce522014-02-10 21:11:26382 // Configures |native_display_delegate_| to return the first |num_outputs|
383 // entries from
[email protected]edc1c802013-08-14 03:55:04384 // |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) {
[email protected]acb217ed2013-04-09 21:52:36388 ASSERT_LE(num_outputs, arraysize(outputs_));
[email protected]71da07e2014-03-18 21:16:04389 std::vector<DisplaySnapshot*> outputs;
[email protected]acb217ed2013-04-09 21:52:36390 for (size_t i = 0; i < num_outputs; ++i)
[email protected]71da07e2014-03-18 21:16:04391 outputs.push_back(&outputs_[i]);
[email protected]72bce522014-02-10 21:11:26392 native_display_delegate_->set_outputs(outputs);
[email protected]edc1c802013-08-14 03:55:04393
394 if (send_events) {
[email protected]3d1cd602014-02-26 23:39:18395 configurator_.OnConfigurationChanged();
[email protected]e6a5824e2014-08-13 14:53:41396 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
[email protected]edc1c802013-08-14 03:55:04397 }
[email protected]acb217ed2013-04-09 21:52:36398 }
399
400 // Initializes |configurator_| with a single internal display.
[email protected]edc1c802013-08-14 03:55:04401 void InitWithSingleOutput() {
402 UpdateOutputs(1, false);
[email protected]b036effd2014-02-05 16:24:54403 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]d30dac82013-07-31 16:17:30404 configurator_.Init(false);
[email protected]b036effd2014-02-05 16:24:54405 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]806f9542014-02-28 18:35:55406 configurator_.ForceInitialConfigure(0);
[email protected]b036effd2014-02-05 16:24:54407 EXPECT_EQ(
408 JoinActions(
409 kGrab,
410 kInitXRandR,
[email protected]71da07e2014-03-18 21:16:04411 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL)
[email protected]b036effd2014-02-05 16:24:54412 .c_str(),
[email protected]71da07e2014-03-18 21:16:04413 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54414 kForceDPMS,
415 kUngrab,
[email protected]b036effd2014-02-05 16:24:54416 NULL),
417 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36418 }
419
420 base::MessageLoop message_loop_;
421 TestStateController state_controller_;
[email protected]c1f30dc2013-05-22 17:27:45422 TestMirroringController mirroring_controller_;
[email protected]1e31cbd2014-04-07 20:06:11423 DisplayConfigurator configurator_;
[email protected]0b1b283b2013-08-17 13:32:18424 TestObserver observer_;
[email protected]b036effd2014-02-05 16:24:54425 scoped_ptr<ActionLogger> log_;
[email protected]72bce522014-02-10 21:11:26426 TestNativeDisplayDelegate* native_display_delegate_; // not owned
[email protected]1e31cbd2014-04-07 20:06:11427 DisplayConfigurator::TestApi test_api_;
[email protected]acb217ed2013-04-09 21:52:36428
[email protected]71da07e2014-03-18 21:16:04429 TestDisplaySnapshot outputs_[2];
[email protected]acb217ed2013-04-09 21:52:36430
431 private:
[email protected]1e31cbd2014-04-07 20:06:11432 DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorTest);
[email protected]acb217ed2013-04-09 21:52:36433};
434
435} // namespace
[email protected]6d980bc2012-09-10 19:28:45436
[email protected]1e31cbd2014-04-07 20:06:11437TEST_F(DisplayConfiguratorTest, FindDisplayModeMatchingSize) {
[email protected]71da07e2014-03-18 21:16:04438 ScopedVector<const DisplayMode> modes;
[email protected]6eebb90b2013-09-17 18:30:27439
440 // Fields are width, height, interlaced, refresh rate.
[email protected]71da07e2014-03-18 21:16:04441 modes.push_back(new DisplayMode(gfx::Size(1920, 1200), false, 60.0));
[email protected]6eebb90b2013-09-17 18:30:27442 // Different rates.
[email protected]71da07e2014-03-18 21:16:04443 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));
[email protected]6eebb90b2013-09-17 18:30:27447 // Interlaced vs non-interlaced.
[email protected]71da07e2014-03-18 21:16:04448 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));
[email protected]6eebb90b2013-09-17 18:30:27450 // Interlaced only.
[email protected]71da07e2014-03-18 21:16:04451 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));
[email protected]6eebb90b2013-09-17 18:30:27454 // Mixed.
[email protected]71da07e2014-03-18 21:16:04455 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));
[email protected]6eebb90b2013-09-17 18:30:27458 // Just one interlaced mode.
[email protected]71da07e2014-03-18 21:16:04459 modes.push_back(new DisplayMode(gfx::Size(640, 480), true, 60.0));
[email protected]6eebb90b2013-09-17 18:30:27460 // Refresh rate not available.
[email protected]71da07e2014-03-18 21:16:04461 modes.push_back(new DisplayMode(gfx::Size(320, 200), false, 0.0));
[email protected]6eebb90b2013-09-17 18:30:27462
[email protected]71da07e2014-03-18 21:16:04463 TestDisplaySnapshot output;
464 output.set_modes(modes.get());
465
466 EXPECT_EQ(modes[0],
[email protected]1e31cbd2014-04-07 20:06:11467 DisplayConfigurator::FindDisplayModeMatchingSize(
[email protected]71da07e2014-03-18 21:16:04468 output, gfx::Size(1920, 1200)));
[email protected]6eebb90b2013-09-17 18:30:27469
470 // Should pick highest refresh rate.
[email protected]71da07e2014-03-18 21:16:04471 EXPECT_EQ(modes[2],
[email protected]1e31cbd2014-04-07 20:06:11472 DisplayConfigurator::FindDisplayModeMatchingSize(
[email protected]71da07e2014-03-18 21:16:04473 output, gfx::Size(1920, 1080)));
[email protected]6eebb90b2013-09-17 18:30:27474
475 // Should pick non-interlaced mode.
[email protected]71da07e2014-03-18 21:16:04476 EXPECT_EQ(modes[6],
[email protected]1e31cbd2014-04-07 20:06:11477 DisplayConfigurator::FindDisplayModeMatchingSize(
[email protected]71da07e2014-03-18 21:16:04478 output, gfx::Size(1280, 720)));
[email protected]6eebb90b2013-09-17 18:30:27479
480 // Interlaced only. Should pick one with the highest refresh rate in
481 // interlaced mode.
[email protected]71da07e2014-03-18 21:16:04482 EXPECT_EQ(modes[9],
[email protected]1e31cbd2014-04-07 20:06:11483 DisplayConfigurator::FindDisplayModeMatchingSize(
[email protected]71da07e2014-03-18 21:16:04484 output, gfx::Size(1024, 768)));
[email protected]6eebb90b2013-09-17 18:30:27485
486 // Mixed: Should pick one with the highest refresh rate in
487 // interlaced mode.
[email protected]71da07e2014-03-18 21:16:04488 EXPECT_EQ(modes[12],
[email protected]1e31cbd2014-04-07 20:06:11489 DisplayConfigurator::FindDisplayModeMatchingSize(
[email protected]71da07e2014-03-18 21:16:04490 output, gfx::Size(1024, 600)));
[email protected]6eebb90b2013-09-17 18:30:27491
492 // Just one interlaced mode.
[email protected]71da07e2014-03-18 21:16:04493 EXPECT_EQ(modes[13],
[email protected]1e31cbd2014-04-07 20:06:11494 DisplayConfigurator::FindDisplayModeMatchingSize(
[email protected]71da07e2014-03-18 21:16:04495 output, gfx::Size(640, 480)));
[email protected]6eebb90b2013-09-17 18:30:27496
497 // Refresh rate not available.
[email protected]71da07e2014-03-18 21:16:04498 EXPECT_EQ(modes[14],
[email protected]1e31cbd2014-04-07 20:06:11499 DisplayConfigurator::FindDisplayModeMatchingSize(
[email protected]71da07e2014-03-18 21:16:04500 output, gfx::Size(320, 200)));
[email protected]6eebb90b2013-09-17 18:30:27501
502 // No mode found.
[email protected]71da07e2014-03-18 21:16:04503 EXPECT_EQ(NULL,
[email protected]1e31cbd2014-04-07 20:06:11504 DisplayConfigurator::FindDisplayModeMatchingSize(
[email protected]71da07e2014-03-18 21:16:04505 output, gfx::Size(1440, 900)));
[email protected]6eebb90b2013-09-17 18:30:27506}
507
[email protected]1e31cbd2014-04-07 20:06:11508TEST_F(DisplayConfiguratorTest, ConnectSecondOutput) {
[email protected]acb217ed2013-04-09 21:52:36509 InitWithSingleOutput();
510
511 // Connect a second output and check that the configurator enters
512 // extended mode.
[email protected]0b1b283b2013-08-17 13:32:18513 observer_.Reset();
[email protected]bcec7fb2014-04-08 20:59:09514 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
[email protected]edc1c802013-08-14 03:55:04515 UpdateOutputs(2, true);
[email protected]71da07e2014-03-18 21:16:04516 const int kDualHeight = small_mode_.size().height() +
[email protected]1e31cbd2014-04-07 20:06:11517 DisplayConfigurator::kVerticalGap +
[email protected]71da07e2014-03-18 21:16:04518 big_mode_.size().height();
[email protected]b036effd2014-02-05 16:24:54519 EXPECT_EQ(
520 JoinActions(
[email protected]b036effd2014-02-05 16:24:54521 kGrab,
[email protected]71da07e2014-03-18 21:16:04522 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() +
[email protected]1e31cbd2014-04-07 20:06:11530 DisplayConfigurator::kVerticalGap))
[email protected]b036effd2014-02-05 16:24:54531 .c_str(),
[email protected]b036effd2014-02-05 16:24:54532 kUngrab,
[email protected]b036effd2014-02-05 16:24:54533 NULL),
534 log_->GetActionsAndClear());
[email protected]857f47c2014-05-17 18:21:06535 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18536 EXPECT_EQ(1, observer_.num_changes());
[email protected]acb217ed2013-04-09 21:52:36537
[email protected]0b1b283b2013-08-17 13:32:18538 observer_.Reset();
[email protected]bcec7fb2014-04-08 20:59:09539 EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
[email protected]b036effd2014-02-05 16:24:54540 EXPECT_EQ(
541 JoinActions(
542 kGrab,
[email protected]71da07e2014-03-18 21:16:04543 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(),
[email protected]b036effd2014-02-05 16:24:54547 kUngrab,
548 NULL),
549 log_->GetActionsAndClear());
[email protected]857f47c2014-05-17 18:21:06550 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18551 EXPECT_EQ(1, observer_.num_changes());
[email protected]acb217ed2013-04-09 21:52:36552
553 // Disconnect the second output.
[email protected]0b1b283b2013-08-17 13:32:18554 observer_.Reset();
[email protected]edc1c802013-08-14 03:55:04555 UpdateOutputs(1, true);
[email protected]b036effd2014-02-05 16:24:54556 EXPECT_EQ(
557 JoinActions(
[email protected]b036effd2014-02-05 16:24:54558 kGrab,
[email protected]71da07e2014-03-18 21:16:04559 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
560 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54561 kUngrab,
[email protected]b036effd2014-02-05 16:24:54562 NULL),
563 log_->GetActionsAndClear());
[email protected]857f47c2014-05-17 18:21:06564 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18565 EXPECT_EQ(1, observer_.num_changes());
[email protected]c1f30dc2013-05-22 17:27:45566
[email protected]6eebb90b2013-09-17 18:30:27567 // Get rid of shared modes to force software mirroring.
[email protected]71da07e2014-03-18 21:16:04568 outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &big_mode_));
[email protected]bcec7fb2014-04-08 20:59:09569 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
[email protected]edc1c802013-08-14 03:55:04570 UpdateOutputs(2, true);
[email protected]b036effd2014-02-05 16:24:54571 EXPECT_EQ(
572 JoinActions(
[email protected]b036effd2014-02-05 16:24:54573 kGrab,
[email protected]71da07e2014-03-18 21:16:04574 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() +
[email protected]1e31cbd2014-04-07 20:06:11582 DisplayConfigurator::kVerticalGap))
[email protected]b036effd2014-02-05 16:24:54583 .c_str(),
[email protected]b036effd2014-02-05 16:24:54584 kUngrab,
[email protected]b036effd2014-02-05 16:24:54585 NULL),
586 log_->GetActionsAndClear());
[email protected]857f47c2014-05-17 18:21:06587 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]c1f30dc2013-05-22 17:27:45588
[email protected]0b1b283b2013-08-17 13:32:18589 observer_.Reset();
[email protected]bcec7fb2014-04-08 20:59:09590 EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
[email protected]b036effd2014-02-05 16:24:54591 EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09592 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
593 configurator_.display_state());
[email protected]857f47c2014-05-17 18:21:06594 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18595 EXPECT_EQ(1, observer_.num_changes());
[email protected]c1f30dc2013-05-22 17:27:45596
[email protected]bcec7fb2014-04-08 20:59:09597 // Setting MULTIPLE_DISPLAY_STATE_DUAL_MIRROR should try to reconfigure.
[email protected]0b1b283b2013-08-17 13:32:18598 observer_.Reset();
[email protected]bcec7fb2014-04-08 20:59:09599 EXPECT_TRUE(
600 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED));
[email protected]b036effd2014-02-05 16:24:54601 EXPECT_EQ(JoinActions(NULL), log_->GetActionsAndClear());
[email protected]857f47c2014-05-17 18:21:06602 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18603 EXPECT_EQ(1, observer_.num_changes());
[email protected]57bed4d2013-06-08 20:54:18604
605 // Set back to software mirror mode.
[email protected]0b1b283b2013-08-17 13:32:18606 observer_.Reset();
[email protected]bcec7fb2014-04-08 20:59:09607 EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR));
[email protected]b036effd2014-02-05 16:24:54608 EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09609 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
610 configurator_.display_state());
[email protected]857f47c2014-05-17 18:21:06611 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18612 EXPECT_EQ(1, observer_.num_changes());
[email protected]57bed4d2013-06-08 20:54:18613
[email protected]c1f30dc2013-05-22 17:27:45614 // Disconnect the second output.
[email protected]0b1b283b2013-08-17 13:32:18615 observer_.Reset();
[email protected]edc1c802013-08-14 03:55:04616 UpdateOutputs(1, true);
[email protected]b036effd2014-02-05 16:24:54617 EXPECT_EQ(
618 JoinActions(
[email protected]b036effd2014-02-05 16:24:54619 kGrab,
[email protected]71da07e2014-03-18 21:16:04620 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
621 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54622 kUngrab,
[email protected]b036effd2014-02-05 16:24:54623 NULL),
624 log_->GetActionsAndClear());
[email protected]857f47c2014-05-17 18:21:06625 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18626 EXPECT_EQ(1, observer_.num_changes());
[email protected]acb217ed2013-04-09 21:52:36627}
628
[email protected]1e31cbd2014-04-07 20:06:11629TEST_F(DisplayConfiguratorTest, SetDisplayPower) {
[email protected]acb217ed2013-04-09 21:52:36630 InitWithSingleOutput();
631
[email protected]bcec7fb2014-04-08 20:59:09632 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
[email protected]0b1b283b2013-08-17 13:32:18633 observer_.Reset();
[email protected]edc1c802013-08-14 03:55:04634 UpdateOutputs(2, true);
[email protected]b036effd2014-02-05 16:24:54635 EXPECT_EQ(
636 JoinActions(
[email protected]b036effd2014-02-05 16:24:54637 kGrab,
[email protected]71da07e2014-03-18 21:16:04638 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(),
[email protected]b036effd2014-02-05 16:24:54642 kUngrab,
[email protected]b036effd2014-02-05 16:24:54643 NULL),
644 log_->GetActionsAndClear());
[email protected]857f47c2014-05-17 18:21:06645 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18646 EXPECT_EQ(1, observer_.num_changes());
[email protected]acb217ed2013-04-09 21:52:36647
648 // Turning off the internal display should switch the external display to
649 // its native mode.
[email protected]0b1b283b2013-08-17 13:32:18650 observer_.Reset();
[email protected]29957af2014-03-14 21:08:56651 configurator_.SetDisplayPower(
652 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
[email protected]1e31cbd2014-04-07 20:06:11653 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54654 EXPECT_EQ(
655 JoinActions(
656 kGrab,
[email protected]71da07e2014-03-18 21:16:04657 GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
[email protected]b036effd2014-02-05 16:24:54658 .c_str(),
[email protected]71da07e2014-03-18 21:16:04659 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
660 GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54661 kForceDPMS,
662 kUngrab,
663 NULL),
664 log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09665 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
[email protected]0b1b283b2013-08-17 13:32:18666 EXPECT_EQ(1, observer_.num_changes());
[email protected]acb217ed2013-04-09 21:52:36667
668 // When all displays are turned off, the framebuffer should switch back
669 // to the mirrored size.
[email protected]0b1b283b2013-08-17 13:32:18670 observer_.Reset();
[email protected]29957af2014-03-14 21:08:56671 configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
[email protected]1e31cbd2014-04-07 20:06:11672 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54673 EXPECT_EQ(
[email protected]71da07e2014-03-18 21:16:04674 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),
[email protected]b036effd2014-02-05 16:24:54681 log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09682 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
[email protected]857f47c2014-05-17 18:21:06683 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18684 EXPECT_EQ(1, observer_.num_changes());
[email protected]acb217ed2013-04-09 21:52:36685
686 // Turn all displays on and check that mirroring is still used.
[email protected]0b1b283b2013-08-17 13:32:18687 observer_.Reset();
[email protected]29957af2014-03-14 21:08:56688 configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
[email protected]1e31cbd2014-04-07 20:06:11689 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54690 EXPECT_EQ(
691 JoinActions(
692 kGrab,
[email protected]71da07e2014-03-18 21:16:04693 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(),
[email protected]b036effd2014-02-05 16:24:54697 kForceDPMS,
698 kUngrab,
699 NULL),
700 log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09701 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
[email protected]857f47c2014-05-17 18:21:06702 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18703 EXPECT_EQ(1, observer_.num_changes());
[email protected]c1f30dc2013-05-22 17:27:45704
[email protected]6eebb90b2013-09-17 18:30:27705 // Get rid of shared modes to force software mirroring.
[email protected]71da07e2014-03-18 21:16:04706 outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &big_mode_));
[email protected]bcec7fb2014-04-08 20:59:09707 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
[email protected]0b1b283b2013-08-17 13:32:18708 observer_.Reset();
[email protected]edc1c802013-08-14 03:55:04709 UpdateOutputs(2, true);
[email protected]71da07e2014-03-18 21:16:04710 const int kDualHeight = small_mode_.size().height() +
[email protected]1e31cbd2014-04-07 20:06:11711 DisplayConfigurator::kVerticalGap +
[email protected]71da07e2014-03-18 21:16:04712 big_mode_.size().height();
[email protected]b036effd2014-02-05 16:24:54713 EXPECT_EQ(
714 JoinActions(
[email protected]b036effd2014-02-05 16:24:54715 kGrab,
[email protected]71da07e2014-03-18 21:16:04716 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() +
[email protected]1e31cbd2014-04-07 20:06:11724 DisplayConfigurator::kVerticalGap))
[email protected]b036effd2014-02-05 16:24:54725 .c_str(),
[email protected]b036effd2014-02-05 16:24:54726 kUngrab,
[email protected]b036effd2014-02-05 16:24:54727 NULL),
728 log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09729 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
730 configurator_.display_state());
[email protected]857f47c2014-05-17 18:21:06731 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18732 EXPECT_EQ(1, observer_.num_changes());
[email protected]c1f30dc2013-05-22 17:27:45733
734 // Turning off the internal display should switch the external display to
735 // its native mode.
[email protected]0b1b283b2013-08-17 13:32:18736 observer_.Reset();
[email protected]29957af2014-03-14 21:08:56737 configurator_.SetDisplayPower(
738 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
[email protected]1e31cbd2014-04-07 20:06:11739 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54740 EXPECT_EQ(
741 JoinActions(
742 kGrab,
[email protected]71da07e2014-03-18 21:16:04743 GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
[email protected]b036effd2014-02-05 16:24:54744 .c_str(),
[email protected]71da07e2014-03-18 21:16:04745 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
746 GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54747 kForceDPMS,
748 kUngrab,
749 NULL),
750 log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09751 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
[email protected]857f47c2014-05-17 18:21:06752 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18753 EXPECT_EQ(1, observer_.num_changes());
[email protected]c1f30dc2013-05-22 17:27:45754
755 // When all displays are turned off, the framebuffer should switch back
756 // to the extended + software mirroring.
[email protected]0b1b283b2013-08-17 13:32:18757 observer_.Reset();
[email protected]29957af2014-03-14 21:08:56758 configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
[email protected]1e31cbd2014-04-07 20:06:11759 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54760 EXPECT_EQ(
761 JoinActions(
762 kGrab,
[email protected]71da07e2014-03-18 21:16:04763 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() +
[email protected]1e31cbd2014-04-07 20:06:11771 DisplayConfigurator::kVerticalGap))
[email protected]b036effd2014-02-05 16:24:54772 .c_str(),
[email protected]b036effd2014-02-05 16:24:54773 kUngrab,
774 NULL),
775 log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09776 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
777 configurator_.display_state());
[email protected]857f47c2014-05-17 18:21:06778 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18779 EXPECT_EQ(1, observer_.num_changes());
[email protected]c1f30dc2013-05-22 17:27:45780
781 // Turn all displays on and check that mirroring is still used.
[email protected]0b1b283b2013-08-17 13:32:18782 observer_.Reset();
[email protected]29957af2014-03-14 21:08:56783 configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
[email protected]1e31cbd2014-04-07 20:06:11784 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54785 EXPECT_EQ(
786 JoinActions(
787 kGrab,
[email protected]71da07e2014-03-18 21:16:04788 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() +
[email protected]1e31cbd2014-04-07 20:06:11796 DisplayConfigurator::kVerticalGap))
[email protected]b036effd2014-02-05 16:24:54797 .c_str(),
[email protected]b036effd2014-02-05 16:24:54798 kForceDPMS,
799 kUngrab,
800 NULL),
801 log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:09802 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
803 configurator_.display_state());
[email protected]857f47c2014-05-17 18:21:06804 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
[email protected]0b1b283b2013-08-17 13:32:18805 EXPECT_EQ(1, observer_.num_changes());
[email protected]acb217ed2013-04-09 21:52:36806}
807
[email protected]1e31cbd2014-04-07 20:06:11808TEST_F(DisplayConfiguratorTest, SuspendAndResume) {
[email protected]acb217ed2013-04-09 21:52:36809 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();
[email protected]b036effd2014-02-05 16:24:54815 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36816 configurator_.ResumeDisplays();
[email protected]e6a5824e2014-08-13 14:53:41817 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
[email protected]b036effd2014-02-05 16:24:54818 EXPECT_EQ(
819 JoinActions(
820 kGrab,
[email protected]71da07e2014-03-18 21:16:04821 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
822 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54823 kForceDPMS,
824 kUngrab,
825 NULL),
826 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36827
828 // Now turn the display off before suspending and check that the
829 // configurator turns it back on and syncs with the server.
[email protected]29957af2014-03-14 21:08:56830 configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
[email protected]1e31cbd2014-04-07 20:06:11831 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54832 EXPECT_EQ(
833 JoinActions(
834 kGrab,
[email protected]71da07e2014-03-18 21:16:04835 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
836 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54837 kUngrab,
838 NULL),
839 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36840
841 configurator_.SuspendDisplays();
[email protected]b036effd2014-02-05 16:24:54842 EXPECT_EQ(
843 JoinActions(
844 kGrab,
[email protected]71da07e2014-03-18 21:16:04845 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
846 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54847 kForceDPMS,
848 kUngrab,
849 kSync,
850 NULL),
851 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36852
853 configurator_.ResumeDisplays();
[email protected]e6a5824e2014-08-13 14:53:41854 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
[email protected]b036effd2014-02-05 16:24:54855 EXPECT_EQ(
856 JoinActions(
857 kGrab,
[email protected]71da07e2014-03-18 21:16:04858 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
859 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54860 kForceDPMS,
861 kUngrab,
862 NULL),
863 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36864
865 // If a second, external display is connected, the displays shouldn't be
866 // powered back on before suspending.
[email protected]bcec7fb2014-04-08 20:59:09867 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
[email protected]edc1c802013-08-14 03:55:04868 UpdateOutputs(2, true);
[email protected]b036effd2014-02-05 16:24:54869 EXPECT_EQ(
870 JoinActions(
[email protected]b036effd2014-02-05 16:24:54871 kGrab,
[email protected]71da07e2014-03-18 21:16:04872 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(),
[email protected]b036effd2014-02-05 16:24:54876 kUngrab,
[email protected]b036effd2014-02-05 16:24:54877 NULL),
878 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36879
[email protected]29957af2014-03-14 21:08:56880 configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
[email protected]1e31cbd2014-04-07 20:06:11881 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54882 EXPECT_EQ(
[email protected]71da07e2014-03-18 21:16:04883 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),
[email protected]b036effd2014-02-05 16:24:54890 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36891
892 configurator_.SuspendDisplays();
893 EXPECT_EQ(JoinActions(kGrab, kUngrab, kSync, NULL),
[email protected]b036effd2014-02-05 16:24:54894 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36895
[email protected]edc1c802013-08-14 03:55:04896 // If a display is disconnected while suspended, the configurator should
[email protected]acb217ed2013-04-09 21:52:36897 // pick up the change.
[email protected]edc1c802013-08-14 03:55:04898 UpdateOutputs(1, false);
[email protected]acb217ed2013-04-09 21:52:36899 configurator_.ResumeDisplays();
[email protected]e6a5824e2014-08-13 14:53:41900 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
[email protected]b036effd2014-02-05 16:24:54901 EXPECT_EQ(
902 JoinActions(
903 kGrab,
[email protected]71da07e2014-03-18 21:16:04904 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
905 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54906 kUngrab,
907 NULL),
908 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36909}
910
[email protected]1e31cbd2014-04-07 20:06:11911TEST_F(DisplayConfiguratorTest, Headless) {
[email protected]edc1c802013-08-14 03:55:04912 UpdateOutputs(0, false);
[email protected]b036effd2014-02-05 16:24:54913 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]d30dac82013-07-31 16:17:30914 configurator_.Init(false);
[email protected]b036effd2014-02-05 16:24:54915 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]806f9542014-02-28 18:35:55916 configurator_.ForceInitialConfigure(0);
[email protected]72bce522014-02-10 21:11:26917 EXPECT_EQ(JoinActions(kGrab, kInitXRandR, kForceDPMS, kUngrab, NULL),
[email protected]b036effd2014-02-05 16:24:54918 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36919
920 // Not much should happen when the display power state is changed while
921 // no displays are connected.
[email protected]29957af2014-03-14 21:08:56922 configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF,
[email protected]1e31cbd2014-04-07 20:06:11923 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]b036effd2014-02-05 16:24:54924 EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
[email protected]29957af2014-03-14 21:08:56925 configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
[email protected]1e31cbd2014-04-07 20:06:11926 DisplayConfigurator::kSetDisplayPowerNoFlags);
[email protected]acb217ed2013-04-09 21:52:36927 EXPECT_EQ(JoinActions(kGrab, kForceDPMS, kUngrab, NULL),
[email protected]b036effd2014-02-05 16:24:54928 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36929
930 // Connect an external display and check that it's configured correctly.
[email protected]71da07e2014-03-18 21:16:04931 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
[email protected]edc1c802013-08-14 03:55:04936 UpdateOutputs(1, true);
[email protected]b036effd2014-02-05 16:24:54937 EXPECT_EQ(
938 JoinActions(
[email protected]b036effd2014-02-05 16:24:54939 kGrab,
[email protected]71da07e2014-03-18 21:16:04940 GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(),
941 GetCrtcAction(outputs_[0], &big_mode_, gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:54942 kUngrab,
[email protected]b036effd2014-02-05 16:24:54943 NULL),
944 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36945}
946
[email protected]1e31cbd2014-04-07 20:06:11947TEST_F(DisplayConfiguratorTest, StartWithTwoOutputs) {
[email protected]edc1c802013-08-14 03:55:04948 UpdateOutputs(2, false);
[email protected]b036effd2014-02-05 16:24:54949 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]d30dac82013-07-31 16:17:30950 configurator_.Init(false);
[email protected]b036effd2014-02-05 16:24:54951 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36952
[email protected]bcec7fb2014-04-08 20:59:09953 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
[email protected]806f9542014-02-28 18:35:55954 configurator_.ForceInitialConfigure(0);
[email protected]b036effd2014-02-05 16:24:54955 EXPECT_EQ(
956 JoinActions(
957 kGrab,
958 kInitXRandR,
[email protected]71da07e2014-03-18 21:16:04959 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(),
[email protected]b036effd2014-02-05 16:24:54963 kForceDPMS,
964 kUngrab,
[email protected]b036effd2014-02-05 16:24:54965 NULL),
966 log_->GetActionsAndClear());
[email protected]acb217ed2013-04-09 21:52:36967}
968
[email protected]bcec7fb2014-04-08 20:59:09969TEST_F(DisplayConfiguratorTest, InvalidMultipleDisplayStates) {
[email protected]edc1c802013-08-14 03:55:04970 UpdateOutputs(0, false);
[email protected]b036effd2014-02-05 16:24:54971 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]d30dac82013-07-31 16:17:30972 configurator_.Init(false);
[email protected]806f9542014-02-28 18:35:55973 configurator_.ForceInitialConfigure(0);
[email protected]0b1b283b2013-08-17 13:32:18974 observer_.Reset();
[email protected]bcec7fb2014-04-08 20:59:09975 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));
[email protected]0b1b283b2013-08-17 13:32:18981 EXPECT_EQ(1, observer_.num_changes());
982 EXPECT_EQ(3, observer_.num_failures());
[email protected]acb217ed2013-04-09 21:52:36983
[email protected]edc1c802013-08-14 03:55:04984 UpdateOutputs(1, true);
[email protected]0b1b283b2013-08-17 13:32:18985 observer_.Reset();
[email protected]bcec7fb2014-04-08 20:59:09986 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));
[email protected]0b1b283b2013-08-17 13:32:18992 EXPECT_EQ(1, observer_.num_changes());
993 EXPECT_EQ(3, observer_.num_failures());
[email protected]acb217ed2013-04-09 21:52:36994
[email protected]bcec7fb2014-04-08 20:59:09995 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
[email protected]edc1c802013-08-14 03:55:04996 UpdateOutputs(2, true);
[email protected]0b1b283b2013-08-17 13:32:18997 observer_.Reset();
[email protected]bcec7fb2014-04-08 20:59:09998 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));
[email protected]0b1b283b2013-08-17 13:32:181003 EXPECT_EQ(2, observer_.num_changes());
1004 EXPECT_EQ(2, observer_.num_failures());
[email protected]acb217ed2013-04-09 21:52:361005}
1006
[email protected]bcec7fb2014-04-08 20:59:091007TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForDisplaysWithoutId) {
[email protected]71da07e2014-03-18 21:16:041008 outputs_[0].set_has_proper_display_id(false);
[email protected]edc1c802013-08-14 03:55:041009 UpdateOutputs(2, false);
[email protected]d30dac82013-07-31 16:17:301010 configurator_.Init(false);
[email protected]bcec7fb2014-04-08 20:59:091011 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
[email protected]806f9542014-02-28 18:35:551012 configurator_.ForceInitialConfigure(0);
[email protected]bcec7fb2014-04-08 20:59:091013 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
1014 configurator_.display_state());
[email protected]edc1c802013-08-14 03:55:041015}
[email protected]2c8a0aa72013-05-16 06:24:481016
[email protected]bcec7fb2014-04-08 20:59:091017TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForDisplaysWithId) {
[email protected]71da07e2014-03-18 21:16:041018 outputs_[0].set_has_proper_display_id(true);
[email protected]edc1c802013-08-14 03:55:041019 UpdateOutputs(2, false);
1020 configurator_.Init(false);
[email protected]bcec7fb2014-04-08 20:59:091021 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
[email protected]806f9542014-02-28 18:35:551022 configurator_.ForceInitialConfigure(0);
[email protected]bcec7fb2014-04-08 20:59:091023 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
[email protected]2c8a0aa72013-05-16 06:24:481024}
1025
[email protected]1e31cbd2014-04-07 20:06:111026TEST_F(DisplayConfiguratorTest, UpdateCachedOutputsEvenAfterFailure) {
[email protected]3d1df542013-09-24 04:26:221027 InitWithSingleOutput();
[email protected]1e31cbd2014-04-07 20:06:111028 const DisplayConfigurator::DisplayStateList* cached =
[email protected]bcec7fb2014-04-08 20:59:091029 &configurator_.cached_displays();
[email protected]3d1df542013-09-24 04:26:221030 ASSERT_EQ(static_cast<size_t>(1), cached->size());
[email protected]71da07e2014-03-18 21:16:041031 EXPECT_EQ(outputs_[0].current_mode(), (*cached)[0].display->current_mode());
[email protected]3d1df542013-09-24 04:26:221032
1033 // After connecting a second output, check that it shows up in
[email protected]bcec7fb2014-04-08 20:59:091034 // |cached_displays_| even if an invalid state is requested.
1035 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
[email protected]3d1df542013-09-24 04:26:221036 UpdateOutputs(2, true);
[email protected]bcec7fb2014-04-08 20:59:091037 cached = &configurator_.cached_displays();
[email protected]3d1df542013-09-24 04:26:221038 ASSERT_EQ(static_cast<size_t>(2), cached->size());
[email protected]71da07e2014-03-18 21:16:041039 EXPECT_EQ(outputs_[0].current_mode(), (*cached)[0].display->current_mode());
1040 EXPECT_EQ(outputs_[1].current_mode(), (*cached)[1].display->current_mode());
[email protected]3d1df542013-09-24 04:26:221041}
1042
[email protected]1e31cbd2014-04-07 20:06:111043TEST_F(DisplayConfiguratorTest, PanelFitting) {
[email protected]6eebb90b2013-09-17 18:30:271044 // Configure the internal display to support only the big mode and the
1045 // external display to support only the small mode.
[email protected]71da07e2014-03-18 21:16:041046 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_));
[email protected]6eebb90b2013-09-17 18:30:271049
[email protected]71da07e2014-03-18 21:16:041050 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_));
[email protected]6eebb90b2013-09-17 18:30:271053
1054 // The small mode should be added to the internal output when requesting
1055 // mirrored mode.
1056 UpdateOutputs(2, false);
[email protected]bcec7fb2014-04-08 20:59:091057 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
[email protected]6eebb90b2013-09-17 18:30:271058 configurator_.Init(true /* is_panel_fitting_enabled */);
[email protected]806f9542014-02-28 18:35:551059 configurator_.ForceInitialConfigure(0);
[email protected]bcec7fb2014-04-08 20:59:091060 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
[email protected]b036effd2014-02-05 16:24:541061 EXPECT_EQ(
1062 JoinActions(
1063 kGrab,
1064 kInitXRandR,
[email protected]71da07e2014-03-18 21:16:041065 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(),
[email protected]b036effd2014-02-05 16:24:541070 kForceDPMS,
1071 kUngrab,
[email protected]b036effd2014-02-05 16:24:541072 NULL),
1073 log_->GetActionsAndClear());
[email protected]6eebb90b2013-09-17 18:30:271074
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());
[email protected]71da07e2014-03-18 21:16:041078 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());
[email protected]6eebb90b2013-09-17 18:30:271084
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).
[email protected]1e31cbd2014-04-07 20:06:111087 const DisplayConfigurator::DisplayState& state =
1088 observer_.latest_outputs()[0];
[email protected]71da07e2014-03-18 21:16:041089 ASSERT_NE(state.display->modes().end(),
1090 std::find(state.display->modes().begin(),
1091 state.display->modes().end(),
1092 &small_mode_));
[email protected]6eebb90b2013-09-17 18:30:271093}
1094
[email protected]bcec7fb2014-04-08 20:59:091095TEST_F(DisplayConfiguratorTest, ContentProtection) {
[email protected]a9318842013-10-02 07:21:131096 configurator_.Init(false);
[email protected]806f9542014-02-28 18:35:551097 configurator_.ForceInitialConfigure(0);
[email protected]b036effd2014-02-05 16:24:541098 EXPECT_NE(kNoActions, log_->GetActionsAndClear());
[email protected]a9318842013-10-02 07:21:131099
[email protected]bcec7fb2014-04-08 20:59:091100 DisplayConfigurator::ContentProtectionClientId id =
1101 configurator_.RegisterContentProtectionClient();
[email protected]a9318842013-10-02 07:21:131102 EXPECT_NE(0u, id);
1103
1104 // One output.
1105 UpdateOutputs(1, true);
[email protected]b036effd2014-02-05 16:24:541106 EXPECT_NE(kNoActions, log_->GetActionsAndClear());
[email protected]a9318842013-10-02 07:21:131107 uint32_t link_mask = 0;
1108 uint32_t protection_mask = 0;
[email protected]bcec7fb2014-04-08 20:59:091109 EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
[email protected]71da07e2014-03-18 21:16:041110 id, outputs_[0].display_id(), &link_mask, &protection_mask));
[email protected]bcec7fb2014-04-08 20:59:091111 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL), link_mask);
1112 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
[email protected]a9318842013-10-02 07:21:131113 protection_mask);
[email protected]b036effd2014-02-05 16:24:541114 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]a9318842013-10-02 07:21:131115
1116 // Two outputs.
1117 UpdateOutputs(2, true);
[email protected]b036effd2014-02-05 16:24:541118 EXPECT_NE(kNoActions, log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:091119 EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
[email protected]71da07e2014-03-18 21:16:041120 id, outputs_[1].display_id(), &link_mask, &protection_mask));
[email protected]bcec7fb2014-04-08 20:59:091121 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
1122 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
[email protected]a9318842013-10-02 07:21:131123 protection_mask);
[email protected]b036effd2014-02-05 16:24:541124 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]a9318842013-10-02 07:21:131125
[email protected]bcec7fb2014-04-08 20:59:091126 EXPECT_TRUE(configurator_.EnableContentProtection(
1127 id, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
[email protected]71da07e2014-03-18 21:16:041128 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED),
[email protected]b036effd2014-02-05 16:24:541129 log_->GetActionsAndClear());
[email protected]a9318842013-10-02 07:21:131130
1131 // Enable protection.
[email protected]29957af2014-03-14 21:08:561132 native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
[email protected]bcec7fb2014-04-08 20:59:091133 EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
[email protected]71da07e2014-03-18 21:16:041134 id, outputs_[1].display_id(), &link_mask, &protection_mask));
[email protected]bcec7fb2014-04-08 20:59:091135 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
1136 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP),
[email protected]a9318842013-10-02 07:21:131137 protection_mask);
[email protected]b036effd2014-02-05 16:24:541138 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]67e6a682013-10-31 10:00:411139
1140 // Protections should be disabled after unregister.
[email protected]bcec7fb2014-04-08 20:59:091141 configurator_.UnregisterContentProtectionClient(id);
[email protected]71da07e2014-03-18 21:16:041142 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED),
[email protected]b036effd2014-02-05 16:24:541143 log_->GetActionsAndClear());
[email protected]a9318842013-10-02 07:21:131144}
1145
[email protected]bcec7fb2014-04-08 20:59:091146TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClients) {
1147 DisplayConfigurator::ContentProtectionClientId client1 =
1148 configurator_.RegisterContentProtectionClient();
1149 DisplayConfigurator::ContentProtectionClientId client2 =
1150 configurator_.RegisterContentProtectionClient();
[email protected]a9318842013-10-02 07:21:131151 EXPECT_NE(client1, client2);
1152
1153 configurator_.Init(false);
[email protected]806f9542014-02-28 18:35:551154 configurator_.ForceInitialConfigure(0);
[email protected]a9318842013-10-02 07:21:131155 UpdateOutputs(2, true);
[email protected]b036effd2014-02-05 16:24:541156 EXPECT_NE(kNoActions, log_->GetActionsAndClear());
[email protected]a9318842013-10-02 07:21:131157
1158 // Clients never know state enableness for methods that they didn't request.
[email protected]bcec7fb2014-04-08 20:59:091159 EXPECT_TRUE(configurator_.EnableContentProtection(
1160 client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP));
[email protected]71da07e2014-03-18 21:16:041161 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
1162 log_->GetActionsAndClear());
[email protected]29957af2014-03-14 21:08:561163 native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
[email protected]a9318842013-10-02 07:21:131164
1165 uint32_t link_mask = 0;
1166 uint32_t protection_mask = 0;
[email protected]bcec7fb2014-04-08 20:59:091167 EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
[email protected]71da07e2014-03-18 21:16:041168 client1, outputs_[1].display_id(), &link_mask, &protection_mask));
[email protected]bcec7fb2014-04-08 20:59:091169 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
1170 EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask);
[email protected]a9318842013-10-02 07:21:131171
[email protected]bcec7fb2014-04-08 20:59:091172 EXPECT_TRUE(configurator_.QueryContentProtectionStatus(
[email protected]71da07e2014-03-18 21:16:041173 client2, outputs_[1].display_id(), &link_mask, &protection_mask));
[email protected]bcec7fb2014-04-08 20:59:091174 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask);
1175 EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask);
[email protected]a9318842013-10-02 07:21:131176
1177 // Protections will be disabled only if no more clients request them.
[email protected]bcec7fb2014-04-08 20:59:091178 EXPECT_TRUE(configurator_.EnableContentProtection(
1179 client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE));
kcwu7bf0d742014-09-24 15:39:471180 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
[email protected]bcec7fb2014-04-08 20:59:091181 EXPECT_TRUE(configurator_.EnableContentProtection(
1182 client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE));
[email protected]1e31cbd2014-04-07 20:06:111183 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED).c_str(),
1184 log_->GetActionsAndClear());
[email protected]a9318842013-10-02 07:21:131185}
1186
kcwu7bf0d742014-09-24 15:39:471187TEST_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
[email protected]1e31cbd2014-04-07 20:06:111217TEST_F(DisplayConfiguratorTest, HandleConfigureCrtcFailure) {
[email protected]63da7fb2014-01-10 00:35:311218 InitWithSingleOutput();
1219
[email protected]71da07e2014-03-18 21:16:041220 ScopedVector<const DisplayMode> modes;
[email protected]1e31cbd2014-04-07 20:06:111221 // The first mode is the mode we are requesting DisplayConfigurator to choose.
[email protected]71da07e2014-03-18 21:16:041222 // 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));
[email protected]63da7fb2014-01-10 00:35:311229
[email protected]63da7fb2014-01-10 00:35:311230 for (unsigned int i = 0; i < arraysize(outputs_); i++) {
[email protected]71da07e2014-03-18 21:16:041231 outputs_[i].set_modes(modes.get());
1232 outputs_[i].set_current_mode(modes[0]);
1233 outputs_[i].set_native_mode(modes[0]);
[email protected]63da7fb2014-01-10 00:35:311234 }
1235
[email protected]bcec7fb2014-04-08 20:59:091236 // 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.
[email protected]72bce522014-02-10 21:11:261239 native_display_delegate_->set_max_configurable_pixels(
[email protected]71da07e2014-03-18 21:16:041240 modes[2]->size().GetArea());
[email protected]bcec7fb2014-04-08 20:59:091241 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
[email protected]63da7fb2014-01-10 00:35:311242 UpdateOutputs(1, true);
1243
[email protected]b036effd2014-02-05 16:24:541244 EXPECT_EQ(
1245 JoinActions(
[email protected]b036effd2014-02-05 16:24:541246 kGrab,
[email protected]71da07e2014-03-18 21:16:041247 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(),
[email protected]b036effd2014-02-05 16:24:541251 kUngrab,
[email protected]b036effd2014-02-05 16:24:541252 NULL),
1253 log_->GetActionsAndClear());
[email protected]63da7fb2014-01-10 00:35:311254
1255 // This test should attempt to configure a mirror mode that will not succeed
1256 // and should end up in extended mode.
[email protected]72bce522014-02-10 21:11:261257 native_display_delegate_->set_max_configurable_pixels(
[email protected]71da07e2014-03-18 21:16:041258 modes[3]->size().GetArea());
[email protected]bcec7fb2014-04-08 20:59:091259 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
[email protected]63da7fb2014-01-10 00:35:311260 UpdateOutputs(2, true);
1261
[email protected]b036effd2014-02-05 16:24:541262 EXPECT_EQ(
1263 JoinActions(
[email protected]b036effd2014-02-05 16:24:541264 kGrab,
[email protected]71da07e2014-03-18 21:16:041265 GetFramebufferAction(modes[0]->size(), &outputs_[0], &outputs_[1])
[email protected]b036effd2014-02-05 16:24:541266 .c_str(),
[email protected]71da07e2014-03-18 21:16:041267 GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:541268 // First mode tried is expected to fail and it will
1269 // retry wil the 4th mode in the list.
[email protected]71da07e2014-03-18 21:16:041270 GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:541271 // Then attempt to configure crtc1 with the first mode.
[email protected]71da07e2014-03-18 21:16:041272 GetCrtcAction(outputs_[1], modes[0], gfx::Point(0, 0)).c_str(),
1273 GetCrtcAction(outputs_[1], modes[3], gfx::Point(0, 0)).c_str(),
[email protected]b036effd2014-02-05 16:24:541274 // 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.
[email protected]71da07e2014-03-18 21:16:041278 GetFramebufferAction(
1279 gfx::Size(modes[0]->size().width(),
1280 modes[0]->size().height() + modes[0]->size().height() +
[email protected]1e31cbd2014-04-07 20:06:111281 DisplayConfigurator::kVerticalGap),
[email protected]71da07e2014-03-18 21:16:041282 &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() +
[email protected]1e31cbd2014-04-07 20:06:111290 DisplayConfigurator::kVerticalGap))
[email protected]b036effd2014-02-05 16:24:541291 .c_str(),
[email protected]71da07e2014-03-18 21:16:041292 GetCrtcAction(outputs_[1],
1293 modes[3],
1294 gfx::Point(0,
1295 modes[0]->size().height() +
[email protected]1e31cbd2014-04-07 20:06:111296 DisplayConfigurator::kVerticalGap))
[email protected]b036effd2014-02-05 16:24:541297 .c_str(),
[email protected]b036effd2014-02-05 16:24:541298 kUngrab,
[email protected]b036effd2014-02-05 16:24:541299 NULL),
1300 log_->GetActionsAndClear());
[email protected]63da7fb2014-01-10 00:35:311301}
1302
derat4a062782014-09-25 21:46:131303// Tests that power state requests are saved after failed configuration attempts
1304// so they can be reused later: http://crosbug.com/p/31571
1305TEST_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
[email protected]29957af2014-03-14 21:08:561341} // namespace ui