diff options
author | dnicoara@chromium.org <dnicoara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-05 16:24:54 +0000 |
---|---|---|
committer | dnicoara@chromium.org <dnicoara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-05 16:24:54 +0000 |
commit | b036effd03c9fc5e49fba2d748a214b862a2d8eb (patch) | |
tree | 01785219f45113bd3b116fc2d6e5a2be9c55b218 /chromeos/display | |
parent | f406ebd11196b5e20a3b7aba3253af79be8845c5 (diff) | |
download | chromium_src-b036effd03c9fc5e49fba2d748a214b862a2d8eb.zip chromium_src-b036effd03c9fc5e49fba2d748a214b862a2d8eb.tar.gz chromium_src-b036effd03c9fc5e49fba2d748a214b862a2d8eb.tar.bz2 |
Split touchscreen configuration into separate delegate
Touchscreen configuration shouldn't be as tightly coupled with display
configuration. In order to simplify the refactoring of OutputConfigurator &
display configuration, I'm breaking down the OutputConfigurator::Delegate into
smaller delegates that focus on more specific tasks. This should allow us to
refactor each component separately and in smaller chunks.
BUG=333413
Review URL: https://codereview.chromium.org/150403004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249019 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/display')
-rw-r--r-- | chromeos/display/output_configurator.cc | 13 | ||||
-rw-r--r-- | chromeos/display/output_configurator.h | 33 | ||||
-rw-r--r-- | chromeos/display/output_configurator_unittest.cc | 1079 | ||||
-rw-r--r-- | chromeos/display/real_output_configurator_delegate.cc | 157 | ||||
-rw-r--r-- | chromeos/display/real_output_configurator_delegate.h | 11 | ||||
-rw-r--r-- | chromeos/display/touchscreen_delegate_x11.cc | 174 | ||||
-rw-r--r-- | chromeos/display/touchscreen_delegate_x11.h | 35 |
7 files changed, 892 insertions, 610 deletions
diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc index 852b794..9ea702c 100644 --- a/chromeos/display/output_configurator.cc +++ b/chromeos/display/output_configurator.cc @@ -16,6 +16,7 @@ #include "base/time/time.h" #include "chromeos/display/output_util.h" #include "chromeos/display/real_output_configurator_delegate.h" +#include "chromeos/display/touchscreen_delegate_x11.h" namespace chromeos { @@ -249,6 +250,11 @@ void OutputConfigurator::SetDelegateForTesting(scoped_ptr<Delegate> delegate) { configure_display_ = true; } +void OutputConfigurator::SetTouchscreenDelegateForTesting( + scoped_ptr<TouchscreenDelegate> delegate) { + touchscreen_delegate_ = delegate.Pass(); +} + void OutputConfigurator::SetInitialDisplayPower(DisplayPowerState power_state) { DCHECK_EQ(output_state_, STATE_INVALID); power_state_ = power_state; @@ -261,6 +267,9 @@ void OutputConfigurator::Init(bool is_panel_fitting_enabled) { if (!delegate_) delegate_.reset(new RealOutputConfiguratorDelegate()); + + if (!touchscreen_delegate_) + touchscreen_delegate_.reset(new TouchscreenDelegateX11()); } void OutputConfigurator::Start(uint32 background_color_argb) { @@ -660,6 +669,7 @@ void OutputConfigurator::ScheduleConfigureOutputs() { void OutputConfigurator::UpdateCachedOutputs() { cached_outputs_ = delegate_->GetOutputs(); + touchscreen_delegate_->AssociateTouchscreens(&cached_outputs_); // Set |selected_mode| fields. for (size_t i = 0; i < cached_outputs_.size(); ++i) { @@ -1001,7 +1011,8 @@ bool OutputConfigurator::EnterState( if (configure_succeeded) { if (output.touch_device_id) - delegate_->ConfigureCTM(output.touch_device_id, output.transform); + touchscreen_delegate_->ConfigureCTM(output.touch_device_id, + output.transform); cached_outputs_[i] = updated_outputs[i]; } else { all_succeeded = false; diff --git a/chromeos/display/output_configurator.h b/chromeos/display/output_configurator.h index 8a8b36d..41126c2 100644 --- a/chromeos/display/output_configurator.h +++ b/chromeos/display/output_configurator.h @@ -243,14 +243,6 @@ class CHROMEOS_EXPORT OutputConfigurator int height, const std::vector<OutputConfigurator::OutputSnapshot>& outputs) = 0; - // Configures XInput's Coordinate Transformation Matrix property. - // |touch_device_id| the ID of the touchscreen device to configure. - // |ctm| contains the desired transformation parameters. The offsets - // in it should be normalized so that 1 corresponds to the X or Y axis - // size for the corresponding offset. - virtual void ConfigureCTM(int touch_device_id, - const CoordinateTransformation& ctm) = 0; - // Sends a D-Bus message to the power manager telling it that the // machine is or is not projecting. virtual void SendProjectingStateToPowerManager(bool projecting) = 0; @@ -262,6 +254,27 @@ class CHROMEOS_EXPORT OutputConfigurator virtual bool SetHDCPState(RROutput id, HDCPState state) = 0; }; + class TouchscreenDelegate { + public: + virtual ~TouchscreenDelegate() {} + + // Searches for touchscreens among input devices, + // and tries to match them up to screens in |outputs|. + // |outputs| is an array of detected screens. + // If a touchscreen with same resolution as an output's native mode + // is detected, its id will be stored in this output. + virtual void AssociateTouchscreens( + std::vector<OutputSnapshot>* outputs) = 0; + + // Configures XInput's Coordinate Transformation Matrix property. + // |touch_device_id| the ID of the touchscreen device to configure. + // |ctm| contains the desired transformation parameters. The offsets + // in it should be normalized so that 1 corresponds to the X or Y axis + // size for the corresponding offset. + virtual void ConfigureCTM(int touch_device_id, + const CoordinateTransformation& ctm) = 0; + }; + // Helper class used by tests. class TestApi { public: @@ -340,6 +353,9 @@ class CHROMEOS_EXPORT OutputConfigurator // true. Should be called before Init(). void SetDelegateForTesting(scoped_ptr<Delegate> delegate); + void SetTouchscreenDelegateForTesting( + scoped_ptr<TouchscreenDelegate> delegate); + // Sets the initial value of |power_state_|. Must be called before Start(). void SetInitialDisplayPower(DisplayPowerState power_state); @@ -512,6 +528,7 @@ class CHROMEOS_EXPORT OutputConfigurator StateController* state_controller_; SoftwareMirroringController* mirroring_controller_; scoped_ptr<Delegate> delegate_; + scoped_ptr<TouchscreenDelegate> touchscreen_delegate_; // Used to enable modes which rely on panel fitting. bool is_panel_fitting_enabled_; diff --git a/chromeos/display/output_configurator_unittest.cc b/chromeos/display/output_configurator_unittest.cc index 7c74bd3..fd62430 100644 --- a/chromeos/display/output_configurator_unittest.cc +++ b/chromeos/display/output_configurator_unittest.cc @@ -97,13 +97,70 @@ std::string JoinActions(const char* action, ...) { return actions; } +class ActionLogger { + public: + ActionLogger() {} + + void AppendAction(const std::string& action) { + if (!actions_.empty()) + actions_ += ","; + actions_ += action; + } + + // Returns a comma-separated string describing the actions that were + // requested since the previous call to GetActionsAndClear() (i.e. + // results are non-repeatable). + std::string GetActionsAndClear() { + std::string actions = actions_; + actions_.clear(); + return actions; + } + + private: + std::string actions_; + + DISALLOW_COPY_AND_ASSIGN(ActionLogger); +}; + +class TestTouchscreenDelegate : public OutputConfigurator::TouchscreenDelegate { + public: + // Ownership of |log| remains with the caller. + explicit TestTouchscreenDelegate(ActionLogger* log) : log_(log) {} + virtual ~TestTouchscreenDelegate() {} + + const OutputConfigurator::CoordinateTransformation& GetCTM( + int touch_device_id) { + return ctms_[touch_device_id]; + } + + // OutputConfigurator::TouchscreenDelegate implementation: + virtual void AssociateTouchscreens( + std::vector<OutputConfigurator::OutputSnapshot>* outputs) OVERRIDE {} + virtual void ConfigureCTM( + int touch_device_id, + const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE { + log_->AppendAction(GetCTMAction(touch_device_id, ctm)); + ctms_[touch_device_id] = ctm; + } + + private: + ActionLogger* log_; // Not owned. + + // Most-recently-configured transformation matrices, keyed by touch device ID. + std::map<int, OutputConfigurator::CoordinateTransformation> ctms_; + + DISALLOW_COPY_AND_ASSIGN(TestTouchscreenDelegate); +}; + class TestDelegate : public OutputConfigurator::Delegate { public: static const int kXRandREventBase = 10; - TestDelegate() + // Ownership of |log| remains with the caller. + explicit TestDelegate(ActionLogger* log) : max_configurable_pixels_(0), - hdcp_state_(HDCP_STATE_UNDESIRED) {} + hdcp_state_(HDCP_STATE_UNDESIRED), + log_(log) {} virtual ~TestDelegate() {} const std::vector<OutputConfigurator::OutputSnapshot>& outputs() const { @@ -120,47 +177,35 @@ class TestDelegate : public OutputConfigurator::Delegate { void set_hdcp_state(HDCPState state) { hdcp_state_ = state; } - // Returns a comma-separated string describing the actions that were - // requested since the previous call to GetActionsAndClear() (i.e. - // results are non-repeatable). - std::string GetActionsAndClear() { - std::string actions = actions_; - actions_.clear(); - return actions; - } - - const OutputConfigurator::CoordinateTransformation& get_ctm( - int touch_device_id) { - return ctms_[touch_device_id]; - } - // OutputConfigurator::Delegate overrides: virtual void InitXRandRExtension(int* event_base) OVERRIDE { - AppendAction(kInitXRandR); + log_->AppendAction(kInitXRandR); *event_base = kXRandREventBase; } - virtual void UpdateXRandRConfiguration( - const base::NativeEvent& event) OVERRIDE { AppendAction(kUpdateXRandR); } - virtual void GrabServer() OVERRIDE { AppendAction(kGrab); } - virtual void UngrabServer() OVERRIDE { AppendAction(kUngrab); } - virtual void SyncWithServer() OVERRIDE { AppendAction(kSync); } + virtual void UpdateXRandRConfiguration(const base::NativeEvent& event) + OVERRIDE { + log_->AppendAction(kUpdateXRandR); + } + virtual void GrabServer() OVERRIDE { log_->AppendAction(kGrab); } + virtual void UngrabServer() OVERRIDE { log_->AppendAction(kUngrab); } + virtual void SyncWithServer() OVERRIDE { log_->AppendAction(kSync); } virtual void SetBackgroundColor(uint32 color_argb) OVERRIDE { - AppendAction(GetBackgroundAction(color_argb)); + log_->AppendAction(GetBackgroundAction(color_argb)); } - virtual void ForceDPMSOn() OVERRIDE { AppendAction(kForceDPMS); } + virtual void ForceDPMSOn() OVERRIDE { log_->AppendAction(kForceDPMS); } virtual std::vector<OutputConfigurator::OutputSnapshot> GetOutputs() OVERRIDE { return outputs_; } virtual void AddOutputMode(RROutput output, RRMode mode) OVERRIDE { - AppendAction(GetAddOutputModeAction(output, mode)); + log_->AppendAction(GetAddOutputModeAction(output, mode)); } virtual bool ConfigureCrtc(RRCrtc crtc, RRMode mode, RROutput output, int x, int y) OVERRIDE { - AppendAction(GetCrtcAction(crtc, x, y, mode, output)); + log_->AppendAction(GetCrtcAction(crtc, x, y, mode, output)); if (max_configurable_pixels_ == 0) return true; @@ -181,20 +226,14 @@ class TestDelegate : public OutputConfigurator::Delegate { int width, int height, const std::vector<OutputConfigurator::OutputSnapshot>& outputs) OVERRIDE { - AppendAction( + log_->AppendAction( GetFramebufferAction(width, height, outputs.size() >= 1 ? outputs[0].crtc : 0, outputs.size() >= 2 ? outputs[1].crtc : 0)); } - virtual void ConfigureCTM( - int touch_device_id, - const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE { - AppendAction(GetCTMAction(touch_device_id, ctm)); - ctms_[touch_device_id] = ctm; - } virtual void SendProjectingStateToPowerManager(bool projecting) OVERRIDE { - AppendAction(projecting ? kProjectingOn : kProjectingOff); + log_->AppendAction(projecting ? kProjectingOn : kProjectingOff); } virtual bool GetHDCPState(RROutput id, HDCPState* state) OVERRIDE { @@ -203,29 +242,11 @@ class TestDelegate : public OutputConfigurator::Delegate { } virtual bool SetHDCPState(RROutput id, HDCPState state) OVERRIDE { - AppendAction(GetSetHDCPStateAction(id, state)); + log_->AppendAction(GetSetHDCPStateAction(id, state)); return true; } private: - struct ModeDetails { - ModeDetails() : width(0), height(0), interlaced(false) {} - ModeDetails(int width, int height, bool interlaced) - : width(width), - height(height), - interlaced(interlaced) {} - - int width; - int height; - bool interlaced; - }; - - void AppendAction(const std::string& action) { - if (!actions_.empty()) - actions_ += ","; - actions_ += action; - } - OutputConfigurator::OutputSnapshot* GetOutputFromId(RROutput output_id) { for (unsigned int i = 0; i < outputs_.size(); i++) { if (outputs_[i].output == output_id) @@ -234,16 +255,9 @@ class TestDelegate : public OutputConfigurator::Delegate { return NULL; } - std::map<RRMode, ModeDetails> modes_; - - // Most-recently-configured transformation matrices, keyed by touch device ID. - std::map<int, OutputConfigurator::CoordinateTransformation> ctms_; - // Outputs to be returned by GetOutputs(). std::vector<OutputConfigurator::OutputSnapshot> outputs_; - std::string actions_; - // |max_configurable_pixels_| represents the maximum number of pixels that // ConfigureCrtc will support. Tests can use this to force ConfigureCrtc // to fail if attempting to set a resolution that is higher than what @@ -255,6 +269,8 @@ class TestDelegate : public OutputConfigurator::Delegate { // Result value of GetHDCPState(). HDCPState hdcp_state_; + ActionLogger* log_; // Not owned. + DISALLOW_COPY_AND_ASSIGN(TestDelegate); }; @@ -371,9 +387,17 @@ class OutputConfiguratorTest : public testing::Test { virtual ~OutputConfiguratorTest() {} virtual void SetUp() OVERRIDE { - delegate_ = new TestDelegate(); + log_.reset(new ActionLogger()); + + delegate_ = new TestDelegate(log_.get()); configurator_.SetDelegateForTesting( scoped_ptr<OutputConfigurator::Delegate>(delegate_)); + + touchscreen_delegate_ = new TestTouchscreenDelegate(log_.get()); + configurator_.SetTouchscreenDelegateForTesting( + scoped_ptr<OutputConfigurator::TouchscreenDelegate>( + touchscreen_delegate_)); + configurator_.set_state_controller(&state_controller_); configurator_.set_mirroring_controller(&mirroring_controller_); @@ -440,17 +464,24 @@ class OutputConfiguratorTest : public testing::Test { // Initializes |configurator_| with a single internal display. void InitWithSingleOutput() { UpdateOutputs(1, false); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); configurator_.Init(false); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); configurator_.Start(0); - EXPECT_EQ(JoinActions(kGrab, kInitXRandR, - GetFramebufferAction(kSmallModeWidth, - kSmallModeHeight, outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - kForceDPMS, kUngrab, kProjectingOff, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + kInitXRandR, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output) + .c_str(), + kForceDPMS, + kUngrab, + kProjectingOff, + NULL), + log_->GetActionsAndClear()); } base::MessageLoop message_loop_; @@ -458,7 +489,9 @@ class OutputConfiguratorTest : public testing::Test { TestMirroringController mirroring_controller_; OutputConfigurator configurator_; TestObserver observer_; + scoped_ptr<ActionLogger> log_; TestDelegate* delegate_; // not owned + TestTouchscreenDelegate* touchscreen_delegate_; // not owned OutputConfigurator::TestApi test_api_; OutputConfigurator::OutputSnapshot outputs_[2]; @@ -547,43 +580,61 @@ TEST_F(OutputConfiguratorTest, ConnectSecondOutput) { UpdateOutputs(2, true); const int kDualHeight = kSmallModeHeight + OutputConfigurator::kVerticalGap + kBigModeHeight; - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kBigModeWidth, kDualHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, - kSmallModeHeight + OutputConfigurator::kVerticalGap, - kBigModeId, outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction( + kBigModeWidth, kDualHeight, outputs_[0].crtc, outputs_[1].crtc) + .c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + kSmallModeHeight + OutputConfigurator::kVerticalGap, + kBigModeId, + outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); observer_.Reset(); EXPECT_TRUE(configurator_.SetDisplayMode(STATE_DUAL_MIRROR)); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kUngrab, + NULL), + log_->GetActionsAndClear()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); // Disconnect the second output. observer_.Reset(); UpdateOutputs(1, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - kUngrab, kProjectingOff, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + kUngrab, + kProjectingOff, + NULL), + log_->GetActionsAndClear()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -591,21 +642,29 @@ TEST_F(OutputConfiguratorTest, ConnectSecondOutput) { outputs_[1].mode_infos.erase(kSmallModeId); state_controller_.set_state(STATE_DUAL_EXTENDED); UpdateOutputs(2, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kBigModeWidth, kDualHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, - kSmallModeHeight + OutputConfigurator::kVerticalGap, - kBigModeId, outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction( + kBigModeWidth, kDualHeight, outputs_[0].crtc, outputs_[1].crtc) + .c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + kSmallModeHeight + OutputConfigurator::kVerticalGap, + kBigModeId, + outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); observer_.Reset(); EXPECT_TRUE(configurator_.SetDisplayMode(STATE_DUAL_MIRROR)); - EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), delegate_->GetActionsAndClear()); + EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear()); EXPECT_EQ(STATE_DUAL_EXTENDED, configurator_.output_state()); EXPECT_TRUE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -613,15 +672,14 @@ TEST_F(OutputConfiguratorTest, ConnectSecondOutput) { // Setting STATE_DUAL_MIRROR should try to reconfigure. observer_.Reset(); EXPECT_TRUE(configurator_.SetDisplayMode(STATE_DUAL_EXTENDED)); - EXPECT_EQ(JoinActions(NULL), delegate_->GetActionsAndClear()); + EXPECT_EQ(JoinActions(NULL), log_->GetActionsAndClear()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); // Set back to software mirror mode. observer_.Reset(); EXPECT_TRUE(configurator_.SetDisplayMode(STATE_DUAL_MIRROR)); - EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear()); EXPECT_EQ(STATE_DUAL_EXTENDED, configurator_.output_state()); EXPECT_TRUE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -629,13 +687,18 @@ TEST_F(OutputConfiguratorTest, ConnectSecondOutput) { // Disconnect the second output. observer_.Reset(); UpdateOutputs(1, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - kUngrab, kProjectingOff, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + kUngrab, + kProjectingOff, + NULL), + log_->GetActionsAndClear()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); } @@ -646,15 +709,22 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) { state_controller_.set_state(STATE_DUAL_MIRROR); observer_.Reset(); UpdateOutputs(2, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -663,15 +733,19 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) { observer_.Reset(); configurator_.SetDisplayPower(DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kBigModeWidth, kBigModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, 0, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kBigModeId, - outputs_[1].output).c_str(), - kForceDPMS, kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kBigModeWidth, kBigModeHeight, outputs_[0].crtc, outputs_[1].crtc) + .c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, 0, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, 0, 0, kBigModeId, outputs_[1].output) + .c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); EXPECT_EQ(STATE_SINGLE, configurator_.output_state()); EXPECT_EQ(1, observer_.num_changes()); @@ -680,15 +754,18 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) { observer_.Reset(); configurator_.SetDisplayPower(DISPLAY_POWER_ALL_OFF, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, 0, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, 0, - outputs_[1].output).c_str(), - kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, 0, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, 0, 0, 0, outputs_[1].output).c_str(), + kUngrab, + NULL), + log_->GetActionsAndClear()); EXPECT_EQ(STATE_DUAL_MIRROR, configurator_.output_state()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -697,15 +774,21 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) { observer_.Reset(); configurator_.SetDisplayPower(DISPLAY_POWER_ALL_ON, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kForceDPMS, kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); EXPECT_EQ(STATE_DUAL_MIRROR, configurator_.output_state()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -717,16 +800,24 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) { UpdateOutputs(2, true); const int kDualHeight = kSmallModeHeight + OutputConfigurator::kVerticalGap + kBigModeHeight; - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kBigModeWidth, kDualHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, - kSmallModeHeight + OutputConfigurator::kVerticalGap, - kBigModeId, outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction( + kBigModeWidth, kDualHeight, outputs_[0].crtc, outputs_[1].crtc) + .c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + kSmallModeHeight + OutputConfigurator::kVerticalGap, + kBigModeId, + outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); EXPECT_EQ(STATE_DUAL_EXTENDED, configurator_.output_state()); EXPECT_TRUE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -736,15 +827,19 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) { observer_.Reset(); configurator_.SetDisplayPower(DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kBigModeWidth, kBigModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, 0, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kBigModeId, - outputs_[1].output).c_str(), - kForceDPMS, kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kBigModeWidth, kBigModeHeight, outputs_[0].crtc, outputs_[1].crtc) + .c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, 0, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, 0, 0, kBigModeId, outputs_[1].output) + .c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); EXPECT_EQ(STATE_SINGLE, configurator_.output_state()); EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -754,16 +849,21 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) { observer_.Reset(); configurator_.SetDisplayPower(DISPLAY_POWER_ALL_OFF, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kBigModeWidth, kDualHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, 0, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, - kSmallModeHeight + OutputConfigurator::kVerticalGap, - 0, outputs_[1].output).c_str(), - kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kBigModeWidth, kDualHeight, outputs_[0].crtc, outputs_[1].crtc) + .c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, 0, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + kSmallModeHeight + OutputConfigurator::kVerticalGap, + 0, + outputs_[1].output).c_str(), + kUngrab, + NULL), + log_->GetActionsAndClear()); EXPECT_EQ(STATE_DUAL_EXTENDED, configurator_.output_state()); EXPECT_TRUE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -772,16 +872,23 @@ TEST_F(OutputConfiguratorTest, SetDisplayPower) { observer_.Reset(); configurator_.SetDisplayPower(DISPLAY_POWER_ALL_ON, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kBigModeWidth, kDualHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, - kSmallModeHeight + OutputConfigurator::kVerticalGap, - kBigModeId, outputs_[1].output).c_str(), - kForceDPMS, kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kBigModeWidth, kDualHeight, outputs_[0].crtc, outputs_[1].crtc) + .c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + kSmallModeHeight + OutputConfigurator::kVerticalGap, + kBigModeId, + outputs_[1].output).c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); EXPECT_EQ(STATE_DUAL_EXTENDED, configurator_.output_state()); EXPECT_TRUE(mirroring_controller_.software_mirroring_enabled()); EXPECT_EQ(1, observer_.num_changes()); @@ -792,40 +899,46 @@ TEST_F(OutputConfiguratorTest, Casting) { // Notify configurator that casting session is started. configurator_.OnCastingSessionStartedOrStopped(true); - EXPECT_EQ(kProjectingOn, delegate_->GetActionsAndClear()); + EXPECT_EQ(kProjectingOn, log_->GetActionsAndClear()); // Verify that the configurator keeps a count of active casting sessions // instead of treating it as a single global state. configurator_.OnCastingSessionStartedOrStopped(true); - EXPECT_EQ(kProjectingOn, delegate_->GetActionsAndClear()); + EXPECT_EQ(kProjectingOn, log_->GetActionsAndClear()); configurator_.OnCastingSessionStartedOrStopped(false); - EXPECT_EQ(kProjectingOn, delegate_->GetActionsAndClear()); + EXPECT_EQ(kProjectingOn, log_->GetActionsAndClear()); // Turn all displays off and check that projecting is not turned off. configurator_.SetDisplayPower(DISPLAY_POWER_ALL_OFF, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, 0, - outputs_[0].output).c_str(), - kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, 0, outputs_[0].output).c_str(), + kUngrab, + NULL), + log_->GetActionsAndClear()); // Turn all displays back on. configurator_.SetDisplayPower(DISPLAY_POWER_ALL_ON, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - kForceDPMS, kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); // Notify configurator that casting session is ended. configurator_.OnCastingSessionStartedOrStopped(false); - EXPECT_EQ(kProjectingOff, delegate_->GetActionsAndClear()); + EXPECT_EQ(kProjectingOff, log_->GetActionsAndClear()); } TEST_F(OutputConfiguratorTest, SuspendAndResume) { @@ -835,143 +948,183 @@ TEST_F(OutputConfiguratorTest, SuspendAndResume) { // on. The configurator should still reprobe on resume in case a display // was connected while suspended. configurator_.SuspendDisplays(); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); configurator_.ResumeDisplays(); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - kForceDPMS, kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); // Now turn the display off before suspending and check that the // configurator turns it back on and syncs with the server. configurator_.SetDisplayPower(DISPLAY_POWER_ALL_OFF, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, 0, - outputs_[0].output).c_str(), - kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, 0, outputs_[0].output).c_str(), + kUngrab, + NULL), + log_->GetActionsAndClear()); configurator_.SuspendDisplays(); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - kForceDPMS, kUngrab, kSync, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + kForceDPMS, + kUngrab, + kSync, + NULL), + log_->GetActionsAndClear()); configurator_.ResumeDisplays(); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - kForceDPMS, kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); // If a second, external display is connected, the displays shouldn't be // powered back on before suspending. state_controller_.set_state(STATE_DUAL_MIRROR); UpdateOutputs(2, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); configurator_.SetDisplayPower(DISPLAY_POWER_ALL_OFF, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, 0, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, 0, - outputs_[1].output).c_str(), - kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, 0, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, 0, 0, 0, outputs_[1].output).c_str(), + kUngrab, + NULL), + log_->GetActionsAndClear()); configurator_.SuspendDisplays(); EXPECT_EQ(JoinActions(kGrab, kUngrab, kSync, NULL), - delegate_->GetActionsAndClear()); + log_->GetActionsAndClear()); // If a display is disconnected while suspended, the configurator should // pick up the change. UpdateOutputs(1, false); configurator_.ResumeDisplays(); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, 0, - outputs_[0].output).c_str(), - kUngrab, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, 0, outputs_[0].output).c_str(), + kUngrab, + NULL), + log_->GetActionsAndClear()); } TEST_F(OutputConfiguratorTest, Headless) { UpdateOutputs(0, false); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); configurator_.Init(false); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); configurator_.Start(0); - EXPECT_EQ(JoinActions(kGrab, kInitXRandR, kForceDPMS, kUngrab, - kProjectingOff, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ(JoinActions( + kGrab, kInitXRandR, kForceDPMS, kUngrab, kProjectingOff, NULL), + log_->GetActionsAndClear()); // Not much should happen when the display power state is changed while // no displays are connected. configurator_.SetDisplayPower(DISPLAY_POWER_ALL_OFF, OutputConfigurator::kSetDisplayPowerNoFlags); - EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), delegate_->GetActionsAndClear()); + EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear()); configurator_.SetDisplayPower(DISPLAY_POWER_ALL_ON, OutputConfigurator::kSetDisplayPowerNoFlags); EXPECT_EQ(JoinActions(kGrab, kForceDPMS, kUngrab, NULL), - delegate_->GetActionsAndClear()); + log_->GetActionsAndClear()); // Connect an external display and check that it's configured correctly. outputs_[0] = outputs_[1]; UpdateOutputs(1, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kBigModeWidth, kBigModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kBigModeId, - outputs_[0].output).c_str(), - kUngrab, kProjectingOff, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction( + kBigModeWidth, kBigModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, kBigModeId, outputs_[0].output) + .c_str(), + kUngrab, + kProjectingOff, + NULL), + log_->GetActionsAndClear()); } TEST_F(OutputConfiguratorTest, StartWithTwoOutputs) { UpdateOutputs(2, false); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); configurator_.Init(false); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); state_controller_.set_state(STATE_DUAL_MIRROR); configurator_.Start(0); - EXPECT_EQ(JoinActions(kGrab, kInitXRandR, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kForceDPMS, kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + kInitXRandR, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kForceDPMS, + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); } TEST_F(OutputConfiguratorTest, InvalidOutputStates) { UpdateOutputs(0, false); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); configurator_.Init(false); configurator_.Start(0); observer_.Reset(); @@ -1027,14 +1180,14 @@ TEST_F(OutputConfiguratorTest, AvoidUnnecessaryProbes) { // the output change events don't trigger an additional probe, which can // block the UI thread. test_api_.SendScreenChangeEvent(); - EXPECT_EQ(kUpdateXRandR, delegate_->GetActionsAndClear()); + EXPECT_EQ(kUpdateXRandR, log_->GetActionsAndClear()); test_api_.SendOutputChangeEvent( outputs_[0].output, outputs_[0].crtc, outputs_[0].current_mode, true); test_api_.SendOutputChangeEvent( outputs_[1].output, outputs_[1].crtc, outputs_[1].current_mode, false); EXPECT_FALSE(test_api_.TriggerConfigureTimeout()); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); // Send an event stating that the second output is connected and check // that it gets updated. @@ -1043,73 +1196,102 @@ TEST_F(OutputConfiguratorTest, AvoidUnnecessaryProbes) { test_api_.SendOutputChangeEvent( outputs_[1].output, outputs_[1].crtc, outputs_[1].current_mode, true); EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); // An event about the second output changing modes should trigger another // reconfigure. test_api_.SendOutputChangeEvent( outputs_[1].output, outputs_[1].crtc, outputs_[1].native_mode, true); EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); // Disconnect the second output. UpdateOutputs(1, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - kUngrab, kProjectingOff, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction( + kSmallModeWidth, kSmallModeHeight, outputs_[0].crtc, 0).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + kUngrab, + kProjectingOff, + NULL), + log_->GetActionsAndClear()); // An additional event about the second output being disconnected should // be ignored. test_api_.SendOutputChangeEvent( outputs_[1].output, outputs_[1].crtc, outputs_[1].current_mode, false); EXPECT_FALSE(test_api_.TriggerConfigureTimeout()); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); // Lower the limit for which the delegate will succeed, which should result // in the second output sticking with its native mode. delegate_->set_max_configurable_pixels(1); UpdateOutputs(2, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - GetFramebufferAction(kBigModeWidth, - kSmallModeHeight + kBigModeHeight + - OutputConfigurator::kVerticalGap, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, kSmallModeHeight + - OutputConfigurator::kVerticalGap, kBigModeId, - outputs_[1].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, kSmallModeHeight + - OutputConfigurator::kVerticalGap, kSmallModeId, - outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + GetFramebufferAction(kBigModeWidth, + kSmallModeHeight + kBigModeHeight + + OutputConfigurator::kVerticalGap, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + kSmallModeHeight + OutputConfigurator::kVerticalGap, + kBigModeId, + outputs_[1].output).c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + kSmallModeHeight + OutputConfigurator::kVerticalGap, + kSmallModeId, + outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); // A change event reporting a mode change on the second output should // trigger another reconfigure. @@ -1117,15 +1299,21 @@ TEST_F(OutputConfiguratorTest, AvoidUnnecessaryProbes) { test_api_.SendOutputChangeEvent( outputs_[1].output, outputs_[1].crtc, outputs_[1].mirror_mode, true); EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); - EXPECT_EQ(JoinActions(kGrab, - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); } TEST_F(OutputConfiguratorTest, UpdateCachedOutputsEvenAfterFailure) { @@ -1167,17 +1355,24 @@ TEST_F(OutputConfiguratorTest, PanelFitting) { configurator_.Init(true /* is_panel_fitting_enabled */); configurator_.Start(0); EXPECT_EQ(STATE_DUAL_MIRROR, configurator_.output_state()); - EXPECT_EQ(JoinActions(kGrab, kInitXRandR, - GetAddOutputModeAction( - outputs_[0].output, kSmallModeId).c_str(), - GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, - outputs_[1].output).c_str(), - kForceDPMS, kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kGrab, + kInitXRandR, + GetAddOutputModeAction(outputs_[0].output, kSmallModeId).c_str(), + GetFramebufferAction(kSmallModeWidth, + kSmallModeHeight, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kSmallModeId, outputs_[0].output).c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kSmallModeId, outputs_[1].output).c_str(), + kForceDPMS, + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); // Both outputs should be using the small mode. ASSERT_EQ(1, observer_.num_changes()); @@ -1199,7 +1394,7 @@ TEST_F(OutputConfiguratorTest, PanelFitting) { TEST_F(OutputConfiguratorTest, OutputProtection) { configurator_.Init(false); configurator_.Start(0); - EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_NE(kNoActions, log_->GetActionsAndClear()); OutputConfigurator::OutputProtectionClientId id = configurator_.RegisterOutputProtectionClient(); @@ -1207,7 +1402,7 @@ TEST_F(OutputConfiguratorTest, OutputProtection) { // One output. UpdateOutputs(1, true); - EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_NE(kNoActions, log_->GetActionsAndClear()); uint32_t link_mask = 0; uint32_t protection_mask = 0; EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(id, @@ -1217,11 +1412,11 @@ TEST_F(OutputConfiguratorTest, OutputProtection) { EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_INTERNAL), link_mask); EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_NONE), protection_mask); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); // Two outputs. UpdateOutputs(2, true); - EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_NE(kNoActions, log_->GetActionsAndClear()); EXPECT_TRUE(configurator_.QueryOutputProtectionStatus(id, outputs_[1].display_id, &link_mask, @@ -1230,14 +1425,14 @@ TEST_F(OutputConfiguratorTest, OutputProtection) { link_mask); EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_NONE), protection_mask); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); EXPECT_TRUE( configurator_.EnableOutputProtection(id, outputs_[1].display_id, OUTPUT_PROTECTION_METHOD_HDCP)); EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, HDCP_STATE_DESIRED), - delegate_->GetActionsAndClear()); + log_->GetActionsAndClear()); // Enable protection. delegate_->set_hdcp_state(HDCP_STATE_ENABLED); @@ -1248,12 +1443,12 @@ TEST_F(OutputConfiguratorTest, OutputProtection) { EXPECT_EQ(static_cast<uint32_t>(OUTPUT_TYPE_HDMI), link_mask); EXPECT_EQ(static_cast<uint32_t>(OUTPUT_PROTECTION_METHOD_HDCP), protection_mask); - EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); // Protections should be disabled after unregister. configurator_.UnregisterOutputProtectionClient(id); EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, HDCP_STATE_UNDESIRED), - delegate_->GetActionsAndClear()); + log_->GetActionsAndClear()); } TEST_F(OutputConfiguratorTest, OutputProtectionTwoClients) { @@ -1266,16 +1461,16 @@ TEST_F(OutputConfiguratorTest, OutputProtectionTwoClients) { configurator_.Init(false); configurator_.Start(0); UpdateOutputs(2, true); - EXPECT_NE(kNoActions, delegate_->GetActionsAndClear()); + EXPECT_NE(kNoActions, log_->GetActionsAndClear()); // Clients never know state enableness for methods that they didn't request. EXPECT_TRUE( configurator_.EnableOutputProtection(client1, outputs_[1].display_id, OUTPUT_PROTECTION_METHOD_HDCP)); - EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, - HDCP_STATE_DESIRED).c_str(), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + GetSetHDCPStateAction(outputs_[1].output, HDCP_STATE_DESIRED).c_str(), + log_->GetActionsAndClear()); delegate_->set_hdcp_state(HDCP_STATE_ENABLED); uint32_t link_mask = 0; @@ -1299,16 +1494,16 @@ TEST_F(OutputConfiguratorTest, OutputProtectionTwoClients) { configurator_.EnableOutputProtection(client2, outputs_[1].display_id, OUTPUT_PROTECTION_METHOD_NONE)); - EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, - HDCP_STATE_DESIRED).c_str(), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + GetSetHDCPStateAction(outputs_[1].output, HDCP_STATE_DESIRED).c_str(), + log_->GetActionsAndClear()); EXPECT_TRUE( configurator_.EnableOutputProtection(client1, outputs_[1].display_id, OUTPUT_PROTECTION_METHOD_NONE)); - EXPECT_EQ(GetSetHDCPStateAction(outputs_[1].output, - HDCP_STATE_UNDESIRED).c_str(), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + GetSetHDCPStateAction(outputs_[1].output, HDCP_STATE_UNDESIRED).c_str(), + log_->GetActionsAndClear()); } TEST_F(OutputConfiguratorTest, CTMForMultiScreens) { @@ -1324,8 +1519,10 @@ TEST_F(OutputConfiguratorTest, CTMForMultiScreens) { kSmallModeHeight + OutputConfigurator::kVerticalGap + kBigModeHeight; const int kDualWidth = kBigModeWidth; - OutputConfigurator::CoordinateTransformation ctm1 = delegate_->get_ctm(1); - OutputConfigurator::CoordinateTransformation ctm2 = delegate_->get_ctm(2); + OutputConfigurator::CoordinateTransformation ctm1 = + touchscreen_delegate_->GetCTM(1); + OutputConfigurator::CoordinateTransformation ctm2 = + touchscreen_delegate_->GetCTM(2); EXPECT_EQ(kSmallModeHeight - 1, round((kDualHeight - 1) * ctm1.y_scale)); EXPECT_EQ(0, round((kDualHeight - 1) * ctm1.y_offset)); @@ -1381,17 +1578,23 @@ TEST_F(OutputConfiguratorTest, HandleConfigureCrtcFailure) { state_controller_.set_state(STATE_SINGLE); UpdateOutputs(1, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction(2560, 1600, - outputs_[0].crtc, 0).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 2, - outputs_[0].output).c_str(), - kUngrab, kProjectingOff, NULL), - delegate_->GetActionsAndClear()); + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction(2560, 1600, outputs_[0].crtc, 0).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode, outputs_[0].output) + .c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kFirstMode + 3, outputs_[0].output) + .c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kFirstMode + 2, outputs_[0].output) + .c_str(), + kUngrab, + kProjectingOff, + NULL), + log_->GetActionsAndClear()); // This test should attempt to configure a mirror mode that will not succeed // and should end up in extended mode. @@ -1401,48 +1604,58 @@ TEST_F(OutputConfiguratorTest, HandleConfigureCrtcFailure) { state_controller_.set_state(STATE_DUAL_MIRROR); UpdateOutputs(2, true); - EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, - GetFramebufferAction( - outputs_[0].mode_infos[kFirstMode].width, - outputs_[0].mode_infos[kFirstMode].height, - outputs_[0].crtc, - outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, - 0, 0, kFirstMode, outputs_[0].output).c_str(), - // First mode tried is expected to fail and it will - // retry wil the 4th mode in the list. - GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3, - outputs_[0].output).c_str(), - // Then attempt to configure crtc1 with the first mode. - GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode, - outputs_[1].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode + 3, - outputs_[1].output).c_str(), - // Since it was requested to go into mirror mode - // and the configured modes were different, it - // should now try and setup a valid configurable - // extended mode. - GetFramebufferAction( - outputs_[0].mode_infos[kFirstMode].width, - outputs_[0].mode_infos[kFirstMode].height + - outputs_[1].mode_infos[kFirstMode].height + - OutputConfigurator::kVerticalGap, - outputs_[0].crtc, outputs_[1].crtc).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3, - outputs_[0].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, - outputs_[1].mode_infos[kFirstMode].height + - OutputConfigurator::kVerticalGap, kFirstMode, - outputs_[1].output).c_str(), - GetCrtcAction(outputs_[1].crtc, 0, - outputs_[1].mode_infos[kFirstMode].height + - OutputConfigurator::kVerticalGap, kFirstMode + 3, - outputs_[1].output).c_str(), - kUngrab, kProjectingOn, NULL), - delegate_->GetActionsAndClear()); - + EXPECT_EQ( + JoinActions( + kUpdateXRandR, + kGrab, + GetFramebufferAction(outputs_[0].mode_infos[kFirstMode].width, + outputs_[0].mode_infos[kFirstMode].height, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode, outputs_[0].output) + .c_str(), + // First mode tried is expected to fail and it will + // retry wil the 4th mode in the list. + GetCrtcAction( + outputs_[0].crtc, 0, 0, kFirstMode + 3, outputs_[0].output) + .c_str(), + // Then attempt to configure crtc1 with the first mode. + GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode, outputs_[1].output) + .c_str(), + GetCrtcAction( + outputs_[1].crtc, 0, 0, kFirstMode + 3, outputs_[1].output) + .c_str(), + // Since it was requested to go into mirror mode + // and the configured modes were different, it + // should now try and setup a valid configurable + // extended mode. + GetFramebufferAction(outputs_[0].mode_infos[kFirstMode].width, + outputs_[0].mode_infos[kFirstMode].height + + outputs_[1].mode_infos[kFirstMode].height + + OutputConfigurator::kVerticalGap, + outputs_[0].crtc, + outputs_[1].crtc).c_str(), + GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode, outputs_[0].output) + .c_str(), + GetCrtcAction( + outputs_[0].crtc, 0, 0, kFirstMode + 3, outputs_[0].output) + .c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + outputs_[1].mode_infos[kFirstMode].height + + OutputConfigurator::kVerticalGap, + kFirstMode, + outputs_[1].output).c_str(), + GetCrtcAction(outputs_[1].crtc, + 0, + outputs_[1].mode_infos[kFirstMode].height + + OutputConfigurator::kVerticalGap, + kFirstMode + 3, + outputs_[1].output).c_str(), + kUngrab, + kProjectingOn, + NULL), + log_->GetActionsAndClear()); } } // namespace chromeos diff --git a/chromeos/display/real_output_configurator_delegate.cc b/chromeos/display/real_output_configurator_delegate.cc index 38c6471..ca816bc 100644 --- a/chromeos/display/real_output_configurator_delegate.cc +++ b/chromeos/display/real_output_configurator_delegate.cc @@ -7,12 +7,8 @@ #include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/extensions/dpms.h> -#include <X11/extensions/XInput.h> -#include <X11/extensions/XInput2.h> #include <X11/extensions/Xrandr.h> -#include <cmath> -#include <set> #include <utility> #include "base/logging.h" @@ -136,7 +132,6 @@ RealOutputConfiguratorDelegate::GetOutputs() { XRRFreeOutputInfo(output_info); } - GetTouchscreens(&outputs); return outputs; } @@ -192,46 +187,6 @@ void RealOutputConfiguratorDelegate::CreateFrameBuffer( XRRSetScreenSize(display_, window_, width, height, mm_width, mm_height); } -void RealOutputConfiguratorDelegate::ConfigureCTM( - int touch_device_id, - const OutputConfigurator::CoordinateTransformation& ctm) { - VLOG(1) << "ConfigureCTM: id=" << touch_device_id - << " scale=" << ctm.x_scale << "x" << ctm.y_scale - << " offset=(" << ctm.x_offset << ", " << ctm.y_offset << ")"; - int ndevices = 0; - XIDeviceInfo* info = XIQueryDevice(display_, touch_device_id, &ndevices); - Atom prop = XInternAtom(display_, "Coordinate Transformation Matrix", False); - Atom float_atom = XInternAtom(display_, "FLOAT", False); - if (ndevices == 1 && prop != None && float_atom != None) { - Atom type; - int format; - unsigned long num_items; - unsigned long bytes_after; - unsigned char* data = NULL; - // Verify that the property exists with correct format, type, etc. - int status = XIGetProperty(display_, info->deviceid, prop, 0, 0, False, - AnyPropertyType, &type, &format, &num_items, &bytes_after, &data); - if (data) - XFree(data); - if (status == Success && type == float_atom && format == 32) { - float value[3][3] = { - { ctm.x_scale, 0.0, ctm.x_offset }, - { 0.0, ctm.y_scale, ctm.y_offset }, - { 0.0, 0.0, 1.0 } - }; - XIChangeProperty(display_, - info->deviceid, - prop, - type, - format, - PropModeReplace, - reinterpret_cast<unsigned char*>(value), - 9); - } - } - XIFreeDeviceInfo(info); -} - void RealOutputConfiguratorDelegate::SendProjectingStateToPowerManager( bool projecting) { chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> @@ -499,116 +454,4 @@ bool RealOutputConfiguratorDelegate::IsOutputAspectPreservingScaling( return ret; } -void RealOutputConfiguratorDelegate::GetTouchscreens( - std::vector<OutputConfigurator::OutputSnapshot>* outputs) { - int ndevices = 0; - Atom valuator_x = XInternAtom(display_, "Abs MT Position X", False); - Atom valuator_y = XInternAtom(display_, "Abs MT Position Y", False); - if (valuator_x == None || valuator_y == None) - return; - - std::set<int> no_match_touchscreen; - XIDeviceInfo* info = XIQueryDevice(display_, XIAllDevices, &ndevices); - for (int i = 0; i < ndevices; i++) { - if (!info[i].enabled || info[i].use != XIFloatingSlave) - continue; // Assume all touchscreens are floating slaves - - double width = -1.0; - double height = -1.0; - bool is_direct_touch = false; - - for (int j = 0; j < info[i].num_classes; j++) { - XIAnyClassInfo* class_info = info[i].classes[j]; - - if (class_info->type == XIValuatorClass) { - XIValuatorClassInfo* valuator_info = - reinterpret_cast<XIValuatorClassInfo*>(class_info); - - if (valuator_x == valuator_info->label) { - // Ignore X axis valuator with unexpected properties - if (valuator_info->number == 0 && valuator_info->mode == Absolute && - valuator_info->min == 0.0) { - width = valuator_info->max; - } - } else if (valuator_y == valuator_info->label) { - // Ignore Y axis valuator with unexpected properties - if (valuator_info->number == 1 && valuator_info->mode == Absolute && - valuator_info->min == 0.0) { - height = valuator_info->max; - } - } - } -#if defined(USE_XI2_MT) - if (class_info->type == XITouchClass) { - XITouchClassInfo* touch_info = - reinterpret_cast<XITouchClassInfo*>(class_info); - is_direct_touch = touch_info->mode == XIDirectTouch; - } -#endif - } - - // Touchscreens should have absolute X and Y axes, - // and be direct touch devices. - if (width > 0.0 && height > 0.0 && is_direct_touch) { - size_t k = 0; - for (; k < outputs->size(); k++) { - OutputConfigurator::OutputSnapshot* output = &(*outputs)[k]; - if (output->native_mode == None || output->touch_device_id != None) - continue; - - const OutputConfigurator::ModeInfo* mode_info = - OutputConfigurator::GetModeInfo(*output, output->native_mode); - if (!mode_info) - continue; - - // Allow 1 pixel difference between screen and touchscreen - // resolutions. Because in some cases for monitor resolution - // 1024x768 touchscreen's resolution would be 1024x768, but for - // some 1023x767. It really depends on touchscreen's firmware - // configuration. - if (std::abs(mode_info->width - width) <= 1.0 && - std::abs(mode_info->height - height) <= 1.0) { - output->touch_device_id = info[i].deviceid; - - VLOG(2) << "Found touchscreen for output #" << k - << " id " << output->touch_device_id - << " width " << width - << " height " << height; - break; - } - } - - if (k == outputs->size()) { - no_match_touchscreen.insert(info[i].deviceid); - VLOG(2) << "No matching output for touchscreen" - << " id " << info[i].deviceid - << " width " << width - << " height " << height; - } - - } - } - - // Sometimes we can't find a matching screen for the touchscreen, e.g. - // due to the touchscreen's reporting range having no correlation with the - // screen's resolution. In this case, we arbitrarily assign unmatched - // touchscreens to unmatched screens. - for (std::set<int>::iterator it = no_match_touchscreen.begin(); - it != no_match_touchscreen.end(); - it++) { - for (size_t i = 0; i < outputs->size(); i++) { - if ((*outputs)[i].type != OUTPUT_TYPE_INTERNAL && - (*outputs)[i].native_mode != None && - (*outputs)[i].touch_device_id == None ) { - (*outputs)[i].touch_device_id = *it; - VLOG(2) << "Arbitrarily matching touchscreen " - << (*outputs)[i].touch_device_id << " to output #" << i; - break; - } - } - } - - XIFreeDeviceInfo(info); -} - } // namespace chromeos diff --git a/chromeos/display/real_output_configurator_delegate.h b/chromeos/display/real_output_configurator_delegate.h index 26940c4..7c7d62b 100644 --- a/chromeos/display/real_output_configurator_delegate.h +++ b/chromeos/display/real_output_configurator_delegate.h @@ -48,9 +48,6 @@ class RealOutputConfiguratorDelegate : public OutputConfigurator::Delegate { int width, int height, const std::vector<OutputConfigurator::OutputSnapshot>& outputs) OVERRIDE; - virtual void ConfigureCTM( - int touch_device_id, - const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE; virtual void SendProjectingStateToPowerManager(bool projecting) OVERRIDE; virtual bool GetHDCPState(RROutput id, HDCPState* state) OVERRIDE; virtual bool SetHDCPState(RROutput id, HDCPState state) OVERRIDE; @@ -78,14 +75,6 @@ class RealOutputConfiguratorDelegate : public OutputConfigurator::Delegate { // Returns whether |id| is configured to preserve aspect when scaling. bool IsOutputAspectPreservingScaling(RROutput id); - // Searches for touchscreens among input devices, - // and tries to match them up to screens in |outputs|. - // |outputs| is an array of detected screens. - // If a touchscreen with same resolution as an output's native mode - // is detected, its id will be stored in this output. - void GetTouchscreens( - std::vector<OutputConfigurator::OutputSnapshot>* outputs); - Display* display_; Window window_; diff --git a/chromeos/display/touchscreen_delegate_x11.cc b/chromeos/display/touchscreen_delegate_x11.cc new file mode 100644 index 0000000..44db4b5 --- /dev/null +++ b/chromeos/display/touchscreen_delegate_x11.cc @@ -0,0 +1,174 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/display/touchscreen_delegate_x11.h" + +#include <X11/extensions/XInput.h> +#include <X11/extensions/XInput2.h> + +#include <cmath> +#include <set> + +#include "base/message_loop/message_pump_x11.h" + +namespace chromeos { + +TouchscreenDelegateX11::TouchscreenDelegateX11() + : display_(base::MessagePumpX11::GetDefaultXDisplay()) {} + +TouchscreenDelegateX11::~TouchscreenDelegateX11() {} + +void TouchscreenDelegateX11::AssociateTouchscreens( + std::vector<OutputConfigurator::OutputSnapshot>* outputs) { + int ndevices = 0; + Atom valuator_x = XInternAtom(display_, "Abs MT Position X", False); + Atom valuator_y = XInternAtom(display_, "Abs MT Position Y", False); + if (valuator_x == None || valuator_y == None) + return; + + std::set<int> no_match_touchscreen; + XIDeviceInfo* info = XIQueryDevice(display_, XIAllDevices, &ndevices); + for (int i = 0; i < ndevices; i++) { + if (!info[i].enabled || info[i].use != XIFloatingSlave) + continue; // Assume all touchscreens are floating slaves + + double width = -1.0; + double height = -1.0; + bool is_direct_touch = false; + + for (int j = 0; j < info[i].num_classes; j++) { + XIAnyClassInfo* class_info = info[i].classes[j]; + + if (class_info->type == XIValuatorClass) { + XIValuatorClassInfo* valuator_info = + reinterpret_cast<XIValuatorClassInfo*>(class_info); + + if (valuator_x == valuator_info->label) { + // Ignore X axis valuator with unexpected properties + if (valuator_info->number == 0 && valuator_info->mode == Absolute && + valuator_info->min == 0.0) { + width = valuator_info->max; + } + } else if (valuator_y == valuator_info->label) { + // Ignore Y axis valuator with unexpected properties + if (valuator_info->number == 1 && valuator_info->mode == Absolute && + valuator_info->min == 0.0) { + height = valuator_info->max; + } + } + } +#if defined(USE_XI2_MT) + if (class_info->type == XITouchClass) { + XITouchClassInfo* touch_info = + reinterpret_cast<XITouchClassInfo*>(class_info); + is_direct_touch = touch_info->mode == XIDirectTouch; + } +#endif + } + + // Touchscreens should have absolute X and Y axes, + // and be direct touch devices. + if (width > 0.0 && height > 0.0 && is_direct_touch) { + size_t k = 0; + for (; k < outputs->size(); k++) { + OutputConfigurator::OutputSnapshot* output = &(*outputs)[k]; + if (output->native_mode == None || output->touch_device_id != None) + continue; + + const OutputConfigurator::ModeInfo* mode_info = + OutputConfigurator::GetModeInfo(*output, output->native_mode); + if (!mode_info) + continue; + + // Allow 1 pixel difference between screen and touchscreen + // resolutions. Because in some cases for monitor resolution + // 1024x768 touchscreen's resolution would be 1024x768, but for + // some 1023x767. It really depends on touchscreen's firmware + // configuration. + if (std::abs(mode_info->width - width) <= 1.0 && + std::abs(mode_info->height - height) <= 1.0) { + output->touch_device_id = info[i].deviceid; + + VLOG(2) << "Found touchscreen for output #" << k + << " id " << output->touch_device_id + << " width " << width + << " height " << height; + break; + } + } + + if (k == outputs->size()) { + no_match_touchscreen.insert(info[i].deviceid); + VLOG(2) << "No matching output for touchscreen" + << " id " << info[i].deviceid + << " width " << width + << " height " << height; + } + + } + } + + // Sometimes we can't find a matching screen for the touchscreen, e.g. + // due to the touchscreen's reporting range having no correlation with the + // screen's resolution. In this case, we arbitrarily assign unmatched + // touchscreens to unmatched screens. + for (std::set<int>::iterator it = no_match_touchscreen.begin(); + it != no_match_touchscreen.end(); + it++) { + for (size_t i = 0; i < outputs->size(); i++) { + if ((*outputs)[i].type != OUTPUT_TYPE_INTERNAL && + (*outputs)[i].native_mode != None && + (*outputs)[i].touch_device_id == None ) { + (*outputs)[i].touch_device_id = *it; + VLOG(2) << "Arbitrarily matching touchscreen " + << (*outputs)[i].touch_device_id << " to output #" << i; + break; + } + } + } + + XIFreeDeviceInfo(info); +} + +void TouchscreenDelegateX11::ConfigureCTM( + int touch_device_id, + const OutputConfigurator::CoordinateTransformation& ctm) { + VLOG(1) << "ConfigureCTM: id=" << touch_device_id + << " scale=" << ctm.x_scale << "x" << ctm.y_scale + << " offset=(" << ctm.x_offset << ", " << ctm.y_offset << ")"; + int ndevices = 0; + XIDeviceInfo* info = XIQueryDevice(display_, touch_device_id, &ndevices); + Atom prop = XInternAtom(display_, "Coordinate Transformation Matrix", False); + Atom float_atom = XInternAtom(display_, "FLOAT", False); + if (ndevices == 1 && prop != None && float_atom != None) { + Atom type; + int format; + unsigned long num_items; + unsigned long bytes_after; + unsigned char* data = NULL; + // Verify that the property exists with correct format, type, etc. + int status = XIGetProperty(display_, info->deviceid, prop, 0, 0, False, + AnyPropertyType, &type, &format, &num_items, &bytes_after, &data); + if (data) + XFree(data); + if (status == Success && type == float_atom && format == 32) { + float value[3][3] = { + { ctm.x_scale, 0.0, ctm.x_offset }, + { 0.0, ctm.y_scale, ctm.y_offset }, + { 0.0, 0.0, 1.0 } + }; + XIChangeProperty(display_, + info->deviceid, + prop, + type, + format, + PropModeReplace, + reinterpret_cast<unsigned char*>(value), + 9); + } + } + XIFreeDeviceInfo(info); +} + +} // namespace chromeos diff --git a/chromeos/display/touchscreen_delegate_x11.h b/chromeos/display/touchscreen_delegate_x11.h new file mode 100644 index 0000000..99cae06 --- /dev/null +++ b/chromeos/display/touchscreen_delegate_x11.h @@ -0,0 +1,35 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_DISPLAY_TOUCHSCREEN_DELEGATE_X11_H_ +#define CHROMEOS_DISPLAY_TOUCHSCREEN_DELEGATE_X11_H_ + +#include "chromeos/display/output_configurator.h" + +struct _XDisplay; +typedef struct _XDisplay Display; + +namespace chromeos { + +class TouchscreenDelegateX11 : public OutputConfigurator::TouchscreenDelegate { + public: + TouchscreenDelegateX11(); + virtual ~TouchscreenDelegateX11(); + + // OutputConfigurator::TouchscreenDelegate implementation: + virtual void AssociateTouchscreens( + std::vector<OutputConfigurator::OutputSnapshot>* outputs) OVERRIDE; + virtual void ConfigureCTM( + int touch_device_id, + const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE; + + private: + Display* display_; + + DISALLOW_COPY_AND_ASSIGN(TouchscreenDelegateX11); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DISPLAY_TOUCHSCREEN_DELEGATE_X11_H_ |