audio_input_renderer_host.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
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_renderer_host.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/numerics/safe_math.h" 11a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/stringprintf.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/media/capture/web_contents_audio_input_stream.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/media/capture/web_contents_capture_util.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/media/media_internals.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_input_device_manager.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/audio_input_sync_writer.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/media/media_stream_manager.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_manager_base.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AudioInputRendererHost::AudioEntry { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry(); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~AudioEntry(); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The AudioInputController that manages the audio input stream. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<media::AudioInputController> controller; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The audio input stream ID in the render view. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int stream_id; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Shared memory for transmission of the audio data. It has 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |shared_memory_segment_count| equal lengthed segments. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemory shared_memory; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int shared_memory_segment_count; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The synchronous writer to be used by the controller. We have the 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ownership of the writer. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<media::AudioInputController::SyncWriter> writer; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set to true after we called Close() for the controller. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pending_close; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputRendererHost::AudioEntry::AudioEntry() 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : stream_id(0), 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_memory_segment_count(0), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_close(false) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputRendererHost::AudioEntry::~AudioEntry() {} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputRendererHost::AudioInputRendererHost( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::AudioManager* audio_manager, 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MediaStreamManager* media_stream_manager, 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AudioMirroringManager* audio_mirroring_manager, 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) media::UserInputMonitor* user_input_monitor) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : BrowserMessageFilter(AudioMsgStart), 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_manager_(audio_manager), 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch media_stream_manager_(media_stream_manager), 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) audio_mirroring_manager_(audio_mirroring_manager), 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) user_input_monitor_(user_input_monitor), 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_(MediaInternals::GetInstance()->CreateAudioLog( 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) media::AudioLogFactory::AUDIO_INPUT_CONTROLLER)) {} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputRendererHost::~AudioInputRendererHost() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(audio_entries_.empty()); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnChannelClosing() { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the IPC channel is gone, close all requested audio streams. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteEntries(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnDestruct() const { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::DeleteOnIOThread::Destruct(this); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnCreated( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::AudioInputController* controller) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AudioInputRendererHost::DoCompleteCreation, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(controller))); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnRecording( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::AudioInputController* controller) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AudioInputRendererHost::DoSendRecordingMessage, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(controller))); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AudioInputRendererHost::OnError(media::AudioInputController* controller, 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) media::AudioInputController::ErrorCode error_code) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &AudioInputRendererHost::DoHandleError, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) make_scoped_refptr(controller), 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_code)); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnData(media::AudioInputController* controller, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* data, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 size) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Only low-latency mode is supported."; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::DoCompleteCreation( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::AudioInputController* controller) { 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry* entry = LookupByController(controller); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!PeerHandle()) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Renderer process handle is invalid."; 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeleteEntryOnError(entry, INVALID_PEER_HANDLE); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry->controller->LowLatencyMode()) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Only low-latency mode is supported."; 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeleteEntryOnError(entry, INVALID_LATENCY_MODE); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once the audio stream is created then complete the creation process by 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mapping shared memory and sharing with the renderer process. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle foreign_memory_handle; 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!entry->shared_memory.ShareToProcess(PeerHandle(), 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &foreign_memory_handle)) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we failed to map and share the shared memory then close the audio 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stream and send an error message. 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeleteEntryOnError(entry, MEMORY_SHARING_FAILED); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioInputSyncWriter* writer = 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<AudioInputSyncWriter*>(entry->writer.get()); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SyncSocket::Handle foreign_socket_handle; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::FileDescriptor foreign_socket_handle; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we failed to prepare the sync socket for the renderer then we fail 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the construction of audio input stream. 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!writer->PrepareForeignSocketHandle(PeerHandle(), 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &foreign_socket_handle)) { 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeleteEntryOnError(entry, SYNC_SOCKET_ERROR); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new AudioInputMsg_NotifyStreamCreated(entry->stream_id, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) foreign_memory_handle, foreign_socket_handle, 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->shared_memory.requested_size(), 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->shared_memory_segment_count)); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::DoSendRecordingMessage( 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::AudioInputController* controller) { 176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(henrika): See crbug.com/115262 for details on why this method 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be implemented. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::DoHandleError( 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) media::AudioInputController* controller, 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) media::AudioInputController::ErrorCode error_code) { 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Log all errors even it is ignored later. 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamManager::SendMessageToNativeLog( 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::StringPrintf("AudioInputController error: %d", error_code)); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // This is a fix for crbug.com/357501. The error can be triggered when closing 190a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // the lid on Macs, which causes more problems than it fixes. 191a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Also, in crbug.com/357569, the goal is to remove usage of the error since 192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // it was added to solve a crash on Windows that no longer can be reproduced. 193a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (error_code == media::AudioInputController::NO_DATA_ERROR) { 194a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DVLOG(1) << "AudioInputRendererHost@" << this << "::DoHandleError: " 195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch << "NO_DATA_ERROR ignored."; 196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 198a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry* entry = LookupByController(controller); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnError(entry->stream_id); 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeleteEntryOnError(entry, AUDIO_INPUT_CONTROLLER_ERROR); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AudioInputRendererHost::OnMessageReceived(const IPC::Message& message, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* message_was_ok) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP_EX(AudioInputRendererHost, message, *message_was_ok) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioInputHostMsg_CreateStream, OnCreateStream) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioInputHostMsg_RecordStream, OnRecordStream) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioInputHostMsg_CloseStream, OnCloseStream) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(AudioInputHostMsg_SetVolume, OnSetVolume) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP_EX() 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnCreateStream( 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int stream_id, 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_view_id, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int session_id, 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const AudioInputHostMsg_CreateStream_Config& config) { 226effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "AudioInputRendererHost@" << this 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << "::OnCreateStream(stream_id=" << stream_id 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << ", render_view_id=" << render_view_id 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << ", session_id=" << session_id << ")"; 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_GT(render_view_id, 0); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // media::AudioParameters is validated in the deserializer. 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (LookupById(stream_id) != NULL) { 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendErrorMessage(stream_id, STREAM_ALREADY_EXISTS); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) media::AudioParameters audio_params(config.params); 241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (media_stream_manager_->audio_input_device_manager()-> 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ShouldUseFakeDevice()) { 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) audio_params.Reset( 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) media::AudioParameters::AUDIO_FAKE, 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) config.params.channel_layout(), config.params.channels(), 0, 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) config.params.sample_rate(), config.params.bits_per_sample(), 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) config.params.frames_per_buffer()); 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if we have the permission to open the device and which device to use. 251a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string device_name; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string device_id = media::AudioManagerBase::kDefaultDeviceId; 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (audio_params.format() != media::AudioParameters::AUDIO_FAKE) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StreamDeviceInfo* info = media_stream_manager_-> 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!info) { 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendErrorMessage(stream_id, PERMISSION_DENIED); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(WARNING) << "No permission has been granted to input stream with " 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "session_id=" << session_id; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 263bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch device_id = info->device.id; 264a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch device_name = info->device.name; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a new AudioEntry structure. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioEntry> entry(new AudioEntry()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const uint32 segment_size = (sizeof(media::AudioInputBufferParameters) + 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) audio_params.GetBytesPerBuffer()); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->shared_memory_segment_count = config.shared_memory_count; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the shared memory and share it with the renderer process 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // using a new SyncWriter object. 276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::CheckedNumeric<uint32> size = segment_size; 277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch size *= entry->shared_memory_segment_count; 278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!size.IsValid() || 279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !entry->shared_memory.CreateAndMapAnonymous(size.ValueOrDie())) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If creation of shared memory failed then send an error message. 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendErrorMessage(stream_id, SHARED_MEMORY_CREATE_FAILED); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioInputSyncWriter> writer( 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new AudioInputSyncWriter(&entry->shared_memory, 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->shared_memory_segment_count)); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!writer->Init()) { 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendErrorMessage(stream_id, SYNC_WRITER_INIT_FAILED); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have successfully created the SyncWriter then assign it to the 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // entry and construct an AudioInputController. 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->writer.reset(writer.release()); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (WebContentsCaptureUtil::IsWebContentsDeviceId(device_id)) { 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry->controller = media::AudioInputController::CreateForStream( 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_manager_->GetTaskRunner(), 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WebContentsAudioInputStream::Create( 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_id, 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_params, 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_manager_->GetWorkerTaskRunner(), 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_mirroring_manager_), 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) entry->writer.get(), 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) user_input_monitor_); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(henrika): replace CreateLowLatency() with Create() as soon 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // as satish has ensured that Speech Input also uses the default low- 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // latency path. See crbug.com/112472 for details. 3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) entry->controller = 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) media::AudioInputController::CreateLowLatency(audio_manager_, 3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) this, 3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) audio_params, 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) device_id, 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) entry->writer.get(), 3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) user_input_monitor_); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!entry->controller.get()) { 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendErrorMessage(stream_id, STREAM_CREATE_ERROR); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the initial AGC state for the audio input stream. Note that, the AGC 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is only supported in AUDIO_PCM_LOW_LATENCY mode. 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY) 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) entry->controller->SetAutomaticGainControl(config.automatic_gain_control); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Since the controller was created successfully, create an entry and add it 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the map. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->stream_id = stream_id; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_entries_.insert(std::make_pair(stream_id, entry.release())); 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamManager::SendMessageToNativeLog( 337a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch "Audio input stream created successfully. Device name: " + device_name); 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) audio_log_->OnCreated(stream_id, audio_params, device_id); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnRecordStream(int stream_id) { 342effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry* entry = LookupById(stream_id); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) { 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->controller->Record(); 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnStarted(stream_id); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnCloseStream(int stream_id) { 355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry* entry = LookupById(stream_id); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseAndDeleteStream(entry); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) { 364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntry* entry = LookupById(stream_id); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry) { 368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->controller->SetVolume(volume); 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnSetVolume(stream_id, volume); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AudioInputRendererHost::SendErrorMessage( 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int stream_id, ErrorCode error_code) { 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MediaStreamManager::SendMessageToNativeLog( 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::StringPrintf("AudioInputRendererHost error: %d", error_code)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new AudioInputMsg_NotifyStreamStateChanged( 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_id, media::AudioInputIPCDelegate::kError)); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::DeleteEntries() { 385effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (AudioEntryMap::iterator i = audio_entries_.begin(); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != audio_entries_.end(); ++i) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseAndDeleteStream(i->second); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::CloseAndDeleteStream(AudioEntry* entry) { 394effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry->pending_close) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry, 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, entry)); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->pending_close = true; 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_log_->OnClosed(entry->stream_id); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioInputRendererHost::DeleteEntry(AudioEntry* entry) { 405effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the entry when this method goes out of scope. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioEntry> entry_deleter(entry); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Erase the entry from the map. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_entries_.erase(entry->stream_id); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AudioInputRendererHost::DeleteEntryOnError(AudioEntry* entry, 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ErrorCode error_code) { 416effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sends the error message first before we close the stream because 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |entry| is destroyed in DeleteEntry(). 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendErrorMessage(entry->stream_id, error_code); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseAndDeleteStream(entry); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputRendererHost::AudioEntry* AudioInputRendererHost::LookupById( 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int stream_id) { 426effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioEntryMap::iterator i = audio_entries_.find(stream_id); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != audio_entries_.end()) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i->second; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioInputRendererHost::AudioEntry* AudioInputRendererHost::LookupByController( 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::AudioInputController* controller) { 436effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Iterate the map of entries. 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(hclam): Implement a faster look up method. 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (AudioEntryMap::iterator i = audio_entries_.begin(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != audio_entries_.end(); ++i) { 442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (controller == i->second->controller.get()) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i->second; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 449