OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/media/audio_stream_monitor.h" | 5 #include "content/browser/media/audio_stream_monitor.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "content/browser/web_contents/web_contents_impl.h" | 9 #include "content/browser/web_contents/web_contents_impl.h" |
10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
11 #include "content/public/browser/invalidate_type.h" | 11 #include "content/public/browser/invalidate_type.h" |
12 #include "content/public/browser/render_frame_host.h" | 12 #include "content/public/browser/render_frame_host.h" |
13 | 13 |
14 namespace content { | 14 namespace content { |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 AudioStreamMonitor* AudioStreamMonitorFromRenderFrame(int render_process_id, | 18 enum class ActionType { STARTING, STOPPING }; |
19 int render_frame_id) { | 19 AudioStreamMonitor* StartStopMonitoringHelper(ActionType action_type, |
20 int render_process_id, | |
21 int render_frame_id) { | |
20 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 22 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
23 | |
24 // It's important that this code uses only the process id for lookup as there | |
25 // may not be a RenderFrameHost or WebContents attached to the RenderProcess | |
26 // at time of call; e.g., in the event of a crash. | |
27 RenderProcessHost* const render_process_host = | |
28 RenderProcessHost::FromID(render_process_id); | |
29 if (!render_process_host) | |
30 return nullptr; | |
31 | |
32 // TODO(dalecurtis, maxmorin): We should really only be sending these when the | |
33 // streams are audible or we don't have power level monitoring. | |
34 if (action_type == ActionType::STARTING) | |
35 render_process_host->OnAudioStreamAdded(); | |
36 else | |
37 render_process_host->OnAudioStreamRemoved(); | |
38 | |
21 WebContentsImpl* const web_contents = | 39 WebContentsImpl* const web_contents = |
22 static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost( | 40 static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost( |
23 RenderFrameHost::FromID(render_process_id, render_frame_id))); | 41 RenderFrameHost::FromID(render_process_id, render_frame_id))); |
24 | |
25 return web_contents ? web_contents->audio_stream_monitor() : nullptr; | 42 return web_contents ? web_contents->audio_stream_monitor() : nullptr; |
26 } | 43 } |
27 | 44 |
28 } // namespace | 45 } // namespace |
29 | 46 |
30 AudioStreamMonitor::AudioStreamMonitor(WebContents* contents) | 47 AudioStreamMonitor::AudioStreamMonitor(WebContents* contents) |
31 : web_contents_(contents), | 48 : web_contents_(contents), |
32 clock_(&default_tick_clock_), | 49 clock_(&default_tick_clock_), |
33 was_recently_audible_(false), | 50 was_recently_audible_(false), |
34 is_audible_(false), | 51 is_audible_(false), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
75 stream_id)); | 92 stream_id)); |
76 } | 93 } |
77 | 94 |
78 // static | 95 // static |
79 void AudioStreamMonitor::StartMonitoringHelper( | 96 void AudioStreamMonitor::StartMonitoringHelper( |
80 int render_process_id, | 97 int render_process_id, |
81 int render_frame_id, | 98 int render_frame_id, |
82 int stream_id, | 99 int stream_id, |
83 const ReadPowerAndClipCallback& read_power_callback) { | 100 const ReadPowerAndClipCallback& read_power_callback) { |
84 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 101 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
85 AudioStreamMonitor* const monitor = | 102 if (AudioStreamMonitor* monitor = StartStopMonitoringHelper( |
86 AudioStreamMonitorFromRenderFrame(render_process_id, render_frame_id); | 103 ActionType::STARTING, render_process_id, render_frame_id)) { |
87 if (!monitor) | 104 if (!power_level_monitoring_available()) { |
88 return; | 105 monitor->OnStreamAdded(); |
89 | 106 } else { |
90 monitor->OnStreamAdded(); | 107 monitor->StartMonitoringStreamOnUIThread(render_process_id, stream_id, |
91 | 108 read_power_callback); |
92 if (!power_level_monitoring_available()) | 109 } |
93 return; | 110 } |
94 | |
95 monitor->StartMonitoringStreamOnUIThread(render_process_id, stream_id, | |
96 read_power_callback); | |
97 } | 111 } |
98 | 112 |
99 // static | 113 // static |
100 void AudioStreamMonitor::StopMonitoringHelper(int render_process_id, | 114 void AudioStreamMonitor::StopMonitoringHelper(int render_process_id, |
101 int render_frame_id, | 115 int render_frame_id, |
102 int stream_id) { | 116 int stream_id) { |
103 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 117 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
104 AudioStreamMonitor* const monitor = | 118 if (AudioStreamMonitor* monitor = StartStopMonitoringHelper( |
105 AudioStreamMonitorFromRenderFrame(render_process_id, render_frame_id); | 119 ActionType::STOPPING, render_process_id, render_frame_id)) { |
106 if (!monitor) | 120 if (!power_level_monitoring_available()) |
107 return; | 121 monitor->OnStreamRemoved(); |
108 | 122 else |
109 monitor->OnStreamRemoved(); | 123 monitor->StopMonitoringStreamOnUIThread(render_process_id, stream_id); |
110 | 124 } |
111 if (!power_level_monitoring_available()) | |
112 return; | |
113 | |
114 monitor->StopMonitoringStreamOnUIThread(render_process_id, stream_id); | |
115 } | 125 } |
116 | 126 |
117 void AudioStreamMonitor::StartMonitoringStreamOnUIThread( | 127 void AudioStreamMonitor::StartMonitoringStreamOnUIThread( |
118 int render_process_id, | 128 int render_process_id, |
119 int stream_id, | 129 int stream_id, |
120 const ReadPowerAndClipCallback& read_power_callback) { | 130 const ReadPowerAndClipCallback& read_power_callback) { |
121 DCHECK(thread_checker_.CalledOnValidThread()); | 131 DCHECK(thread_checker_.CalledOnValidThread()); |
122 DCHECK(!read_power_callback.is_null()); | 132 DCHECK(!read_power_callback.is_null()); |
Max Morin
2017/02/07 11:51:19
DCHECK that stream_id is not already monitored? An
DaleCurtis
2017/02/08 23:15:10
Done.
| |
123 poll_callbacks_[StreamID(render_process_id, stream_id)] = read_power_callback; | 133 poll_callbacks_[StreamID(render_process_id, stream_id)] = read_power_callback; |
124 if (!poll_timer_.IsRunning()) { | 134 if (!poll_timer_.IsRunning()) { |
125 poll_timer_.Start( | 135 poll_timer_.Start( |
126 FROM_HERE, | 136 FROM_HERE, base::TimeDelta::FromSeconds(1) / |
127 base::TimeDelta::FromSeconds(1) / | 137 static_cast<int>(kPowerMeasurementsPerSecond), |
128 static_cast<int>(kPowerMeasurementsPerSecond), | |
129 base::Bind(&AudioStreamMonitor::Poll, base::Unretained(this))); | 138 base::Bind(&AudioStreamMonitor::Poll, base::Unretained(this))); |
130 } | 139 } |
131 } | 140 } |
132 | 141 |
133 void AudioStreamMonitor::StopMonitoringStreamOnUIThread(int render_process_id, | 142 void AudioStreamMonitor::StopMonitoringStreamOnUIThread(int render_process_id, |
134 int stream_id) { | 143 int stream_id) { |
135 DCHECK(thread_checker_.CalledOnValidThread()); | 144 DCHECK(thread_checker_.CalledOnValidThread()); |
136 poll_callbacks_.erase(StreamID(render_process_id, stream_id)); | 145 poll_callbacks_.erase(StreamID(render_process_id, stream_id)); |
137 if (poll_callbacks_.empty()) | 146 if (poll_callbacks_.empty()) |
138 poll_timer_.Stop(); | 147 poll_timer_.Stop(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 } else if (!off_timer_.IsRunning()) { | 189 } else if (!off_timer_.IsRunning()) { |
181 off_timer_.Start( | 190 off_timer_.Start( |
182 FROM_HERE, | 191 FROM_HERE, |
183 off_time - now, | 192 off_time - now, |
184 base::Bind(&AudioStreamMonitor::MaybeToggle, base::Unretained(this))); | 193 base::Bind(&AudioStreamMonitor::MaybeToggle, base::Unretained(this))); |
185 } | 194 } |
186 } | 195 } |
187 | 196 |
188 void AudioStreamMonitor::OnStreamAdded() { | 197 void AudioStreamMonitor::OnStreamAdded() { |
189 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 198 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
190 ++active_streams_; | 199 DCHECK(!power_level_monitoring_available()); |
191 | 200 if (++active_streams_ == 1) { |
192 if (power_level_monitoring_available()) | |
193 return; | |
194 | |
195 if (active_streams_ == 1) { | |
196 is_audible_ = true; | 201 is_audible_ = true; |
197 web_contents_->OnAudioStateChanged(true); | 202 web_contents_->OnAudioStateChanged(true); |
198 MaybeToggle(); | 203 MaybeToggle(); |
199 } | 204 } |
200 } | 205 } |
201 | 206 |
202 void AudioStreamMonitor::OnStreamRemoved() { | 207 void AudioStreamMonitor::OnStreamRemoved() { |
203 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 208 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
204 --active_streams_; | 209 DCHECK(!power_level_monitoring_available()); |
205 | 210 if (--active_streams_ == 0) { |
o1ka
2017/02/07 09:38:02
DCHECK(active_streams_ > 0)?
DaleCurtis
2017/02/07 22:09:16
Done.
| |
206 if (power_level_monitoring_available()) | |
207 return; | |
208 | |
209 if (active_streams_ == 0) { | |
210 is_audible_ = false; | 211 is_audible_ = false; |
211 web_contents_->OnAudioStateChanged(false); | 212 web_contents_->OnAudioStateChanged(false); |
212 MaybeToggle(); | 213 MaybeToggle(); |
213 } | 214 } |
214 } | 215 } |
215 | 216 |
216 } // namespace content | 217 } // namespace content |
OLD | NEW |