1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/display/chromeos/display_configurator.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <stdint.h> 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <cmath> 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <cstdarg> 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <map> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/compiler_specific.h" 1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/format_macros.h" 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/memory/scoped_vector.h" 189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/display/chromeos/test/test_display_snapshot.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/display/types/display_mode.h" 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/display/types/native_display_delegate.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ui { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Strings returned by TestNativeDisplayDelegate::GetActionsAndClear() to 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// describe various actions that were performed. 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kInitXRandR[] = "init"; 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kGrab[] = "grab"; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kUngrab[] = "ungrab"; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kSync[] = "sync"; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kForceDPMS[] = "dpms"; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// String returned by TestNativeDisplayDelegate::GetActionsAndClear() if no 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// actions were requested. 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kNoActions[] = ""; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)std::string DisplaySnapshotToString(const DisplaySnapshot& output) { 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return base::StringPrintf("id=%" PRId64, output.display_id()); 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns a string describing a TestNativeDisplayDelegate::SetBackgroundColor() 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// call. 47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstd::string GetBackgroundAction(uint32_t color_argb) { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::StringPrintf("background(0x%x)", color_argb); 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns a string describing a TestNativeDisplayDelegate::AddOutputMode() 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// call. 5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)std::string GetAddOutputModeAction(const DisplaySnapshot& output, 5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplayMode* mode) { 5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return base::StringPrintf("add_mode(output=%" PRId64 ",mode=%s)", 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output.display_id(), 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) mode->ToString().c_str()); 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Returns a string describing a TestNativeDisplayDelegate::Configure() 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// call. 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)std::string GetCrtcAction(const DisplaySnapshot& output, 6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplayMode* mode, 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const gfx::Point& origin) { 6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return base::StringPrintf("crtc(display=[%s],x=%d,y=%d,mode=[%s])", 6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DisplaySnapshotToString(output).c_str(), 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) origin.x(), 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) origin.y(), 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) mode ? mode->ToString().c_str() : "NULL"); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns a string describing a TestNativeDisplayDelegate::CreateFramebuffer() 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// call. 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)std::string GetFramebufferAction(const gfx::Size& size, 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplaySnapshot* out1, 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplaySnapshot* out2) { 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::StringPrintf( 7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "framebuffer(width=%d,height=%d,display1=%s,display2=%s)", 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size.width(), 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size.height(), 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) out1 ? DisplaySnapshotToString(*out1).c_str() : "NULL", 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) out2 ? DisplaySnapshotToString(*out2).c_str() : "NULL"); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns a string describing a TestNativeDisplayDelegate::SetHDCPState() call. 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)std::string GetSetHDCPStateAction(const DisplaySnapshot& output, 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) HDCPState state) { 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return base::StringPrintf( 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "set_hdcp(id=%" PRId64 ",state=%d)", output.display_id(), state); 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Joins a sequence of strings describing actions (e.g. kScreenDim) such 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// that they can be compared against a string returned by 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ActionLogger::GetActionsAndClear(). The list of actions must be 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// terminated by a NULL pointer. 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string JoinActions(const char* action, ...) { 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string actions; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) va_list arg_list; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) va_start(arg_list, action); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (action) { 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!actions.empty()) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) actions += ","; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) actions += action; 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) action = va_arg(arg_list, const char*); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) va_end(arg_list); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return actions; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ActionLogger { 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ActionLogger() {} 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void AppendAction(const std::string& action) { 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!actions_.empty()) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) actions_ += ","; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) actions_ += action; 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns a comma-separated string describing the actions that were 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // requested since the previous call to GetActionsAndClear() (i.e. 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // results are non-repeatable). 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string GetActionsAndClear() { 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string actions = actions_; 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) actions_.clear(); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return actions; 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string actions_; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ActionLogger); 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class TestNativeDisplayDelegate : public NativeDisplayDelegate { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ownership of |log| remains with the caller. 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit TestNativeDisplayDelegate(ActionLogger* log) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : max_configurable_pixels_(0), 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hdcp_state_(HDCP_STATE_UNDESIRED), 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_(log) {} 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~TestNativeDisplayDelegate() {} 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::vector<DisplaySnapshot*>& outputs() const { return outputs_; } 14623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) void set_outputs(const std::vector<DisplaySnapshot*>& outputs) { 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outputs_ = outputs; 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void set_max_configurable_pixels(int pixels) { 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) max_configurable_pixels_ = pixels; 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void set_hdcp_state(HDCPState state) { hdcp_state_ = state; } 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // DisplayConfigurator::Delegate overrides: 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void Initialize() OVERRIDE { log_->AppendAction(kInitXRandR); } 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void GrabServer() OVERRIDE { log_->AppendAction(kGrab); } 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void UngrabServer() OVERRIDE { log_->AppendAction(kUngrab); } 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SyncWithServer() OVERRIDE { log_->AppendAction(kSync); } 161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual void SetBackgroundColor(uint32_t color_argb) OVERRIDE { 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->AppendAction(GetBackgroundAction(color_argb)); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void ForceDPMSOn() OVERRIDE { log_->AppendAction(kForceDPMS); } 165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual std::vector<DisplaySnapshot*> GetDisplays() OVERRIDE { 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return outputs_; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 16823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void AddMode(const DisplaySnapshot& output, 16923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplayMode* mode) OVERRIDE { 17023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_->AppendAction(GetAddOutputModeAction(output, mode)); 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 17223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual bool Configure(const DisplaySnapshot& output, 17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplayMode* mode, 17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const gfx::Point& origin) OVERRIDE { 17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_->AppendAction(GetCrtcAction(output, mode, origin)); 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (max_configurable_pixels_ == 0) 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!mode) 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return mode->size().GetArea() <= max_configurable_pixels_; 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void CreateFrameBuffer(const gfx::Size& size) OVERRIDE { 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->AppendAction( 18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(size, 18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_.size() >= 1 ? outputs_[0] : NULL, 18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_.size() >= 2 ? outputs_[1] : NULL)); 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 19123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual bool GetHDCPState(const DisplaySnapshot& output, 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HDCPState* state) OVERRIDE { 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *state = hdcp_state_; 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual bool SetHDCPState(const DisplaySnapshot& output, 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HDCPState state) OVERRIDE { 19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_->AppendAction(GetSetHDCPStateAction(output, state)); 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual std::vector<ui::ColorCalibrationProfile> 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GetAvailableColorCalibrationProfiles(const DisplaySnapshot& output) OVERRIDE { 205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return std::vector<ui::ColorCalibrationProfile>(); 206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual bool SetColorCalibrationProfile( 20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplaySnapshot& output, 21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::ColorCalibrationProfile new_profile) OVERRIDE { 21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void AddObserver(NativeDisplayObserver* observer) OVERRIDE {} 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void RemoveObserver(NativeDisplayObserver* observer) OVERRIDE {} 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Outputs to be returned by GetDisplays(). 22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::vector<DisplaySnapshot*> outputs_; 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |max_configurable_pixels_| represents the maximum number of pixels that 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Configure will support. Tests can use this to force Configure 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to fail if attempting to set a resolution that is higher than what 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a device might support under a given circumstance. 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // A value of 0 means that no limit is enforced and Configure will 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // return success regardless of the resolution. 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int max_configurable_pixels_; 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Result value of GetHDCPState(). 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HDCPState hdcp_state_; 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ActionLogger* log_; // Not owned. 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestNativeDisplayDelegate); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass TestObserver : public DisplayConfigurator::Observer { 2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch explicit TestObserver(DisplayConfigurator* configurator) 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : configurator_(configurator) { 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Reset(); 2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) configurator_->AddObserver(this); 2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~TestObserver() { configurator_->RemoveObserver(this); } 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int num_changes() const { return num_changes_; } 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int num_failures() const { return num_failures_; } 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DisplayConfigurator::DisplayStateList& latest_outputs() const { 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return latest_outputs_; 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MultipleDisplayState latest_failed_state() const { 253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return latest_failed_state_; 254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void Reset() { 2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) num_changes_ = 0; 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) num_failures_ = 0; 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) latest_outputs_.clear(); 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch latest_failed_state_ = MULTIPLE_DISPLAY_STATE_INVALID; 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // DisplayConfigurator::Observer overrides: 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual void OnDisplayModeChanged( 265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DisplayConfigurator::DisplayStateList& outputs) OVERRIDE { 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) num_changes_++; 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) latest_outputs_ = outputs; 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual void OnDisplayModeChangeFailed(MultipleDisplayState failed_new_state) 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OVERRIDE { 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) num_failures_++; 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) latest_failed_state_ = failed_new_state; 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator* configurator_; // Not owned. 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Number of times that OnDisplayMode*() has been called. 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int num_changes_; 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int num_failures_; 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Parameters most recently passed to OnDisplayMode*(). 284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::DisplayStateList latest_outputs_; 285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MultipleDisplayState latest_failed_state_; 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestObserver); 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 290c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass TestStateController : public DisplayConfigurator::StateController { 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TestStateController() : state_(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {} 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~TestStateController() {} 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch void set_state(MultipleDisplayState state) { state_ = state; } 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // DisplayConfigurator::StateController overrides: 298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual MultipleDisplayState GetStateForDisplayIds( 299effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::vector<int64_t>& outputs) const OVERRIDE { 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return state_; 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 302effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual bool GetResolutionForDisplayId(int64_t display_id, 30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Size* size) const OVERRIDE { 304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MultipleDisplayState state_; 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestStateController); 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class TestMirroringController 314c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : public DisplayConfigurator::SoftwareMirroringController { 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TestMirroringController() : software_mirroring_enabled_(false) {} 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~TestMirroringController() {} 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void SetSoftwareMirroring(bool enabled) OVERRIDE { 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) software_mirroring_enabled_ = enabled; 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual bool SoftwareMirroringEnabled() const OVERRIDE { 32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return software_mirroring_enabled_; 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool software_mirroring_enabled_; 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestMirroringController); 33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass DisplayConfiguratorTest : public testing::Test { 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfiguratorTest() 33623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : small_mode_(gfx::Size(1366, 768), false, 60.0f), 33723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) big_mode_(gfx::Size(2560, 1600), false, 60.0f), 33823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) observer_(&configurator_), 33923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) test_api_(&configurator_) {} 340c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual ~DisplayConfiguratorTest() {} 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() OVERRIDE { 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_.reset(new ActionLogger()); 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_display_delegate_ = new TestNativeDisplayDelegate(log_.get()); 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci configurator_.SetDelegateForTesting( 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<NativeDisplayDelegate>(native_display_delegate_)); 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) configurator_.set_state_controller(&state_controller_); 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) configurator_.set_mirroring_controller(&mirroring_controller_); 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 35223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::vector<const DisplayMode*> modes; 35323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(&small_mode_); 35423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 35523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) TestDisplaySnapshot* o = &outputs_[0]; 35623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_current_mode(&small_mode_); 35723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_native_mode(&small_mode_); 35823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_modes(modes); 359c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch o->set_type(DISPLAY_CONNECTION_TYPE_INTERNAL); 36023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_is_aspect_preserving_scaling(true); 36123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_display_id(123); 36223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_has_proper_display_id(true); 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) o = &outputs_[1]; 36523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_current_mode(&big_mode_); 36623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_native_mode(&big_mode_); 36723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(&big_mode_); 36823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_modes(modes); 369c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch o->set_type(DISPLAY_CONNECTION_TYPE_HDMI); 37023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_is_aspect_preserving_scaling(true); 37123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_display_id(456); 37223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) o->set_has_proper_display_id(true); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, false); 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Predefined modes that can be used by outputs. 37823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplayMode small_mode_; 37923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const DisplayMode big_mode_; 38023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Configures |native_display_delegate_| to return the first |num_outputs| 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // entries from 3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |outputs_|. If |send_events| is true, also sends screen-change and 3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // output-change events to |configurator_| and triggers the configure 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // timeout if one was scheduled. 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void UpdateOutputs(size_t num_outputs, bool send_events) { 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_LE(num_outputs, arraysize(outputs_)); 38923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::vector<DisplaySnapshot*> outputs; 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < num_outputs; ++i) 39123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs.push_back(&outputs_[i]); 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_display_delegate_->set_outputs(outputs); 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (send_events) { 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.OnConfigurationChanged(); 3966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); 3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initializes |configurator_| with a single internal display. 4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void InitWithSingleOutput() { 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(1, false); 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) configurator_.Init(false); 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kInitXRandR, 41123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL) 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 41323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop message_loop_; 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestStateController state_controller_; 42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TestMirroringController mirroring_controller_; 423c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator configurator_; 4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TestObserver observer_; 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ActionLogger> log_; 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TestNativeDisplayDelegate* native_display_delegate_; // not owned 427c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::TestApi test_api_; 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 42923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) TestDisplaySnapshot outputs_[2]; 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 432c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorTest); 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 437c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, FindDisplayModeMatchingSize) { 43823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ScopedVector<const DisplayMode> modes; 439d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 440d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Fields are width, height, interlaced, refresh rate. 44123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1920, 1200), false, 60.0)); 442d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Different rates. 44323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 30.0)); 44423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 50.0)); 44523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0)); 44623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 0.0)); 447d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Interlaced vs non-interlaced. 44823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1280, 720), true, 60.0)); 44923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1280, 720), false, 40.0)); 450d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Interlaced only. 45123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 0.0)); 45223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 40.0)); 45323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 60.0)); 454d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Mixed. 45523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1024, 600), true, 60.0)); 45623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1024, 600), false, 40.0)); 45723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1024, 600), false, 50.0)); 458d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Just one interlaced mode. 45923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(640, 480), true, 60.0)); 460d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Refresh rate not available. 46123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(320, 200), false, 0.0)); 462d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 46323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) TestDisplaySnapshot output; 46423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output.set_modes(modes.get()); 46523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 46623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(modes[0], 467c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::FindDisplayModeMatchingSize( 46823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output, gfx::Size(1920, 1200))); 469d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 470d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Should pick highest refresh rate. 47123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(modes[2], 472c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::FindDisplayModeMatchingSize( 47323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output, gfx::Size(1920, 1080))); 474d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 475d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Should pick non-interlaced mode. 47623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(modes[6], 477c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::FindDisplayModeMatchingSize( 47823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output, gfx::Size(1280, 720))); 479d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 480d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Interlaced only. Should pick one with the highest refresh rate in 481d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // interlaced mode. 48223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(modes[9], 483c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::FindDisplayModeMatchingSize( 48423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output, gfx::Size(1024, 768))); 485d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Mixed: Should pick one with the highest refresh rate in 487d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // interlaced mode. 48823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(modes[12], 489c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::FindDisplayModeMatchingSize( 49023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output, gfx::Size(1024, 600))); 491d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Just one interlaced mode. 49323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(modes[13], 494c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::FindDisplayModeMatchingSize( 49523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output, gfx::Size(640, 480))); 496d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 497d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Refresh rate not available. 49823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(modes[14], 499c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::FindDisplayModeMatchingSize( 50023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output, gfx::Size(320, 200))); 501d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 502d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // No mode found. 50323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(NULL, 504c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::FindDisplayModeMatchingSize( 50523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) output, gfx::Size(1440, 900))); 506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 507d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 508c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, ConnectSecondOutput) { 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InitWithSingleOutput(); 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Connect a second output and check that the configurator enters 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // extended mode. 5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 514c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); 5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, true); 51623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kDualHeight = small_mode_.size().height() + 517c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap + 51823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) big_mode_.size().height(); 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 52223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), 52323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[0], 52423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[1]).c_str(), 52523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 52623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], 52723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &big_mode_, 52823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Point(0, 52923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) small_mode_.size().height() + 530c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap)) 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR)); 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 54323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1]) 54423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) .c_str(), 54523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 54623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(), 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 55290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 55390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Disconnect the second output. 5543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(1, true); 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 55923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), 56023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 5653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 567d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Get rid of shared modes to force software mirroring. 56823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &big_mode_)); 569c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); 5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, true); 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 57423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), 57523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[0], 57623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[1]).c_str(), 57723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 57823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], 57923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &big_mode_, 58023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Point(0, 58123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) small_mode_.size().height() + 582c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap)) 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 58890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 590c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR)); 5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear()); 592c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, 593c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.display_state()); 594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled()); 5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 597c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Setting MULTIPLE_DISPLAY_STATE_DUAL_MIRROR should try to reconfigure. 5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 599c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE( 600c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED)); 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(JoinActions(NULL), log_->GetActionsAndClear()); 602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Set back to software mirror mode. 6063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 607c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR)); 6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear()); 609c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, 610c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.display_state()); 611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled()); 6123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Disconnect the second output. 6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(1, true); 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 62023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), 62123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 6263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 629c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, SetDisplayPower) { 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InitWithSingleOutput(); 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 632c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR); 6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, true); 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 63823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1]) 63923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) .c_str(), 64023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 64123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(), 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 6463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Turning off the internal display should switch the external display to 649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // its native mode. 6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 651a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower( 652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, 653c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 65723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1]) 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 65923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(), 66023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(), 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 665c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state()); 6663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // When all displays are turned off, the framebuffer should switch back 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to the mirrored size. 6703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, 672c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 67423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) JoinActions(kGrab, 67523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction( 67623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) small_mode_.size(), &outputs_[0], &outputs_[1]).c_str(), 67723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(), 67823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(), 67923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kUngrab, 68023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL), 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 682c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state()); 683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 6843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Turn all displays on and check that mirroring is still used. 6873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, 689c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 69323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1]) 69423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) .c_str(), 69523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 69623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(), 6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 701c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state()); 702cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 7033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 70490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 705d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Get rid of shared modes to force software mirroring. 70623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &big_mode_)); 707c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR); 7083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 7093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, true); 71023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const int kDualHeight = small_mode_.size().height() + 711c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap + 71223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) big_mode_.size().height(); 7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 71623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), 71723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[0], 71823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[1]).c_str(), 71923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 72023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], 72123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &big_mode_, 72223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Point(0, 72323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) small_mode_.size().height() + 724c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap)) 7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 729c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, 730c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.display_state()); 731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled()); 7323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 73390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 73490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Turning off the internal display should switch the external display to 73590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // its native mode. 7363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 737a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower( 738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, 739c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 74323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1]) 7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 74523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(), 74623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(), 7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 751c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state()); 752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); 7533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 75490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 75590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // When all displays are turned off, the framebuffer should switch back 75690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // to the extended + software mirroring. 7573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, 759c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 76323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), 76423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[0], 76523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[1]).c_str(), 76623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(), 76723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], 76823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, 76923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Point(0, 77023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) small_mode_.size().height() + 771c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap)) 7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 776c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, 777c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.display_state()); 778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled()); 7793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 78190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Turn all displays on and check that mirroring is still used. 7823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, 784c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 78823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), 78923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[0], 79023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[1]).c_str(), 79123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 79223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], 79323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &big_mode_, 79423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Point(0, 79523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) small_mode_.size().height() + 796c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap)) 7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 802c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, 803c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.display_state()); 804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled()); 8053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 808c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, SuspendAndResume) { 809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InitWithSingleOutput(); 810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // No preparation is needed before suspending when the display is already 812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // on. The configurator should still reprobe on resume in case a display 813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // was connected while suspended. 814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) configurator_.SuspendDisplays(); 8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) configurator_.ResumeDisplays(); 8176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); 8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 82123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), 82223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Now turn the display off before suspending and check that the 829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // configurator turns it back on and syncs with the server. 830a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, 831c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 83523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), 83623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(), 8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 8385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 8395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) configurator_.SuspendDisplays(); 8425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 8435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 8445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 84523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), 84623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 8475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 8485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kSync, 8505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 8515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) configurator_.ResumeDisplays(); 8546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); 8555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 8575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 85823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), 85923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If a second, external display is connected, the displays shouldn't be 866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // powered back on before suspending. 867c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR); 8683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, true); 8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 87223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1]) 87323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) .c_str(), 87423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 87523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(), 8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 880a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, 881c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 88323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) JoinActions(kGrab, 88423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction( 88523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) small_mode_.size(), &outputs_[0], &outputs_[1]).c_str(), 88623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(), 88723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(), 88823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kUngrab, 88923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL), 8905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) configurator_.SuspendDisplays(); 893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(JoinActions(kGrab, kUngrab, kSync, NULL), 8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If a display is disconnected while suspended, the configurator should 897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // pick up the change. 8983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(1, false); 899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) configurator_.ResumeDisplays(); 9006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); 9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 90423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), 90523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(), 9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 9085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 911c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, Headless) { 9123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(0, false); 9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 914a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) configurator_.Init(false); 9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 916a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 9175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(JoinActions(kGrab, kInitXRandR, kForceDPMS, kUngrab, NULL), 9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Not much should happen when the display power state is changed while 921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // no displays are connected. 922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, 923c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 9245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear()); 925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, 926c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kSetDisplayPowerNoFlags); 927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(JoinActions(kGrab, kForceDPMS, kUngrab, NULL), 9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Connect an external display and check that it's configured correctly. 93123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_current_mode(outputs_[1].current_mode()); 93223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_native_mode(outputs_[1].native_mode()); 93323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_modes(outputs_[1].modes()); 93423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_type(outputs_[1].type()); 93523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(1, true); 9375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 9385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 94023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(), 94123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &big_mode_, gfx::Point(0, 0)).c_str(), 9425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 9435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 947c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, StartWithTwoOutputs) { 9483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, false); 9495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 950a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) configurator_.Init(false); 9515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 953c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR); 954a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kInitXRandR, 95923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1]) 96023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) .c_str(), 96123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 96223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(), 9635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 9645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 9655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 9665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 969c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, InvalidMultipleDisplayStates) { 9703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(0, false); 9715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 972a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) configurator_.Init(false); 973a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 9743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 975c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS)); 976c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE)); 977c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE( 978c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR)); 979c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE( 980c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED)); 9813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 9823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(3, observer_.num_failures()); 983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(1, true); 9853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 986c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS)); 987c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE)); 988c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE( 989c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR)); 990c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE( 991c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED)); 9923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(1, observer_.num_changes()); 9933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(3, observer_.num_failures()); 994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 995c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); 9963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, true); 9973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer_.Reset(); 998c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS)); 999c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE)); 1000c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR)); 1001c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE( 1002c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED)); 10033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(2, observer_.num_changes()); 10043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(2, observer_.num_failures()); 1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1007c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForDisplaysWithoutId) { 100823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_has_proper_display_id(false); 10093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, false); 1010a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) configurator_.Init(false); 1011c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR); 1012a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 1013c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, 1014c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.display_state()); 10153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 101690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1017c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForDisplaysWithId) { 101823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_has_proper_display_id(true); 10193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateOutputs(2, false); 10203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) configurator_.Init(false); 1021c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR); 1022a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 1023c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state()); 10243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 10253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1026c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, UpdateCachedOutputsEvenAfterFailure) { 102768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InitWithSingleOutput(); 1028c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DisplayConfigurator::DisplayStateList* cached = 1029c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &configurator_.cached_displays(); 103068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ASSERT_EQ(static_cast<size_t>(1), cached->size()); 103123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(outputs_[0].current_mode(), (*cached)[0].display->current_mode()); 103268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 103368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // After connecting a second output, check that it shows up in 1034c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // |cached_displays_| even if an invalid state is requested. 1035c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE); 103668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateOutputs(2, true); 1037c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cached = &configurator_.cached_displays(); 103868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ASSERT_EQ(static_cast<size_t>(2), cached->size()); 103923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(outputs_[0].current_mode(), (*cached)[0].display->current_mode()); 104023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(outputs_[1].current_mode(), (*cached)[1].display->current_mode()); 104168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 104268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1043c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, PanelFitting) { 1044d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Configure the internal display to support only the big mode and the 1045d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // external display to support only the small mode. 104623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_current_mode(&big_mode_); 104723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_native_mode(&big_mode_); 104823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[0].set_modes(std::vector<const DisplayMode*>(1, &big_mode_)); 104923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 105023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[1].set_current_mode(&small_mode_); 105123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[1].set_native_mode(&small_mode_); 105223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &small_mode_)); 1053d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1054d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The small mode should be added to the internal output when requesting 1055d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // mirrored mode. 1056d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UpdateOutputs(2, false); 1057c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR); 1058d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) configurator_.Init(true /* is_panel_fitting_enabled */); 1059a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 1060c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state()); 10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 10625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 10635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kInitXRandR, 106523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetAddOutputModeAction(outputs_[0], &small_mode_).c_str(), 106623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1]) 106723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) .c_str(), 106823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 106923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(), 10705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kForceDPMS, 10715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 10725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 10735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 1074d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1075d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Both outputs should be using the small mode. 1076d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_EQ(1, observer_.num_changes()); 1077d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_EQ(static_cast<size_t>(2), observer_.latest_outputs().size()); 107823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(&small_mode_, observer_.latest_outputs()[0].mirror_mode); 107923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(&small_mode_, 108023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) observer_.latest_outputs()[0].display->current_mode()); 108123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(&small_mode_, observer_.latest_outputs()[1].mirror_mode); 108223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(&small_mode_, 108323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) observer_.latest_outputs()[1].display->current_mode()); 1084d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1085d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Also check that the newly-added small mode is present in the internal 1086d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // snapshot that was passed to the observer (http://crbug.com/289159). 1087c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DisplayConfigurator::DisplayState& state = 1088c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch observer_.latest_outputs()[0]; 108923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ASSERT_NE(state.display->modes().end(), 109023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::find(state.display->modes().begin(), 109123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) state.display->modes().end(), 109223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &small_mode_)); 1093d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 1094d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1095c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, ContentProtection) { 10964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) configurator_.Init(false); 1097a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 10985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_NE(kNoActions, log_->GetActionsAndClear()); 10994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::ContentProtectionClientId id = 1101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.RegisterContentProtectionClient(); 11024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_NE(0u, id); 11034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // One output. 11054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateOutputs(1, true); 11065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_NE(kNoActions, log_->GetActionsAndClear()); 11074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t link_mask = 0; 11084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t protection_mask = 0; 1109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.QueryContentProtectionStatus( 111023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) id, outputs_[0].display_id(), &link_mask, &protection_mask)); 1111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL), link_mask); 1112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE), 11134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) protection_mask); 11145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 11154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Two outputs. 11174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateOutputs(2, true); 11185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_NE(kNoActions, log_->GetActionsAndClear()); 1119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.QueryContentProtectionStatus( 112023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) id, outputs_[1].display_id(), &link_mask, &protection_mask)); 1121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask); 1122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE), 11234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) protection_mask); 11245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 11254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.EnableContentProtection( 1127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch id, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP)); 112823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED), 11295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 11304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Enable protection. 1132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED); 1133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.QueryContentProtectionStatus( 113423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) id, outputs_[1].display_id(), &link_mask, &protection_mask)); 1135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask); 1136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP), 11374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) protection_mask); 11385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 11390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 11400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Protections should be disabled after unregister. 1141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.UnregisterContentProtectionClient(id); 114223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED), 11435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 11444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 11454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, ContentProtectionTwoClients) { 1147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::ContentProtectionClientId client1 = 1148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.RegisterContentProtectionClient(); 1149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::ContentProtectionClientId client2 = 1150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch configurator_.RegisterContentProtectionClient(); 11514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_NE(client1, client2); 11524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) configurator_.Init(false); 1154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) configurator_.ForceInitialConfigure(0); 11554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UpdateOutputs(2, true); 11565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_NE(kNoActions, log_->GetActionsAndClear()); 11574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Clients never know state enableness for methods that they didn't request. 1159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.EnableContentProtection( 1160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP)); 116123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(), 116223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) log_->GetActionsAndClear()); 1163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED); 11644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t link_mask = 0; 11664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t protection_mask = 0; 1167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.QueryContentProtectionStatus( 116823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) client1, outputs_[1].display_id(), &link_mask, &protection_mask)); 1169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask); 1170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP, protection_mask); 1171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.QueryContentProtectionStatus( 117323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) client2, outputs_[1].display_id(), &link_mask, &protection_mask)); 1174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), link_mask); 1175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask); 11764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Protections will be disabled only if no more clients request them. 1178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.EnableContentProtection( 1179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE)); 11801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 1181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(configurator_.EnableContentProtection( 1182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE)); 1183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED).c_str(), 1184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch log_->GetActionsAndClear()); 11854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 11864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(DisplayConfiguratorTest, ContentProtectionTwoClientsEnable) { 11881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DisplayConfigurator::ContentProtectionClientId client1 = 11891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci configurator_.RegisterContentProtectionClient(); 11901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DisplayConfigurator::ContentProtectionClientId client2 = 11911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci configurator_.RegisterContentProtectionClient(); 11921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_NE(client1, client2); 11931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 11941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci configurator_.Init(false); 11951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci configurator_.ForceInitialConfigure(0); 11961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UpdateOutputs(2, true); 11971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_->GetActionsAndClear(); 11981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 11991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Only enable once if HDCP is enabling. 12001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(configurator_.EnableContentProtection( 12011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP)); 12021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci native_display_delegate_->set_hdcp_state(HDCP_STATE_DESIRED); 12031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(configurator_.EnableContentProtection( 12041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP)); 12051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(), 12061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_->GetActionsAndClear()); 12071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED); 12081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 12091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Don't enable again if HDCP is already active. 12101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(configurator_.EnableContentProtection( 12111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP)); 12121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(configurator_.EnableContentProtection( 12131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP)); 12141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); 12151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 12161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(DisplayConfiguratorTest, HandleConfigureCrtcFailure) { 12185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) InitWithSingleOutput(); 12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 122023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ScopedVector<const DisplayMode> modes; 1221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // The first mode is the mode we are requesting DisplayConfigurator to choose. 122223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // The test will be setup so that this mode will fail and it will have to 122323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // choose the next best option. 122423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(2560, 1600), false, 60.0)); 122523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1024, 768), false, 60.0)); 122623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1280, 720), false, 60.0)); 122723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 60.0)); 122823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0)); 12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (unsigned int i = 0; i < arraysize(outputs_); i++) { 123123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[i].set_modes(modes.get()); 123223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[i].set_current_mode(modes[0]); 123323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) outputs_[i].set_native_mode(modes[0]); 12345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // First test simply fails in MULTIPLE_DISPLAY_STATE_SINGLE mode. This is 1237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // probably unrealistic but we want to make sure any assumptions don't creep 1238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // in. 12395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_display_delegate_->set_max_configurable_pixels( 124023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes[2]->size().GetArea()); 1241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE); 12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateOutputs(1, true); 12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 12455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 12465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 124723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(), 124823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(), 124923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(), 125023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], modes[2], gfx::Point(0, 0)).c_str(), 12515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 12525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 12535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 12545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This test should attempt to configure a mirror mode that will not succeed 12565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and should end up in extended mode. 12575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_display_delegate_->set_max_configurable_pixels( 125823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes[3]->size().GetArea()); 1259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR); 12605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateOutputs(2, true); 12615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ( 12635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JoinActions( 12645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kGrab, 126523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction(modes[0]->size(), &outputs_[0], &outputs_[1]) 12665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 126723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(), 12685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // First mode tried is expected to fail and it will 12695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // retry wil the 4th mode in the list. 127023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(), 12715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Then attempt to configure crtc1 with the first mode. 127223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], modes[0], gfx::Point(0, 0)).c_str(), 127323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], modes[3], gfx::Point(0, 0)).c_str(), 12745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Since it was requested to go into mirror mode 12755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and the configured modes were different, it 12765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // should now try and setup a valid configurable 12775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // extended mode. 127823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetFramebufferAction( 127923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Size(modes[0]->size().width(), 128023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes[0]->size().height() + modes[0]->size().height() + 1281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap), 128223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[0], 128323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &outputs_[1]).c_str(), 128423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(), 128523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(), 128623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], 128723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes[0], 128823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Point(0, 128923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes[0]->size().height() + 1290c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap)) 12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 129223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetCrtcAction(outputs_[1], 129323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes[3], 129423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::Point(0, 129523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) modes[0]->size().height() + 1296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayConfigurator::kVerticalGap)) 12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .c_str(), 12985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kUngrab, 12995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL), 13005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_->GetActionsAndClear()); 13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 13025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests that power state requests are saved after failed configuration attempts 13041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// so they can be reused later: http://crosbug.com/p/31571 13051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(DisplayConfiguratorTest, SaveDisplayPowerStateOnConfigFailure) { 13061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Start out with two displays in extended mode. 13071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); 13081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci configurator_.Init(false); 13091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci configurator_.ForceInitialConfigure(0); 13101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_->GetActionsAndClear(); 13111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 13121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Turn off the internal display, simulating docked mode. 13131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(configurator_.SetDisplayPower( 13141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, 13151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DisplayConfigurator::kSetDisplayPowerNoFlags)); 13161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_->GetActionsAndClear(); 13171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 13181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Make all subsequent configuration requests fail and try to turn the 13191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // internal display back on. 13201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci native_display_delegate_->set_max_configurable_pixels(1); 13211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(configurator_.SetDisplayPower( 13221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chromeos::DISPLAY_POWER_ALL_ON, 13231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DisplayConfigurator::kSetDisplayPowerNoFlags)); 13241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_->GetActionsAndClear(); 13251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 13261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Simulate the external display getting disconnected and check that the 13271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // internal display is turned on (i.e. DISPLAY_POWER_ALL_ON is used) rather 13281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // than the earlier DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON state. 13291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci native_display_delegate_->set_max_configurable_pixels(0); 13301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UpdateOutputs(1, true); 13311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ( 13321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci JoinActions( 13331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kGrab, 13341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), 13351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), 13361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kUngrab, 13371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL), 13381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_->GetActionsAndClear()); 13391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 13401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace ui 1342