| Index: content/renderer/media/user_media_client_impl_unittest.cc
 | 
| diff --git a/content/renderer/media/user_media_client_impl_unittest.cc b/content/renderer/media/user_media_client_impl_unittest.cc
 | 
| index 2bc5cbd3a6f4955e2f802645c5e3aceadbf6c593..c0de733a48ecc0fdcb855e380f9e1d5dcba87a29 100644
 | 
| --- a/content/renderer/media/user_media_client_impl_unittest.cc
 | 
| +++ b/content/renderer/media/user_media_client_impl_unittest.cc
 | 
| @@ -32,6 +32,8 @@
 | 
|  #include "third_party/WebKit/public/platform/WebVector.h"
 | 
|  #include "third_party/WebKit/public/web/WebHeap.h"
 | 
|  
 | 
| +using testing::_;
 | 
| +
 | 
|  namespace content {
 | 
|  
 | 
|  class MockMediaStreamVideoCapturerSource : public MockMediaStreamVideoSource {
 | 
| @@ -49,7 +51,7 @@
 | 
|  class MockMediaDevicesDispatcherHost
 | 
|      : public ::mojom::MediaDevicesDispatcherHost {
 | 
|   public:
 | 
| -  MockMediaDevicesDispatcherHost() : binding_(this) {}
 | 
| +  MockMediaDevicesDispatcherHost() {}
 | 
|    void EnumerateDevices(bool request_audio_input,
 | 
|                          bool request_video_input,
 | 
|                          bool request_audio_output,
 | 
| @@ -81,13 +83,6 @@
 | 
|                      const url::Origin& security_origin));
 | 
|    MOCK_METHOD2(UnsubscribeDeviceChangeNotifications,
 | 
|                 void(MediaDeviceType type, uint32_t subscription_id));
 | 
| -
 | 
| -  ::mojom::MediaDevicesDispatcherHostPtr CreateInterfacePtrAndBind() {
 | 
| -    return binding_.CreateInterfacePtrAndBind();
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_;
 | 
|  };
 | 
|  
 | 
|  class UserMediaClientImplUnderTest : public UserMediaClientImpl {
 | 
| @@ -241,6 +236,10 @@
 | 
|  
 | 
|  class UserMediaClientImplTest : public ::testing::Test {
 | 
|   public:
 | 
| +  UserMediaClientImplTest()
 | 
| +      : binding_user_media(&media_devices_dispatcher_),
 | 
| +        binding_event_dispatcher_(&media_devices_dispatcher_) {}
 | 
| +
 | 
|    void SetUp() override {
 | 
|      // Create our test object.
 | 
|      child_process_.reset(new ChildProcess());
 | 
| @@ -250,10 +249,15 @@
 | 
|          dependency_factory_.get(),
 | 
|          std::unique_ptr<MediaStreamDispatcher>(ms_dispatcher_)));
 | 
|      used_media_impl_->SetMediaDevicesDispatcherForTesting(
 | 
| -        media_devices_dispatcher_.CreateInterfacePtrAndBind());
 | 
| +        binding_user_media.CreateInterfacePtrAndBind());
 | 
| +    base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher =
 | 
| +        MediaDevicesEventDispatcher::GetForRenderFrame(nullptr);
 | 
| +    event_dispatcher->SetMediaDevicesDispatcherForTesting(
 | 
| +        binding_event_dispatcher_.CreateInterfacePtrAndBind());
 | 
|    }
 | 
|  
 | 
|    void TearDown() override {
 | 
| +    MediaDevicesEventDispatcher::GetForRenderFrame(nullptr)->OnDestruct();
 | 
|      used_media_impl_.reset();
 | 
|      blink::WebHeap::collectAllGarbageForTesting();
 | 
|    }
 | 
| @@ -331,6 +335,9 @@
 | 
|    std::unique_ptr<ChildProcess> child_process_;
 | 
|    MockMediaStreamDispatcher* ms_dispatcher_;  // Owned by |used_media_impl_|.
 | 
|    MockMediaDevicesDispatcherHost media_devices_dispatcher_;
 | 
| +  mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_user_media;
 | 
| +  mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_event_dispatcher_;
 | 
| +
 | 
|    std::unique_ptr<UserMediaClientImplUnderTest> used_media_impl_;
 | 
|    std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
 | 
|  };
 | 
| @@ -653,14 +660,37 @@
 | 
|  }
 | 
|  
 | 
|  TEST_F(UserMediaClientImplTest, ObserveMediaDeviceChanges) {
 | 
| -  // For a null UserMediaRequest (no audio requested), we expect false.
 | 
| -  EXPECT_EQ(0U, ms_dispatcher_->NumDeviceChangeSubscribers());
 | 
| +  EXPECT_CALL(
 | 
| +      media_devices_dispatcher_,
 | 
| +      SubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_AUDIO_INPUT, _, _));
 | 
| +  EXPECT_CALL(
 | 
| +      media_devices_dispatcher_,
 | 
| +      SubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_VIDEO_INPUT, _, _));
 | 
| +  EXPECT_CALL(
 | 
| +      media_devices_dispatcher_,
 | 
| +      SubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, _, _));
 | 
|    used_media_impl_->SetMediaDeviceChangeObserver();
 | 
| -  EXPECT_EQ(1U, ms_dispatcher_->NumDeviceChangeSubscribers());
 | 
| -  used_media_impl_->OnDevicesChanged();
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +
 | 
| +  base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher =
 | 
| +      MediaDevicesEventDispatcher::GetForRenderFrame(nullptr);
 | 
| +  event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_AUDIO_INPUT,
 | 
| +                                                MediaDeviceInfoArray());
 | 
| +  event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_VIDEO_INPUT,
 | 
| +                                                MediaDeviceInfoArray());
 | 
| +  event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT,
 | 
| +                                                MediaDeviceInfoArray());
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
| +
 | 
| +  EXPECT_CALL(media_devices_dispatcher_, UnsubscribeDeviceChangeNotifications(
 | 
| +                                             MEDIA_DEVICE_TYPE_AUDIO_INPUT, _));
 | 
| +  EXPECT_CALL(media_devices_dispatcher_, UnsubscribeDeviceChangeNotifications(
 | 
| +                                             MEDIA_DEVICE_TYPE_VIDEO_INPUT, _));
 | 
| +  EXPECT_CALL(
 | 
| +      media_devices_dispatcher_,
 | 
| +      UnsubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, _));
 | 
|    used_media_impl_->RemoveMediaDeviceChangeObserver();
 | 
| -  EXPECT_EQ(0U, ms_dispatcher_->NumDeviceChangeSubscribers());
 | 
| -  used_media_impl_->OnDevicesChanged();
 | 
| +  base::RunLoop().RunUntilIdle();
 | 
|  }
 | 
|  
 | 
|  // This test what happens if the audio stream has same id with video stream.
 | 
| 
 |