Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(644)

Side by Side Diff: content/browser/renderer_host/media/audio_renderer_host.cc

Issue 2125143003: Add back RenderFrameHost sanity-check to AudioRendererHost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: REBASE again Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/logging.h"
14 #include "base/memory/shared_memory.h" 13 #include "base/memory/shared_memory.h"
15 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
16 #include "base/process/process.h" 15 #include "base/process/process.h"
17 #include "content/browser/bad_message.h" 16 #include "content/browser/bad_message.h"
18 #include "content/browser/browser_main_loop.h" 17 #include "content/browser/browser_main_loop.h"
19 #include "content/browser/media/audio_stream_monitor.h" 18 #include "content/browser/media/audio_stream_monitor.h"
20 #include "content/browser/media/capture/audio_mirroring_manager.h" 19 #include "content/browser/media/capture/audio_mirroring_manager.h"
21 #include "content/browser/media/media_internals.h" 20 #include "content/browser/media/media_internals.h"
22 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 21 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
23 #include "content/browser/renderer_host/media/audio_sync_reader.h" 22 #include "content/browser/renderer_host/media/audio_sync_reader.h"
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 *params = media::AudioParameters::UnavailableDeviceParams(); 108 *params = media::AudioParameters::UnavailableDeviceParams();
110 } 109 }
111 110
112 void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time) { 111 void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time) {
113 UMA_HISTOGRAM_CUSTOM_TIMES("Media.Audio.OutputDeviceAuthorizationTime", 112 UMA_HISTOGRAM_CUSTOM_TIMES("Media.Audio.OutputDeviceAuthorizationTime",
114 base::TimeTicks::Now() - auth_start_time, 113 base::TimeTicks::Now() - auth_start_time,
115 base::TimeDelta::FromMilliseconds(1), 114 base::TimeDelta::FromMilliseconds(1),
116 base::TimeDelta::FromMilliseconds(5000), 50); 115 base::TimeDelta::FromMilliseconds(5000), 50);
117 } 116 }
118 117
118 #if DCHECK_IS_ON()
119 // Check that the routing ID references a valid RenderFrameHost, and run
120 // |callback| on the IO thread with true if the ID is valid.
121 void ValidateRenderFrameId(int render_process_id,
122 int render_frame_id,
123 const base::Callback<void(bool)>& callback) {
124 DCHECK_CURRENTLY_ON(BrowserThread::UI);
125 const bool frame_exists =
126 !!RenderFrameHost::FromID(render_process_id, render_frame_id);
127 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
128 base::Bind(callback, frame_exists));
129 }
130 #endif // DCHECK_IS_ON()
131
119 } // namespace 132 } // namespace
120 133
121 class AudioRendererHost::AudioEntry 134 class AudioRendererHost::AudioEntry
122 : public media::AudioOutputController::EventHandler { 135 : public media::AudioOutputController::EventHandler {
123 public: 136 public:
124 AudioEntry(AudioRendererHost* host, 137 AudioEntry(AudioRendererHost* host,
125 int stream_id, 138 int stream_id,
126 int render_frame_id, 139 int render_frame_id,
127 const media::AudioParameters& params, 140 const media::AudioParameters& params,
128 const std::string& output_device_id, 141 const std::string& output_device_id,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 const std::string& salt) 222 const std::string& salt)
210 : BrowserMessageFilter(AudioMsgStart), 223 : BrowserMessageFilter(AudioMsgStart),
211 render_process_id_(render_process_id), 224 render_process_id_(render_process_id),
212 audio_manager_(audio_manager), 225 audio_manager_(audio_manager),
213 mirroring_manager_(mirroring_manager), 226 mirroring_manager_(mirroring_manager),
214 audio_log_(media_internals->CreateAudioLog( 227 audio_log_(media_internals->CreateAudioLog(
215 media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)), 228 media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)),
216 media_stream_manager_(media_stream_manager), 229 media_stream_manager_(media_stream_manager),
217 num_playing_streams_(0), 230 num_playing_streams_(0),
218 salt_(salt), 231 salt_(salt),
232 #if DCHECK_IS_ON()
233 validate_render_frame_id_function_(&ValidateRenderFrameId),
234 #endif // DCHECK_IS_ON()
219 max_simultaneous_streams_(0) { 235 max_simultaneous_streams_(0) {
220 DCHECK(audio_manager_); 236 DCHECK(audio_manager_);
221 DCHECK(media_stream_manager_); 237 DCHECK(media_stream_manager_);
222 } 238 }
223 239
224 AudioRendererHost::~AudioRendererHost() { 240 AudioRendererHost::~AudioRendererHost() {
225 DCHECK_CURRENTLY_ON(BrowserThread::IO); 241 DCHECK_CURRENTLY_ON(BrowserThread::IO);
226 CHECK(audio_entries_.empty()); 242 CHECK(audio_entries_.empty());
227 243
228 // If we had any streams, report UMA stats for the maximum number of 244 // If we had any streams, report UMA stats for the maximum number of
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string())); 553 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string()));
538 } 554 }
539 555
540 void AudioRendererHost::OnCreateStream(int stream_id, 556 void AudioRendererHost::OnCreateStream(int stream_id,
541 int render_frame_id, 557 int render_frame_id,
542 const media::AudioParameters& params) { 558 const media::AudioParameters& params) {
543 DCHECK_CURRENTLY_ON(BrowserThread::IO); 559 DCHECK_CURRENTLY_ON(BrowserThread::IO);
544 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream" 560 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream"
545 << "(stream_id=" << stream_id << ")"; 561 << "(stream_id=" << stream_id << ")";
546 562
563 // Determine whether to use the device_unique_id from an authorization, or an
564 // empty string (i.e., when no previous authorization was requested, assume
565 // default device).
566 std::string device_unique_id;
547 const auto& auth_data = authorizations_.find(stream_id); 567 const auto& auth_data = authorizations_.find(stream_id);
548 568 if (auth_data != authorizations_.end()) {
549 // If no previous authorization requested, assume default device 569 CHECK(auth_data->second.first);
550 if (auth_data == authorizations_.end()) { 570 device_unique_id.swap(auth_data->second.second);
551 DoCreateStream(stream_id, render_frame_id, params, std::string()); 571 authorizations_.erase(auth_data);
552 return;
553 } 572 }
554 573
555 CHECK(auth_data->second.first); 574 #if DCHECK_IS_ON()
556 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second); 575 // When DCHECKs are turned on, hop over to the UI thread to validate the
557 authorizations_.erase(auth_data); 576 // |render_frame_id|, then continue stream creation on the IO thread. See
577 // comment at top of DoCreateStream() for further details.
578 BrowserThread::PostTask(
579 BrowserThread::UI, FROM_HERE,
580 base::Bind(validate_render_frame_id_function_, render_process_id_,
581 render_frame_id,
582 base::Bind(&AudioRendererHost::DoCreateStream, this, stream_id,
583 render_frame_id, params, device_unique_id)));
584 #else
585 DoCreateStream(stream_id, render_frame_id, params, device_unique_id,
586 render_frame_id > 0);
587 #endif // DCHECK_IS_ON()
558 } 588 }
559 589
560 void AudioRendererHost::DoCreateStream(int stream_id, 590 void AudioRendererHost::DoCreateStream(int stream_id,
561 int render_frame_id, 591 int render_frame_id,
562 const media::AudioParameters& params, 592 const media::AudioParameters& params,
563 const std::string& device_unique_id) { 593 const std::string& device_unique_id,
594 bool render_frame_id_is_valid) {
564 DCHECK_CURRENTLY_ON(BrowserThread::IO); 595 DCHECK_CURRENTLY_ON(BrowserThread::IO);
565 596
566 // media::AudioParameters is validated in the deserializer. 597 // Fail early if either of two sanity-checks fail:
567 if (LookupById(stream_id) != NULL) { 598 // 1. There should not yet exist an AudioEntry for the given |stream_id|
599 // since the renderer may not create two streams with the same ID.
600 // 2. The render frame ID was either invalid or the render frame host it
601 // references has shutdown before the request could be fulfilled (race
602 // condition). Renderers must *always* specify a valid render frame ID
603 // for each audio output they create, as several browser-level features
604 // depend on this (e.g., OOM manager, UI audio indicator, muting, audio
605 // capture).
606 // Note: media::AudioParameters is validated in the deserializer, so there is
607 // no need to check that here.
608 if (LookupById(stream_id)) {
568 SendErrorMessage(stream_id); 609 SendErrorMessage(stream_id);
569 return; 610 return;
570 } 611 }
612 if (!render_frame_id_is_valid) {
613 SendErrorMessage(stream_id);
614 return;
615 }
571 616
572 // Create the shared memory and share with the renderer process. 617 // Create the shared memory and share with the renderer process.
573 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) + 618 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) +
574 AudioBus::CalculateMemorySize(params); 619 AudioBus::CalculateMemorySize(params);
575 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); 620 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
576 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) { 621 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) {
577 SendErrorMessage(stream_id); 622 SendErrorMessage(stream_id);
578 return; 623 return;
579 } 624 }
580 625
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 callback.Run(false, device_info); 872 callback.Run(false, device_info);
828 } 873 }
829 874
830 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { 875 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
831 DCHECK_CURRENTLY_ON(BrowserThread::IO); 876 DCHECK_CURRENTLY_ON(BrowserThread::IO);
832 const auto& i = authorizations_.find(stream_id); 877 const auto& i = authorizations_.find(stream_id);
833 return i != authorizations_.end(); 878 return i != authorizations_.end();
834 } 879 }
835 880
836 } // namespace content 881 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698