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 {}; | |
DaleCurtis
2016/09/16 23:29:12
Just return nullptr?
Max Morin
2016/09/19 10:13:01
Done.
| |
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(); |
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
| |
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 |