| Index: content/renderer/pepper_plugin_delegate_impl.cc
 | 
| diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc
 | 
| index 94bbaf0e4cce424d697c16076a095b7b1920c4a2..e1453e593c353d6e29ec0c626c0543b8a464d351 100644
 | 
| --- a/content/renderer/pepper_plugin_delegate_impl.cc
 | 
| +++ b/content/renderer/pepper_plugin_delegate_impl.cc
 | 
| @@ -35,6 +35,7 @@
 | 
|  #include "content/renderer/gpu/gpu_channel_host.h"
 | 
|  #include "content/renderer/gpu/renderer_gl_context.h"
 | 
|  #include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h"
 | 
| +#include "content/renderer/media/audio_input_message_filter.h"
 | 
|  #include "content/renderer/media/audio_message_filter.h"
 | 
|  #include "content/renderer/media/video_capture_impl_manager.h"
 | 
|  #include "content/renderer/p2p/p2p_transport_impl.h"
 | 
| @@ -170,7 +171,7 @@ class PlatformAudioImpl
 | 
|   public:
 | 
|    PlatformAudioImpl()
 | 
|        : client_(NULL), stream_id_(0),
 | 
| -        main_message_loop_(MessageLoop::current()) {
 | 
| +        main_message_loop_proxy_(base::MessageLoopProxy::current()) {
 | 
|      filter_ = RenderThreadImpl::current()->audio_message_filter();
 | 
|    }
 | 
|  
 | 
| @@ -184,7 +185,7 @@ class PlatformAudioImpl
 | 
|    // Initialize this audio context. StreamCreated() will be called when the
 | 
|    // stream is created.
 | 
|    bool Initialize(uint32_t sample_rate, uint32_t sample_count,
 | 
| -       webkit::ppapi::PluginDelegate::PlatformAudio::Client* client);
 | 
| +       webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client);
 | 
|  
 | 
|    // PlatformAudio implementation (called on main thread).
 | 
|    virtual bool StartPlayback();
 | 
| @@ -216,7 +217,7 @@ class PlatformAudioImpl
 | 
|  
 | 
|    // The client to notify when the stream is created. THIS MUST ONLY BE
 | 
|    // ACCESSED ON THE MAIN THREAD.
 | 
| -  webkit::ppapi::PluginDelegate::PlatformAudio::Client* client_;
 | 
| +  webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client_;
 | 
|  
 | 
|    // MessageFilter used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
 | 
|    // I/O thread except to send messages and get the message loop.
 | 
| @@ -226,14 +227,14 @@ class PlatformAudioImpl
 | 
|    // or else you could race with the initialize function which sets it.
 | 
|    int32 stream_id_;
 | 
|  
 | 
| -  MessageLoop* main_message_loop_;
 | 
| +  base::MessageLoopProxy* main_message_loop_proxy_;
 | 
|  
 | 
|    DISALLOW_COPY_AND_ASSIGN(PlatformAudioImpl);
 | 
|  };
 | 
|  
 | 
|  bool PlatformAudioImpl::Initialize(
 | 
|      uint32_t sample_rate, uint32_t sample_count,
 | 
| -    webkit::ppapi::PluginDelegate::PlatformAudio::Client* client) {
 | 
| +    webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) {
 | 
|  
 | 
|    DCHECK(client);
 | 
|    // Make sure we don't call init more than once.
 | 
| @@ -324,18 +325,184 @@ void PlatformAudioImpl::OnLowLatencyCreated(
 | 
|  #endif
 | 
|    DCHECK(length);
 | 
|  
 | 
| -  if (MessageLoop::current() == main_message_loop_) {
 | 
| +  if (base::MessageLoopProxy::current() == main_message_loop_proxy_) {
 | 
|      // Must dereference the client only on the main thread. Shutdown may have
 | 
|      // occurred while the request was in-flight, so we need to NULL check.
 | 
|      if (client_)
 | 
|        client_->StreamCreated(handle, length, socket_handle);
 | 
|    } else {
 | 
| -    main_message_loop_->PostTask(FROM_HERE,
 | 
| +    main_message_loop_proxy_->PostTask(FROM_HERE,
 | 
|          NewRunnableMethod(this, &PlatformAudioImpl::OnLowLatencyCreated,
 | 
|                            handle, socket_handle, length));
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +class PlatformAudioInputImpl
 | 
| +    : public webkit::ppapi::PluginDelegate::PlatformAudioInput,
 | 
| +      public AudioInputMessageFilter::Delegate,
 | 
| +      public base::RefCountedThreadSafe<PlatformAudioInputImpl> {
 | 
| + public:
 | 
| +  PlatformAudioInputImpl()
 | 
| +      : client_(NULL), stream_id_(0),
 | 
| +        main_message_loop_proxy_(base::MessageLoopProxy::current()) {
 | 
| +    filter_ = RenderThreadImpl::current()->audio_input_message_filter();
 | 
| +  }
 | 
| +
 | 
| +  virtual ~PlatformAudioInputImpl() {
 | 
| +    // Make sure we have been shut down. Warning: this will usually happen on
 | 
| +    // the I/O thread!
 | 
| +    DCHECK_EQ(0, stream_id_);
 | 
| +    DCHECK(!client_);
 | 
| +  }
 | 
| +
 | 
| +  // Initialize this audio context. StreamCreated() will be called when the
 | 
| +  // stream is created.
 | 
| +  bool Initialize(
 | 
| +    uint32_t sample_rate, uint32_t sample_count,
 | 
| +    webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client);
 | 
| +
 | 
| +  // PlatformAudio implementation (called on main thread).
 | 
| +  virtual bool StartCapture();
 | 
| +  virtual bool StopCapture();
 | 
| +  virtual void ShutDown();
 | 
| +
 | 
| + private:
 | 
| +  // I/O thread backends to above functions.
 | 
| +  void InitializeOnIOThread(const AudioParameters& params);
 | 
| +  void StartCaptureOnIOThread();
 | 
| +  void StopCaptureOnIOThread();
 | 
| +  void ShutDownOnIOThread();
 | 
| +
 | 
| +  virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle,
 | 
| +                                   base::SyncSocket::Handle socket_handle,
 | 
| +                                   uint32 length);
 | 
| +
 | 
| +  virtual void OnVolume(double volume) {}
 | 
| +
 | 
| +  virtual void OnStateChanged(AudioStreamState state) {}
 | 
| +
 | 
| +  virtual void OnDeviceReady(int index) {}
 | 
| +
 | 
| +  // The client to notify when the stream is created. THIS MUST ONLY BE
 | 
| +  // ACCESSED ON THE MAIN THREAD.
 | 
| +  webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client_;
 | 
| +
 | 
| +  // MessageFilter used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
 | 
| +  // I/O thread except to send messages and get the message loop.
 | 
| +  scoped_refptr<AudioInputMessageFilter> filter_;
 | 
| +
 | 
| +  // Our ID on the MessageFilter. THIS MUST ONLY BE ACCESSED ON THE I/O THREAD
 | 
| +  // or else you could race with the initialize function which sets it.
 | 
| +  int32 stream_id_;
 | 
| +
 | 
| +  base::MessageLoopProxy* main_message_loop_proxy_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(PlatformAudioInputImpl);
 | 
| +};
 | 
| +
 | 
| +bool PlatformAudioInputImpl::Initialize(
 | 
| +    uint32_t sample_rate, uint32_t sample_count,
 | 
| +    webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) {
 | 
| +  DCHECK(client);
 | 
| +  // Make sure we don't call init more than once.
 | 
| +  DCHECK_EQ(0, stream_id_);
 | 
| +
 | 
| +  client_ = client;
 | 
| +
 | 
| +  AudioParameters params;
 | 
| +  params.format = AudioParameters::AUDIO_PCM_LINEAR;
 | 
| +  params.channels = 1;
 | 
| +  params.sample_rate = sample_rate;
 | 
| +  params.bits_per_sample = 16;
 | 
| +  params.samples_per_packet = sample_count;
 | 
| +
 | 
| +  ChildProcess::current()->io_message_loop()->PostTask(
 | 
| +      FROM_HERE,
 | 
| +      NewRunnableMethod(this, &PlatformAudioInputImpl::InitializeOnIOThread,
 | 
| +                        params));
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
| +bool PlatformAudioInputImpl::StartCapture() {
 | 
| +  ChildProcess::current()->io_message_loop()->PostTask(
 | 
| +    FROM_HERE,
 | 
| +    NewRunnableMethod(this,
 | 
| +        &PlatformAudioInputImpl::StartCaptureOnIOThread));
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
| +bool PlatformAudioInputImpl::StopCapture() {
 | 
| +  ChildProcess::current()->io_message_loop()->PostTask(
 | 
| +    FROM_HERE,
 | 
| +    NewRunnableMethod(this,
 | 
| +        &PlatformAudioInputImpl::StopCaptureOnIOThread));
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
| +void PlatformAudioInputImpl::ShutDown() {
 | 
| +  // Called on the main thread to stop all audio callbacks. We must only change
 | 
| +  // the client on the main thread, and the delegates from the I/O thread.
 | 
| +  client_ = NULL;
 | 
| +  ChildProcess::current()->io_message_loop()->PostTask(
 | 
| +      FROM_HERE,
 | 
| +      base::Bind(&PlatformAudioInputImpl::ShutDownOnIOThread, this));
 | 
| +}
 | 
| +
 | 
| +void PlatformAudioInputImpl::InitializeOnIOThread(
 | 
| +    const AudioParameters& params) {
 | 
| +  stream_id_ = filter_->AddDelegate(this);
 | 
| +  filter_->Send(new AudioInputHostMsg_CreateStream(stream_id_, params, true));
 | 
| +}
 | 
| +
 | 
| +void PlatformAudioInputImpl::StartCaptureOnIOThread() {
 | 
| +  if (stream_id_)
 | 
| +    filter_->Send(new AudioInputHostMsg_RecordStream(stream_id_));
 | 
| +}
 | 
| +
 | 
| +void PlatformAudioInputImpl::StopCaptureOnIOThread() {
 | 
| +  if (stream_id_)
 | 
| +    filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_));
 | 
| +}
 | 
| +
 | 
| +void PlatformAudioInputImpl::ShutDownOnIOThread() {
 | 
| +  // Make sure we don't call shutdown more than once.
 | 
| +  if (!stream_id_)
 | 
| +    return;
 | 
| +
 | 
| +  filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_));
 | 
| +  filter_->RemoveDelegate(stream_id_);
 | 
| +  stream_id_ = 0;
 | 
| +
 | 
| +  Release();  // Release for the delegate, balances out the reference taken in
 | 
| +              // PepperPluginDelegateImpl::CreateAudioInput.
 | 
| +}
 | 
| +
 | 
| +void PlatformAudioInputImpl::OnLowLatencyCreated(
 | 
| +    base::SharedMemoryHandle handle,
 | 
| +    base::SyncSocket::Handle socket_handle,
 | 
| +    uint32 length) {
 | 
| +
 | 
| +#if defined(OS_WIN)
 | 
| +  DCHECK(handle);
 | 
| +  DCHECK(socket_handle);
 | 
| +#else
 | 
| +  DCHECK_NE(-1, handle.fd);
 | 
| +  DCHECK_NE(-1, socket_handle);
 | 
| +#endif
 | 
| +  DCHECK(length);
 | 
| +
 | 
| +  if (base::MessageLoopProxy::current() == main_message_loop_proxy_) {
 | 
| +    // Must dereference the client only on the main thread. Shutdown may have
 | 
| +    // occurred while the request was in-flight, so we need to NULL check.
 | 
| +    if (client_)
 | 
| +      client_->StreamCreated(handle, length, socket_handle);
 | 
| +  } else {
 | 
| +    main_message_loop_proxy_->PostTask(FROM_HERE,
 | 
| +        NewRunnableMethod(this, &PlatformAudioInputImpl::OnLowLatencyCreated,
 | 
| +                          handle, socket_handle, length));
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  class DispatcherDelegate : public ppapi::proxy::ProxyChannel::Delegate {
 | 
|   public:
 | 
|    virtual ~DispatcherDelegate() {}
 | 
| @@ -1087,8 +1254,9 @@ void PepperPluginDelegateImpl::SelectedFindResultChanged(int identifier,
 | 
|  
 | 
|  webkit::ppapi::PluginDelegate::PlatformAudio*
 | 
|  PepperPluginDelegateImpl::CreateAudio(
 | 
| -    uint32_t sample_rate, uint32_t sample_count,
 | 
| -    webkit::ppapi::PluginDelegate::PlatformAudio::Client* client) {
 | 
| +    uint32_t sample_rate,
 | 
| +    uint32_t sample_count,
 | 
| +    webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) {
 | 
|    scoped_refptr<PlatformAudioImpl> audio(new PlatformAudioImpl());
 | 
|    if (audio->Initialize(sample_rate, sample_count, client)) {
 | 
|      // Balanced by Release invoked in PlatformAudioImpl::ShutDownOnIOThread().
 | 
| @@ -1098,6 +1266,21 @@ PepperPluginDelegateImpl::CreateAudio(
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +webkit::ppapi::PluginDelegate::PlatformAudioInput*
 | 
| +PepperPluginDelegateImpl::CreateAudioInput(
 | 
| +    uint32_t sample_rate,
 | 
| +    uint32_t sample_count,
 | 
| +    webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) {
 | 
| +  scoped_refptr<PlatformAudioInputImpl>
 | 
| +    audio_input(new PlatformAudioInputImpl());
 | 
| +  if (audio_input->Initialize(sample_rate, sample_count, client)) {
 | 
| +    // Balanced by Release invoked in
 | 
| +    // PlatformAudioInputImpl::ShutDownOnIOThread().
 | 
| +    return audio_input.release();
 | 
| +  }
 | 
| +  return NULL;
 | 
| +}
 | 
| +
 | 
|  // If a broker has not already been created for this plugin, creates one.
 | 
|  webkit::ppapi::PluginDelegate::PpapiBroker*
 | 
|  PepperPluginDelegateImpl::ConnectToPpapiBroker(
 | 
| 
 |