| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/user_media_client_impl.h" | 5 #include "content/renderer/media/user_media_client_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "mojo/public/cpp/bindings/binding.h" | 25 #include "mojo/public/cpp/bindings/binding.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 27 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" | 27 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" |
| 28 #include "third_party/WebKit/public/platform/WebMediaStream.h" | 28 #include "third_party/WebKit/public/platform/WebMediaStream.h" |
| 29 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" | 29 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" |
| 30 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 30 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
| 31 #include "third_party/WebKit/public/platform/WebString.h" | 31 #include "third_party/WebKit/public/platform/WebString.h" |
| 32 #include "third_party/WebKit/public/platform/WebVector.h" | 32 #include "third_party/WebKit/public/platform/WebVector.h" |
| 33 #include "third_party/WebKit/public/web/WebHeap.h" | 33 #include "third_party/WebKit/public/web/WebHeap.h" |
| 34 | 34 |
| 35 using testing::_; |
| 36 |
| 35 namespace content { | 37 namespace content { |
| 36 | 38 |
| 37 class MockMediaStreamVideoCapturerSource : public MockMediaStreamVideoSource { | 39 class MockMediaStreamVideoCapturerSource : public MockMediaStreamVideoSource { |
| 38 public: | 40 public: |
| 39 MockMediaStreamVideoCapturerSource( | 41 MockMediaStreamVideoCapturerSource( |
| 40 const StreamDeviceInfo& device, | 42 const StreamDeviceInfo& device, |
| 41 const SourceStoppedCallback& stop_callback, | 43 const SourceStoppedCallback& stop_callback, |
| 42 PeerConnectionDependencyFactory* factory) | 44 PeerConnectionDependencyFactory* factory) |
| 43 : MockMediaStreamVideoSource(false) { | 45 : MockMediaStreamVideoSource(false) { |
| 44 SetDeviceInfo(device); | 46 SetDeviceInfo(device); |
| 45 SetStopCallback(stop_callback); | 47 SetStopCallback(stop_callback); |
| 46 } | 48 } |
| 47 }; | 49 }; |
| 48 | 50 |
| 49 class MockMediaDevicesDispatcherHost | 51 class MockMediaDevicesDispatcherHost |
| 50 : public ::mojom::MediaDevicesDispatcherHost { | 52 : public ::mojom::MediaDevicesDispatcherHost { |
| 51 public: | 53 public: |
| 52 MockMediaDevicesDispatcherHost() : binding_(this) {} | 54 MockMediaDevicesDispatcherHost() {} |
| 53 void EnumerateDevices(bool request_audio_input, | 55 void EnumerateDevices(bool request_audio_input, |
| 54 bool request_video_input, | 56 bool request_video_input, |
| 55 bool request_audio_output, | 57 bool request_audio_output, |
| 56 const url::Origin& security_origin, | 58 const url::Origin& security_origin, |
| 57 const EnumerateDevicesCallback& callback) override { | 59 const EnumerateDevicesCallback& callback) override { |
| 58 std::vector<std::vector<MediaDeviceInfo>> result(NUM_MEDIA_DEVICE_TYPES); | 60 std::vector<std::vector<MediaDeviceInfo>> result(NUM_MEDIA_DEVICE_TYPES); |
| 59 if (request_audio_input) { | 61 if (request_audio_input) { |
| 60 result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].push_back(MediaDeviceInfo( | 62 result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].push_back(MediaDeviceInfo( |
| 61 "fake_audio_input 1", "Fake Audio Input 1", "fake_group 1")); | 63 "fake_audio_input 1", "Fake Audio Input 1", "fake_group 1")); |
| 62 result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].push_back(MediaDeviceInfo( | 64 result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].push_back(MediaDeviceInfo( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 74 } | 76 } |
| 75 callback.Run(result); | 77 callback.Run(result); |
| 76 } | 78 } |
| 77 | 79 |
| 78 MOCK_METHOD3(SubscribeDeviceChangeNotifications, | 80 MOCK_METHOD3(SubscribeDeviceChangeNotifications, |
| 79 void(MediaDeviceType type, | 81 void(MediaDeviceType type, |
| 80 uint32_t subscription_id, | 82 uint32_t subscription_id, |
| 81 const url::Origin& security_origin)); | 83 const url::Origin& security_origin)); |
| 82 MOCK_METHOD2(UnsubscribeDeviceChangeNotifications, | 84 MOCK_METHOD2(UnsubscribeDeviceChangeNotifications, |
| 83 void(MediaDeviceType type, uint32_t subscription_id)); | 85 void(MediaDeviceType type, uint32_t subscription_id)); |
| 84 | |
| 85 ::mojom::MediaDevicesDispatcherHostPtr CreateInterfacePtrAndBind() { | |
| 86 return binding_.CreateInterfacePtrAndBind(); | |
| 87 } | |
| 88 | |
| 89 private: | |
| 90 mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_; | |
| 91 }; | 86 }; |
| 92 | 87 |
| 93 class UserMediaClientImplUnderTest : public UserMediaClientImpl { | 88 class UserMediaClientImplUnderTest : public UserMediaClientImpl { |
| 94 public: | 89 public: |
| 95 enum RequestState { | 90 enum RequestState { |
| 96 REQUEST_NOT_STARTED, | 91 REQUEST_NOT_STARTED, |
| 97 REQUEST_NOT_COMPLETE, | 92 REQUEST_NOT_COMPLETE, |
| 98 REQUEST_SUCCEEDED, | 93 REQUEST_SUCCEEDED, |
| 99 REQUEST_FAILED, | 94 REQUEST_FAILED, |
| 100 }; | 95 }; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 content::MediaStreamRequestResult result_; | 229 content::MediaStreamRequestResult result_; |
| 235 blink::WebString result_name_; | 230 blink::WebString result_name_; |
| 236 blink::WebVector<blink::WebMediaDeviceInfo> last_devices_; | 231 blink::WebVector<blink::WebMediaDeviceInfo> last_devices_; |
| 237 PeerConnectionDependencyFactory* factory_; | 232 PeerConnectionDependencyFactory* factory_; |
| 238 bool create_source_that_fails_; | 233 bool create_source_that_fails_; |
| 239 MockMediaStreamVideoCapturerSource* video_source_; | 234 MockMediaStreamVideoCapturerSource* video_source_; |
| 240 }; | 235 }; |
| 241 | 236 |
| 242 class UserMediaClientImplTest : public ::testing::Test { | 237 class UserMediaClientImplTest : public ::testing::Test { |
| 243 public: | 238 public: |
| 239 UserMediaClientImplTest() |
| 240 : binding_user_media(&media_devices_dispatcher_), |
| 241 binding_event_dispatcher_(&media_devices_dispatcher_) {} |
| 242 |
| 244 void SetUp() override { | 243 void SetUp() override { |
| 245 // Create our test object. | 244 // Create our test object. |
| 246 child_process_.reset(new ChildProcess()); | 245 child_process_.reset(new ChildProcess()); |
| 247 dependency_factory_.reset(new MockPeerConnectionDependencyFactory()); | 246 dependency_factory_.reset(new MockPeerConnectionDependencyFactory()); |
| 248 ms_dispatcher_ = new MockMediaStreamDispatcher(); | 247 ms_dispatcher_ = new MockMediaStreamDispatcher(); |
| 249 used_media_impl_.reset(new UserMediaClientImplUnderTest( | 248 used_media_impl_.reset(new UserMediaClientImplUnderTest( |
| 250 dependency_factory_.get(), | 249 dependency_factory_.get(), |
| 251 std::unique_ptr<MediaStreamDispatcher>(ms_dispatcher_))); | 250 std::unique_ptr<MediaStreamDispatcher>(ms_dispatcher_))); |
| 252 used_media_impl_->SetMediaDevicesDispatcherForTesting( | 251 used_media_impl_->SetMediaDevicesDispatcherForTesting( |
| 253 media_devices_dispatcher_.CreateInterfacePtrAndBind()); | 252 binding_user_media.CreateInterfacePtrAndBind()); |
| 253 base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher = |
| 254 MediaDevicesEventDispatcher::GetForRenderFrame(nullptr); |
| 255 event_dispatcher->SetMediaDevicesDispatcherForTesting( |
| 256 binding_event_dispatcher_.CreateInterfacePtrAndBind()); |
| 254 } | 257 } |
| 255 | 258 |
| 256 void TearDown() override { | 259 void TearDown() override { |
| 260 MediaDevicesEventDispatcher::GetForRenderFrame(nullptr)->OnDestruct(); |
| 257 used_media_impl_.reset(); | 261 used_media_impl_.reset(); |
| 258 blink::WebHeap::collectAllGarbageForTesting(); | 262 blink::WebHeap::collectAllGarbageForTesting(); |
| 259 } | 263 } |
| 260 | 264 |
| 261 void LoadNewDocumentInFrame() { | 265 void LoadNewDocumentInFrame() { |
| 262 used_media_impl_->WillCommitProvisionalLoad(); | 266 used_media_impl_->WillCommitProvisionalLoad(); |
| 263 } | 267 } |
| 264 | 268 |
| 265 blink::WebMediaStream RequestLocalMediaStream() { | 269 blink::WebMediaStream RequestLocalMediaStream() { |
| 266 used_media_impl_->RequestUserMedia(); | 270 used_media_impl_->RequestUserMedia(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 ms_dispatcher_->audio_input_request_id()); | 328 ms_dispatcher_->audio_input_request_id()); |
| 325 used_media_impl_->DeleteRequest(ms_dispatcher_->audio_input_request_id()); | 329 used_media_impl_->DeleteRequest(ms_dispatcher_->audio_input_request_id()); |
| 326 return result; | 330 return result; |
| 327 } | 331 } |
| 328 | 332 |
| 329 protected: | 333 protected: |
| 330 base::MessageLoop message_loop_; | 334 base::MessageLoop message_loop_; |
| 331 std::unique_ptr<ChildProcess> child_process_; | 335 std::unique_ptr<ChildProcess> child_process_; |
| 332 MockMediaStreamDispatcher* ms_dispatcher_; // Owned by |used_media_impl_|. | 336 MockMediaStreamDispatcher* ms_dispatcher_; // Owned by |used_media_impl_|. |
| 333 MockMediaDevicesDispatcherHost media_devices_dispatcher_; | 337 MockMediaDevicesDispatcherHost media_devices_dispatcher_; |
| 338 mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_user_media; |
| 339 mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_event_dispatcher_; |
| 340 |
| 334 std::unique_ptr<UserMediaClientImplUnderTest> used_media_impl_; | 341 std::unique_ptr<UserMediaClientImplUnderTest> used_media_impl_; |
| 335 std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_; | 342 std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_; |
| 336 }; | 343 }; |
| 337 | 344 |
| 338 TEST_F(UserMediaClientImplTest, GenerateMediaStream) { | 345 TEST_F(UserMediaClientImplTest, GenerateMediaStream) { |
| 339 // Generate a stream with both audio and video. | 346 // Generate a stream with both audio and video. |
| 340 blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); | 347 blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); |
| 341 } | 348 } |
| 342 | 349 |
| 343 // Test that the same source object is used if two MediaStreams are generated | 350 // Test that the same source object is used if two MediaStreams are generated |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 EXPECT_FALSE(AudioRequestHasAutomaticDeviceSelection( | 653 EXPECT_FALSE(AudioRequestHasAutomaticDeviceSelection( |
| 647 factory.CreateWebMediaConstraints())); | 654 factory.CreateWebMediaConstraints())); |
| 648 | 655 |
| 649 factory.Reset(); | 656 factory.Reset(); |
| 650 factory.basic().renderToAssociatedSink.setExact(false); | 657 factory.basic().renderToAssociatedSink.setExact(false); |
| 651 EXPECT_FALSE(AudioRequestHasAutomaticDeviceSelection( | 658 EXPECT_FALSE(AudioRequestHasAutomaticDeviceSelection( |
| 652 factory.CreateWebMediaConstraints())); | 659 factory.CreateWebMediaConstraints())); |
| 653 } | 660 } |
| 654 | 661 |
| 655 TEST_F(UserMediaClientImplTest, ObserveMediaDeviceChanges) { | 662 TEST_F(UserMediaClientImplTest, ObserveMediaDeviceChanges) { |
| 656 // For a null UserMediaRequest (no audio requested), we expect false. | 663 EXPECT_CALL( |
| 657 EXPECT_EQ(0U, ms_dispatcher_->NumDeviceChangeSubscribers()); | 664 media_devices_dispatcher_, |
| 665 SubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_AUDIO_INPUT, _, _)); |
| 666 EXPECT_CALL( |
| 667 media_devices_dispatcher_, |
| 668 SubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_VIDEO_INPUT, _, _)); |
| 669 EXPECT_CALL( |
| 670 media_devices_dispatcher_, |
| 671 SubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, _, _)); |
| 658 used_media_impl_->SetMediaDeviceChangeObserver(); | 672 used_media_impl_->SetMediaDeviceChangeObserver(); |
| 659 EXPECT_EQ(1U, ms_dispatcher_->NumDeviceChangeSubscribers()); | 673 base::RunLoop().RunUntilIdle(); |
| 660 used_media_impl_->OnDevicesChanged(); | 674 |
| 675 base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher = |
| 676 MediaDevicesEventDispatcher::GetForRenderFrame(nullptr); |
| 677 event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_AUDIO_INPUT, |
| 678 MediaDeviceInfoArray()); |
| 679 event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_VIDEO_INPUT, |
| 680 MediaDeviceInfoArray()); |
| 681 event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, |
| 682 MediaDeviceInfoArray()); |
| 683 base::RunLoop().RunUntilIdle(); |
| 684 |
| 685 EXPECT_CALL(media_devices_dispatcher_, UnsubscribeDeviceChangeNotifications( |
| 686 MEDIA_DEVICE_TYPE_AUDIO_INPUT, _)); |
| 687 EXPECT_CALL(media_devices_dispatcher_, UnsubscribeDeviceChangeNotifications( |
| 688 MEDIA_DEVICE_TYPE_VIDEO_INPUT, _)); |
| 689 EXPECT_CALL( |
| 690 media_devices_dispatcher_, |
| 691 UnsubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, _)); |
| 661 used_media_impl_->RemoveMediaDeviceChangeObserver(); | 692 used_media_impl_->RemoveMediaDeviceChangeObserver(); |
| 662 EXPECT_EQ(0U, ms_dispatcher_->NumDeviceChangeSubscribers()); | 693 base::RunLoop().RunUntilIdle(); |
| 663 used_media_impl_->OnDevicesChanged(); | |
| 664 } | 694 } |
| 665 | 695 |
| 666 // This test what happens if the audio stream has same id with video stream. | 696 // This test what happens if the audio stream has same id with video stream. |
| 667 TEST_F(UserMediaClientImplTest, AudioVideoWithSameId) { | 697 TEST_F(UserMediaClientImplTest, AudioVideoWithSameId) { |
| 668 ms_dispatcher_->TestSameId(); | 698 ms_dispatcher_->TestSameId(); |
| 669 | 699 |
| 670 // Generate a stream with both audio and video. | 700 // Generate a stream with both audio and video. |
| 671 blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); | 701 blink::WebMediaStream mixed_desc = RequestLocalMediaStream(); |
| 672 | 702 |
| 673 // Remove video track. This should trigger | 703 // Remove video track. This should trigger |
| 674 // UserMediaClientImpl::OnLocalSourceStopped, and has video track to be | 704 // UserMediaClientImpl::OnLocalSourceStopped, and has video track to be |
| 675 // removed from its |local_sources_|. | 705 // removed from its |local_sources_|. |
| 676 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; | 706 blink::WebVector<blink::WebMediaStreamTrack> video_tracks; |
| 677 mixed_desc.videoTracks(video_tracks); | 707 mixed_desc.videoTracks(video_tracks); |
| 678 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]); | 708 MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]); |
| 679 video_track->Stop(); | 709 video_track->Stop(); |
| 680 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); | 710 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); |
| 681 EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter()); | 711 EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter()); |
| 682 | 712 |
| 683 // Now we load a new document in the web frame. If in the above Stop() call, | 713 // Now we load a new document in the web frame. If in the above Stop() call, |
| 684 // UserMediaClientImpl accidentally removed audio track, then video track will | 714 // UserMediaClientImpl accidentally removed audio track, then video track will |
| 685 // be removed again here, which is incorrect. | 715 // be removed again here, which is incorrect. |
| 686 LoadNewDocumentInFrame(); | 716 LoadNewDocumentInFrame(); |
| 687 blink::WebHeap::collectAllGarbageForTesting(); | 717 blink::WebHeap::collectAllGarbageForTesting(); |
| 688 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); | 718 EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter()); |
| 689 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); | 719 EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter()); |
| 690 } | 720 } |
| 691 | 721 |
| 692 } // namespace content | 722 } // namespace content |
| OLD | NEW |