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.
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"
27 class MockMediaStreamVideoCapturerSource : public MockMediaStreamVideoSource {
29 MockMediaStreamVideoCapturerSource(
30 const StreamDeviceInfo& device,
31 const SourceStoppedCallback& stop_callback,
32 PeerConnectionDependencyFactory* factory)
33 : MockMediaStreamVideoSource(false) {
34 SetDeviceInfo(device);
35 SetStopCallback(stop_callback);
39 class UserMediaClientImplUnderTest : public UserMediaClientImpl {
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),
56 factory_(dependency_factory),
60 void RequestUserMedia() {
61 blink::WebUserMediaRequest user_media_request;
62 state_ = REQUEST_NOT_COMPLETE;
63 requestUserMedia(user_media_request);
66 void RequestMediaDevices() {
67 blink::WebMediaDevicesRequest media_devices_request;
68 state_ = REQUEST_NOT_COMPLETE;
69 requestMediaDevices(media_devices_request);
72 void RequestSources() {
73 blink::WebMediaStreamTrackSourcesRequest sources_request;
74 state_ = REQUEST_NOT_COMPLETE;
75 requestSources(sources_request);
78 virtual void GetUserMediaRequestSucceeded(
79 const blink::WebMediaStream& stream,
80 blink::WebUserMediaRequest* request_info) OVERRIDE {
81 last_generated_stream_ = stream;
82 state_ = REQUEST_SUCCEEDED;
85 virtual void GetUserMediaRequestFailed(
86 blink::WebUserMediaRequest* request_info,
87 content::MediaStreamRequestResult result) OVERRIDE {
88 last_generated_stream_.reset();
89 state_ = REQUEST_FAILED;
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;
100 result_name_ = result_name;
103 virtual void EnumerateDevicesSucceded(
104 blink::WebMediaDevicesRequest* request,
105 blink::WebVector<blink::WebMediaDeviceInfo>& devices) OVERRIDE {
106 state_ = REQUEST_SUCCEEDED;
107 last_devices_ = devices;
110 virtual void EnumerateSourcesSucceded(
111 blink::WebMediaStreamTrackSourcesRequest* request,
112 blink::WebVector<blink::WebSourceInfo>& sources) OVERRIDE {
113 state_ = REQUEST_SUCCEEDED;
114 last_sources_ = sources;
117 virtual MediaStreamVideoSource* CreateVideoSource(
118 const StreamDeviceInfo& device,
119 const MediaStreamSource::SourceStoppedCallback& stop_callback) OVERRIDE {
120 video_source_ = new MockMediaStreamVideoCapturerSource(device,
123 return video_source_;
126 const blink::WebMediaStream& last_generated_stream() {
127 return last_generated_stream_;
130 const blink::WebVector<blink::WebMediaDeviceInfo>& last_devices() {
131 return last_devices_;
134 const blink::WebVector<blink::WebSourceInfo>& last_sources() {
135 return last_sources_;
138 void ClearLastGeneratedStream() {
139 last_generated_stream_.reset();
142 MockMediaStreamVideoCapturerSource* last_created_video_source() const {
143 return video_source_;
146 RequestState request_state() const { return state_; }
147 content::MediaStreamRequestResult error_reason() const { return result_; }
148 blink::WebString error_name() const { return result_name_; }
151 blink::WebMediaStream last_generated_stream_;
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_;
161 class UserMediaClientImplTest : public ::testing::Test {
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()));
173 virtual void TearDown() OVERRIDE {
174 used_media_impl_.reset();
175 blink::WebHeap::collectAllGarbageForTesting();
178 blink::WebMediaStream RequestLocalMediaStream() {
179 used_media_impl_->RequestUserMedia();
180 FakeMediaStreamDispatcherRequestUserMediaComplete();
181 StartMockedVideoSource();
183 EXPECT_EQ(UserMediaClientImplUnderTest::REQUEST_SUCCEEDED,
184 used_media_impl_->request_state());
186 blink::WebMediaStream desc = used_media_impl_->last_generated_stream();
187 content::MediaStream* native_stream =
188 content::MediaStream::GetMediaStream(desc);
189 if (!native_stream) {
194 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
195 desc.audioTracks(audio_tracks);
196 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
197 desc.videoTracks(video_tracks);
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());
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());
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());
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());
235 void StartMockedVideoSource() {
236 MockMediaStreamVideoCapturerSource* video_source =
237 used_media_impl_->last_created_video_source();
238 if (video_source->SourceHasAttemptedToStart())
239 video_source->StartMockedSource();
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();
250 void FailToCreateNextAudioCapturer() {
251 dependency_factory_->FailToCreateNextAudioCapturer();
252 blink::WebHeap::collectGarbageForTesting();
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_;
263 TEST_F(UserMediaClientImplTest, GenerateMediaStream) {
264 // Generate a stream with both audio and video.
265 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
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();
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());
281 EXPECT_EQ(desc1_video_tracks[0].source().extraData(),
282 desc2_video_tracks[0].source().extraData());
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());
291 EXPECT_EQ(desc1_audio_tracks[0].source().extraData(),
292 desc2_audio_tracks[0].source().extraData());
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
301 ms_dispatcher_->IncrementSessionId();
302 blink::WebMediaStream desc2 = RequestLocalMediaStream();
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());
311 EXPECT_NE(desc1_video_tracks[0].source().extraData(),
312 desc2_video_tracks[0].source().extraData());
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());
321 EXPECT_NE(desc1_audio_tracks[0].source().extraData(),
322 desc2_audio_tracks[0].source().extraData());
325 TEST_F(UserMediaClientImplTest, StopLocalTracks) {
326 // Generate a stream with both audio and video.
327 blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
329 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
330 mixed_desc.audioTracks(audio_tracks);
331 MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
333 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
335 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
336 mixed_desc.videoTracks(video_tracks);
337 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
339 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
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();
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());
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());
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());
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());
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
381 used_media_impl_->ClearLastGeneratedStream();
382 blink::WebHeap::collectGarbageForTesting();
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());
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());
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());
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());
431 // This test what happens if UserMediaClientImpl is deleted before a source has
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();
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());
454 // This test what happens if the WebFrame is closed while the sources are being
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());
467 // This test what happens if stop is called on a track after the frame has
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());
476 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
477 mixed_desc.audioTracks(audio_tracks);
478 MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
480 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
482 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
483 mixed_desc.videoTracks(video_tracks);
484 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
486 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
489 TEST_F(UserMediaClientImplTest, EnumerateMediaDevices) {
490 used_media_impl_->RequestMediaDevices();
491 FakeMediaStreamDispatcherRequestMediaDevicesComplete();
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());
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,
503 EXPECT_FALSE(device->label().isEmpty());
504 EXPECT_FALSE(device->groupId().isEmpty());
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,
511 EXPECT_FALSE(device->label().isEmpty());
512 EXPECT_FALSE(device->groupId().isEmpty());
514 // Video input devices.
515 device = &used_media_impl_->last_devices()[2];
516 EXPECT_FALSE(device->deviceId().isEmpty());
517 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindVideoInput,
519 EXPECT_FALSE(device->label().isEmpty());
520 EXPECT_TRUE(device->groupId().isEmpty());
522 device = &used_media_impl_->last_devices()[3];
523 EXPECT_FALSE(device->deviceId().isEmpty());
524 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindVideoInput,
526 EXPECT_FALSE(device->label().isEmpty());
527 EXPECT_TRUE(device->groupId().isEmpty());
529 // Audio output device.
530 device = &used_media_impl_->last_devices()[4];
531 EXPECT_FALSE(device->deviceId().isEmpty());
532 EXPECT_EQ(blink::WebMediaDeviceInfo::MediaDeviceKindAudioOutput,
534 EXPECT_FALSE(device->label().isEmpty());
535 EXPECT_FALSE(device->groupId().isEmpty());
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()));
544 TEST_F(UserMediaClientImplTest, EnumerateSources) {
545 used_media_impl_->RequestSources();
546 FakeMediaStreamDispatcherRequestSourcesComplete();
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());
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());
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());
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());
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());
580 } // namespace content