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
13namespace ash {
14namespace {
15
16ui::TestDisplaySnapshot* CreateInternalSnapshot() {
17  ui::TestDisplaySnapshot* output = new ui::TestDisplaySnapshot();
18  output->set_type(ui::DISPLAY_CONNECTION_TYPE_INTERNAL);
19  return output;
20}
21
22ui::TestDisplaySnapshot* CreateVGASnapshot() {
23  ui::TestDisplaySnapshot* output = new ui::TestDisplaySnapshot();
24  output->set_type(ui::DISPLAY_CONNECTION_TYPE_VGA);
25  return output;
26}
27
28ui::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
40class 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
62TEST_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
71TEST_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
81TEST_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
91TEST_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
103TEST_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
114TEST_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
127TEST_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
139TEST_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
157TEST_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
171TEST_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