1 // Copyright (c) 2012 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 <string> 6 7 #include "base/memory/ref_counted.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/message_loop/message_loop.h" 10 #include "content/common/media/media_stream_messages.h" 11 #include "content/public/common/media_stream_request.h" 12 #include "content/renderer/media/media_stream_dispatcher.h" 13 #include "content/renderer/media/media_stream_dispatcher_eventhandler.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "url/gurl.h" 16 17 namespace content { 18 namespace { 19 20 const int kRouteId = 0; 21 const int kAudioSessionId = 3; 22 const int kVideoSessionId = 5; 23 const int kRequestId1 = 10; 24 const int kRequestId2 = 20; 25 const int kRequestId3 = 30; 26 const int kRequestId4 = 40; 27 static const char kLabel[] = "test"; 28 29 const MediaStreamType kAudioType = MEDIA_DEVICE_AUDIO_CAPTURE; 30 const MediaStreamType kVideoType = MEDIA_DEVICE_VIDEO_CAPTURE; 31 const MediaStreamType kNoAudioType = MEDIA_NO_SERVICE; 32 33 class MockMediaStreamDispatcherEventHandler 34 : public MediaStreamDispatcherEventHandler, 35 public base::SupportsWeakPtr<MockMediaStreamDispatcherEventHandler> { 36 public: 37 MockMediaStreamDispatcherEventHandler() 38 : request_id_(-1) {} 39 40 virtual void OnStreamGenerated( 41 int request_id, 42 const std::string &label, 43 const StreamDeviceInfoArray& audio_device_array, 44 const StreamDeviceInfoArray& video_device_array) OVERRIDE { 45 request_id_ = request_id; 46 label_ = label; 47 } 48 49 virtual void OnStreamGenerationFailed(int request_id) OVERRIDE { 50 request_id_ = request_id; 51 } 52 53 virtual void OnStopGeneratedStream(const std::string& label) OVERRIDE { 54 label_ = label; 55 } 56 57 virtual void OnDevicesEnumerated( 58 int request_id, 59 const StreamDeviceInfoArray& device_array) OVERRIDE { 60 request_id_ = request_id; 61 } 62 63 virtual void OnDevicesEnumerationFailed(int request_id) OVERRIDE { 64 request_id_ = request_id; 65 } 66 67 virtual void OnDeviceOpened( 68 int request_id, 69 const std::string& label, 70 const StreamDeviceInfo& video_device) OVERRIDE { 71 request_id_ = request_id; 72 label_ = label; 73 } 74 75 virtual void OnDeviceOpenFailed(int request_id) OVERRIDE { 76 request_id_ = request_id; 77 } 78 79 int request_id_; 80 std::string label_; 81 82 DISALLOW_COPY_AND_ASSIGN(MockMediaStreamDispatcherEventHandler); 83 }; 84 85 } // namespace 86 87 TEST(MediaStreamDispatcherTest, BasicStream) { 88 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 89 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); 90 scoped_ptr<MockMediaStreamDispatcherEventHandler> 91 handler(new MockMediaStreamDispatcherEventHandler); 92 StreamOptions components(kAudioType, kVideoType); 93 GURL security_origin; 94 95 int ipc_request_id1 = dispatcher->next_ipc_id_; 96 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), 97 components, security_origin); 98 int ipc_request_id2 = dispatcher->next_ipc_id_; 99 EXPECT_NE(ipc_request_id1, ipc_request_id2); 100 dispatcher->GenerateStream(kRequestId2, handler.get()->AsWeakPtr(), 101 components, security_origin); 102 EXPECT_EQ(dispatcher->requests_.size(), size_t(2)); 103 104 StreamDeviceInfoArray audio_device_array(1); 105 StreamDeviceInfo audio_device_info; 106 audio_device_info.device.name = "Microphone"; 107 audio_device_info.device.type = kAudioType; 108 audio_device_info.session_id = kAudioSessionId; 109 audio_device_array[0] = audio_device_info; 110 111 StreamDeviceInfoArray video_device_array(1); 112 StreamDeviceInfo video_device_info; 113 video_device_info.device.name = "Camera"; 114 video_device_info.device.type = kVideoType; 115 video_device_info.session_id = kVideoSessionId; 116 video_device_array[0] = video_device_info; 117 118 // Complete the creation of stream1. 119 std::string stream_label1 = std::string("stream1"); 120 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( 121 kRouteId, ipc_request_id1, stream_label1, 122 audio_device_array, video_device_array)); 123 EXPECT_EQ(handler->request_id_, kRequestId1); 124 EXPECT_EQ(handler->label_, stream_label1); 125 126 // Complete the creation of stream2. 127 std::string stream_label2 = std::string("stream2"); 128 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( 129 kRouteId, ipc_request_id2, stream_label2, 130 audio_device_array, video_device_array)); 131 EXPECT_EQ(handler->request_id_, kRequestId2); 132 EXPECT_EQ(handler->label_, stream_label2); 133 134 EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); 135 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(2)); 136 137 // Check the session_id of stream2. 138 EXPECT_EQ(dispatcher->audio_session_id(stream_label2, 0), kAudioSessionId); 139 EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), kVideoSessionId); 140 141 // Stop stream2. 142 dispatcher->StopStream(stream_label2); 143 EXPECT_EQ(dispatcher->audio_session_id(stream_label2, 0), 144 StreamDeviceInfo::kNoId); 145 EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), 146 StreamDeviceInfo::kNoId); 147 148 // Stop stream1. 149 dispatcher->StopStream(stream_label1); 150 EXPECT_EQ(dispatcher->audio_session_id(stream_label1, 0), 151 StreamDeviceInfo::kNoId); 152 EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), 153 StreamDeviceInfo::kNoId); 154 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); 155 156 // Verify that the request has been completed. 157 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); 158 EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); 159 } 160 161 TEST(MediaStreamDispatcherTest, BasicStreamForDevice) { 162 static const char kDeviceId[] = "/dev/video0"; 163 164 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 165 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); 166 scoped_ptr<MockMediaStreamDispatcherEventHandler> 167 handler(new MockMediaStreamDispatcherEventHandler); 168 StreamOptions components(kNoAudioType, kVideoType); 169 components.audio_device_id = kDeviceId; 170 components.video_device_id = kDeviceId; 171 GURL security_origin; 172 173 int ipc_request_id1 = dispatcher->next_ipc_id_; 174 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), 175 components, security_origin); 176 int ipc_request_id2 = dispatcher->next_ipc_id_; 177 EXPECT_NE(ipc_request_id1, ipc_request_id2); 178 dispatcher->GenerateStream(kRequestId2, handler.get()->AsWeakPtr(), 179 components, security_origin); 180 EXPECT_EQ(dispatcher->requests_.size(), size_t(2)); 181 182 // No audio requested. 183 StreamDeviceInfoArray audio_device_array; 184 185 StreamDeviceInfoArray video_device_array(1); 186 StreamDeviceInfo video_device_info; 187 video_device_info.device.name = "Fake Video Capture Device"; 188 video_device_info.device.type = kVideoType; 189 video_device_info.session_id = kVideoSessionId; 190 video_device_array[0] = video_device_info; 191 192 // Complete the creation of stream1. 193 std::string stream_label1 = std::string("stream1"); 194 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( 195 kRouteId, ipc_request_id1, stream_label1, 196 audio_device_array, video_device_array)); 197 EXPECT_EQ(handler->request_id_, kRequestId1); 198 EXPECT_EQ(handler->label_, stream_label1); 199 200 // Complete the creation of stream2. 201 std::string stream_label2 = std::string("stream2"); 202 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( 203 kRouteId, ipc_request_id2, stream_label2, 204 audio_device_array, video_device_array)); 205 EXPECT_EQ(handler->request_id_, kRequestId2); 206 EXPECT_EQ(handler->label_, stream_label2); 207 208 EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); 209 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(2)); 210 211 // Check the session_id of stream2. 212 EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), kVideoSessionId); 213 214 // Stop stream2. 215 dispatcher->StopStream(stream_label2); 216 EXPECT_EQ(dispatcher->audio_session_id(stream_label2, 0), 217 StreamDeviceInfo::kNoId); 218 EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), 219 StreamDeviceInfo::kNoId); 220 221 // Stop stream1. 222 dispatcher->StopStream(stream_label1); 223 EXPECT_EQ(dispatcher->audio_session_id(stream_label1, 0), 224 StreamDeviceInfo::kNoId); 225 EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), 226 StreamDeviceInfo::kNoId); 227 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); 228 229 // Verify that the request has been completed. 230 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); 231 EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); 232 } 233 234 TEST(MediaStreamDispatcherTest, BasicVideoDevice) { 235 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 236 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); 237 scoped_ptr<MockMediaStreamDispatcherEventHandler> 238 handler1(new MockMediaStreamDispatcherEventHandler); 239 scoped_ptr<MockMediaStreamDispatcherEventHandler> 240 handler2(new MockMediaStreamDispatcherEventHandler); 241 GURL security_origin; 242 243 int ipc_request_id1 = dispatcher->next_ipc_id_; 244 dispatcher->EnumerateDevices( 245 kRequestId1, handler1.get()->AsWeakPtr(), 246 kVideoType, 247 security_origin); 248 int ipc_request_id2 = dispatcher->next_ipc_id_; 249 EXPECT_NE(ipc_request_id1, ipc_request_id2); 250 dispatcher->EnumerateDevices( 251 kRequestId2, handler2.get()->AsWeakPtr(), 252 kVideoType, 253 security_origin); 254 EXPECT_EQ(dispatcher->video_enumeration_state_.requests.size(), size_t(2)); 255 256 StreamDeviceInfoArray video_device_array(1); 257 StreamDeviceInfo video_device_info; 258 video_device_info.device.name = "Camera"; 259 video_device_info.device.id = "device_path"; 260 video_device_info.device.type = kVideoType; 261 video_device_info.session_id = kVideoSessionId; 262 video_device_array[0] = video_device_info; 263 264 // Complete the enumeration request and all requesters should receive reply. 265 dispatcher->OnMessageReceived(MediaStreamMsg_DevicesEnumerated( 266 kRouteId, ipc_request_id1, kLabel, video_device_array)); 267 EXPECT_EQ(handler1->request_id_, kRequestId1); 268 EXPECT_EQ(handler2->request_id_, kRequestId2); 269 270 EXPECT_EQ(dispatcher->video_enumeration_state_.requests.size(), size_t(2)); 271 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); 272 273 int ipc_request_id3 = dispatcher->next_ipc_id_; 274 dispatcher->OpenDevice(kRequestId3, handler1.get()->AsWeakPtr(), 275 video_device_info.device.id, 276 kVideoType, 277 security_origin); 278 int ipc_request_id4 = dispatcher->next_ipc_id_; 279 EXPECT_NE(ipc_request_id3, ipc_request_id4); 280 dispatcher->OpenDevice(kRequestId4, handler1.get()->AsWeakPtr(), 281 video_device_info.device.id, 282 kVideoType, 283 security_origin); 284 EXPECT_EQ(dispatcher->requests_.size(), size_t(2)); 285 286 // Complete the OpenDevice of request 1. 287 std::string stream_label1 = std::string("stream1"); 288 dispatcher->OnMessageReceived(MediaStreamMsg_DeviceOpened( 289 kRouteId, ipc_request_id3, stream_label1, video_device_info)); 290 EXPECT_EQ(handler1->request_id_, kRequestId3); 291 292 // Complete the OpenDevice of request 2. 293 std::string stream_label2 = std::string("stream2"); 294 dispatcher->OnMessageReceived(MediaStreamMsg_DeviceOpened( 295 kRouteId, ipc_request_id4, stream_label2, video_device_info)); 296 EXPECT_EQ(handler1->request_id_, kRequestId4); 297 298 EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); 299 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(2)); 300 301 // Check the video_session_id. 302 EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), kVideoSessionId); 303 EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), kVideoSessionId); 304 305 // Stop stream2. 306 dispatcher->StopStream(stream_label2); 307 EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), 308 StreamDeviceInfo::kNoId); 309 310 // Stop stream1. 311 dispatcher->StopStream(stream_label1); 312 EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), 313 StreamDeviceInfo::kNoId); 314 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); 315 316 // Verify that the request have been completed. 317 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); 318 EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); 319 } 320 321 TEST(MediaStreamDispatcherTest, TestFailure) { 322 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 323 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); 324 scoped_ptr<MockMediaStreamDispatcherEventHandler> 325 handler(new MockMediaStreamDispatcherEventHandler); 326 StreamOptions components(kAudioType, kVideoType); 327 GURL security_origin; 328 329 // Test failure when creating a stream. 330 int ipc_request_id1 = dispatcher->next_ipc_id_; 331 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), 332 components, security_origin); 333 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerationFailed( 334 kRouteId, ipc_request_id1)); 335 336 // Verify that the request have been completed. 337 EXPECT_EQ(handler->request_id_, kRequestId1); 338 EXPECT_EQ(dispatcher->requests_.size(), size_t(0)); 339 340 // Create a new stream. 341 ipc_request_id1 = dispatcher->next_ipc_id_; 342 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), 343 components, security_origin); 344 345 StreamDeviceInfoArray audio_device_array(1); 346 StreamDeviceInfo audio_device_info; 347 audio_device_info.device.name = "Microphone"; 348 audio_device_info.device.type = kAudioType; 349 audio_device_info.session_id = kAudioSessionId; 350 audio_device_array[0] = audio_device_info; 351 352 StreamDeviceInfoArray video_device_array(1); 353 StreamDeviceInfo video_device_info; 354 video_device_info.device.name = "Camera"; 355 video_device_info.device.type = kVideoType; 356 video_device_info.session_id = kVideoSessionId; 357 video_device_array[0] = video_device_info; 358 359 // Complete the creation of stream1. 360 std::string stream_label1 = std::string("stream1"); 361 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( 362 kRouteId, ipc_request_id1, stream_label1, 363 audio_device_array, video_device_array)); 364 EXPECT_EQ(handler->request_id_, kRequestId1); 365 EXPECT_EQ(handler->label_, stream_label1); 366 EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), kVideoSessionId); 367 368 // Stop stream1. 369 dispatcher->StopStream(stream_label1); 370 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0)); 371 } 372 373 TEST(MediaStreamDispatcherTest, CancelGenerateStream) { 374 scoped_ptr<base::MessageLoop> message_loop(new base::MessageLoop()); 375 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL)); 376 scoped_ptr<MockMediaStreamDispatcherEventHandler> 377 handler(new MockMediaStreamDispatcherEventHandler); 378 StreamOptions components(kAudioType, kVideoType); 379 int ipc_request_id1 = dispatcher->next_ipc_id_; 380 381 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(), 382 components, GURL()); 383 dispatcher->GenerateStream(kRequestId2, handler.get()->AsWeakPtr(), 384 components, GURL()); 385 386 EXPECT_EQ(2u, dispatcher->requests_.size()); 387 dispatcher->CancelGenerateStream(kRequestId2, handler.get()->AsWeakPtr()); 388 EXPECT_EQ(1u, dispatcher->requests_.size()); 389 390 // Complete the creation of stream1. 391 StreamDeviceInfo audio_device_info; 392 audio_device_info.device.name = "Microphone"; 393 audio_device_info.device.type = kAudioType; 394 audio_device_info.session_id = kAudioSessionId; 395 StreamDeviceInfoArray audio_device_array(1); 396 audio_device_array[0] = audio_device_info; 397 398 StreamDeviceInfo video_device_info; 399 video_device_info.device.name = "Camera"; 400 video_device_info.device.type = kVideoType; 401 video_device_info.session_id = kVideoSessionId; 402 StreamDeviceInfoArray video_device_array(1); 403 video_device_array[0] = video_device_info; 404 405 std::string stream_label1 = "stream1"; 406 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated( 407 kRouteId, ipc_request_id1, stream_label1, 408 audio_device_array, video_device_array)); 409 EXPECT_EQ(handler->request_id_, kRequestId1); 410 EXPECT_EQ(handler->label_, stream_label1); 411 EXPECT_EQ(0u, dispatcher->requests_.size()); 412 } 413 414 } // namespace content 415