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 kServers = "s"; 19 static const std::string kUrl = "u"; 20 21 class MockWebRTCInternalsProxy : public WebRTCInternalsUIObserver { 22 public: 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 30 std::string command() { 31 return command_; 32 } 33 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: 45 WebRTCInternalsTest() : io_thread_(BrowserThread::UI, &io_loop_) { 46 WebRTCInternals::GetInstance()->ResetForTesting(); 47 } 48 49 protected: 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 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 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 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 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, kServers, kContraints); 103 EXPECT_EQ("", observer->command()); 104 105 WebRTCInternals::GetInstance()->OnRemovePeerConnection(3, 4); 106 } 107 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, kServers, 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, "servers", kServers); 123 VerifyString(dict, "constraints", kContraints); 124 125 WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); 126 WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2); 127 } 128 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, kServers, 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 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, kServers, 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 WebRTCInternals::GetInstance()->OnRemovePeerConnection(1, 2); 170 WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); 171 } 172 173 TEST_F(WebRTCInternalsTest, AddGetUserMedia) { 174 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy()); 175 176 // Add one observer before "getUserMedia". 177 WebRTCInternals::GetInstance()->AddObserver(observer.get()); 178 179 const int rid = 1; 180 const int pid = 2; 181 const std::string audio_constraint = "aaa"; 182 const std::string video_constraint = "vvv"; 183 WebRTCInternals::GetInstance()->OnGetUserMedia( 184 rid, pid, kUrl, true, true, audio_constraint, video_constraint); 185 186 EXPECT_EQ("addGetUserMedia", observer->command()); 187 VerifyGetUserMediaData( 188 observer->value(), rid, pid, kUrl, audio_constraint, video_constraint); 189 190 WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); 191 } 192 193 TEST_F(WebRTCInternalsTest, SendAllUpdateWithGetUserMedia) { 194 const int rid = 1; 195 const int pid = 2; 196 const std::string audio_constraint = "aaa"; 197 const std::string video_constraint = "vvv"; 198 WebRTCInternals::GetInstance()->OnGetUserMedia( 199 rid, pid, kUrl, true, true, audio_constraint, video_constraint); 200 201 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy()); 202 // Add one observer after "getUserMedia". 203 WebRTCInternals::GetInstance()->AddObserver(observer.get()); 204 WebRTCInternals::GetInstance()->UpdateObserver(observer.get()); 205 206 EXPECT_EQ("addGetUserMedia", observer->command()); 207 VerifyGetUserMediaData( 208 observer->value(), rid, pid, kUrl, audio_constraint, video_constraint); 209 210 WebRTCInternals::GetInstance()->RemoveObserver(observer.get()); 211 } 212 213 TEST_F(WebRTCInternalsTest, SendAllUpdatesWithPeerConnectionUpdate) { 214 const int rid = 0, pid = 1, lid = 2; 215 const std::string update_type = "fakeType"; 216 const std::string update_value = "fakeValue"; 217 218 WebRTCInternals::GetInstance()->OnAddPeerConnection( 219 rid, pid, lid, kUrl, kServers, kContraints); 220 WebRTCInternals::GetInstance()->OnUpdatePeerConnection( 221 pid, lid, update_type, update_value); 222 223 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy()); 224 WebRTCInternals::GetInstance()->AddObserver(observer.get()); 225 226 WebRTCInternals::GetInstance()->UpdateObserver(observer.get()); 227 228 EXPECT_EQ("updateAllPeerConnections", observer->command()); 229 230 base::ListValue* list = NULL; 231 EXPECT_TRUE(observer->value()->GetAsList(&list)); 232 EXPECT_EQ(1U, list->GetSize()); 233 234 base::DictionaryValue* dict = NULL; 235 EXPECT_TRUE((*list->begin())->GetAsDictionary(&dict)); 236 237 VerifyInt(dict, "rid", rid); 238 VerifyInt(dict, "pid", pid); 239 VerifyInt(dict, "lid", lid); 240 VerifyString(dict, "url", kUrl); 241 VerifyString(dict, "servers", kServers); 242 VerifyString(dict, "constraints", kContraints); 243 244 base::ListValue* log = NULL; 245 EXPECT_TRUE(dict->GetList("log", &log)); 246 EXPECT_EQ(1U, log->GetSize()); 247 248 EXPECT_TRUE((*log->begin())->GetAsDictionary(&dict)); 249 VerifyString(dict, "type", update_type); 250 VerifyString(dict, "value", update_value); 251 } 252 253 TEST_F(WebRTCInternalsTest, OnAddStats) { 254 const int rid = 0, pid = 1, lid = 2; 255 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy()); 256 WebRTCInternals::GetInstance()->AddObserver(observer.get()); 257 WebRTCInternals::GetInstance()->OnAddPeerConnection( 258 rid, pid, lid, kUrl, kServers, kContraints); 259 260 base::ListValue list; 261 list.AppendString("xxx"); 262 list.AppendString("yyy"); 263 WebRTCInternals::GetInstance()->OnAddStats(pid, lid, list); 264 265 EXPECT_EQ("addStats", observer->command()); 266 base::DictionaryValue* dict = NULL; 267 EXPECT_TRUE(observer->value()->GetAsDictionary(&dict)); 268 269 VerifyInt(dict, "pid", pid); 270 VerifyInt(dict, "lid", lid); 271 VerifyList(dict, "reports", list); 272 } 273 274 TEST_F(WebRTCInternalsTest, AecRecordingFileSelectionCanceled) { 275 scoped_ptr<MockWebRTCInternalsProxy> observer(new MockWebRTCInternalsProxy()); 276 WebRTCInternals::GetInstance()->AddObserver(observer.get()); 277 WebRTCInternals::GetInstance()->FileSelectionCanceled(NULL); 278 EXPECT_EQ("aecRecordingFileSelectionCancelled", observer->command()); 279 EXPECT_EQ(NULL, observer->value()); 280 } 281 282 } // namespace content 283