Chromium Code Reviews| Index: content/browser/renderer_host/media/audio_renderer_host.cc |
| diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc |
| index 9e33d82aff60381664dae784eabeba681f814309..e959f1c8bc4250bb7b1ccb66fbe9fd24ab66f97a 100644 |
| --- a/content/browser/renderer_host/media/audio_renderer_host.cc |
| +++ b/content/browser/renderer_host/media/audio_renderer_host.cc |
| @@ -10,6 +10,7 @@ |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/lazy_instance.h" |
| +#include "base/memory/ptr_util.h" |
| #include "base/memory/shared_memory.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/process/process.h" |
| @@ -134,15 +135,16 @@ void ValidateRenderFrameId(int render_process_id, |
| class AudioRendererHost::AudioEntry |
| : public media::AudioOutputController::EventHandler { |
| public: |
| - AudioEntry(AudioRendererHost* host, |
| - int stream_id, |
| - int render_frame_id, |
| - const media::AudioParameters& params, |
| - const std::string& output_device_id, |
| - std::unique_ptr<base::SharedMemory> shared_memory, |
| - std::unique_ptr<media::AudioOutputController::SyncReader> reader); |
| ~AudioEntry() override; |
| + // Returns nullptr on failure. |
| + static std::unique_ptr<AudioRendererHost::AudioEntry> Create( |
| + AudioRendererHost* host, |
| + int stream_id, |
| + int render_frame_id, |
| + const media::AudioParameters& params, |
| + const std::string& output_device_id); |
| + |
| int stream_id() const { |
| return stream_id_; |
| } |
| @@ -151,18 +153,20 @@ class AudioRendererHost::AudioEntry |
| media::AudioOutputController* controller() const { return controller_.get(); } |
| - base::SharedMemory* shared_memory() { |
| - return shared_memory_.get(); |
| - } |
| - |
| - media::AudioOutputController::SyncReader* reader() const { |
| - return reader_.get(); |
| - } |
| + AudioSyncReader* reader() const { return reader_.get(); } |
| + // Used by ARH to track the number of active streams for UMA stats. |
| bool playing() const { return playing_; } |
| void set_playing(bool playing) { playing_ = playing; } |
| private: |
| + AudioEntry(AudioRendererHost* host, |
| + int stream_id, |
| + int render_frame_id, |
| + const media::AudioParameters& params, |
| + const std::string& output_device_id, |
| + std::unique_ptr<AudioSyncReader> reader); |
| + |
| // media::AudioOutputController::EventHandler implementation. |
| void OnCreated() override; |
| void OnPlaying() override; |
| @@ -175,16 +179,15 @@ class AudioRendererHost::AudioEntry |
| // The routing ID of the source RenderFrame. |
| const int render_frame_id_; |
| - // Shared memory for transmission of the audio data. Used by |reader_|. |
| - const std::unique_ptr<base::SharedMemory> shared_memory_; |
| - |
| // The synchronous reader to be used by |controller_|. |
| - const std::unique_ptr<media::AudioOutputController::SyncReader> reader_; |
| + const std::unique_ptr<AudioSyncReader> reader_; |
| // The AudioOutputController that manages the audio stream. |
| const scoped_refptr<media::AudioOutputController> controller_; |
| bool playing_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(AudioEntry); |
| }; |
| AudioRendererHost::AudioEntry::AudioEntry( |
| @@ -193,12 +196,10 @@ AudioRendererHost::AudioEntry::AudioEntry( |
| int render_frame_id, |
| const media::AudioParameters& params, |
| const std::string& output_device_id, |
| - std::unique_ptr<base::SharedMemory> shared_memory, |
| - std::unique_ptr<media::AudioOutputController::SyncReader> reader) |
| + std::unique_ptr<AudioSyncReader> reader) |
| : host_(host), |
| stream_id_(stream_id), |
| render_frame_id_(render_frame_id), |
| - shared_memory_(std::move(shared_memory)), |
| reader_(std::move(reader)), |
| controller_(media::AudioOutputController::Create(host->audio_manager_, |
| this, |
| @@ -206,11 +207,27 @@ AudioRendererHost::AudioEntry::AudioEntry( |
| output_device_id, |
| reader_.get())), |
| playing_(false) { |
| - DCHECK(controller_.get()); |
| + DCHECK(controller_); |
| } |
| AudioRendererHost::AudioEntry::~AudioEntry() {} |
| +// static |
| +std::unique_ptr<AudioRendererHost::AudioEntry> |
| +AudioRendererHost::AudioEntry::Create(AudioRendererHost* host, |
| + int stream_id, |
| + int render_frame_id, |
| + const media::AudioParameters& params, |
| + const std::string& output_device_id) { |
| + std::unique_ptr<AudioSyncReader> reader(AudioSyncReader::Create(params)); |
| + if (!reader) { |
| + return {}; |
|
DaleCurtis
2016/09/16 23:29:12
Just return nullptr?
Max Morin
2016/09/19 10:13:01
Done.
|
| + } |
| + return base::WrapUnique(new AudioEntry(host, stream_id, render_frame_id, |
| + params, output_device_id, |
| + std::move(reader))); |
| +} |
| + |
| /////////////////////////////////////////////////////////////////////////////// |
| // AudioRendererHost implementations. |
| @@ -326,41 +343,37 @@ void AudioRendererHost::DoCompleteCreation(int stream_id) { |
| return; |
| } |
| - // Once the audio stream is created then complete the creation process by |
| - // mapping shared memory and sharing with the renderer process. |
| - base::SharedMemoryHandle foreign_memory_handle; |
| - if (!entry->shared_memory()->ShareToProcess(PeerHandle(), |
| - &foreign_memory_handle)) { |
| - // If we failed to map and share the shared memory then close the audio |
| - // stream and send an error message. |
| - ReportErrorAndClose(entry->stream_id()); |
| - return; |
| - } |
| - |
| - AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); |
| + // Now construction is done and we are ready to send the shared memory and the |
| + // sync socket to the renderer. |
| + base::SharedMemory* shared_memory = entry->reader()->shared_memory(); |
| + base::CancelableSyncSocket* foreign_socket = |
| + entry->reader()->foreign_socket(); |
| + base::SharedMemoryHandle foreign_memory_handle; |
| base::SyncSocket::TransitDescriptor socket_descriptor; |
| + size_t shared_memory_size = shared_memory->requested_size(); |
|
DaleCurtis
2016/09/16 23:29:12
Do we sanitize this anywhere else? Otherwise seems
Max Morin
2016/09/19 10:13:01
This is sanitized in the IPC system: https://cs.ch
|
| - // If we failed to prepare the sync socket for the renderer then we fail |
| - // the construction of audio stream. |
| - if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) { |
| + if (!(shared_memory->ShareToProcess(PeerHandle(), &foreign_memory_handle) && |
| + foreign_socket->PrepareTransitDescriptor(PeerHandle(), |
| + &socket_descriptor))) { |
| + // Something went wrong in preparing the IPC handles. |
| ReportErrorAndClose(entry->stream_id()); |
| return; |
| } |
| Send(new AudioMsg_NotifyStreamCreated( |
| - entry->stream_id(), foreign_memory_handle, socket_descriptor, |
| - entry->shared_memory()->requested_size())); |
| + stream_id, foreign_memory_handle, socket_descriptor, |
| + base::checked_cast<uint32_t>(shared_memory_size))); |
| } |
| void AudioRendererHost::DidValidateRenderFrame(int stream_id, bool is_valid) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (!is_valid) { |
| - DLOG(WARNING) << "Render frame for stream (id=" << stream_id |
| - << ") no longer exists."; |
| - ReportErrorAndClose(stream_id); |
| - } |
| + if (!is_valid) { |
| + DLOG(WARNING) << "Render frame for stream (id=" << stream_id |
| + << ") no longer exists."; |
| + ReportErrorAndClose(stream_id); |
| + } |
| } |
| void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, |
| @@ -608,18 +621,9 @@ void AudioRendererHost::OnCreateStream(int stream_id, |
| base::Bind(&AudioRendererHost::DidValidateRenderFrame, this, |
| stream_id))); |
| - // Create the shared memory and share with the renderer process. |
| - uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) + |
| - AudioBus::CalculateMemorySize(params); |
| - std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); |
| - if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) { |
| - SendErrorMessage(stream_id); |
| - return; |
| - } |
| - |
| - std::unique_ptr<AudioSyncReader> reader( |
| - new AudioSyncReader(shared_memory.get(), params)); |
| - if (!reader->Init()) { |
| + std::unique_ptr<AudioEntry> entry = AudioEntry::Create( |
| + this, stream_id, render_frame_id, params, device_unique_id); |
| + if (!entry) { |
| SendErrorMessage(stream_id); |
| return; |
| } |
| @@ -629,9 +633,6 @@ void AudioRendererHost::OnCreateStream(int stream_id, |
| if (media_observer) |
| media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); |
| - std::unique_ptr<AudioEntry> entry( |
| - new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id, |
| - std::move(shared_memory), std::move(reader))); |
| if (mirroring_manager_) { |
| mirroring_manager_->AddDiverter( |
| render_process_id_, entry->render_frame_id(), entry->controller()); |