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/renderer/media/audio_input_message_filter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/media/audio_messages.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kStreamIDNotSet = -1;
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AudioInputMessageFilter::AudioInputIPCImpl
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public NON_EXPORTED_BASE(media::AudioInputIPC) {
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AudioInputIPCImpl(const scoped_refptr<AudioInputMessageFilter>& filter,
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    int render_view_id);
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~AudioInputIPCImpl();
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // media::AudioInputIPC implementation.
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void CreateStream(media::AudioInputIPCDelegate* delegate,
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            int session_id,
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const media::AudioParameters& params,
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            bool automatic_gain_control,
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            uint32 total_segments) OVERRIDE;
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void RecordStream() OVERRIDE;
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetVolume(double volume) OVERRIDE;
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void CloseStream() OVERRIDE;
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const scoped_refptr<AudioInputMessageFilter> filter_;
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int render_view_id_;
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int stream_id_;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AudioInputMessageFilter* AudioInputMessageFilter::g_filter = NULL;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AudioInputMessageFilter::AudioInputMessageFilter(
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : channel_(NULL),
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      io_message_loop_(io_message_loop) {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!g_filter);
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g_filter = this;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputMessageFilter::~AudioInputMessageFilter() {
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_EQ(g_filter, this);
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  g_filter = NULL;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputMessageFilter* AudioInputMessageFilter::Get() {
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return g_filter;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AudioInputMessageFilter::Send(IPC::Message* message) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(io_message_loop_->BelongsToCurrentThread());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel_) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete message;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    channel_->Send(message);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioInputMessageFilter::OnMessageReceived(const IPC::Message& message) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(io_message_loop_->BelongsToCurrentThread());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(AudioInputMessageFilter, message)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamCreated,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnStreamCreated)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamVolume, OnStreamVolume)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamStateChanged,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnStreamStateChanged)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputMessageFilter::OnFilterAdded(IPC::Channel* channel) {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(io_message_loop_->BelongsToCurrentThread());
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Captures the channel for IPC.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_ = channel;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputMessageFilter::OnFilterRemoved() {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(io_message_loop_->BelongsToCurrentThread());
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Once removed, a filter will not be used again.  At this time all
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // delegates must be notified so they release their reference.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OnChannelClosing();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputMessageFilter::OnChannelClosing() {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(io_message_loop_->BelongsToCurrentThread());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_ = NULL;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DLOG_IF(WARNING, !delegates_.IsEmpty())
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Not all audio devices have been closed.";
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDMap<media::AudioInputIPCDelegate>::iterator it(&delegates_);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!it.IsAtEnd()) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    it.GetCurrentValue()->OnIPCClosed();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegates_.Remove(it.GetCurrentKey());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    it.Advance();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputMessageFilter::OnStreamCreated(
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int stream_id,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SharedMemoryHandle handle,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SyncSocket::Handle socket_handle,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::FileDescriptor socket_descriptor,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32 length,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32 total_segments) {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(io_message_loop_->BelongsToCurrentThread());
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SyncSocket::Handle socket_handle = socket_descriptor.fd;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  << " audio capturer (stream_id=" << stream_id << ").";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SharedMemory::CloseHandle(handle);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SyncSocket socket(socket_handle);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Forward message to the stream delegate.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate->OnStreamCreated(handle, socket_handle, length, total_segments);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputMessageFilter::OnStreamVolume(int stream_id, double volume) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(io_message_loop_->BelongsToCurrentThread());
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  << " audio capturer.";
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate->OnVolume(volume);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputMessageFilter::OnStreamStateChanged(
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int stream_id, media::AudioInputIPCDelegate::State state) {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(io_message_loop_->BelongsToCurrentThread());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  << " audio renderer.";
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate->OnStateChanged(state);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AudioInputMessageFilter::AudioInputIPCImpl::AudioInputIPCImpl(
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const scoped_refptr<AudioInputMessageFilter>& filter, int render_view_id)
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : filter_(filter),
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      render_view_id_(render_view_id),
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream_id_(kStreamIDNotSet) {}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AudioInputMessageFilter::AudioInputIPCImpl::~AudioInputIPCImpl() {}
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<media::AudioInputIPC> AudioInputMessageFilter::CreateAudioInputIPC(
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int render_view_id) {
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_GT(render_view_id, 0);
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return scoped_ptr<media::AudioInputIPC>(
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new AudioInputIPCImpl(this, render_view_id));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioInputMessageFilter::AudioInputIPCImpl::CreateStream(
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    media::AudioInputIPCDelegate* delegate,
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int session_id,
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const media::AudioParameters& params,
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool automatic_gain_control,
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint32 total_segments) {
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(delegate);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_id_ = filter_->delegates_.Add(delegate);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AudioInputHostMsg_CreateStream_Config config;
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  config.params = params;
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  config.automatic_gain_control = automatic_gain_control;
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  config.shared_memory_count = total_segments;
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  filter_->Send(new AudioInputHostMsg_CreateStream(
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream_id_, render_view_id_, session_id, config));
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioInputMessageFilter::AudioInputIPCImpl::RecordStream() {
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_NE(stream_id_, kStreamIDNotSet);
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  filter_->Send(new AudioInputHostMsg_RecordStream(stream_id_));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioInputMessageFilter::AudioInputIPCImpl::SetVolume(double volume) {
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_NE(stream_id_, kStreamIDNotSet);
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  filter_->Send(new AudioInputHostMsg_SetVolume(stream_id_, volume));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioInputMessageFilter::AudioInputIPCImpl::CloseStream() {
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_NE(stream_id_, kStreamIDNotSet);
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_));
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  filter_->delegates_.Remove(stream_id_);
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_id_ = kStreamIDNotSet;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
217