1 // Copyright (c) 2013 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 "base/memory/scoped_ptr.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/values.h"
8 #include "content/browser/media/webrtc_internals.h"
9 #include "content/browser/media/webrtc_internals_ui_observer.h"
10 #include "content/public/test/test_browser_thread.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace content {
14
15 namespace {
16
17 static const std::string kContraints = "c";
18 static const std::string kRtcConfiguration = "r";
19 static const std::string kUrl = "u";
20
21 class MockWebRTCInternalsProxy : public WebRTCInternalsUIObserver {
22 public:
OnUpdate(const std::string & command,const base::Value * value)23 virtual void OnUpdate(const std::string& command,
24 const base::Value* value) OVERRIDE {
25 command_ = command;
26 if (value)
27 value_.reset(value->DeepCopy());
28 }
29
command()30 std::string command() {
31 return command_;
32 }
33
value()34 base::Value* value() {
35 return value_.get();
36 }
37
38 private:
39 std::string command_;
40 scoped_ptr<base::Value> value_;
41 };
42
43 class WebRTCInternalsTest : public testing::Test {
44 public:
WebRTCInternalsTest()45 WebRTCInternalsTest() : io_thread_(BrowserThread::UI, &io_loop_) {
46 WebRTCInternals::GetInstance()->ResetForTesting();
47 }
48
49 protected:
VerifyString(const base::DictionaryValue * dict,const std::string & key,const std::string & expected)50 void VerifyString(const base::DictionaryValue* dict,
51 const std::string& key,
52 const std::string& expected) {
53 std::string actual;
54 EXPECT_TRUE(dict->GetString(key, &actual));
55 EXPECT_EQ(expected, actual);
56 }
57
VerifyInt(const base::DictionaryValue * dict,const std::string & key,int expected)58 void VerifyInt(const base::DictionaryValue* dict,
59 const std::string& key,
60 int expected) {
61 int actual;
62 EXPECT_TRUE(dict->GetInteger(key, &actual));
63 EXPECT_EQ(expected, actual);
64 }
65
VerifyList(const base::DictionaryValue * dict,const std::string & key,const base::ListValue & expected)66 void VerifyList(const base::DictionaryValue* dict,
67 const std::string& key,
68 const base::ListValue& expected) {
69 const base::ListValue* actual = NULL;
70 EXPECT_TRUE(dict->GetList(key, &actual));
71 EXPECT_TRUE(expected.Equals(actual));
72 }
73
VerifyGetUserMediaData(base::Value * actual_data,int rid,int pid,const std::string & origin,const std::string & audio,const std::string & video)74 void VerifyGetUserMediaData(base::Value* actual_data,
75 int rid,
76 int pid,
77 const std::string& origin,
78 const std::string& audio,
79 const std::string& video) {
80 base::DictionaryValue* dict = NULL;
81 EXPECT_TRUE(actual_data->GetAsDictionary(&dict));
82
83 VerifyInt(dict, "rid", rid);
84 VerifyInt(dict, "pid", pid);
85 VerifyString(dict, "origin", origin);
86 VerifyString(dict, "audio", audio);
87 VerifyString(dict, "video", video);
88 }
89
90 base::MessageLoop io_loop_;
91 TestBrowserThread io_thread_;
92 };
93
94 } // namespace
95
TEST_F(WebRTCInternalsTest,AddRemoveObserver)96 TEST_F(WebRTCInternalsTest, AddRemoveObserver) {
97 scoped_ptr<MockWebRTCInternalsProxy> observer(
98 new MockWebRTCInternalsProxy());
99 WebRTCInternals::GetInstance()->AddObserver(observer.get());
100 WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
101 WebRTCInternals::GetInstance()->OnAddPeerConnection(
102 0, 3, 4, kUrl, kRtcConfiguration, kContraints);
103 EXPECT_EQ("", observer->command());
104
105 WebRTCInternals::GetInstance()->OnRemovePeerConnection(3, 4);
106 }
107
TEST_F(WebRTCInternalsTest,SendAddPeerConnectionUpdate)108 TEST_F(WebRTCInternalsTest, SendAddPeerConnectionUpdate) {
109 scoped_ptr<MockWebRTCInternalsProxy> observer(
110 new MockWebRTCInternalsProxy());
111 WebRTCInternals::GetInstance()->AddObserver(observer.get());
112 WebRTCInternals::GetInstance()->OnAddPeerConnection(
113 0, 1, 2, kUrl, kRtcConfiguration, kContraints);
114 EXPECT_EQ("addPeerConnection", observer->command());
115
116 base::DictionaryValue* dict = NULL;
117 EXPECT_TRUE(observer->value()->GetAsDictionary(&dict));
118
119 VerifyInt(dict, "pid", 1);
120 VerifyInt(dict, "lid", 2);
121 VerifyString(dict, "url", kUrl);
122 VerifyString(dict, "rtcConfiguration", kRtcConfiguration);
123 VerifyString(dict, "constraints", kContraints);
124
125 WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
126 WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2);
127 }
128
TEST_F(WebRTCInternalsTest,SendRemovePeerConnectionUpdate)129 TEST_F(WebRTCInternalsTest, SendRemovePeerConnectionUpdate) {
130 scoped_ptr<MockWebRTCInternalsProxy> observer(
131 new MockWebRTCInternalsProxy());
132 WebRTCInternals::GetInstance()->AddObserver(observer.get());
133 WebRTCInternals::GetInstance()->OnAddPeerConnection(
134 0, 1, 2, kUrl, kRtcConfiguration, kContraints);
135 WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2);
136 EXPECT_EQ("removePeerConnection", observer->command());
137
138 base::DictionaryValue* dict = NULL;
139 EXPECT_TRUE(observer->value()->GetAsDictionary(&dict));
140
141 VerifyInt(dict, "pid", 1);
142 VerifyInt(dict, "lid", 2);
143
144 WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
145 }
146
TEST_F(WebRTCInternalsTest,SendUpdatePeerConnectionUpdate)147 TEST_F(WebRTCInternalsTest, SendUpdatePeerConnectionUpdate) {
148 scoped_ptr<MockWebRTCInternalsProxy> observer(
149 new MockWebRTCInternalsProxy());
150 WebRTCInternals::GetInstance()->AddObserver(observer.get());
151 WebRTCInternals::GetInstance()->OnAddPeerConnection(
152 0, 1, 2, kUrl, kRtcConfiguration, kContraints);
153
154 const std::string update_type = "fakeType";
155 const std::string update_value = "fakeValue";
156 WebRTCInternals::GetInstance()->OnUpdatePeerConnection(
157 1, 2, update_type, update_value);
158
159 EXPECT_EQ("updatePeerConnection", observer->command());
160
161 base::DictionaryValue* dict = NULL;
162 EXPECT_TRUE(observer->value()->GetAsDictionary(&dict));
163
164 VerifyInt(dict, "pid", 1);
165 VerifyInt(dict, "lid", 2);
166 VerifyString(dict, "type", update_type);
167 VerifyString(dict, "value", update_value);
168
169 std::string time;
170 EXPECT_TRUE(dict->GetString("time", &time));
171 EXPECT_FALSE(time.empty());
172
173 WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2);
174 WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
175 }
176
TEST_F(WebRTCInternalsTest,AddGetUserMedia)177 TEST_F(WebRTCInternalsTest, AddGetUserMedia) {
178 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy());
179
180 // Add one observer before "getUserMedia".
181 WebRTCInternals::GetInstance()->AddObserver(observer.get());
182
183 const int rid = 1;
184 const int pid = 2;
185 const std::string audio_constraint = "aaa";
186 const std::string video_constraint = "vvv";
187 WebRTCInternals::GetInstance()->OnGetUserMedia(
188 rid, pid, kUrl, true, true, audio_constraint, video_constraint);
189
190 EXPECT_EQ("addGetUserMedia", observer->command());
191 VerifyGetUserMediaData(
192 observer->value(), rid, pid, kUrl, audio_constraint, video_constraint);
193
194 WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
195 }
196
TEST_F(WebRTCInternalsTest,SendAllUpdateWithGetUserMedia)197 TEST_F(WebRTCInternalsTest, SendAllUpdateWithGetUserMedia) {
198 const int rid = 1;
199 const int pid = 2;
200 const std::string audio_constraint = "aaa";
201 const std::string video_constraint = "vvv";
202 WebRTCInternals::GetInstance()->OnGetUserMedia(
203 rid, pid, kUrl, true, true, audio_constraint, video_constraint);
204
205 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy());
206 // Add one observer after "getUserMedia".
207 WebRTCInternals::GetInstance()->AddObserver(observer.get());
208 WebRTCInternals::GetInstance()->UpdateObserver(observer.get());
209
210 EXPECT_EQ("addGetUserMedia", observer->command());
211 VerifyGetUserMediaData(
212 observer->value(), rid, pid, kUrl, audio_constraint, video_constraint);
213
214 WebRTCInternals::GetInstance()->RemoveObserver(observer.get());
215 }
216
TEST_F(WebRTCInternalsTest,SendAllUpdatesWithPeerConnectionUpdate)217 TEST_F(WebRTCInternalsTest, SendAllUpdatesWithPeerConnectionUpdate) {
218 const int rid = 0, pid = 1, lid = 2;
219 const std::string update_type = "fakeType";
220 const std::string update_value = "fakeValue";
221
222 WebRTCInternals::GetInstance()->OnAddPeerConnection(
223 rid, pid, lid, kUrl, kRtcConfiguration, kContraints);
224 WebRTCInternals::GetInstance()->OnUpdatePeerConnection(
225 pid, lid, update_type, update_value);
226
227 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy());
228 WebRTCInternals::GetInstance()->AddObserver(observer.get());
229
230 WebRTCInternals::GetInstance()->UpdateObserver(observer.get());
231
232 EXPECT_EQ("updateAllPeerConnections", observer->command());
233
234 base::ListValue* list = NULL;
235 EXPECT_TRUE(observer->value()->GetAsList(&list));
236 EXPECT_EQ(1U, list->GetSize());
237
238 base::DictionaryValue* dict = NULL;
239 EXPECT_TRUE((*list->begin())->GetAsDictionary(&dict));
240
241 VerifyInt(dict, "rid", rid);
242 VerifyInt(dict, "pid", pid);
243 VerifyInt(dict, "lid", lid);
244 VerifyString(dict, "url", kUrl);
245 VerifyString(dict, "rtcConfiguration", kRtcConfiguration);
246 VerifyString(dict, "constraints", kContraints);
247
248 base::ListValue* log = NULL;
249 EXPECT_TRUE(dict->GetList("log", &log));
250 EXPECT_EQ(1U, log->GetSize());
251
252 EXPECT_TRUE((*log->begin())->GetAsDictionary(&dict));
253 VerifyString(dict, "type", update_type);
254 VerifyString(dict, "value", update_value);
255 std::string time;
256 EXPECT_TRUE(dict->GetString("time", &time));
257 EXPECT_FALSE(time.empty());
258 }
259
TEST_F(WebRTCInternalsTest,OnAddStats)260 TEST_F(WebRTCInternalsTest, OnAddStats) {
261 const int rid = 0, pid = 1, lid = 2;
262 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy());
263 WebRTCInternals::GetInstance()->AddObserver(observer.get());
264 WebRTCInternals::GetInstance()->OnAddPeerConnection(
265 rid, pid, lid, kUrl, kRtcConfiguration, kContraints);
266
267 base::ListValue list;
268 list.AppendString("xxx");
269 list.AppendString("yyy");
270 WebRTCInternals::GetInstance()->OnAddStats(pid, lid, list);
271
272 EXPECT_EQ("addStats", observer->command());
273 base::DictionaryValue* dict = NULL;
274 EXPECT_TRUE(observer->value()->GetAsDictionary(&dict));
275
276 VerifyInt(dict, "pid", pid);
277 VerifyInt(dict, "lid", lid);
278 VerifyList(dict, "reports", list);
279 }
280
TEST_F(WebRTCInternalsTest,AecRecordingFileSelectionCanceled)281 TEST_F(WebRTCInternalsTest, AecRecordingFileSelectionCanceled) {
282 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy());
283 WebRTCInternals::GetInstance()->AddObserver(observer.get());
284 WebRTCInternals::GetInstance()->FileSelectionCanceled(NULL);
285 EXPECT_EQ("aecRecordingFileSelectionCancelled", observer->command());
286 EXPECT_EQ(NULL, observer->value());
287 }
288
289 } // namespace content
290