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)
5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_platform_audio_input.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_process.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/media/audio_input_message_filter.h"
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_audio_input_host.h"
14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_media_device_manager.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/renderer/render_frame_impl.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_thread_impl.h"
17558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/render_view_impl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_manager_base.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/shared_impl/ppb_audio_config_shared.h"
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
25558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperPlatformAudioInput* PepperPlatformAudioInput::Create(
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int render_frame_id,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& device_id,
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GURL& document_url,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int sample_rate,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int frames_per_buffer,
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    PepperAudioInputHost* client) {
32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_refptr<PepperPlatformAudioInput> audio_input(
33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      new PepperPlatformAudioInput());
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (audio_input->Initialize(render_frame_id,
35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              device_id,
36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              document_url,
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              sample_rate,
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              frames_per_buffer,
39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              client)) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Balanced by Release invoked in
41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // PepperPlatformAudioInput::ShutDownOnIOThread().
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    audio_input->AddRef();
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return audio_input.get();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::StartCapture() {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  io_message_loop_proxy_->PostTask(
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&PepperPlatformAudioInput::StartCaptureOnIOThread, this));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::StopCapture() {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  io_message_loop_proxy_->PostTask(
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&PepperPlatformAudioInput::StopCaptureOnIOThread, this));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::ShutDown() {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure we don't call shutdown more than once.
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!client_)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called on the main thread to stop all audio callbacks. We must only change
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the client on the main thread, and the delegates from the I/O thread.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_ = NULL;
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  io_message_loop_proxy_->PostTask(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
76558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&PepperPlatformAudioInput::ShutDownOnIOThread, this));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::OnStreamCreated(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SharedMemoryHandle handle,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SyncSocket::Handle socket_handle,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int length,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int total_segments) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(handle);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(socket_handle);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(-1, handle.fd);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(-1, socket_handle);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(length);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(yzshen): Make use of circular buffer scheme. crbug.com/181449.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(1, total_segments);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (base::MessageLoopProxy::current().get() !=
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      main_message_loop_proxy_.get()) {
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If shutdown has occurred, |client_| will be NULL and the handles will be
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // cleaned up on the main thread.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    main_message_loop_proxy_->PostTask(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Bind(&PepperPlatformAudioInput::OnStreamCreated,
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   this,
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   handle,
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   socket_handle,
105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   length,
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   total_segments));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Must dereference the client only on the main thread. Shutdown may have
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // occurred while the request was in-flight, so we need to NULL check.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (client_) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_->StreamCreated(handle, length, socket_handle);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Clean up the handles.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::SyncSocket temp_socket(socket_handle);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::SharedMemory temp_shared_memory(handle, false);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
120558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::OnVolume(double volume) {}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::OnStateChanged(
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    media::AudioInputIPCDelegate::State state) {}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid PepperPlatformAudioInput::OnIPCClosed() { ipc_.reset(); }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperPlatformAudioInput::~PepperPlatformAudioInput() {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we have been shut down. Warning: this may happen on the I/O
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread!
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Although these members should be accessed on a specific thread (either the
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // main thread or the I/O thread), it should be fine to examine their value
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here.
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!ipc_);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!client_);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(label_.empty());
136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(!pending_open_device_);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperPlatformAudioInput::PepperPlatformAudioInput()
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : client_(NULL),
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      main_message_loop_proxy_(base::MessageLoopProxy::current()),
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()),
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      render_frame_id_(MSG_ROUTING_NONE),
144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      create_stream_sent_(false),
145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      pending_open_device_(false),
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      pending_open_device_id_(-1) {}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool PepperPlatformAudioInput::Initialize(
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int render_frame_id,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& device_id,
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GURL& document_url,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int sample_rate,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int frames_per_buffer,
154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    PepperAudioInputHost* client) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RenderFrameImpl* const render_frame =
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      RenderFrameImpl::FromRoutingID(render_frame_id);
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!render_frame || !client)
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  render_frame_id_ = render_frame_id;
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  client_ = client;
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!GetMediaDeviceManager())
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ipc_ = RenderThreadImpl::current()
169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch             ->audio_input_message_filter()
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             ->CreateAudioInputIPC(render_frame->render_view()->GetRoutingID());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR,
173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                media::CHANNEL_LAYOUT_MONO,
174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                ppapi::kAudioInputChannels,
175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                sample_rate,
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                ppapi::kBitsPerAudioInputSample,
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                frames_per_buffer);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We need to open the device and obtain the label and session ID before
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // initializing.
181558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  pending_open_device_id_ = GetMediaDeviceManager()->OpenDevice(
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PP_DEVICETYPE_DEV_AUDIOCAPTURE,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_id.empty() ? media::AudioManagerBase::kDefaultDeviceId : device_id,
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      document_url,
185558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&PepperPlatformAudioInput::OnDeviceOpened, this));
186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  pending_open_device_ = true;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
191558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::InitializeOnIOThread(int session_id) {
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!ipc_)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We will be notified by OnStreamCreated().
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  create_stream_sent_ = true;
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ipc_->CreateStream(this, session_id, params_, false, 1);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
202558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::StartCaptureOnIOThread() {
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ipc_)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ipc_->RecordStream();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
209558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::StopCaptureOnIOThread() {
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(yzshen): We cannot re-start capturing if the stream is closed.
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (ipc_ && create_stream_sent_) {
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ipc_->CloseStream();
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ipc_.reset();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::ShutDownOnIOThread() {
220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StopCaptureOnIOThread();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  main_message_loop_proxy_->PostTask(
225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      FROM_HERE, base::Bind(&PepperPlatformAudioInput::CloseDevice, this));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();  // Release for the delegate, balances out the reference taken in
228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch              // PepperPlatformAudioInput::Create.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
231558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::OnDeviceOpened(int request_id,
232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                              bool succeeded,
233558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                              const std::string& label) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  pending_open_device_ = false;
237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  pending_open_device_id_ = -1;
238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (succeeded && device_manager) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!label.empty());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    label_ = label;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (client_) {
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      int session_id = device_manager->GetSessionID(
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PP_DEVICETYPE_DEV_AUDIOCAPTURE, label);
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      io_message_loop_proxy_->PostTask(
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          base::Bind(&PepperPlatformAudioInput::InitializeOnIOThread,
250a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                     this,
251a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                     session_id));
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Shutdown has occurred.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CloseDevice();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyStreamCreationFailed();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
261558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::CloseDevice() {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!label_.empty()) {
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (device_manager)
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      device_manager->CloseDevice(label_);
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    label_.clear();
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (pending_open_device_) {
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    PepperMediaDeviceManager* const device_manager = GetMediaDeviceManager();
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (device_manager)
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      device_manager->CancelOpenDevice(pending_open_device_id_);
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    pending_open_device_ = false;
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    pending_open_device_id_ = -1;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
279558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperPlatformAudioInput::NotifyStreamCreationFailed() {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (client_)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_->StreamCreationFailed();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperMediaDeviceManager* PepperPlatformAudioInput::GetMediaDeviceManager() {
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RenderFrameImpl* const render_frame =
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      RenderFrameImpl::FromRoutingID(render_frame_id_);
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return render_frame ?
292ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      PepperMediaDeviceManager::GetForRenderFrame(render_frame).get() : NULL;
293558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
296