1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ash/display/projecting_observer_chromeos.h" 6 7 #include "base/memory/scoped_vector.h" 8 #include "chromeos/dbus/dbus_thread_manager.h" 9 #include "chromeos/dbus/fake_power_manager_client.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 #include "ui/display/chromeos/test/test_display_snapshot.h" 12 13 namespace ash { 14 namespace { 15 16 ui::TestDisplaySnapshot* CreateInternalSnapshot() { 17 ui::TestDisplaySnapshot* output = new ui::TestDisplaySnapshot(); 18 output->set_type(ui::DISPLAY_CONNECTION_TYPE_INTERNAL); 19 return output; 20 } 21 22 ui::TestDisplaySnapshot* CreateVGASnapshot() { 23 ui::TestDisplaySnapshot* output = new ui::TestDisplaySnapshot(); 24 output->set_type(ui::DISPLAY_CONNECTION_TYPE_VGA); 25 return output; 26 } 27 28 ui::DisplayConfigurator::DisplayStateList CreateOutputs( 29 const ScopedVector<ui::TestDisplaySnapshot>& displays) { 30 ui::DisplayConfigurator::DisplayStateList outputs; 31 for (size_t i = 0; i < displays.size(); ++i) { 32 ui::DisplayConfigurator::DisplayState state; 33 state.display = displays[i]; 34 outputs.push_back(state); 35 } 36 37 return outputs; 38 } 39 40 class ProjectingObserverTest : public testing::Test { 41 public: 42 ProjectingObserverTest() : observer_(new ProjectingObserver()) { 43 fake_power_client_ = new chromeos::FakePowerManagerClient(); 44 45 chromeos::DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient( 46 scoped_ptr<chromeos::PowerManagerClient>(fake_power_client_)); 47 } 48 49 virtual ~ProjectingObserverTest() { 50 chromeos::DBusThreadManager::Shutdown(); 51 } 52 53 protected: 54 scoped_ptr<ProjectingObserver> observer_; 55 chromeos::FakePowerManagerClient* fake_power_client_; // Not owned. 56 57 DISALLOW_COPY_AND_ASSIGN(ProjectingObserverTest); 58 }; 59 60 } // namespace 61 62 TEST_F(ProjectingObserverTest, CheckNoDisplay) { 63 ScopedVector<ui::TestDisplaySnapshot> displays; 64 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 65 observer_->OnDisplayModeChanged(outputs); 66 67 EXPECT_EQ(1, fake_power_client_->num_set_is_projecting_calls()); 68 EXPECT_FALSE(fake_power_client_->is_projecting()); 69 } 70 71 TEST_F(ProjectingObserverTest, CheckWithoutInternalDisplay) { 72 ScopedVector<ui::TestDisplaySnapshot> displays; 73 displays.push_back(CreateVGASnapshot()); 74 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 75 observer_->OnDisplayModeChanged(outputs); 76 77 EXPECT_EQ(1, fake_power_client_->num_set_is_projecting_calls()); 78 EXPECT_FALSE(fake_power_client_->is_projecting()); 79 } 80 81 TEST_F(ProjectingObserverTest, CheckWithInternalDisplay) { 82 ScopedVector<ui::TestDisplaySnapshot> displays; 83 displays.push_back(CreateInternalSnapshot()); 84 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 85 observer_->OnDisplayModeChanged(outputs); 86 87 EXPECT_EQ(1, fake_power_client_->num_set_is_projecting_calls()); 88 EXPECT_FALSE(fake_power_client_->is_projecting()); 89 } 90 91 TEST_F(ProjectingObserverTest, CheckWithTwoVGADisplays) { 92 ScopedVector<ui::TestDisplaySnapshot> displays; 93 displays.push_back(CreateVGASnapshot()); 94 displays.push_back(CreateVGASnapshot()); 95 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 96 observer_->OnDisplayModeChanged(outputs); 97 98 EXPECT_EQ(1, fake_power_client_->num_set_is_projecting_calls()); 99 // We need at least 1 internal display to set projecting to on. 100 EXPECT_FALSE(fake_power_client_->is_projecting()); 101 } 102 103 TEST_F(ProjectingObserverTest, CheckWithInternalAndVGADisplays) { 104 ScopedVector<ui::TestDisplaySnapshot> displays; 105 displays.push_back(CreateInternalSnapshot()); 106 displays.push_back(CreateVGASnapshot()); 107 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 108 observer_->OnDisplayModeChanged(outputs); 109 110 EXPECT_EQ(1, fake_power_client_->num_set_is_projecting_calls()); 111 EXPECT_TRUE(fake_power_client_->is_projecting()); 112 } 113 114 TEST_F(ProjectingObserverTest, CheckWithVGADisplayAndOneCastingSession) { 115 ScopedVector<ui::TestDisplaySnapshot> displays; 116 displays.push_back(CreateVGASnapshot()); 117 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 118 observer_->OnDisplayModeChanged(outputs); 119 120 observer_->OnCastingSessionStartedOrStopped(true); 121 122 EXPECT_EQ(2, fake_power_client_->num_set_is_projecting_calls()); 123 // Need at least one internal display to set projecting state to |true|. 124 EXPECT_FALSE(fake_power_client_->is_projecting()); 125 } 126 127 TEST_F(ProjectingObserverTest, CheckWithInternalDisplayAndOneCastingSession) { 128 ScopedVector<ui::TestDisplaySnapshot> displays; 129 displays.push_back(CreateInternalSnapshot()); 130 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 131 observer_->OnDisplayModeChanged(outputs); 132 133 observer_->OnCastingSessionStartedOrStopped(true); 134 135 EXPECT_EQ(2, fake_power_client_->num_set_is_projecting_calls()); 136 EXPECT_TRUE(fake_power_client_->is_projecting()); 137 } 138 139 TEST_F(ProjectingObserverTest, CheckProjectingAfterClosingACastingSession) { 140 ScopedVector<ui::TestDisplaySnapshot> displays; 141 displays.push_back(CreateInternalSnapshot()); 142 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 143 observer_->OnDisplayModeChanged(outputs); 144 145 observer_->OnCastingSessionStartedOrStopped(true); 146 observer_->OnCastingSessionStartedOrStopped(true); 147 148 EXPECT_EQ(3, fake_power_client_->num_set_is_projecting_calls()); 149 EXPECT_TRUE(fake_power_client_->is_projecting()); 150 151 observer_->OnCastingSessionStartedOrStopped(false); 152 153 EXPECT_EQ(4, fake_power_client_->num_set_is_projecting_calls()); 154 EXPECT_TRUE(fake_power_client_->is_projecting()); 155 } 156 157 TEST_F(ProjectingObserverTest, 158 CheckStopProjectingAfterClosingAllCastingSessions) { 159 ScopedVector<ui::TestDisplaySnapshot> displays; 160 displays.push_back(CreateInternalSnapshot()); 161 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 162 observer_->OnDisplayModeChanged(outputs); 163 164 observer_->OnCastingSessionStartedOrStopped(true); 165 observer_->OnCastingSessionStartedOrStopped(false); 166 167 EXPECT_EQ(3, fake_power_client_->num_set_is_projecting_calls()); 168 EXPECT_FALSE(fake_power_client_->is_projecting()); 169 } 170 171 TEST_F(ProjectingObserverTest, 172 CheckStopProjectingAfterDisconnectingSecondOutput) { 173 ScopedVector<ui::TestDisplaySnapshot> displays; 174 displays.push_back(CreateInternalSnapshot()); 175 displays.push_back(CreateVGASnapshot()); 176 ui::DisplayConfigurator::DisplayStateList outputs = CreateOutputs(displays); 177 observer_->OnDisplayModeChanged(outputs); 178 179 // Remove VGA output. 180 outputs.erase(outputs.begin() + 1); 181 observer_->OnDisplayModeChanged(outputs); 182 183 EXPECT_EQ(2, fake_power_client_->num_set_is_projecting_calls()); 184 EXPECT_FALSE(fake_power_client_->is_projecting()); 185 } 186 187 } // namespace ash 188