| 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 |