| Index: content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
 | 
| diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
 | 
| index 658d47b892ed3af485a2d4d55134eebbc0bbdd03..a050760cc58304f5b8dbaac7b6423bb42a47425c 100644
 | 
| --- a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
 | 
| +++ b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
 | 
| @@ -26,10 +26,14 @@
 | 
|  #include "media/audio/mock_audio_manager.h"
 | 
|  #include "media/base/media_switches.h"
 | 
|  #include "media/capture/video/fake_video_capture_device_factory.h"
 | 
| +#include "mojo/public/cpp/bindings/binding.h"
 | 
|  #include "testing/gmock/include/gmock/gmock.h"
 | 
|  #include "testing/gtest/include/gtest/gtest.h"
 | 
|  #include "url/origin.h"
 | 
|  
 | 
| +using testing::_;
 | 
| +using testing::SaveArg;
 | 
| +
 | 
|  namespace content {
 | 
|  
 | 
|  namespace {
 | 
| @@ -44,6 +48,21 @@ void PhysicalDevicesEnumerated(base::Closure quit_closure,
 | 
|    quit_closure.Run();
 | 
|  }
 | 
|  
 | 
| +class MockMediaDevicesListener : public ::mojom::MediaDevicesListener {
 | 
| + public:
 | 
| +  MockMediaDevicesListener() : binding_(this) {}
 | 
| +
 | 
| +  MOCK_METHOD3(OnDevicesChanged,
 | 
| +               void(MediaDeviceType, uint32_t, const MediaDeviceInfoArray&));
 | 
| +
 | 
| +  ::mojom::MediaDevicesListenerPtr CreateInterfacePtrAndBind() {
 | 
| +    return binding_.CreateInterfacePtrAndBind();
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  mojo::Binding<::mojom::MediaDevicesListener> binding_;
 | 
| +};
 | 
| +
 | 
|  }  // namespace
 | 
|  
 | 
|  class MediaDevicesDispatcherHostTest : public testing::Test {
 | 
| @@ -161,13 +180,28 @@ class MediaDevicesDispatcherHostTest : public testing::Test {
 | 
|    }
 | 
|  
 | 
|    // Returns true if all devices have labels, false otherwise.
 | 
| -  bool DoesContainLabels(
 | 
| -      const std::vector<std::vector<MediaDeviceInfo>>& enumeration) {
 | 
| -    for (const auto& device_info_array : enumeration) {
 | 
| -      for (const auto& device_info : device_info_array) {
 | 
| -        if (device_info.label.empty())
 | 
| -          return false;
 | 
| -      }
 | 
| +  bool DoesContainLabels(const MediaDeviceInfoArray& device_infos) {
 | 
| +    for (const auto& device_info : device_infos) {
 | 
| +      if (device_info.label.empty())
 | 
| +        return false;
 | 
| +    }
 | 
| +    return true;
 | 
| +  }
 | 
| +
 | 
| +  // Returns true if all devices have labels, false otherwise.
 | 
| +  bool DoesContainLabels(const std::vector<MediaDeviceInfoArray>& enumeration) {
 | 
| +    for (const auto& device_infos : enumeration) {
 | 
| +      if (!DoesContainLabels(device_infos))
 | 
| +        return false;
 | 
| +    }
 | 
| +    return true;
 | 
| +  }
 | 
| +
 | 
| +  // Returns true if no devices have labels, false otherwise.
 | 
| +  bool DoesNotContainLabels(const MediaDeviceInfoArray& device_infos) {
 | 
| +    for (const auto& device_info : device_infos) {
 | 
| +      if (!device_info.label.empty())
 | 
| +        return false;
 | 
|      }
 | 
|      return true;
 | 
|    }
 | 
| @@ -175,15 +209,44 @@ class MediaDevicesDispatcherHostTest : public testing::Test {
 | 
|    // Returns true if no devices have labels, false otherwise.
 | 
|    bool DoesNotContainLabels(
 | 
|        const std::vector<std::vector<MediaDeviceInfo>>& enumeration) {
 | 
| -    for (const auto& device_info_array : enumeration) {
 | 
| -      for (const auto& device_info : device_info_array) {
 | 
| -        if (!device_info.label.empty())
 | 
| -          return false;
 | 
| -      }
 | 
| +    for (const auto& device_infos : enumeration) {
 | 
| +      if (!DoesNotContainLabels(device_infos))
 | 
| +        return false;
 | 
|      }
 | 
|      return true;
 | 
|    }
 | 
|  
 | 
| +  void SubscribeAndWaitForResult(bool has_permission) {
 | 
| +    MediaDevicesPermissionChecker permission_checker;
 | 
| +    permission_checker.OverridePermissionsForTesting(has_permission);
 | 
| +    host_->SetPermissionChecker(permission_checker);
 | 
| +    uint32_t subscription_id = 0u;
 | 
| +    url::Origin origin(GURL("http://localhost"));
 | 
| +    for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
 | 
| +      MediaDeviceType type = static_cast<MediaDeviceType>(i);
 | 
| +      host_->SubscribeDeviceChangeNotifications(type, subscription_id, origin);
 | 
| +      MockMediaDevicesListener device_change_listener;
 | 
| +      host_->SetDeviceChangeListenerForTesting(
 | 
| +          device_change_listener.CreateInterfacePtrAndBind());
 | 
| +      MediaDeviceInfoArray changed_devices;
 | 
| +      EXPECT_CALL(device_change_listener,
 | 
| +                  OnDevicesChanged(type, subscription_id, testing::_))
 | 
| +          .WillRepeatedly(SaveArg<2>(&changed_devices));
 | 
| +
 | 
| +      // Simulate device-change notification
 | 
| +      MediaDeviceInfoArray updated_devices = {
 | 
| +          {"fake_device_id", "fake_label", "fake_group"}};
 | 
| +      host_->OnDevicesChanged(type, updated_devices);
 | 
| +      base::RunLoop().RunUntilIdle();
 | 
| +      host_->UnsubscribeDeviceChangeNotifications(type, subscription_id);
 | 
| +
 | 
| +      if (has_permission)
 | 
| +        EXPECT_TRUE(DoesContainLabels(changed_devices));
 | 
| +      else
 | 
| +        EXPECT_TRUE(DoesNotContainLabels(changed_devices));
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
|    std::unique_ptr<MediaDevicesDispatcherHost> host_;
 | 
|    std::unique_ptr<MediaStreamManager> media_stream_manager_;
 | 
|    content::TestBrowserThreadBundle thread_bundle_;
 | 
| @@ -193,7 +256,7 @@ class MediaDevicesDispatcherHostTest : public testing::Test {
 | 
|    MediaDeviceEnumeration physical_devices_;
 | 
|    url::Origin origin_;
 | 
|  
 | 
| -  std::vector<std::vector<MediaDeviceInfo>> enumerated_devices_;
 | 
| +  std::vector<MediaDeviceInfoArray> enumerated_devices_;
 | 
|  };
 | 
|  
 | 
|  TEST_F(MediaDevicesDispatcherHostTest, EnumerateAudioInputDevices) {
 | 
| @@ -236,4 +299,12 @@ TEST_F(MediaDevicesDispatcherHostTest, EnumerateAllDevicesNoAccess) {
 | 
|    EXPECT_TRUE(DoesNotContainLabels(enumerated_devices_));
 | 
|  }
 | 
|  
 | 
| +TEST_F(MediaDevicesDispatcherHostTest, SubscribeDeviceChange) {
 | 
| +  SubscribeAndWaitForResult(true);
 | 
| +}
 | 
| +
 | 
| +TEST_F(MediaDevicesDispatcherHostTest, SubscribeDeviceChangeNoAccess) {
 | 
| +  SubscribeAndWaitForResult(false);
 | 
| +}
 | 
| +
 | 
|  };  // namespace content
 | 
| 
 |