Index: content/browser/media/audio_stream_monitor.cc |
diff --git a/content/browser/media/audio_stream_monitor.cc b/content/browser/media/audio_stream_monitor.cc |
index ba86d56a8f05f5b8c1ba9bc5d8e3f581b7d3f96a..f2782a6be18f5ebe2fccfa2fff1d87c686a816e6 100644 |
--- a/content/browser/media/audio_stream_monitor.cc |
+++ b/content/browser/media/audio_stream_monitor.cc |
@@ -15,13 +15,30 @@ namespace content { |
namespace { |
-AudioStreamMonitor* AudioStreamMonitorFromRenderFrame(int render_process_id, |
- int render_frame_id) { |
+enum class ActionType { STARTING, STOPPING }; |
+AudioStreamMonitor* StartStopMonitoringHelper(ActionType action_type, |
+ int render_process_id, |
+ int render_frame_id) { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ |
+ // It's important that this code uses only the process id for lookup as there |
+ // may not be a RenderFrameHost or WebContents attached to the RenderProcess |
+ // at time of call; e.g., in the event of a crash. |
+ RenderProcessHost* const render_process_host = |
+ RenderProcessHost::FromID(render_process_id); |
+ if (!render_process_host) |
+ return nullptr; |
+ |
+ // TODO(dalecurtis, maxmorin): We should really only be sending these when the |
+ // streams are audible or we don't have power level monitoring. |
+ if (action_type == ActionType::STARTING) |
+ render_process_host->OnAudioStreamAdded(); |
+ else |
+ render_process_host->OnAudioStreamRemoved(); |
+ |
WebContentsImpl* const web_contents = |
static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost( |
RenderFrameHost::FromID(render_process_id, render_frame_id))); |
- |
return web_contents ? web_contents->audio_stream_monitor() : nullptr; |
} |
@@ -82,18 +99,15 @@ void AudioStreamMonitor::StartMonitoringHelper( |
int stream_id, |
const ReadPowerAndClipCallback& read_power_callback) { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- AudioStreamMonitor* const monitor = |
- AudioStreamMonitorFromRenderFrame(render_process_id, render_frame_id); |
- if (!monitor) |
- return; |
- |
- monitor->OnStreamAdded(); |
- |
- if (!power_level_monitoring_available()) |
- return; |
- |
- monitor->StartMonitoringStreamOnUIThread(render_process_id, stream_id, |
- read_power_callback); |
+ if (AudioStreamMonitor* monitor = StartStopMonitoringHelper( |
+ ActionType::STARTING, render_process_id, render_frame_id)) { |
+ if (!power_level_monitoring_available()) { |
+ monitor->OnStreamAdded(); |
+ } else { |
+ monitor->StartMonitoringStreamOnUIThread(render_process_id, stream_id, |
+ read_power_callback); |
+ } |
+ } |
} |
// static |
@@ -101,17 +115,13 @@ void AudioStreamMonitor::StopMonitoringHelper(int render_process_id, |
int render_frame_id, |
int stream_id) { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- AudioStreamMonitor* const monitor = |
- AudioStreamMonitorFromRenderFrame(render_process_id, render_frame_id); |
- if (!monitor) |
- return; |
- |
- monitor->OnStreamRemoved(); |
- |
- if (!power_level_monitoring_available()) |
- return; |
- |
- monitor->StopMonitoringStreamOnUIThread(render_process_id, stream_id); |
+ if (AudioStreamMonitor* monitor = StartStopMonitoringHelper( |
+ ActionType::STOPPING, render_process_id, render_frame_id)) { |
+ if (!power_level_monitoring_available()) |
+ monitor->OnStreamRemoved(); |
+ else |
+ monitor->StopMonitoringStreamOnUIThread(render_process_id, stream_id); |
+ } |
} |
void AudioStreamMonitor::StartMonitoringStreamOnUIThread( |
@@ -120,12 +130,15 @@ void AudioStreamMonitor::StartMonitoringStreamOnUIThread( |
const ReadPowerAndClipCallback& read_power_callback) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(!read_power_callback.is_null()); |
- poll_callbacks_[StreamID(render_process_id, stream_id)] = read_power_callback; |
+ |
+ const StreamID qualified_id(render_process_id, stream_id); |
+ DCHECK(poll_callbacks_.find(qualified_id) == poll_callbacks_.end()); |
+ poll_callbacks_[qualified_id] = read_power_callback; |
+ |
if (!poll_timer_.IsRunning()) { |
poll_timer_.Start( |
- FROM_HERE, |
- base::TimeDelta::FromSeconds(1) / |
- static_cast<int>(kPowerMeasurementsPerSecond), |
+ FROM_HERE, base::TimeDelta::FromSeconds(1) / |
+ static_cast<int>(kPowerMeasurementsPerSecond), |
base::Bind(&AudioStreamMonitor::Poll, base::Unretained(this))); |
} |
} |
@@ -133,7 +146,11 @@ void AudioStreamMonitor::StartMonitoringStreamOnUIThread( |
void AudioStreamMonitor::StopMonitoringStreamOnUIThread(int render_process_id, |
int stream_id) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- poll_callbacks_.erase(StreamID(render_process_id, stream_id)); |
+ |
+ const StreamID qualified_id(render_process_id, stream_id); |
+ DCHECK(poll_callbacks_.find(qualified_id) != poll_callbacks_.end()); |
+ poll_callbacks_.erase(qualified_id); |
+ |
if (poll_callbacks_.empty()) |
poll_timer_.Stop(); |
} |
@@ -187,12 +204,8 @@ void AudioStreamMonitor::MaybeToggle() { |
void AudioStreamMonitor::OnStreamAdded() { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- ++active_streams_; |
- |
- if (power_level_monitoring_available()) |
- return; |
- |
- if (active_streams_ == 1) { |
+ DCHECK(!power_level_monitoring_available()); |
+ if (++active_streams_ == 1u) { |
is_audible_ = true; |
web_contents_->OnAudioStateChanged(true); |
MaybeToggle(); |
@@ -201,12 +214,9 @@ void AudioStreamMonitor::OnStreamAdded() { |
void AudioStreamMonitor::OnStreamRemoved() { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- --active_streams_; |
- |
- if (power_level_monitoring_available()) |
- return; |
- |
- if (active_streams_ == 0) { |
+ DCHECK(!power_level_monitoring_available()); |
+ DCHECK_GT(active_streams_, 0u); |
+ if (--active_streams_ == 0u) { |
is_audible_ = false; |
web_contents_->OnAudioStateChanged(false); |
MaybeToggle(); |