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 "base/memory/scoped_ptr.h" 6 #include "base/message_loop/message_loop.h" 7 #include "base/strings/utf_string_conversions.h" 8 #include "content/child/child_process.h" 9 #include "content/renderer/media/media_stream.h" 10 #include "content/renderer/media/media_stream_track.h" 11 #include "content/renderer/media/mock_media_stream_dispatcher.h" 12 #include "content/renderer/media/mock_media_stream_video_source.h" 13 #include "content/renderer/media/user_media_client_impl.h" 14 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" 17 #include "third_party/WebKit/public/platform/WebMediaStream.h" 18 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 19 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 20 #include "third_party/WebKit/public/platform/WebMediaStreamTrackSourcesRequest.h" 21 #include "third_party/WebKit/public/platform/WebString.h" 22 #include "third_party/WebKit/public/platform/WebVector.h" 23 #include "third_party/WebKit/public/web/WebHeap.h" 24 25 namespace content { 26 27 class MockMediaStreamVideoCapturerSource : public MockMediaStreamVideoSource { 28 public: 29 MockMediaStreamVideoCapturerSource( 30 const StreamDeviceInfo& device, 31 const SourceStoppedCallback& stop_callback, 32 PeerConnectionDependencyFactory* factory) 33 : MockMediaStreamVideoSource(false) { 34 SetDeviceInfo(device); 35 SetStopCallback(stop_callback); 36 } 37 }; 38 39 class UserMediaClientImplUnderTest : public UserMediaClientImpl { 40 public: 41 enum RequestState { 42 REQUEST_NOT_STARTED, 43 REQUEST_NOT_COMPLETE, 44 REQUEST_SUCCEEDED, 45 REQUEST_FAILED, 46 }; 47 48 UserMediaClientImplUnderTest( 49 PeerConnectionDependencyFactory* dependency_factory, 50 scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher) 51 : UserMediaClientImpl( 52 NULL, dependency_factory, media_stream_dispatcher.Pass()), 53 state_(REQUEST_NOT_STARTED), 54 result_(NUM_MEDIA_REQUEST_RESULTS), 55 result_name_(""), 56 factory_(dependency_factory), 57 video_source_(NULL) { 58 } 59 60 void RequestUserMedia() { 61 blink::WebUserMediaRequest user_media_request; 62 state_ = REQUEST_NOT_COMPLETE; 63 requestUserMedia(user_media_request); 64 } 65 66 void RequestMediaDevices() { 67 blink::WebMediaDevicesRequest media_devices_request; 68 state_ = REQUEST_NOT_COMPLETE; 69 requestMediaDevices(media_devices_request); 70 } 71 72 void RequestSources() { 73 blink::WebMediaStreamTrackSourcesRequest sources_request; 74 state_ = REQUEST_NOT_COMPLETE; 75 requestSources(sources_request); 76 } 77 78 virtual void GetUserMediaRequestSucceeded( 79 const blink::WebMediaStream& stream, 80 blink::WebUserMediaRequest* request_info) OVERRIDE { 81 last_generated_stream_ = stream; 82 state_ = REQUEST_SUCCEEDED; 83 } 84 85 virtual void GetUserMediaRequestFailed( 86 blink::WebUserMediaRequest* request_info, 87 content::MediaStreamRequestResult result) OVERRIDE { 88 last_generated_stream_.reset(); 89 state_ = REQUEST_FAILED; 90 result_ = result; 91 } 92 93 virtual void GetUserMediaRequestTrackStartedFailed( 94 blink::WebUserMediaRequest* request_info, 95 MediaStreamRequestResult result, 96 const blink::WebString& result_name) OVERRIDE { 97 last_generated_stream_.reset(); 98 state_ = REQUEST_FAILED; 99 result_ = result; 100 result_name_ = result_name; 101 } 102 103 virtual void EnumerateDevicesSucceded( 104 blink::WebMediaDevicesRequest* request, 105 blink::WebVector<blink::WebMediaDeviceInfo>& devices) OVERRIDE { 106 state_ = REQUEST_SUCCEEDED; 107 last_devices_ = devices; 108 } 109 110 virtual void EnumerateSourcesSucceded( 111 blink::WebMediaStreamTrackSourcesRequest* request, 112 blink::WebVector<blink::WebSourceInfo>& sources) OVERRIDE { 113 state_ = REQUEST_SUCCEEDED; 114 last_sources_ = sources; 115 } 116 117 virtual MediaStreamVideoSource* CreateVideoSource( 118 const StreamDeviceInfo& device, 119 const MediaStreamSource::SourceStoppedCallback& stop_callback) OVERRIDE { 120 video_source_ = new MockMediaStreamVideoCapturerSource(device, 121 stop_callback, 122 factory_); 123 return video_source_; 124 } 125 126 const blink::WebMediaStream& last_generated_stream() { 127 return last_generated_stream_; 128 } 129 130 const blink::WebVector<blink::WebMediaDeviceInfo>& last_devices() { 131 return last_devices_; 132 } 133 134 const blink::WebVector<blink::WebSourceInfo>& last_sources() { 135 return last_sources_; 136 } 137 138 void ClearLastGeneratedStream() { 139 last_generated_stream_.reset(); 140 } 141 142 MockMediaStreamVideoCapturerSource* last_created_video_source() const { 143 return video_source_; 144 } 145 146 RequestState request_state() const { return state_; } 147 content::MediaStreamRequestResult error_reason() const { return result_; } 148 blink::WebString error_name() const { return result_name_; } 149 150 private: 151 blink::WebMediaStream last_generated_stream_; 152 RequestState state_; 153 content::MediaStreamRequestResult result_; 154 blink::WebString result_name_; 155 blink::WebVector<blink::WebMediaDeviceInfo> last_devices_; 156 blink::WebVector<blink::WebSourceInfo> last_sources_; 157 PeerConnectionDependencyFactory* factory_; 158 MockMediaStreamVideoCapturerSource* video_source_; 159 }; 160 161 class UserMediaClientImplTest : public ::testing::Test { 162 public: 163 virtual void SetUp() { 164 // Create our test object. 165 child_process_.reset(new ChildProcess()); 166 dependency_factory_.reset(new MockPeerConnectionDependencyFactory()); 167 ms_dispatcher_ = new MockMediaStreamDispatcher(); 168 used_media_impl_.reset(new UserMediaClientImplUnderTest( 169 dependency_factory_.get(), 170 scoped_ptr<MediaStreamDispatcher>(ms_dispatcher_).Pass())); 171 } 172 173 virtual void TearDown() OVERRIDE { 174 used_media_impl_.reset(); 175 blink::WebHeap::collectAllGarbageForTesting(); 176 } 177 178 blink::WebMediaStream RequestLocalMediaStream() { 179 used_media_impl_->RequestUserMedia(); 180 FakeMediaStreamDispatcherRequestUserMediaComplete(); 181 StartMockedVideoSource(); 182 183 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_SUCCEEDED, 184 used_media_impl_->request_state()); 185 186 blink::WebMediaStream desc = used_media_impl_->last_generated_stream(); 187 content::MediaStream* native_stream = 188 content::MediaStream::GetMediaStream(desc); 189 if (!native_stream) { 190 ADD_FAILURE(); 191 return desc; 192 } 193 194 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; 195 desc.audioTracks(audio_tracks); 196 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; 197 desc.videoTracks(video_tracks); 198 199 EXPECT_EQ(1u, audio_tracks.size()); 200 EXPECT_EQ(1u, video_tracks.size()); 201 EXPECT_NE(audio_tracks[0].id(), video_tracks[0].id()); 202 return desc; 203 } 204 205 void FakeMediaStreamDispatcherRequestUserMediaComplete() { 206 // Audio request ID is used as the shared request ID. 207 used_media_impl_->OnStreamGenerated( 208 ms_dispatcher_->audio_input_request_id(), 209 ms_dispatcher_->stream_label(), 210 ms_dispatcher_->audio_input_array(), 211 ms_dispatcher_->video_array()); 212 } 213 214 void FakeMediaStreamDispatcherRequestMediaDevicesComplete() { 215 used_media_impl_->OnDevicesEnumerated( 216 ms_dispatcher_->audio_input_request_id(), 217 ms_dispatcher_->audio_input_array()); 218 used_media_impl_->OnDevicesEnumerated( 219 ms_dispatcher_->audio_output_request_id(), 220 ms_dispatcher_->audio_output_array()); 221 used_media_impl_->OnDevicesEnumerated( 222 ms_dispatcher_->video_request_id(), 223 ms_dispatcher_->video_array()); 224 } 225 226 void FakeMediaStreamDispatcherRequestSourcesComplete() { 227 used_media_impl_->OnDevicesEnumerated( 228 ms_dispatcher_->audio_input_request_id(), 229 ms_dispatcher_->audio_input_array()); 230 used_media_impl_->OnDevicesEnumerated( 231 ms_dispatcher_->video_request_id(), 232 ms_dispatcher_->video_array()); 233 } 234 235 void StartMockedVideoSource() { 236 MockMediaStreamVideoCapturerSource* video_source = 237 used_media_impl_->last_created_video_source(); 238 if (video_source->SourceHasAttemptedToStart()) 239 video_source->StartMockedSource(); 240 } 241 242 void FailToStartMockedVideoSource() { 243 MockMediaStreamVideoCapturerSource* video_source = 244 used_media_impl_->last_created_video_source(); 245 if (video_source->SourceHasAttemptedToStart()) 246 video_source->FailToStartMockedSource(); 247 blink::WebHeap::collectGarbageForTesting(); 248 } 249 250 void FailToCreateNextAudioCapturer() { 251 dependency_factory_->FailToCreateNextAudioCapturer(); 252 blink::WebHeap::collectGarbageForTesting(); 253 } 254 255 protected: 256 base::MessageLoop message_loop_; 257 scoped_ptr<ChildProcess> child_process_; 258 MockMediaStreamDispatcher* ms_dispatcher_; // Owned by |used_media_impl_|. 259 scoped_ptr<UserMediaClientImplUnderTest> used_media_impl_; 260 scoped_ptr<MockPeerConnectionDependencyFactory> dependency_factory_; 261 }; 262 263 TEST_F(UserMediaClientImplTest, GenerateMediaStream) { 264 // Generate a stream with both audio and video. 265 blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); 266 } 267 268 // Test that the same source object is used if two MediaStreams are generated 269 // using the same source. 270 TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithSameSource) { 271 blink::WebMediaStream desc1 = RequestLocalMediaStream(); 272 blink::WebMediaStream desc2 = RequestLocalMediaStream(); 273 274 blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks; 275 desc1.videoTracks(desc1_video_tracks); 276 blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks; 277 desc2.videoTracks(desc2_video_tracks); 278 EXPECT_EQ(desc1_video_tracks[0].source().id(), 279 desc2_video_tracks[0].source().id()); 280 281 EXPECT_EQ(desc1_video_tracks[0].source().extraData(), 282 desc2_video_tracks[0].source().extraData()); 283 284 blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks; 285 desc1.audioTracks(desc1_audio_tracks); 286 blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks; 287 desc2.audioTracks(desc2_audio_tracks); 288 EXPECT_EQ(desc1_audio_tracks[0].source().id(), 289 desc2_audio_tracks[0].source().id()); 290 291 EXPECT_EQ(desc1_audio_tracks[0].source().extraData(), 292 desc2_audio_tracks[0].source().extraData()); 293 } 294 295 // Test that the same source object is not used if two MediaStreams are 296 // generated using different sources. 297 TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithDifferentSources) { 298 blink::WebMediaStream desc1 = RequestLocalMediaStream(); 299 // Make sure another device is selected (another |session_id|) in the next 300 // gUM request. 301 ms_dispatcher_->IncrementSessionId(); 302 blink::WebMediaStream desc2 = RequestLocalMediaStream(); 303 304 blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks; 305 desc1.videoTracks(desc1_video_tracks); 306 blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks; 307 desc2.videoTracks(desc2_video_tracks); 308 EXPECT_NE(desc1_video_tracks[0].source().id(), 309 desc2_video_tracks[0].source().id()); 310 311 EXPECT_NE(desc1_video_tracks[0].source().extraData(), 312 desc2_video_tracks[0].source().extraData()); 313 314 blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks; 315 desc1.audioTracks(desc1_audio_tracks); 316 blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks; 317 desc2.audioTracks(desc2_audio_tracks); 318 EXPECT_NE(desc1_audio_tracks[0].source().id(), 319 desc2_audio_tracks[0].source().id()); 320 321 EXPECT_NE(desc1_audio_tracks[0].source().extraData(), 322 desc2_audio_tracks[0].source().extraData()); 323 } 324 325 TEST_F(UserMediaClientImplTest, StopLocalTracks) { 326 // Generate a stream with both audio and video. 327 blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); 328 329 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; 330 mixed_desc.audioTracks(audio_tracks); 331 MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]); 332 audio_track->Stop(); 333 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 334 335 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; 336 mixed_desc.videoTracks(video_tracks); 337 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]); 338 video_track->Stop(); 339 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 340 } 341 342 // This test that a source is not stopped even if the tracks in a 343 // MediaStream is stopped if there are two MediaStreams with tracks using the 344 // same device. The source is stopped 345 // if there are no more MediaStream tracks using the device. 346 TEST_F(UserMediaClientImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) { 347 // Generate a stream with both audio and video. 348 blink::WebMediaStream desc1 = RequestLocalMediaStream(); 349 blink::WebMediaStream desc2 = RequestLocalMediaStream(); 350 351 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks1; 352 desc1.audioTracks(audio_tracks1); 353 MediaStreamTrack* audio_track1 = MediaStreamTrack::GetTrack(audio_tracks1[0]); 354 audio_track1->Stop(); 355 EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter()); 356 357 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks2; 358 desc2.audioTracks(audio_tracks2); 359 MediaStreamTrack* audio_track2 = MediaStreamTrack::GetTrack(audio_tracks2[0]); 360 audio_track2->Stop(); 361 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 362 363 blink::WebVector<blink::WebMediaStreamTrack> video_tracks1; 364 desc1.videoTracks(video_tracks1); 365 MediaStreamTrack* video_track1 = MediaStreamTrack::GetTrack(video_tracks1[0]); 366 video_track1->Stop(); 367 EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter()); 368 369 blink::WebVector<blink::WebMediaStreamTrack> video_tracks2; 370 desc2.videoTracks(video_tracks2); 371 MediaStreamTrack* video_track2 = MediaStreamTrack::GetTrack(video_tracks2[0]); 372 video_track2->Stop(); 373 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 374 } 375 376 TEST_F(UserMediaClientImplTest, StopSourceWhenMediaStreamGoesOutOfScope) { 377 // Generate a stream with both audio and video. 378 RequestLocalMediaStream(); 379 // Makes sure the test itself don't hold a reference to the created 380 // MediaStream. 381 used_media_impl_->ClearLastGeneratedStream(); 382 blink::WebHeap::collectGarbageForTesting(); 383 384 // Expect the sources to be stopped when the MediaStream goes out of scope. 385 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 386 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 387 } 388 389 // Test that the MediaStreams are deleted if the owning WebFrame is closing. 390 // In the unit test the owning frame is NULL. 391 TEST_F(UserMediaClientImplTest, FrameWillClose) { 392 // Test a stream with both audio and video. 393 blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); 394 blink::WebMediaStream desc2 = RequestLocalMediaStream(); 395 used_media_impl_->FrameWillClose(); 396 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 397 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 398 } 399 400 // This test what happens if a video source to a MediaSteam fails to start. 401 TEST_F(UserMediaClientImplTest, MediaVideoSourceFailToStart) { 402 used_media_impl_->RequestUserMedia(); 403 FakeMediaStreamDispatcherRequestUserMediaComplete(); 404 FailToStartMockedVideoSource(); 405 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_FAILED, 406 used_media_impl_->request_state()); 407 EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE, 408 used_media_impl_->error_reason()); 409 blink::WebHeap::collectGarbageForTesting(); 410 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 411 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 412 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 413 } 414 415 // This test what happens if an audio source fail to initialize. 416 TEST_F(UserMediaClientImplTest, MediaAudioSourceFailToInitialize) { 417 FailToCreateNextAudioCapturer(); 418 used_media_impl_->RequestUserMedia(); 419 FakeMediaStreamDispatcherRequestUserMediaComplete(); 420 StartMockedVideoSource(); 421 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_FAILED, 422 used_media_impl_->request_state()); 423 EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE, 424 used_media_impl_->error_reason()); 425 blink::WebHeap::collectGarbageForTesting(); 426 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 427 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 428 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 429 } 430 431 // This test what happens if UserMediaClientImpl is deleted before a source has 432 // started. 433 TEST_F(UserMediaClientImplTest, MediaStreamImplShutDown) { 434 used_media_impl_->RequestUserMedia(); 435 FakeMediaStreamDispatcherRequestUserMediaComplete(); 436 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 437 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_NOT_COMPLETE, 438 used_media_impl_->request_state()); 439 used_media_impl_.reset(); 440 } 441 442 // This test what happens if the WebFrame is closed while the MediaStream is 443 // being generated by the MediaStreamDispatcher. 444 TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingStream) { 445 used_media_impl_->RequestUserMedia(); 446 used_media_impl_->FrameWillClose(); 447 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 448 EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter()); 449 EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter()); 450 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_NOT_COMPLETE, 451 used_media_impl_->request_state()); 452 } 453 454 // This test what happens if the WebFrame is closed while the sources are being 455 // started. 456 TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingSources) { 457 used_media_impl_->RequestUserMedia(); 458 FakeMediaStreamDispatcherRequestUserMediaComplete(); 459 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 460 used_media_impl_->FrameWillClose(); 461 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 462 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 463 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_NOT_COMPLETE, 464 used_media_impl_->request_state()); 465 } 466 467 // This test what happens if stop is called on a track after the frame has 468 // been reloaded. 469 TEST_F(UserMediaClientImplTest, StopTrackAfterReload) { 470 blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); 471 EXPECT_EQ(1, ms_dispatcher_->request_stream_counter()); 472 used_media_impl_->FrameWillClose(); 473 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 474 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 475 476 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; 477 mixed_desc.audioTracks(audio_tracks); 478 MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]); 479 audio_track->Stop(); 480 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); 481 482 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; 483 mixed_desc.videoTracks(video_tracks); 484 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]); 485 video_track->Stop(); 486 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); 487 } 488 489 TEST_F(UserMediaClientImplTest, EnumerateMediaDevices) { 490 used_media_impl_->RequestMediaDevices(); 491 FakeMediaStreamDispatcherRequestMediaDevicesComplete(); 492 493 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_SUCCEEDED, 494 used_media_impl_->request_state()); 495 EXPECT_EQ(static_cast<size_t>(5), used_media_impl_->last_devices().size()); 496 497 // Audio input device with matched output ID. 498 const blink::WebMediaDeviceInfo* device = 499 &used_media_impl_->last_devices()[0]; 500 EXPECT_FALSE(device->deviceId().isEmpty()); 501 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput, 502 device->kind()); 503 EXPECT_FALSE(device->label().isEmpty()); 504 EXPECT_FALSE(device->groupId().isEmpty()); 505 506 // Audio input device without matched output ID. 507 device = &used_media_impl_->last_devices()[1]; 508 EXPECT_FALSE(device->deviceId().isEmpty()); 509 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput, 510 device->kind()); 511 EXPECT_FALSE(device->label().isEmpty()); 512 EXPECT_FALSE(device->groupId().isEmpty()); 513 514 // Video input devices. 515 device = &used_media_impl_->last_devices()[2]; 516 EXPECT_FALSE(device->deviceId().isEmpty()); 517 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindVideoInput, 518 device->kind()); 519 EXPECT_FALSE(device->label().isEmpty()); 520 EXPECT_TRUE(device->groupId().isEmpty()); 521 522 device = &used_media_impl_->last_devices()[3]; 523 EXPECT_FALSE(device->deviceId().isEmpty()); 524 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindVideoInput, 525 device->kind()); 526 EXPECT_FALSE(device->label().isEmpty()); 527 EXPECT_TRUE(device->groupId().isEmpty()); 528 529 // Audio output device. 530 device = &used_media_impl_->last_devices()[4]; 531 EXPECT_FALSE(device->deviceId().isEmpty()); 532 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindAudioOutput, 533 device->kind()); 534 EXPECT_FALSE(device->label().isEmpty()); 535 EXPECT_FALSE(device->groupId().isEmpty()); 536 537 // Verfify group IDs. 538 EXPECT_TRUE(used_media_impl_->last_devices()[0].groupId().equals( 539 used_media_impl_->last_devices()[4].groupId())); 540 EXPECT_FALSE(used_media_impl_->last_devices()[1].groupId().equals( 541 used_media_impl_->last_devices()[4].groupId())); 542 } 543 544 TEST_F(UserMediaClientImplTest, EnumerateSources) { 545 used_media_impl_->RequestSources(); 546 FakeMediaStreamDispatcherRequestSourcesComplete(); 547 548 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_SUCCEEDED, 549 used_media_impl_->request_state()); 550 EXPECT_EQ(static_cast<size_t>(4), used_media_impl_->last_sources().size()); 551 552 // Audio input devices. 553 const blink::WebSourceInfo* source = &used_media_impl_->last_sources()[0]; 554 EXPECT_FALSE(source->id().isEmpty()); 555 EXPECT_EQ(blink::WebSourceInfo::SourceKindAudio, source->kind()); 556 EXPECT_FALSE(source->label().isEmpty()); 557 EXPECT_EQ(blink::WebSourceInfo::VideoFacingModeNone, source->facing()); 558 559 source = &used_media_impl_->last_sources()[1]; 560 EXPECT_FALSE(source->id().isEmpty()); 561 EXPECT_EQ(blink::WebSourceInfo::SourceKindAudio, source->kind()); 562 EXPECT_FALSE(source->label().isEmpty()); 563 EXPECT_EQ(blink::WebSourceInfo::VideoFacingModeNone, source->facing()); 564 565 // Video input device user facing. 566 source = &used_media_impl_->last_sources()[2]; 567 EXPECT_FALSE(source->id().isEmpty()); 568 EXPECT_EQ(blink::WebSourceInfo::SourceKindVideo, source->kind()); 569 EXPECT_FALSE(source->label().isEmpty()); 570 EXPECT_EQ(blink::WebSourceInfo::VideoFacingModeUser, source->facing()); 571 572 // Video input device environment facing. 573 source = &used_media_impl_->last_sources()[3]; 574 EXPECT_FALSE(source->id().isEmpty()); 575 EXPECT_EQ(blink::WebSourceInfo::SourceKindVideo, source->kind()); 576 EXPECT_FALSE(source->label().isEmpty()); 577 EXPECT_EQ(blink::WebSourceInfo::VideoFacingModeEnvironment, source->facing()); 578 } 579 580 } // namespace content 581