[go: nahoru, domu]

Remove AudioOutputDeviceEnumerator. Replace usage with MediaDevicesManager.

Drive-by:
  Stop using std::array literals to specify devices to enumerate. Use device types as indexes.
  This makes it easier to understand what is being requested and removes reliance on the order of elements in the array.

BUG=647660

Review-Url: https://codereview.chromium.org/2368213002
Cr-Commit-Position: refs/heads/master@{#420959}
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 1ea4d12e..4da7d26 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1047,8 +1047,6 @@
     "renderer_host/media/audio_input_renderer_host.h",
     "renderer_host/media/audio_input_sync_writer.cc",
     "renderer_host/media/audio_input_sync_writer.h",
-    "renderer_host/media/audio_output_device_enumerator.cc",
-    "renderer_host/media/audio_output_device_enumerator.h",
     "renderer_host/media/audio_renderer_host.cc",
     "renderer_host/media/audio_renderer_host.h",
     "renderer_host/media/audio_sync_reader.cc",
diff --git a/content/browser/renderer_host/media/audio_output_device_enumerator.cc b/content/browser/renderer_host/media/audio_output_device_enumerator.cc
deleted file mode 100644
index e215d08..0000000
--- a/content/browser/renderer_host/media/audio_output_device_enumerator.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/media/audio_output_device_enumerator.h"
-
-#include "base/callback_helpers.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/task_runner_util.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "media/audio/audio_device_description.h"
-#include "media/audio/audio_manager.h"
-
-namespace content {
-
-namespace {
-
-AudioOutputDeviceEnumeration EnumerateDevicesOnDeviceThread(
-    media::AudioManager* audio_manager) {
-  DCHECK(audio_manager->GetTaskRunner()->BelongsToCurrentThread());
-
-  AudioOutputDeviceEnumeration snapshot;
-  media::AudioDeviceNames device_names;
-  audio_manager->GetAudioOutputDeviceNames(&device_names);
-
-  snapshot.has_actual_devices = !device_names.empty();
-
-  // If no devices in enumeration, return a list with a default device
-  if (!snapshot.has_actual_devices) {
-    snapshot.devices.push_back(
-        {media::AudioDeviceDescription::kDefaultDeviceId,
-         media::AudioDeviceDescription::GetDefaultDeviceName(),
-         audio_manager->GetGroupIDOutput(
-             media::AudioDeviceDescription::kDefaultDeviceId),
-         audio_manager->GetDefaultOutputStreamParameters()});
-    return snapshot;
-  }
-
-  for (const media::AudioDeviceName& name : device_names) {
-    snapshot.devices.push_back(
-        {name.unique_id, name.device_name,
-         audio_manager->GetGroupIDOutput(name.unique_id),
-         name.unique_id == media::AudioDeviceDescription::kDefaultDeviceId
-             ? audio_manager->GetDefaultOutputStreamParameters()
-             : audio_manager->GetOutputStreamParameters(name.unique_id)});
-  }
-  return snapshot;
-}
-
-}  // namespace
-
-AudioOutputDeviceInfo::AudioOutputDeviceInfo() {}
-
-AudioOutputDeviceInfo::~AudioOutputDeviceInfo() {}
-
-AudioOutputDeviceInfo::AudioOutputDeviceInfo(
-    const std::string& unique_id,
-    const std::string& device_name,
-    const std::string& group_id,
-    media::AudioParameters output_params)
-    : unique_id(unique_id),
-      device_name(device_name),
-      group_id(group_id),
-      output_params(output_params) {}
-
-AudioOutputDeviceInfo::AudioOutputDeviceInfo(
-    const AudioOutputDeviceInfo& audio_output_device_info) = default;
-
-AudioOutputDeviceInfo::AudioOutputDeviceInfo(
-    AudioOutputDeviceInfo&& audio_output_device_info) = default;
-
-AudioOutputDeviceInfo& AudioOutputDeviceInfo::operator=(
-    const AudioOutputDeviceInfo& audio_output_device_info) = default;
-
-AudioOutputDeviceEnumeration::AudioOutputDeviceEnumeration(
-    const std::vector<AudioOutputDeviceInfo>& devices,
-    bool has_actual_devices)
-    : devices(devices), has_actual_devices(has_actual_devices) {}
-
-AudioOutputDeviceEnumeration::AudioOutputDeviceEnumeration()
-    : has_actual_devices(false) {}
-
-AudioOutputDeviceEnumeration::AudioOutputDeviceEnumeration(
-    const AudioOutputDeviceEnumeration& other) = default;
-
-AudioOutputDeviceEnumeration::~AudioOutputDeviceEnumeration() {}
-
-AudioOutputDeviceEnumerator::AudioOutputDeviceEnumerator(
-    media::AudioManager* audio_manager,
-    CachePolicy cache_policy)
-    : audio_manager_(audio_manager),
-      cache_policy_(cache_policy),
-      current_event_sequence_(0),
-      seq_last_enumeration_(0),
-      seq_last_invalidation_(0),
-      is_enumeration_ongoing_(false),
-      weak_factory_(this) {}
-
-AudioOutputDeviceEnumerator::~AudioOutputDeviceEnumerator() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void AudioOutputDeviceEnumerator::Enumerate(
-    const AudioOutputDeviceEnumerationCB& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  // If caching is disabled, force a cache invalidation
-  if (cache_policy_ == CACHE_POLICY_NO_CACHING) {
-    InvalidateCache();
-  }
-
-  if (IsLastEnumerationValid()) {
-    DCHECK(pending_callbacks_.empty());
-    callback.Run(cache_);
-  } else {
-    pending_callbacks_.push_back(callback);
-    if (!is_enumeration_ongoing_) {
-      DoEnumerateDevices();
-    }
-  }
-}
-
-void AudioOutputDeviceEnumerator::InvalidateCache() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  seq_last_invalidation_ = NewEventSequence();
-}
-
-void AudioOutputDeviceEnumerator::SetCachePolicy(CachePolicy policy) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (policy == CACHE_POLICY_NO_CACHING)
-    InvalidateCache();
-
-  cache_policy_ = policy;
-}
-
-bool AudioOutputDeviceEnumerator::IsCacheEnabled() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return cache_policy_ != CACHE_POLICY_NO_CACHING;
-}
-
-void AudioOutputDeviceEnumerator::DoEnumerateDevices() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  is_enumeration_ongoing_ = true;
-  seq_last_enumeration_ = NewEventSequence();
-  base::PostTaskAndReplyWithResult(
-      audio_manager_->GetTaskRunner(), FROM_HERE,
-      base::Bind(&EnumerateDevicesOnDeviceThread, audio_manager_),
-      base::Bind(&AudioOutputDeviceEnumerator::DevicesEnumerated,
-                 weak_factory_.GetWeakPtr()));
-}
-
-void AudioOutputDeviceEnumerator::DevicesEnumerated(
-    const AudioOutputDeviceEnumeration& snapshot) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  is_enumeration_ongoing_ = false;
-  if (IsLastEnumerationValid()) {
-    cache_ = snapshot;
-    while (!pending_callbacks_.empty()) {
-      AudioOutputDeviceEnumerationCB callback = pending_callbacks_.front();
-      pending_callbacks_.pop_front();
-      base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::Bind(callback, snapshot));
-    }
-    pending_callbacks_.clear();
-  } else {
-    DoEnumerateDevices();
-  }
-}
-
-int64_t AudioOutputDeviceEnumerator::NewEventSequence() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return ++current_event_sequence_;
-}
-
-bool AudioOutputDeviceEnumerator::IsLastEnumerationValid() const {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return seq_last_enumeration_ > seq_last_invalidation_ &&
-         !is_enumeration_ongoing_;
-}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/media/audio_output_device_enumerator.h b/content/browser/renderer_host/media/audio_output_device_enumerator.h
deleted file mode 100644
index c250425..0000000
--- a/content/browser/renderer_host/media/audio_output_device_enumerator.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// AudioOutputDeviceEnumerator is used to enumerate audio output devices.
-// It can return cached results of previous enumerations in order to boost
-// performance.
-// All its public methods must be called on the thread where the object is
-// created.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_DEVICE_ENUMERATOR_H_
-#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_DEVICE_ENUMERATOR_H_
-
-#include <stdint.h>
-
-#include <list>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
-#include "media/base/audio_parameters.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace media {
-class AudioManager;
-}
-
-namespace content {
-
-// AudioOutputDeviceInfo describes information about an audio output device.
-// The enumerations returned by AudioOutputDeviceEnumerator::Enumerate() contain
-// elements of this type. It is used only in the browser side.
-struct AudioOutputDeviceInfo {
-  AudioOutputDeviceInfo();
-  AudioOutputDeviceInfo(const AudioOutputDeviceInfo& audio_output_device_info);
-  AudioOutputDeviceInfo(AudioOutputDeviceInfo&& audio_output_device_info);
-  AudioOutputDeviceInfo& operator=(
-      const AudioOutputDeviceInfo& audio_output_device_info);
-  AudioOutputDeviceInfo(const std::string& unique_id,
-                        const std::string& device_name,
-                        const std::string& group_id,
-                        media::AudioParameters output_params);
-  ~AudioOutputDeviceInfo();
-  std::string unique_id;
-  std::string device_name;
-  std::string group_id;
-  media::AudioParameters output_params;
-};
-
-// The result of an enumeration. It is used only in the browser side.
-struct AudioOutputDeviceEnumeration {
- public:
-  AudioOutputDeviceEnumeration(
-      const std::vector<AudioOutputDeviceInfo>& devices,
-      bool has_actual_devices);
-  AudioOutputDeviceEnumeration();
-  AudioOutputDeviceEnumeration(const AudioOutputDeviceEnumeration& other);
-  ~AudioOutputDeviceEnumeration();
-
-  std::vector<AudioOutputDeviceInfo> devices;
-  bool has_actual_devices;
-};
-
-typedef base::Callback<void(const AudioOutputDeviceEnumeration&)>
-    AudioOutputDeviceEnumerationCB;
-
-class CONTENT_EXPORT AudioOutputDeviceEnumerator {
- public:
-  enum CachePolicy {
-    CACHE_POLICY_NO_CACHING,
-    CACHE_POLICY_MANUAL_INVALIDATION
-  };
-  AudioOutputDeviceEnumerator(media::AudioManager* audio_manager,
-                              CachePolicy cache_policy);
-  ~AudioOutputDeviceEnumerator();
-
-  // Does an enumeration and provides the results to the callback.
-  // If there are no physical devices, the result contains a single entry with
-  // the default parameters provided by the underlying audio manager and with
-  // the |has_actual_devices| field set to false.
-  // The behavior with no physical devices is there to ease the transition
-  // from the use of RenderThreadImpl::GetAudioHardwareConfig(), which always
-  // provides default parameters, even if there are no devices.
-  // See https://crbug.com/549125.
-  // Some audio managers always report a single device, regardless of the
-  // physical devices in the system. In this case the |has_actual_devices| field
-  // is set to true to differentiate from the case of no physical devices.
-  void Enumerate(const AudioOutputDeviceEnumerationCB& callback);
-
-  // Invalidates the current cache.
-  void InvalidateCache();
-
-  // Sets the cache policy.
-  void SetCachePolicy(CachePolicy cache_policy);
-
-  // Returns true if the caching policy is different from
-  // CACHE_POLICY_NO_CACHING, false otherwise.
-  bool IsCacheEnabled();
-
- private:
-  void InitializeOnIOThread();
-  void DoEnumerateDevices();
-  AudioOutputDeviceEnumeration DoEnumerateDevicesOnDeviceThread();
-  void DevicesEnumerated(const AudioOutputDeviceEnumeration& snapshot);
-  int64_t NewEventSequence();
-  bool IsLastEnumerationValid() const;
-
-  media::AudioManager* const audio_manager_;
-  CachePolicy cache_policy_;
-  AudioOutputDeviceEnumeration cache_;
-  std::list<AudioOutputDeviceEnumerationCB> pending_callbacks_;
-
-  // sequential number that serves as logical clock
-  int64_t current_event_sequence_;
-
-  int64_t seq_last_enumeration_;
-  int64_t seq_last_invalidation_;
-  bool is_enumeration_ongoing_;
-
-  base::ThreadChecker thread_checker_;
-  base::WeakPtrFactory<AudioOutputDeviceEnumerator> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioOutputDeviceEnumerator);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_DEVICE_ENUMERATOR_H_
diff --git a/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc b/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc
deleted file mode 100644
index cc502ae..0000000
--- a/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/media/audio_output_device_enumerator.h"
-
-#include <memory>
-#include <string>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "media/audio/audio_device_description.h"
-#include "media/audio/fake_audio_log_factory.h"
-#include "media/audio/fake_audio_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::_;
-
-namespace content {
-
-namespace {
-
-class MockAudioManager : public media::FakeAudioManager {
- public:
-  MockAudioManager(size_t num_devices)
-      : FakeAudioManager(base::ThreadTaskRunnerHandle::Get(),
-                         base::ThreadTaskRunnerHandle::Get(),
-                         &fake_audio_log_factory_),
-        num_devices_(num_devices) {}
-  MockAudioManager() : MockAudioManager(0) {}
-  ~MockAudioManager() override {}
-
-  MOCK_METHOD1(MockGetAudioOutputDeviceNames, void(media::AudioDeviceNames*));
-
-  void GetAudioOutputDeviceNames(
-      media::AudioDeviceNames* device_names) override {
-    DCHECK(device_names->empty());
-    MockGetAudioOutputDeviceNames(device_names);
-    if (num_devices_ > 0) {
-      device_names->push_back(media::AudioDeviceName::CreateDefault());
-      for (size_t i = 0; i < num_devices_; i++) {
-        device_names->push_back(
-            media::AudioDeviceName("FakeDeviceName_" + base::IntToString(i),
-                                   "FakeDeviceId_" + base::IntToString(i)));
-      }
-    }
-  }
-
- private:
-  media::FakeAudioLogFactory fake_audio_log_factory_;
-  size_t num_devices_;
-  DISALLOW_COPY_AND_ASSIGN(MockAudioManager);
-};
-
-// Fake audio manager that exposes only the default device
-class OnlyDefaultDeviceAudioManager : public MockAudioManager {
- public:
-  OnlyDefaultDeviceAudioManager() {}
-  ~OnlyDefaultDeviceAudioManager() override {}
-  void GetAudioOutputDeviceNames(
-      media::AudioDeviceNames* device_names) override {
-    DCHECK(device_names->empty());
-    MockGetAudioOutputDeviceNames(device_names);
-    device_names->push_front(media::AudioDeviceName::CreateDefault());
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(OnlyDefaultDeviceAudioManager);
-};
-
-}  // namespace
-
-class AudioOutputDeviceEnumeratorTest : public ::testing::Test {
- public:
-  AudioOutputDeviceEnumeratorTest() {}
-  ~AudioOutputDeviceEnumeratorTest() override {}
-
-  MOCK_METHOD1(MockCallback, void(const AudioOutputDeviceEnumeration&));
-
-  // Performs n calls to MockCallback (one by QuitCallback)
-  // and n-1 calls to Enumerate
-  void EnumerateCallback(AudioOutputDeviceEnumerator* enumerator,
-                         int n,
-                         const AudioOutputDeviceEnumeration& result) {
-    MockCallback(result);
-    if (n > 1) {
-      enumerator->Enumerate(
-          base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCallback,
-                     base::Unretained(this), enumerator, n - 1));
-    } else {
-      enumerator->Enumerate(
-          base::Bind(&AudioOutputDeviceEnumeratorTest::QuitCallback,
-                     base::Unretained(this)));
-    }
-  }
-
-  void EnumerateCountCallback(size_t num_entries_expected,
-                              bool actual_devices_expected,
-                              const AudioOutputDeviceEnumeration& result) {
-    EXPECT_EQ(actual_devices_expected, result.has_actual_devices);
-    EXPECT_EQ(num_entries_expected, result.devices.size());
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                  run_loop_.QuitClosure());
-  }
-
-  void QuitCallback(const AudioOutputDeviceEnumeration& result) {
-    MockCallback(result);
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                  run_loop_.QuitClosure());
-  }
-
- protected:
-  TestBrowserThreadBundle thread_bundle_;
-  std::unique_ptr<MockAudioManager, media::AudioManagerDeleter> audio_manager_;
-  base::RunLoop run_loop_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AudioOutputDeviceEnumeratorTest);
-};
-
-TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateWithCache) {
-  const int num_calls = 10;
-  audio_manager_.reset(new MockAudioManager());
-  EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(1);
-  EXPECT_CALL(*this, MockCallback(_)).Times(num_calls);
-  AudioOutputDeviceEnumerator enumerator(
-      audio_manager_.get(),
-      AudioOutputDeviceEnumerator::CACHE_POLICY_MANUAL_INVALIDATION);
-  enumerator.Enumerate(
-      base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCallback,
-                 base::Unretained(this), &enumerator, num_calls - 1));
-  run_loop_.Run();
-}
-
-TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateWithNoCache) {
-  const int num_calls = 10;
-  audio_manager_.reset(new MockAudioManager());
-  EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_))
-      .Times(num_calls);
-  EXPECT_CALL(*this, MockCallback(_)).Times(num_calls);
-  AudioOutputDeviceEnumerator enumerator(
-      audio_manager_.get(),
-      AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
-  enumerator.Enumerate(
-      base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCallback,
-                 base::Unretained(this), &enumerator, num_calls - 1));
-  run_loop_.Run();
-}
-
-TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateNoDevices) {
-  audio_manager_.reset(new MockAudioManager());
-  EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_));
-  AudioOutputDeviceEnumerator enumerator(
-      audio_manager_.get(),
-      AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
-  enumerator.Enumerate(
-      base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCountCallback,
-                 base::Unretained(this), 1, false));
-  run_loop_.Run();
-}
-
-TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateOnlyDefaultDevice) {
-  audio_manager_.reset(new OnlyDefaultDeviceAudioManager());
-  EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_));
-  AudioOutputDeviceEnumerator enumerator(
-      audio_manager_.get(),
-      AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
-  enumerator.Enumerate(
-      base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCountCallback,
-                 base::Unretained(this), 1, true));
-  run_loop_.Run();
-}
-
-TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateOneDevice) {
-  size_t num_devices = 1;
-  audio_manager_.reset(new MockAudioManager(num_devices));
-  EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_));
-  AudioOutputDeviceEnumerator enumerator(
-      audio_manager_.get(),
-      AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
-  enumerator.Enumerate(
-      base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCountCallback,
-                 base::Unretained(this), num_devices + 1, true));
-  run_loop_.Run();
-}
-
-TEST_F(AudioOutputDeviceEnumeratorTest, EnumerateMultipleDevices) {
-  size_t num_devices = 5;
-  audio_manager_.reset(new MockAudioManager(num_devices));
-  EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_));
-  AudioOutputDeviceEnumerator enumerator(
-      audio_manager_.get(),
-      AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING);
-  enumerator.Enumerate(
-      base::Bind(&AudioOutputDeviceEnumeratorTest::EnumerateCountCallback,
-                 base::Unretained(this), num_devices + 1, true));
-  run_loop_.Run();
-}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc
index e07ede6..77d21c8 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -75,19 +75,6 @@
   return true;
 }
 
-AudioOutputDeviceInfo GetDefaultDeviceInfoOnDeviceThread(
-    media::AudioManager* audio_manager) {
-  DCHECK(audio_manager->GetTaskRunner()->BelongsToCurrentThread());
-  AudioOutputDeviceInfo default_device_info = {
-      media::AudioDeviceDescription::kDefaultDeviceId,
-      media::AudioDeviceDescription::GetDefaultDeviceName(),
-      audio_manager->GetGroupIDOutput(
-          media::AudioDeviceDescription::kDefaultDeviceId),
-      audio_manager->GetDefaultOutputStreamParameters()};
-
-  return default_device_info;
-}
-
 void NotifyRenderProcessHostThatAudioStateChanged(int render_process_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
@@ -491,87 +478,8 @@
 
   authorizations_.insert(
       MakeAuthorizationData(stream_id, false, std::string()));
-  CheckOutputDeviceAccess(
-      render_frame_id, device_id, security_origin,
-      base::Bind(&AudioRendererHost::OnDeviceAuthorized, this, stream_id,
-                 device_id, security_origin, auth_start_time));
-}
-
-void AudioRendererHost::OnDeviceAuthorized(int stream_id,
-                                           const std::string& device_id,
-                                           const url::Origin& security_origin,
-                                           base::TimeTicks auth_start_time,
-                                           bool have_access) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  const auto& auth_data = authorizations_.find(stream_id);
-
-  // A close request was received while access check was in progress.
-  if (auth_data == authorizations_.end()) {
-    UMALogDeviceAuthorizationTime(auth_start_time);
-    return;
-  }
-
-  if (!have_access) {
-    authorizations_.erase(auth_data);
-    UMALogDeviceAuthorizationTime(auth_start_time);
-    Send(new AudioMsg_NotifyDeviceAuthorized(
-        stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED,
-        media::AudioParameters::UnavailableDeviceParams(), std::string()));
-    return;
-  }
-
-  // If enumerator caching is disabled, avoid the enumeration if the default
-  // device is requested, since no device ID translation is needed.
-  // If enumerator caching is enabled, it is better to use its cache, even
-  // for the default device.
-  if (media::AudioDeviceDescription::IsDefaultDevice(device_id) &&
-      !media_stream_manager_->audio_output_device_enumerator()
-           ->IsCacheEnabled()) {
-    base::PostTaskAndReplyWithResult(
-        audio_manager_->GetTaskRunner(), FROM_HERE,
-        base::Bind(&GetDefaultDeviceInfoOnDeviceThread, audio_manager_),
-        base::Bind(&AudioRendererHost::OnDeviceIDTranslated, this, stream_id,
-                   auth_start_time, true));
-  } else {
-    media_stream_manager_->audio_output_device_enumerator()->Enumerate(
-        base::Bind(&AudioRendererHost::TranslateDeviceID, this, device_id,
-                   security_origin,
-                   base::Bind(&AudioRendererHost::OnDeviceIDTranslated, this,
-                              stream_id, auth_start_time)));
-  }
-}
-
-void AudioRendererHost::OnDeviceIDTranslated(
-    int stream_id,
-    base::TimeTicks auth_start_time,
-    bool device_found,
-    const AudioOutputDeviceInfo& device_info) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  const auto& auth_data = authorizations_.find(stream_id);
-
-  // A close request was received while translation was in progress
-  if (auth_data == authorizations_.end()) {
-    UMALogDeviceAuthorizationTime(auth_start_time);
-    return;
-  }
-
-  if (!device_found) {
-    authorizations_.erase(auth_data);
-    UMALogDeviceAuthorizationTime(auth_start_time);
-    Send(new AudioMsg_NotifyDeviceAuthorized(
-        stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND,
-        media::AudioParameters::UnavailableDeviceParams(), std::string()));
-    return;
-  }
-
-  auth_data->second.first = true;
-  auth_data->second.second = device_info.unique_id;
-
-  media::AudioParameters output_params = device_info.output_params;
-  MaybeFixAudioParameters(&output_params);
-  UMALogDeviceAuthorizationTime(auth_start_time);
-  Send(new AudioMsg_NotifyDeviceAuthorized(
-      stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string()));
+  CheckOutputDeviceAccess(render_frame_id, device_id, security_origin,
+                          stream_id, auth_start_time);
 }
 
 void AudioRendererHost::OnCreateStream(int stream_id,
@@ -790,7 +698,8 @@
     int render_frame_id,
     const std::string& device_id,
     const url::Origin& security_origin,
-    const OutputDeviceAccessCB& callback) {
+    int stream_id,
+    base::TimeTicks auth_start_time) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   // Check security origin if nondefault device is requested.
@@ -803,8 +712,9 @@
     return;
   }
 
-  if (device_id.empty()) {
-    callback.Run(true);
+  if (media::AudioDeviceDescription::IsDefaultDevice(device_id)) {
+    AccessChecked(nullptr, device_id, security_origin, stream_id,
+                  auth_start_time, true);
   } else {
     // Check that MediaStream device permissions have been granted,
     // hence the use of a MediaStreamUIProxy.
@@ -815,45 +725,129 @@
     // MEDIA_DEVICE_AUDIO_OUTPUT.
     // TODO(guidou): Change to MEDIA_DEVICE_AUDIO_OUTPUT when support becomes
     // available. http://crbug.com/498675
-    ui_proxy->CheckAccess(security_origin, MEDIA_DEVICE_AUDIO_CAPTURE,
-                          render_process_id_, render_frame_id,
-                          base::Bind(&AudioRendererHost::AccessChecked, this,
-                                     base::Passed(&ui_proxy), callback));
+    ui_proxy->CheckAccess(
+        security_origin, MEDIA_DEVICE_AUDIO_CAPTURE, render_process_id_,
+        render_frame_id,
+        base::Bind(&AudioRendererHost::AccessChecked, this,
+                   base::Passed(&ui_proxy), device_id, security_origin,
+                   stream_id, auth_start_time));
   }
 }
 
 void AudioRendererHost::AccessChecked(
     std::unique_ptr<MediaStreamUIProxy> ui_proxy,
-    const OutputDeviceAccessCB& callback,
+    const std::string& device_id,
+    const url::Origin& security_origin,
+    int stream_id,
+    base::TimeTicks auth_start_time,
     bool have_access) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  callback.Run(have_access);
+
+  const auto& auth_data = authorizations_.find(stream_id);
+  if (auth_data == authorizations_.end()) {
+    // A close request was received while access check was in progress.
+    UMALogDeviceAuthorizationTime(auth_start_time);
+    return;
+  }
+
+  if (!have_access) {
+    authorizations_.erase(auth_data);
+    UMALogDeviceAuthorizationTime(auth_start_time);
+    Send(new AudioMsg_NotifyDeviceAuthorized(
+        stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED,
+        media::AudioParameters::UnavailableDeviceParams(), std::string()));
+    return;
+  }
+
+  // For default device, read output parameters directly. Nondefault devices
+  // require translation first.
+  if (media::AudioDeviceDescription::IsDefaultDevice(device_id)) {
+    base::PostTaskAndReplyWithResult(
+        audio_manager_->GetTaskRunner(), FROM_HERE,
+        base::Bind(&AudioRendererHost::GetDeviceParametersOnDeviceThread, this,
+                   media::AudioDeviceDescription::kDefaultDeviceId),
+        base::Bind(&AudioRendererHost::DeviceParametersReceived, this,
+                   stream_id, auth_start_time, true,
+                   media::AudioDeviceDescription::kDefaultDeviceId));
+  } else {
+    MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+    devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
+    media_stream_manager_->media_devices_manager()->EnumerateDevices(
+        devices_to_enumerate,
+        base::Bind(&AudioRendererHost::TranslateDeviceID, this, device_id,
+                   security_origin, stream_id, auth_start_time));
+  }
 }
 
 void AudioRendererHost::TranslateDeviceID(
     const std::string& device_id,
     const url::Origin& security_origin,
-    const OutputDeviceInfoCB& callback,
-    const AudioOutputDeviceEnumeration& enumeration) {
+    int stream_id,
+    base::TimeTicks auth_start_time,
+    const MediaDeviceEnumeration& enumeration) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  for (const AudioOutputDeviceInfo& device_info : enumeration.devices) {
-    if (device_id.empty()) {
-      if (device_info.unique_id ==
-          media::AudioDeviceDescription::kDefaultDeviceId) {
-        callback.Run(true, device_info);
-        return;
-      }
-    } else if (content::DoesMediaDeviceIDMatchHMAC(
-                   salt_, security_origin, device_id, device_info.unique_id)) {
-      callback.Run(true, device_info);
+  DCHECK(!media::AudioDeviceDescription::IsDefaultDevice(device_id));
+  for (const MediaDeviceInfo& device_info :
+       enumeration[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT]) {
+    if (content::DoesMediaDeviceIDMatchHMAC(salt_, security_origin, device_id,
+                                            device_info.device_id)) {
+      base::PostTaskAndReplyWithResult(
+          audio_manager_->GetTaskRunner(), FROM_HERE,
+          base::Bind(&AudioRendererHost::GetDeviceParametersOnDeviceThread,
+                     this, device_info.device_id),
+          base::Bind(&AudioRendererHost::DeviceParametersReceived, this,
+                     stream_id, auth_start_time, true, device_info.device_id));
       return;
     }
   }
-  DCHECK(!device_id.empty());  // Default device must always be found
-  AudioOutputDeviceInfo device_info = {
-      std::string(), std::string(), std::string(),
-      media::AudioParameters::UnavailableDeviceParams()};
-  callback.Run(false, device_info);
+  DeviceParametersReceived(stream_id, auth_start_time, false, std::string(),
+                           media::AudioParameters::UnavailableDeviceParams());
+}
+
+media::AudioParameters AudioRendererHost::GetDeviceParametersOnDeviceThread(
+    const std::string& unique_id) {
+  DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
+
+  if (media::AudioDeviceDescription::IsDefaultDevice(unique_id))
+    return audio_manager_->GetDefaultOutputStreamParameters();
+
+  return audio_manager_->GetOutputStreamParameters(unique_id);
+}
+
+void AudioRendererHost::DeviceParametersReceived(
+    int stream_id,
+    base::TimeTicks auth_start_time,
+    bool device_found,
+    const std::string& unique_id,
+    const media::AudioParameters& output_params) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  const auto& auth_data = authorizations_.find(stream_id);
+
+  // A close request was received while translation was in progress
+  if (auth_data == authorizations_.end()) {
+    UMALogDeviceAuthorizationTime(auth_start_time);
+    return;
+  }
+
+  if (!device_found) {
+    authorizations_.erase(auth_data);
+    UMALogDeviceAuthorizationTime(auth_start_time);
+    Send(new AudioMsg_NotifyDeviceAuthorized(
+        stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND,
+        media::AudioParameters::UnavailableDeviceParams(),
+        std::string() /* matched_device_id */));
+    return;
+  }
+
+  auth_data->second.first = true;
+  auth_data->second.second = unique_id;
+
+  media::AudioParameters params = std::move(output_params);
+  MaybeFixAudioParameters(&params);
+  UMALogDeviceAuthorizationTime(auth_start_time);
+  Send(new AudioMsg_NotifyDeviceAuthorized(
+      stream_id, media::OUTPUT_DEVICE_STATUS_OK, params,
+      std::string() /* matched_device_id */));
 }
 
 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
diff --git a/content/browser/renderer_host/media/audio_renderer_host.h b/content/browser/renderer_host/media/audio_renderer_host.h
index 99e5066..5643bed 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.h
+++ b/content/browser/renderer_host/media/audio_renderer_host.h
@@ -54,7 +54,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/process/process.h"
 #include "base/sequenced_task_runner_helpers.h"
-#include "content/browser/renderer_host/media/audio_output_device_enumerator.h"
+#include "content/browser/renderer_host/media/media_devices_manager.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/browser/browser_thread.h"
@@ -119,13 +119,6 @@
   // |have_access| is true only if there is permission to access the device.
   typedef base::Callback<void(bool have_access)> OutputDeviceAccessCB;
 
-  // Internal callback type for information requests about an output device.
-  // |success| indicates the operation was successful. If true, |device_info|
-  // contains data about the device.
-  typedef base::Callback<void(bool success,
-                              const AudioOutputDeviceInfo& device_info)>
-      OutputDeviceInfoCB;
-
   // The type of a function that is run on the UI thread to check whether the
   // routing IDs reference a valid RenderFrameHost. The function then runs
   // |callback| on the IO thread with true/false if valid/invalid.
@@ -175,19 +168,6 @@
 
   // Helper methods.
 
-  // Proceed with device authorization after checking permissions.
-  void OnDeviceAuthorized(int stream_id,
-                          const std::string& device_id,
-                          const url::Origin& security_origin,
-                          base::TimeTicks auth_start_time,
-                          bool have_access);
-
-  // Proceed with device authorization after translating device ID.
-  void OnDeviceIDTranslated(int stream_id,
-                            base::TimeTicks auth_start_time,
-                            bool device_found,
-                            const AudioOutputDeviceInfo& device_info);
-
   // Complete the process of creating an audio stream. This will set up the
   // shared memory or shared socket in low latency mode and send the
   // NotifyStreamCreated message to the peer.
@@ -224,18 +204,35 @@
   void CheckOutputDeviceAccess(int render_frame_id,
                                const std::string& device_id,
                                const url::Origin& security_origin,
-                               const OutputDeviceAccessCB& callback);
+                               int stream_id,
+                               base::TimeTicks auth_start_time);
 
-  // Invoke |callback| after permission to use a device has been checked.
+  // Proceed with device authorization after checking permissions.
   void AccessChecked(std::unique_ptr<MediaStreamUIProxy> ui_proxy,
-                     const OutputDeviceAccessCB& callback,
+                     const std::string& device_id,
+                     const url::Origin& security_origin,
+                     int stream_id,
+                     base::TimeTicks auth_start_time,
                      bool have_access);
 
   // Translate the hashed |device_id| to a unique device ID.
   void TranslateDeviceID(const std::string& device_id,
                          const url::Origin& security_origin,
-                         const OutputDeviceInfoCB& callback,
-                         const AudioOutputDeviceEnumeration& enumeration);
+                         int stream_id,
+                         base::TimeTicks auth_start_time,
+                         const MediaDeviceEnumeration& enumeration);
+
+  // Get audio hardware parameters on the device thread.
+  media::AudioParameters GetDeviceParametersOnDeviceThread(
+      const std::string& device_id);
+
+  // Proceed with device authorization after translating device ID and
+  // receiving hardware parameters.
+  void DeviceParametersReceived(int stream_id,
+                                base::TimeTicks auth_start_time,
+                                bool device_found,
+                                const std::string& unique_id,
+                                const media::AudioParameters& output_params);
 
   // Helper method to check if the authorization procedure for stream
   // |stream_id| has started.
diff --git a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
index 8da9bdfa..a8ab77f 100644
--- a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
@@ -74,7 +74,8 @@
 
 class MockAudioRendererHost : public AudioRendererHost {
  public:
-  MockAudioRendererHost(media::AudioManager* audio_manager,
+  MockAudioRendererHost(base::RunLoop* auth_run_loop,
+                        media::AudioManager* audio_manager,
                         AudioMirroringManager* mirroring_manager,
                         MediaInternals* media_internals,
                         MediaStreamManager* media_stream_manager,
@@ -85,7 +86,8 @@
                           media_internals,
                           media_stream_manager,
                           salt),
-        shared_memory_length_(0) {
+        shared_memory_length_(0),
+        auth_run_loop_(auth_run_loop) {
     set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId);
   }
 
@@ -139,6 +141,7 @@
                                 const std::string& matched_device_id) {
     OnDeviceAuthorized(stream_id, device_status, output_params,
                        matched_device_id);
+    auth_run_loop_->Quit();
   }
 
   void OnNotifyStreamCreated(
@@ -182,19 +185,11 @@
   std::unique_ptr<base::SharedMemory> shared_memory_;
   std::unique_ptr<base::SyncSocket> sync_socket_;
   uint32_t shared_memory_length_;
+  base::RunLoop* auth_run_loop_;  // Used to wait for authorization.
 
   DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost);
 };
 
-namespace {
-
-void WaitForEnumeration(base::RunLoop* loop,
-                        const AudioOutputDeviceEnumeration& e) {
-  loop->Quit();
-}
-
-}  // namespace
-
 class AudioRendererHostTest : public testing::Test {
  public:
   AudioRendererHostTest() {
@@ -203,20 +198,10 @@
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kUseFakeDeviceForMediaStream);
     media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
-
-    // Enable caching to make enumerations run in a single thread
-    media_stream_manager_->audio_output_device_enumerator()->SetCachePolicy(
-        AudioOutputDeviceEnumerator::CACHE_POLICY_MANUAL_INVALIDATION);
-    base::RunLoop().RunUntilIdle();
-    base::RunLoop run_loop;
-    media_stream_manager_->audio_output_device_enumerator()->Enumerate(
-        base::Bind(&WaitForEnumeration, &run_loop));
-    run_loop.Run();
-
-    host_ =
-        new MockAudioRendererHost(audio_manager_.get(), &mirroring_manager_,
-                                  MediaInternals::GetInstance(),
-                                  media_stream_manager_.get(), std::string());
+    host_ = new MockAudioRendererHost(
+        &auth_run_loop_, audio_manager_.get(), &mirroring_manager_,
+        MediaInternals::GetInstance(), media_stream_manager_.get(),
+        std::string());
 
     // Simulate IPC channel connected.
     host_->set_peer_process_for_testing(base::Process::Current());
@@ -272,6 +257,7 @@
     }
     host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id,
                                         device_id, security_origin);
+    auth_run_loop_.Run();
     if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) {
       host_->OnCreateStream(kStreamId, kRenderFrameId, params);
 
@@ -365,6 +351,7 @@
   media::ScopedAudioManagerPtr audio_manager_;
   MockAudioMirroringManager mirroring_manager_;
   scoped_refptr<MockAudioRendererHost> host_;
+  base::RunLoop auth_run_loop_;
 
   DISALLOW_COPY_AND_ASSIGN(AudioRendererHostTest);
 };
diff --git a/content/browser/renderer_host/media/media_devices_manager.h b/content/browser/renderer_host/media/media_devices_manager.h
index 9849421..55acd9a 100644
--- a/content/browser/renderer_host/media/media_devices_manager.h
+++ b/content/browser/renderer_host/media/media_devices_manager.h
@@ -40,8 +40,13 @@
 class CONTENT_EXPORT MediaDevicesManager
     : public base::SystemMonitor::DevicesChangedObserver {
  public:
-  // Use MediaDeviceType values to index on this type.
-  using BoolDeviceTypes = std::array<bool, NUM_MEDIA_DEVICE_TYPES>;
+  // Use MediaDeviceType values to index on this type. By default all device
+  // types are false.
+  class BoolDeviceTypes final
+      : public std::array<bool, NUM_MEDIA_DEVICE_TYPES> {
+   public:
+    BoolDeviceTypes() { fill(false); }
+  };
 
   using EnumerationCallback =
       base::Callback<void(const MediaDeviceEnumeration&)>;
diff --git a/content/browser/renderer_host/media/media_devices_manager_unittest.cc b/content/browser/renderer_host/media/media_devices_manager_unittest.cc
index c49404ad..23c3701 100644
--- a/content/browser/renderer_host/media/media_devices_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_devices_manager_unittest.cc
@@ -167,10 +167,12 @@
       .Times(0);
   EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(0);
   EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{true, false, false}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -183,10 +185,12 @@
       .Times(kNumCalls);
   EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(0);
   EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{false, true, false}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -200,10 +204,12 @@
   EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_))
       .Times(kNumCalls);
   EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{false, false, true}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -216,10 +222,13 @@
   EXPECT_CALL(*audio_manager_, MockGetAudioInputDeviceNames(_))
       .Times(kNumCalls);
   EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{true, false, true}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -234,10 +243,13 @@
   EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
   EnableCache(MEDIA_DEVICE_TYPE_AUDIO_INPUT);
   EnableCache(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{true, false, true}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -251,10 +263,12 @@
   EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(0);
   EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
   EnableCache(MEDIA_DEVICE_TYPE_VIDEO_INPUT);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{false, true, false}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -277,10 +291,13 @@
   audio_manager_->SetNumAudioOutputDevices(num_audio_output_devices);
   EnableCache(MEDIA_DEVICE_TYPE_AUDIO_INPUT);
   EnableCache(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{true, false, true}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -300,7 +317,7 @@
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{true, false, true}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -325,10 +342,12 @@
   size_t num_video_input_devices = 5;
   video_capture_device_factory_->set_number_of_devices(num_video_input_devices);
   EnableCache(MEDIA_DEVICE_TYPE_VIDEO_INPUT);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{false, true, false}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -345,7 +364,7 @@
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{false, true, false}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -373,10 +392,14 @@
   EnableCache(MEDIA_DEVICE_TYPE_AUDIO_INPUT);
   EnableCache(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT);
   EnableCache(MEDIA_DEVICE_TYPE_VIDEO_INPUT);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{true, true, true}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
@@ -402,7 +425,7 @@
   for (int i = 0; i < kNumCalls; i++) {
     base::RunLoop run_loop;
     media_devices_manager_->EnumerateDevices(
-        {{true, true, true}},
+        devices_to_enumerate,
         base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
                    base::Unretained(this), &run_loop));
     run_loop.Run();
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index a2ac1450..1595e142 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -315,8 +315,10 @@
     ASSERT_GT(physical_video_devices_.size(), 0u);
 
     base::RunLoop run_loop;
+    MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+    devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
     media_stream_manager_->media_devices_manager()->EnumerateDevices(
-        {{true, false, false}},
+        devices_to_enumerate,
         base::Bind(&AudioInputDevicesEnumerated, run_loop.QuitClosure(),
                    &physical_audio_devices_));
     run_loop.Run();
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 7401862..df4566b 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -484,13 +484,6 @@
   return audio_input_device_manager_.get();
 }
 
-AudioOutputDeviceEnumerator*
-MediaStreamManager::audio_output_device_enumerator() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DCHECK(audio_output_device_enumerator_.get());
-  return audio_output_device_enumerator_.get();
-}
-
 MediaDevicesManager* MediaStreamManager::media_devices_manager() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(media_devices_manager_.get());
@@ -769,9 +762,10 @@
   if (request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT) {
     DCHECK_EQ(MEDIA_NO_SERVICE, request->video_type());
     request->SetState(MEDIA_DEVICE_AUDIO_OUTPUT, MEDIA_REQUEST_STATE_REQUESTED);
+    MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+    devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
     media_devices_manager_->EnumerateDevices(
-        {{false /* audio input */, false /* video input*/,
-          true /* audio output */}},
+        devices_to_enumerate,
         base::Bind(&MediaStreamManager::AudioOutputDevicesEnumerated,
                    base::Unretained(this), label));
     return;
@@ -980,8 +974,11 @@
   // base::Unretained is safe here because MediaStreamManager is deleted on the
   // UI thread, after the IO thread has been stopped.
   DCHECK(request_audio_input || request_video_input);
+  MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = request_audio_input;
+  devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = request_video_input;
   media_devices_manager_->EnumerateDevices(
-      {{request_audio_input, request_video_input, false /* no audio output */}},
+      devices_to_enumerate,
       base::Bind(&MediaStreamManager::DevicesEnumerated, base::Unretained(this),
                  request_audio_input, request_video_input, label));
 }
@@ -1486,9 +1483,6 @@
   video_capture_manager_->Register(this, device_task_runner_);
 #endif
 
-  audio_output_device_enumerator_.reset(new AudioOutputDeviceEnumerator(
-      audio_manager_, AudioOutputDeviceEnumerator::CACHE_POLICY_NO_CACHING));
-
   media_devices_manager_.reset(
       new MediaDevicesManager(audio_manager_, video_capture_manager_, this));
 }
@@ -1797,7 +1791,6 @@
 
   audio_input_device_manager_ = NULL;
   video_capture_manager_ = NULL;
-  audio_output_device_enumerator_ = NULL;
   media_devices_manager_ = NULL;
   g_media_stream_manager_tls_ptr.Pointer()->Set(NULL);
 }
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h
index 0d91543..28fb1028 100644
--- a/content/browser/renderer_host/media/media_stream_manager.h
+++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -39,7 +39,6 @@
 #include "base/power_monitor/power_observer.h"
 #include "base/threading/thread.h"
 #include "build/build_config.h"
-#include "content/browser/renderer_host/media/audio_output_device_enumerator.h"
 #include "content/browser/renderer_host/media/media_devices_manager.h"
 #include "content/browser/renderer_host/media/media_stream_provider.h"
 #include "content/common/content_export.h"
@@ -94,11 +93,6 @@
   // Used to access AudioInputDeviceManager.
   AudioInputDeviceManager* audio_input_device_manager();
 
-  // TODO(guidou): Remove when AudioRendererHost migrates to
-  // MediaDevicesManager. See http://crbug.com/647660.
-  // Used to access AudioOutputDeviceEnumerator.
-  AudioOutputDeviceEnumerator* audio_output_device_enumerator();
-
   // Used to access MediaDevicesManager.
   MediaDevicesManager* media_devices_manager();
 
@@ -438,7 +432,6 @@
   media::AudioManager* const audio_manager_;  // not owned
   scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_;
   scoped_refptr<VideoCaptureManager> video_capture_manager_;
-  std::unique_ptr<AudioOutputDeviceEnumerator> audio_output_device_enumerator_;
 #if defined(OS_WIN)
   base::Thread video_capture_thread_;
 #endif
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index d5a1fb2a..1c52692 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1161,7 +1161,6 @@
     "../browser/renderer_host/media/audio_input_debug_writer_unittest.cc",
     "../browser/renderer_host/media/audio_input_device_manager_unittest.cc",
     "../browser/renderer_host/media/audio_input_sync_writer_unittest.cc",
-    "../browser/renderer_host/media/audio_output_device_enumerator_unittest.cc",
     "../browser/renderer_host/media/audio_renderer_host_unittest.cc",
     "../browser/renderer_host/media/media_devices_manager_unittest.cc",
     "../browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc",