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