audio_input_device_manager.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_input_device_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_input_device_manager_event_handler.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/media_stream_request.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_device_name.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_input_ipc.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_manager_base.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int AudioInputDeviceManager::kFakeOpenSessionId = 1;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Starting id for the first capture session.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputDeviceManager::AudioInputDeviceManager(
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media::AudioManager* audio_manager)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : listener_(NULL),
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_capture_session_id_(kFirstSessionId),
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      use_fake_device_(false),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      audio_manager_(audio_manager) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputDeviceManager::~AudioInputDeviceManager() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::Register(
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MediaStreamProviderListener* listener,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::MessageLoopProxy* device_thread_loop) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!listener_);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!device_loop_);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_ = listener;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_loop_ = device_thread_loop;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::Unregister() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(listener_);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_ = NULL;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::EnumerateDevices() {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(listener_);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_loop_->PostTask(
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&AudioInputDeviceManager::EnumerateOnDeviceThread, this));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AudioInputDeviceManager::Open(const StreamDeviceInfo& device) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a new id for this device.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int session_id = next_capture_session_id_++;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_loop_->PostTask(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 this, session_id, device));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session_id;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::Close(int session_id) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(listener_);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the device has been stopped, if not, send stop signal.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EventHandlerMap::iterator it = event_handlers_.find(session_id);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != event_handlers_.end()) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    it->second->OnDeviceStopped(session_id);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event_handlers_.erase(it);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_loop_->PostTask(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&AudioInputDeviceManager::CloseOnDeviceThread,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 this, session_id));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::Start(
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int session_id, AudioInputDeviceManagerEventHandler* handler) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(handler);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Solution for not using MediaStreamManager. This is needed when Start() is
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called without using Open(), we post default device for test purpose.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And we do not store the info for the kFakeOpenSessionId but return
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the callback immediately.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (session_id == kFakeOpenSessionId) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler->OnDeviceStarted(session_id,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             media::AudioManagerBase::kDefaultDeviceId);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Look up the device_id of the session so we can notify the renderer that
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the device has started. If the session has not been started,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // use the empty device_id to indicate that Start() failed.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string device_id;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event_handlers_.insert(std::make_pair(session_id, handler)).second) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StreamDeviceMap::const_iterator it = devices_.find(session_id);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it != devices_.end())
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_id = it->second.device_id;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Post a callback through the AudioInputRendererHost to notify the renderer
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that the device has started.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handler->OnDeviceStarted(session_id, device_id);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::Stop(int session_id) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Erase the event handler referenced by the session_id.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_handlers_.erase(session_id);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::UseFakeDevice() {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  use_fake_device_ = true;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioInputDeviceManager::ShouldUseFakeDevice() const {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return use_fake_device_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::EnumerateOnDeviceThread() {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsOnDeviceThread());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AudioManager is guaranteed to outlive MediaStreamManager in
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BrowserMainloop.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::AudioDeviceNames device_names;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  audio_manager_->GetAudioInputDeviceNames(&device_names);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamDeviceInfoArray* devices = new StreamDeviceInfoArray;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (media::AudioDeviceNames::iterator it = device_names.begin();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != device_names.end();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++it) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTE: Only support enumeration of the MEDIA_DEVICE_AUDIO_CAPTURE type.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    devices->push_back(StreamDeviceInfo(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MEDIA_DEVICE_AUDIO_CAPTURE, it->device_name,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it->unique_id, false));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the device list through the listener by posting a task on
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IO thread since MediaStreamManager handles the callback asynchronously.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&AudioInputDeviceManager::DevicesEnumeratedOnIOThread,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 this,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 devices));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::OpenOnDeviceThread(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int session_id, const StreamDeviceInfo& device) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsOnDeviceThread());
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the session_id and device to the map.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!devices_.insert(std::make_pair(session_id, device)).second) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    devices_[session_id] = device;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the |session_id| through the listener by posting a task on
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IO thread since MediaStreamManager handles the callback asynchronously.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(BrowserThread::IO,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          FROM_HERE,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::Bind(&AudioInputDeviceManager::OpenedOnIOThread,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     this,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     device.stream_type, session_id));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::CloseOnDeviceThread(int session_id) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsOnDeviceThread());
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamDeviceMap::iterator it = devices_.find(session_id);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == devices_.end())
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MediaStreamDeviceType stream_type = it->second.stream_type;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  devices_.erase(it);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Post a callback through the listener on IO thread since
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MediaStreamManager handles the callback asynchronously.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(BrowserThread::IO,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          FROM_HERE,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::Bind(&AudioInputDeviceManager::ClosedOnIOThread,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     this,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     stream_type, session_id));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::DevicesEnumeratedOnIOThread(
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StreamDeviceInfoArray* devices) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that |devices| gets deleted on exit.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<StreamDeviceInfoArray> devices_array(devices);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTE: Only support enumeration of the MEDIA_DEVICE_AUDIO_CAPTURE type.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->DevicesEnumerated(MEDIA_DEVICE_AUDIO_CAPTURE, *devices_array);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::OpenedOnIOThread(
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MediaStreamDeviceType stream_type, int session_id) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->Opened(stream_type, session_id);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputDeviceManager::ClosedOnIOThread(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MediaStreamDeviceType stream_type, int session_id) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->Closed(stream_type, session_id);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioInputDeviceManager::IsOnDeviceThread() const {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return device_loop_->BelongsToCurrentThread();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
229