1 // Copyright 2015 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.
6 #include "base/containers/hash_tables.h"
7 #include "base/json/json_writer.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/browser/media/router/media_sinks_observer.h"
11 #include "chrome/browser/media/router/media_source_helper.h"
12 #include "chrome/browser/media/router/mock_media_router.h"
13 #include "chrome/browser/ui/webui/media_router/query_result_manager.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 using testing::ContainerEq
;
19 using testing::IsEmpty
;
22 using testing::Return
;
25 namespace media_router
{
29 class MockObserver
: public QueryResultManager::Observer
{
31 MOCK_METHOD1(OnResultsUpdated
, void(
32 const std::vector
<MediaSinkWithCastModes
>& sinks
));
37 class QueryResultManagerTest
: public ::testing::Test
{
39 QueryResultManagerTest()
40 : mock_router_(), query_result_manager_(&mock_router_
) {
43 void DiscoverSinks(MediaCastMode cast_mode
, const MediaSource
& source
) {
44 EXPECT_CALL(mock_router_
, RegisterMediaSinksObserver(_
)).Times(1);
45 EXPECT_CALL(mock_observer_
, OnResultsUpdated(_
)).Times(1);
46 query_result_manager_
.StartSinksQuery(cast_mode
, source
);
49 MockMediaRouter mock_router_
;
50 QueryResultManager query_result_manager_
;
51 MockObserver mock_observer_
;
54 DISALLOW_COPY_AND_ASSIGN(QueryResultManagerTest
);
57 MATCHER_P(VectorEquals
, expected
, "") {
58 if (expected
.size() != arg
.size()) {
61 for (int i
= 0; i
< static_cast<int>(expected
.size()); i
++) {
62 if (!expected
[i
].Equals(arg
[i
])) {
69 TEST_F(QueryResultManagerTest
, Observers
) {
72 query_result_manager_
.AddObserver(&ob1
);
73 query_result_manager_
.AddObserver(&ob2
);
75 EXPECT_CALL(ob1
, OnResultsUpdated(_
)).Times(1);
76 EXPECT_CALL(ob2
, OnResultsUpdated(_
)).Times(1);
77 query_result_manager_
.NotifyOnResultsUpdated();
79 query_result_manager_
.RemoveObserver(&ob2
);
80 EXPECT_CALL(ob1
, OnResultsUpdated(_
)).Times(1);
81 query_result_manager_
.NotifyOnResultsUpdated();
83 query_result_manager_
.RemoveObserver(&ob1
);
84 query_result_manager_
.NotifyOnResultsUpdated();
87 TEST_F(QueryResultManagerTest
, StartStopSinksQuery
) {
88 CastModeSet cast_modes
;
90 query_result_manager_
.GetSupportedCastModes(&cast_modes
);
91 EXPECT_TRUE(cast_modes
.empty());
92 MediaSource actual_source
=
93 query_result_manager_
.GetSourceForCastMode(MediaCastMode::DEFAULT
);
94 EXPECT_TRUE(actual_source
.Empty());
96 MediaSource
source(ForPresentationUrl("http://fooUrl"));
97 EXPECT_CALL(mock_router_
, RegisterMediaSinksObserver(_
)).Times(1);
98 query_result_manager_
.StartSinksQuery(MediaCastMode::DEFAULT
, source
);
100 query_result_manager_
.GetSupportedCastModes(&cast_modes
);
101 EXPECT_EQ(1u, cast_modes
.size());
102 EXPECT_TRUE(ContainsKey(cast_modes
, MediaCastMode::DEFAULT
));
103 actual_source
= query_result_manager_
.GetSourceForCastMode(
104 MediaCastMode::DEFAULT
);
105 EXPECT_TRUE(source
.Equals(actual_source
));
107 // Register a different source for the same cast mode.
108 MediaSource
another_source(ForPresentationUrl("http://barUrl"));
109 EXPECT_CALL(mock_router_
, UnregisterMediaSinksObserver(_
)).Times(1);
110 EXPECT_CALL(mock_router_
, RegisterMediaSinksObserver(_
)).Times(1);
111 query_result_manager_
.StartSinksQuery(
112 MediaCastMode::DEFAULT
, another_source
);
114 query_result_manager_
.GetSupportedCastModes(&cast_modes
);
115 EXPECT_EQ(1u, cast_modes
.size());
116 EXPECT_TRUE(ContainsKey(cast_modes
, MediaCastMode::DEFAULT
));
117 actual_source
= query_result_manager_
.GetSourceForCastMode(
118 MediaCastMode::DEFAULT
);
119 EXPECT_TRUE(another_source
.Equals(actual_source
));
121 EXPECT_CALL(mock_router_
, UnregisterMediaSinksObserver(_
)).Times(1);
122 query_result_manager_
.StopSinksQuery(MediaCastMode::DEFAULT
);
124 query_result_manager_
.GetSupportedCastModes(&cast_modes
);
125 EXPECT_TRUE(cast_modes
.empty());
126 actual_source
= query_result_manager_
.GetSourceForCastMode(
127 MediaCastMode::DEFAULT
);
128 EXPECT_TRUE(actual_source
.Empty());
131 TEST_F(QueryResultManagerTest
, MultipleQueries
) {
132 MediaSink
sink1("sinkId1", "Sink 1");
133 MediaSink
sink2("sinkId2", "Sink 2");
134 MediaSink
sink3("sinkId3", "Sink 3");
135 MediaSink
sink4("sinkId4", "Sink 4");
136 MediaSink
sink5("sinkId5", "Sink 5");
138 query_result_manager_
.AddObserver(&mock_observer_
);
139 DiscoverSinks(MediaCastMode::DEFAULT
, ForPresentationUrl("http://barUrl"));
140 DiscoverSinks(MediaCastMode::TAB_MIRROR
, ForTabMediaSource(123));
142 // Scenario (results in this order):
143 // Action: DEFAULT -> [1, 2, 3]
145 // Sinks: [1 -> {DEFAULT}, 2 -> {DEFAULT}, 3 -> {DEFAULT}]
146 std::vector
<MediaSinkWithCastModes
> expected_sinks
;
147 expected_sinks
.push_back(MediaSinkWithCastModes(sink1
));
148 expected_sinks
.back().cast_modes
.insert(MediaCastMode::DEFAULT
);
149 expected_sinks
.push_back(MediaSinkWithCastModes(sink2
));
150 expected_sinks
.back().cast_modes
.insert(MediaCastMode::DEFAULT
);
151 expected_sinks
.push_back(MediaSinkWithCastModes(sink3
));
152 expected_sinks
.back().cast_modes
.insert(MediaCastMode::DEFAULT
);
154 const auto& sinks_observers
= query_result_manager_
.sinks_observers_
;
155 auto sinks_observer_it
= sinks_observers
.find(MediaCastMode::DEFAULT
);
156 ASSERT_TRUE(sinks_observer_it
!= sinks_observers
.end());
157 ASSERT_TRUE(sinks_observer_it
->second
.get());
159 std::vector
<MediaSink
> sinks_query_result
;
160 sinks_query_result
.push_back(sink1
);
161 sinks_query_result
.push_back(sink2
);
162 sinks_query_result
.push_back(sink3
);
163 EXPECT_CALL(mock_observer_
,
164 OnResultsUpdated(VectorEquals(expected_sinks
))).Times(1);
165 sinks_observer_it
->second
->OnSinksReceived(sinks_query_result
);
167 // Action: TAB_MIRROR -> [2, 3, 4]
169 // Sinks: [1 -> {DEFAULT}, 2 -> {DEFAULT, TAB_MIRROR},
170 // 3 -> {DEFAULT, TAB_MIRROR}, 4 -> {TAB_MIRROR}]
171 expected_sinks
.clear();
172 expected_sinks
.push_back(MediaSinkWithCastModes(sink1
));
173 expected_sinks
.back().cast_modes
.insert(MediaCastMode::DEFAULT
);
174 expected_sinks
.push_back(MediaSinkWithCastModes(sink2
));
175 expected_sinks
.back().cast_modes
.insert(MediaCastMode::DEFAULT
);
176 expected_sinks
.back().cast_modes
.insert(MediaCastMode::TAB_MIRROR
);
177 expected_sinks
.push_back(MediaSinkWithCastModes(sink3
));
178 expected_sinks
.back().cast_modes
.insert(MediaCastMode::DEFAULT
);
179 expected_sinks
.back().cast_modes
.insert(MediaCastMode::TAB_MIRROR
);
180 expected_sinks
.push_back(MediaSinkWithCastModes(sink4
));
181 expected_sinks
.back().cast_modes
.insert(MediaCastMode::TAB_MIRROR
);
183 sinks_query_result
.clear();
184 sinks_query_result
.push_back(sink2
);
185 sinks_query_result
.push_back(sink3
);
186 sinks_query_result
.push_back(sink4
);
188 sinks_observer_it
= sinks_observers
.find(MediaCastMode::TAB_MIRROR
);
189 ASSERT_TRUE(sinks_observer_it
!= sinks_observers
.end());
190 ASSERT_TRUE(sinks_observer_it
->second
.get());
191 EXPECT_CALL(mock_observer_
,
192 OnResultsUpdated(VectorEquals(expected_sinks
))).Times(1);
193 sinks_observer_it
->second
->OnSinksReceived(sinks_query_result
);
195 // Action: Update default presentation URL
197 // Sinks: [2 -> {TAB_MIRROR}, 3 -> {TAB_MIRROR}, 4 -> {TAB_MIRROR}]
198 expected_sinks
.clear();
199 expected_sinks
.push_back(MediaSinkWithCastModes(sink2
));
200 expected_sinks
.back().cast_modes
.insert(MediaCastMode::TAB_MIRROR
);
201 expected_sinks
.push_back(MediaSinkWithCastModes(sink3
));
202 expected_sinks
.back().cast_modes
.insert(MediaCastMode::TAB_MIRROR
);
203 expected_sinks
.push_back(MediaSinkWithCastModes(sink4
));
204 expected_sinks
.back().cast_modes
.insert(MediaCastMode::TAB_MIRROR
);
206 EXPECT_CALL(mock_router_
, UnregisterMediaSinksObserver(_
)).Times(1);
207 EXPECT_CALL(mock_router_
, RegisterMediaSinksObserver(_
)).Times(1);
208 EXPECT_CALL(mock_observer_
,
209 OnResultsUpdated(VectorEquals(expected_sinks
))).Times(1);
210 query_result_manager_
.StartSinksQuery(
211 MediaCastMode::DEFAULT
,
212 ForPresentationUrl("http://bazurl.com"));
214 // Action: Remove TAB_MIRROR observer
217 expected_sinks
.clear();
218 EXPECT_CALL(mock_observer_
,
219 OnResultsUpdated(VectorEquals(expected_sinks
))).Times(1);
220 EXPECT_CALL(mock_router_
, UnregisterMediaSinksObserver(_
)).Times(1);
221 query_result_manager_
.StopSinksQuery(MediaCastMode::TAB_MIRROR
);
223 // Remaining observers: DEFAULT observer, which will be removed on destruction
224 EXPECT_CALL(mock_router_
, UnregisterMediaSinksObserver(_
)).Times(1);
227 } // namespace media_router