| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/media/audio_renderer_host.h" | 5 #include "content/browser/renderer_host/media/audio_renderer_host.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/memory/ptr_util.h" |
| 13 #include "base/memory/shared_memory.h" | 14 #include "base/memory/shared_memory.h" |
| 14 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/process/process.h" | 16 #include "base/process/process.h" |
| 16 #include "content/browser/bad_message.h" | 17 #include "content/browser/bad_message.h" |
| 17 #include "content/browser/browser_main_loop.h" | 18 #include "content/browser/browser_main_loop.h" |
| 18 #include "content/browser/media/audio_stream_monitor.h" | 19 #include "content/browser/media/audio_stream_monitor.h" |
| 19 #include "content/browser/media/capture/audio_mirroring_manager.h" | 20 #include "content/browser/media/capture/audio_mirroring_manager.h" |
| 20 #include "content/browser/media/media_internals.h" | 21 #include "content/browser/media/media_internals.h" |
| 21 #include "content/browser/renderer_host/media/audio_input_device_manager.h" | 22 #include "content/browser/renderer_host/media/audio_input_device_manager.h" |
| 22 #include "content/browser/renderer_host/media/audio_sync_reader.h" | 23 #include "content/browser/renderer_host/media/audio_sync_reader.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 !!RenderFrameHost::FromID(render_process_id, render_frame_id); | 128 !!RenderFrameHost::FromID(render_process_id, render_frame_id); |
| 128 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 129 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 129 base::Bind(callback, frame_exists)); | 130 base::Bind(callback, frame_exists)); |
| 130 } | 131 } |
| 131 | 132 |
| 132 } // namespace | 133 } // namespace |
| 133 | 134 |
| 134 class AudioRendererHost::AudioEntry | 135 class AudioRendererHost::AudioEntry |
| 135 : public media::AudioOutputController::EventHandler { | 136 : public media::AudioOutputController::EventHandler { |
| 136 public: | 137 public: |
| 137 AudioEntry(AudioRendererHost* host, | |
| 138 int stream_id, | |
| 139 int render_frame_id, | |
| 140 const media::AudioParameters& params, | |
| 141 const std::string& output_device_id, | |
| 142 std::unique_ptr<base::SharedMemory> shared_memory, | |
| 143 std::unique_ptr<media::AudioOutputController::SyncReader> reader); | |
| 144 ~AudioEntry() override; | 138 ~AudioEntry() override; |
| 145 | 139 |
| 140 // Returns nullptr on failure. |
| 141 static std::unique_ptr<AudioRendererHost::AudioEntry> Create( |
| 142 AudioRendererHost* host, |
| 143 int stream_id, |
| 144 int render_frame_id, |
| 145 const media::AudioParameters& params, |
| 146 const std::string& output_device_id); |
| 147 |
| 146 int stream_id() const { | 148 int stream_id() const { |
| 147 return stream_id_; | 149 return stream_id_; |
| 148 } | 150 } |
| 149 | 151 |
| 150 int render_frame_id() const { return render_frame_id_; } | 152 int render_frame_id() const { return render_frame_id_; } |
| 151 | 153 |
| 152 media::AudioOutputController* controller() const { return controller_.get(); } | 154 media::AudioOutputController* controller() const { return controller_.get(); } |
| 153 | 155 |
| 154 base::SharedMemory* shared_memory() { | 156 AudioSyncReader* reader() const { return reader_.get(); } |
| 155 return shared_memory_.get(); | |
| 156 } | |
| 157 | 157 |
| 158 media::AudioOutputController::SyncReader* reader() const { | 158 // Used by ARH to track the number of active streams for UMA stats. |
| 159 return reader_.get(); | |
| 160 } | |
| 161 | |
| 162 bool playing() const { return playing_; } | 159 bool playing() const { return playing_; } |
| 163 void set_playing(bool playing) { playing_ = playing; } | 160 void set_playing(bool playing) { playing_ = playing; } |
| 164 | 161 |
| 165 private: | 162 private: |
| 163 AudioEntry(AudioRendererHost* host, |
| 164 int stream_id, |
| 165 int render_frame_id, |
| 166 const media::AudioParameters& params, |
| 167 const std::string& output_device_id, |
| 168 std::unique_ptr<AudioSyncReader> reader); |
| 169 |
| 166 // media::AudioOutputController::EventHandler implementation. | 170 // media::AudioOutputController::EventHandler implementation. |
| 167 void OnCreated() override; | 171 void OnCreated() override; |
| 168 void OnPlaying() override; | 172 void OnPlaying() override; |
| 169 void OnPaused() override; | 173 void OnPaused() override; |
| 170 void OnError() override; | 174 void OnError() override; |
| 171 | 175 |
| 172 AudioRendererHost* const host_; | 176 AudioRendererHost* const host_; |
| 173 const int stream_id_; | 177 const int stream_id_; |
| 174 | 178 |
| 175 // The routing ID of the source RenderFrame. | 179 // The routing ID of the source RenderFrame. |
| 176 const int render_frame_id_; | 180 const int render_frame_id_; |
| 177 | 181 |
| 178 // Shared memory for transmission of the audio data. Used by |reader_|. | |
| 179 const std::unique_ptr<base::SharedMemory> shared_memory_; | |
| 180 | |
| 181 // The synchronous reader to be used by |controller_|. | 182 // The synchronous reader to be used by |controller_|. |
| 182 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_; | 183 const std::unique_ptr<AudioSyncReader> reader_; |
| 183 | 184 |
| 184 // The AudioOutputController that manages the audio stream. | 185 // The AudioOutputController that manages the audio stream. |
| 185 const scoped_refptr<media::AudioOutputController> controller_; | 186 const scoped_refptr<media::AudioOutputController> controller_; |
| 186 | 187 |
| 187 bool playing_; | 188 bool playing_; |
| 189 |
| 190 DISALLOW_COPY_AND_ASSIGN(AudioEntry); |
| 188 }; | 191 }; |
| 189 | 192 |
| 190 AudioRendererHost::AudioEntry::AudioEntry( | 193 AudioRendererHost::AudioEntry::AudioEntry( |
| 191 AudioRendererHost* host, | 194 AudioRendererHost* host, |
| 192 int stream_id, | 195 int stream_id, |
| 193 int render_frame_id, | 196 int render_frame_id, |
| 194 const media::AudioParameters& params, | 197 const media::AudioParameters& params, |
| 195 const std::string& output_device_id, | 198 const std::string& output_device_id, |
| 196 std::unique_ptr<base::SharedMemory> shared_memory, | 199 std::unique_ptr<AudioSyncReader> reader) |
| 197 std::unique_ptr<media::AudioOutputController::SyncReader> reader) | |
| 198 : host_(host), | 200 : host_(host), |
| 199 stream_id_(stream_id), | 201 stream_id_(stream_id), |
| 200 render_frame_id_(render_frame_id), | 202 render_frame_id_(render_frame_id), |
| 201 shared_memory_(std::move(shared_memory)), | |
| 202 reader_(std::move(reader)), | 203 reader_(std::move(reader)), |
| 203 controller_(media::AudioOutputController::Create(host->audio_manager_, | 204 controller_(media::AudioOutputController::Create(host->audio_manager_, |
| 204 this, | 205 this, |
| 205 params, | 206 params, |
| 206 output_device_id, | 207 output_device_id, |
| 207 reader_.get())), | 208 reader_.get())), |
| 208 playing_(false) { | 209 playing_(false) { |
| 209 DCHECK(controller_.get()); | 210 DCHECK(controller_); |
| 210 } | 211 } |
| 211 | 212 |
| 212 AudioRendererHost::AudioEntry::~AudioEntry() {} | 213 AudioRendererHost::AudioEntry::~AudioEntry() {} |
| 213 | 214 |
| 215 // static |
| 216 std::unique_ptr<AudioRendererHost::AudioEntry> |
| 217 AudioRendererHost::AudioEntry::Create(AudioRendererHost* host, |
| 218 int stream_id, |
| 219 int render_frame_id, |
| 220 const media::AudioParameters& params, |
| 221 const std::string& output_device_id) { |
| 222 std::unique_ptr<AudioSyncReader> reader(AudioSyncReader::Create(params)); |
| 223 if (!reader) { |
| 224 return nullptr; |
| 225 } |
| 226 return base::WrapUnique(new AudioEntry(host, stream_id, render_frame_id, |
| 227 params, output_device_id, |
| 228 std::move(reader))); |
| 229 } |
| 230 |
| 214 /////////////////////////////////////////////////////////////////////////////// | 231 /////////////////////////////////////////////////////////////////////////////// |
| 215 // AudioRendererHost implementations. | 232 // AudioRendererHost implementations. |
| 216 | 233 |
| 217 AudioRendererHost::AudioRendererHost(int render_process_id, | 234 AudioRendererHost::AudioRendererHost(int render_process_id, |
| 218 media::AudioManager* audio_manager, | 235 media::AudioManager* audio_manager, |
| 219 AudioMirroringManager* mirroring_manager, | 236 AudioMirroringManager* mirroring_manager, |
| 220 MediaInternals* media_internals, | 237 MediaInternals* media_internals, |
| 221 MediaStreamManager* media_stream_manager, | 238 MediaStreamManager* media_stream_manager, |
| 222 const std::string& salt) | 239 const std::string& salt) |
| 223 : BrowserMessageFilter(AudioMsgStart), | 240 : BrowserMessageFilter(AudioMsgStart), |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 ReportErrorAndClose(stream_id); | 336 ReportErrorAndClose(stream_id); |
| 320 return; | 337 return; |
| 321 } | 338 } |
| 322 | 339 |
| 323 AudioEntry* const entry = LookupById(stream_id); | 340 AudioEntry* const entry = LookupById(stream_id); |
| 324 if (!entry) { | 341 if (!entry) { |
| 325 ReportErrorAndClose(stream_id); | 342 ReportErrorAndClose(stream_id); |
| 326 return; | 343 return; |
| 327 } | 344 } |
| 328 | 345 |
| 329 // Once the audio stream is created then complete the creation process by | 346 // Now construction is done and we are ready to send the shared memory and the |
| 330 // mapping shared memory and sharing with the renderer process. | 347 // sync socket to the renderer. |
| 348 base::SharedMemory* shared_memory = entry->reader()->shared_memory(); |
| 349 base::CancelableSyncSocket* foreign_socket = |
| 350 entry->reader()->foreign_socket(); |
| 351 |
| 331 base::SharedMemoryHandle foreign_memory_handle; | 352 base::SharedMemoryHandle foreign_memory_handle; |
| 332 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), | 353 base::SyncSocket::TransitDescriptor socket_descriptor; |
| 333 &foreign_memory_handle)) { | 354 size_t shared_memory_size = shared_memory->requested_size(); |
| 334 // If we failed to map and share the shared memory then close the audio | |
| 335 // stream and send an error message. | |
| 336 ReportErrorAndClose(entry->stream_id()); | |
| 337 return; | |
| 338 } | |
| 339 | 355 |
| 340 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); | 356 if (!(shared_memory->ShareToProcess(PeerHandle(), &foreign_memory_handle) && |
| 341 | 357 foreign_socket->PrepareTransitDescriptor(PeerHandle(), |
| 342 base::SyncSocket::TransitDescriptor socket_descriptor; | 358 &socket_descriptor))) { |
| 343 | 359 // Something went wrong in preparing the IPC handles. |
| 344 // If we failed to prepare the sync socket for the renderer then we fail | |
| 345 // the construction of audio stream. | |
| 346 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) { | |
| 347 ReportErrorAndClose(entry->stream_id()); | 360 ReportErrorAndClose(entry->stream_id()); |
| 348 return; | 361 return; |
| 349 } | 362 } |
| 350 | 363 |
| 351 Send(new AudioMsg_NotifyStreamCreated( | 364 Send(new AudioMsg_NotifyStreamCreated( |
| 352 entry->stream_id(), foreign_memory_handle, socket_descriptor, | 365 stream_id, foreign_memory_handle, socket_descriptor, |
| 353 entry->shared_memory()->requested_size())); | 366 base::checked_cast<uint32_t>(shared_memory_size))); |
| 354 } | 367 } |
| 355 | 368 |
| 356 void AudioRendererHost::DidValidateRenderFrame(int stream_id, bool is_valid) { | 369 void AudioRendererHost::DidValidateRenderFrame(int stream_id, bool is_valid) { |
| 357 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 370 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 358 | 371 |
| 359 if (!is_valid) { | 372 if (!is_valid) { |
| 360 DLOG(WARNING) << "Render frame for stream (id=" << stream_id | 373 DLOG(WARNING) << "Render frame for stream (id=" << stream_id |
| 361 << ") no longer exists."; | 374 << ") no longer exists."; |
| 362 ReportErrorAndClose(stream_id); | 375 ReportErrorAndClose(stream_id); |
| 363 } | 376 } |
| 364 } | 377 } |
| 365 | 378 |
| 366 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, | 379 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, |
| 367 bool is_playing) { | 380 bool is_playing) { |
| 368 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 381 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 369 | 382 |
| 370 AudioEntry* const entry = LookupById(stream_id); | 383 AudioEntry* const entry = LookupById(stream_id); |
| 371 if (!entry) | 384 if (!entry) |
| 372 return; | 385 return; |
| 373 | 386 |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 // a valid render frame. This validation is important for all the reasons | 614 // a valid render frame. This validation is important for all the reasons |
| 602 // stated in the comments above. This does not block stream creation, but will | 615 // stated in the comments above. This does not block stream creation, but will |
| 603 // force-close the stream later if validation fails. | 616 // force-close the stream later if validation fails. |
| 604 BrowserThread::PostTask( | 617 BrowserThread::PostTask( |
| 605 BrowserThread::UI, FROM_HERE, | 618 BrowserThread::UI, FROM_HERE, |
| 606 base::Bind(validate_render_frame_id_function_, render_process_id_, | 619 base::Bind(validate_render_frame_id_function_, render_process_id_, |
| 607 render_frame_id, | 620 render_frame_id, |
| 608 base::Bind(&AudioRendererHost::DidValidateRenderFrame, this, | 621 base::Bind(&AudioRendererHost::DidValidateRenderFrame, this, |
| 609 stream_id))); | 622 stream_id))); |
| 610 | 623 |
| 611 // Create the shared memory and share with the renderer process. | 624 std::unique_ptr<AudioEntry> entry = AudioEntry::Create( |
| 612 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) + | 625 this, stream_id, render_frame_id, params, device_unique_id); |
| 613 AudioBus::CalculateMemorySize(params); | 626 if (!entry) { |
| 614 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); | |
| 615 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) { | |
| 616 SendErrorMessage(stream_id); | 627 SendErrorMessage(stream_id); |
| 617 return; | 628 return; |
| 618 } | 629 } |
| 619 | |
| 620 std::unique_ptr<AudioSyncReader> reader( | |
| 621 new AudioSyncReader(shared_memory.get(), params)); | |
| 622 if (!reader->Init()) { | |
| 623 SendErrorMessage(stream_id); | |
| 624 return; | |
| 625 } | |
| 626 | 630 |
| 627 MediaObserver* const media_observer = | 631 MediaObserver* const media_observer = |
| 628 GetContentClient()->browser()->GetMediaObserver(); | 632 GetContentClient()->browser()->GetMediaObserver(); |
| 629 if (media_observer) | 633 if (media_observer) |
| 630 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); | 634 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); |
| 631 | 635 |
| 632 std::unique_ptr<AudioEntry> entry( | |
| 633 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id, | |
| 634 std::move(shared_memory), std::move(reader))); | |
| 635 if (mirroring_manager_) { | 636 if (mirroring_manager_) { |
| 636 mirroring_manager_->AddDiverter( | 637 mirroring_manager_->AddDiverter( |
| 637 render_process_id_, entry->render_frame_id(), entry->controller()); | 638 render_process_id_, entry->render_frame_id(), entry->controller()); |
| 638 } | 639 } |
| 639 audio_entries_.insert(std::make_pair(stream_id, entry.release())); | 640 audio_entries_.insert(std::make_pair(stream_id, entry.release())); |
| 640 g_audio_streams_tracker.Get().IncreaseStreamCount(); | 641 g_audio_streams_tracker.Get().IncreaseStreamCount(); |
| 641 | 642 |
| 642 audio_log_->OnCreated(stream_id, params, device_unique_id); | 643 audio_log_->OnCreated(stream_id, params, device_unique_id); |
| 643 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry( | 644 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry( |
| 644 stream_id, render_process_id_, render_frame_id, audio_log_.get()); | 645 stream_id, render_process_id_, render_frame_id, audio_log_.get()); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 callback.Run(false, device_info); | 856 callback.Run(false, device_info); |
| 856 } | 857 } |
| 857 | 858 |
| 858 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { | 859 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { |
| 859 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 860 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 860 const auto& i = authorizations_.find(stream_id); | 861 const auto& i = authorizations_.find(stream_id); |
| 861 return i != authorizations_.end(); | 862 return i != authorizations_.end(); |
| 862 } | 863 } |
| 863 | 864 |
| 864 } // namespace content | 865 } // namespace content |
| OLD | NEW |