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 <map> | 7 #include <map> |
8 #include <memory> | 8 #include <memory> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... |
23 using ::testing::InvokeWithoutArgs; | 23 using ::testing::InvokeWithoutArgs; |
24 | 24 |
25 namespace content { | 25 namespace content { |
26 | 26 |
27 namespace { | 27 namespace { |
28 | 28 |
29 const int kRenderProcessId = 1; | 29 const int kRenderProcessId = 1; |
30 const int kAnotherRenderProcessId = 2; | 30 const int kAnotherRenderProcessId = 2; |
31 const int kStreamId = 3; | 31 const int kStreamId = 3; |
32 const int kAnotherStreamId = 6; | 32 const int kAnotherStreamId = 6; |
| 33 const int kRenderFrameId = 4; |
| 34 const int kAnotherRenderFrameId = 8; |
33 | 35 |
34 // Used to confirm audio indicator state changes occur at the correct times. | 36 // Used to confirm audio indicator state changes occur at the correct times. |
35 class MockWebContentsDelegate : public WebContentsDelegate { | 37 class MockWebContentsDelegate : public WebContentsDelegate { |
36 public: | 38 public: |
37 MOCK_METHOD2(NavigationStateChanged, | 39 MOCK_METHOD2(NavigationStateChanged, |
38 void(WebContents* source, InvalidateTypes changed_flags)); | 40 void(WebContents* source, InvalidateTypes changed_flags)); |
39 }; | 41 }; |
40 | 42 |
41 } // namespace | 43 } // namespace |
42 | 44 |
(...skipping 26 matching lines...) Expand all Loading... |
69 } | 71 } |
70 | 72 |
71 void SetStreamPower(int stream_id, float power) { | 73 void SetStreamPower(int stream_id, float power) { |
72 current_power_[stream_id] = power; | 74 current_power_[stream_id] = power; |
73 } | 75 } |
74 | 76 |
75 void SimulatePollTimerFired() { monitor_->Poll(); } | 77 void SimulatePollTimerFired() { monitor_->Poll(); } |
76 | 78 |
77 void SimulateOffTimerFired() { monitor_->MaybeToggle(); } | 79 void SimulateOffTimerFired() { monitor_->MaybeToggle(); } |
78 | 80 |
79 void ExpectIsPolling(int render_process_id, int stream_id, bool is_polling) { | 81 void ExpectIsPolling(int render_process_id, |
80 const AudioStreamMonitor::StreamID key(render_process_id, stream_id); | 82 int render_frame_id, |
| 83 int stream_id, |
| 84 bool is_polling) { |
| 85 const AudioStreamMonitor::StreamID key = {render_process_id, |
| 86 render_frame_id, stream_id}; |
81 EXPECT_EQ(is_polling, monitor_->poll_callbacks_.find(key) != | 87 EXPECT_EQ(is_polling, monitor_->poll_callbacks_.find(key) != |
82 monitor_->poll_callbacks_.end()); | 88 monitor_->poll_callbacks_.end()); |
83 EXPECT_EQ(!monitor_->poll_callbacks_.empty(), | 89 EXPECT_EQ(!monitor_->poll_callbacks_.empty(), |
84 power_level_monitoring_available() | 90 power_level_monitoring_available() |
85 ? monitor_->poll_timer_.IsRunning() | 91 ? monitor_->poll_timer_.IsRunning() |
86 : monitor_->IsCurrentlyAudible()); | 92 : monitor_->IsCurrentlyAudible()); |
87 } | 93 } |
88 | 94 |
89 void ExpectTabWasRecentlyAudible(bool was_audible, | 95 void ExpectTabWasRecentlyAudible(bool was_audible, |
90 const base::TimeTicks& last_blurt_time) { | 96 const base::TimeTicks& last_blurt_time) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 static_cast<int>(AudioStreamMonitor::kPowerMeasurementsPerSecond); | 139 static_cast<int>(AudioStreamMonitor::kPowerMeasurementsPerSecond); |
134 } | 140 } |
135 | 141 |
136 static base::TimeDelta holding_period() { | 142 static base::TimeDelta holding_period() { |
137 return base::TimeDelta::FromMilliseconds( | 143 return base::TimeDelta::FromMilliseconds( |
138 AudioStreamMonitor::kHoldOnMilliseconds); | 144 AudioStreamMonitor::kHoldOnMilliseconds); |
139 } | 145 } |
140 | 146 |
141 void StartMonitoring( | 147 void StartMonitoring( |
142 int render_process_id, | 148 int render_process_id, |
| 149 int render_frame_id, |
143 int stream_id, | 150 int stream_id, |
144 const AudioStreamMonitor::ReadPowerAndClipCallback& callback) { | 151 const AudioStreamMonitor::ReadPowerAndClipCallback& callback) { |
145 if (!power_level_monitoring_available() && | 152 if (!power_level_monitoring_available() && |
146 monitor_->poll_callbacks_.empty()) { | 153 monitor_->poll_callbacks_.empty()) { |
147 ExpectCurrentlyAudibleChangeNotification(true); | 154 ExpectCurrentlyAudibleChangeNotification(true); |
148 } | 155 } |
149 monitor_->StartMonitoringStreamOnUIThread(render_process_id, stream_id, | 156 monitor_->StartMonitoringStreamOnUIThread( |
150 callback); | 157 render_process_id, render_frame_id, stream_id, callback); |
151 } | 158 } |
152 | 159 |
153 void StopMonitoring(int render_process_id, int stream_id) { | 160 void StopMonitoring(int render_process_id, |
| 161 int render_frame_id, |
| 162 int stream_id) { |
154 if (!power_level_monitoring_available() && | 163 if (!power_level_monitoring_available() && |
155 monitor_->poll_callbacks_.size() == 1u) { | 164 monitor_->poll_callbacks_.size() == 1u) { |
156 ExpectCurrentlyAudibleChangeNotification(false); | 165 ExpectCurrentlyAudibleChangeNotification(false); |
157 } | 166 } |
158 monitor_->StopMonitoringStreamOnUIThread(render_process_id, stream_id); | 167 monitor_->StopMonitoringStreamOnUIThread(render_process_id, render_frame_id, |
| 168 stream_id); |
159 } | 169 } |
160 | 170 |
161 bool power_level_monitoring_available() { | 171 bool power_level_monitoring_available() { |
162 return AudioStreamMonitor::power_level_monitoring_available(); | 172 return AudioStreamMonitor::power_level_monitoring_available(); |
163 } | 173 } |
164 | 174 |
165 protected: | 175 protected: |
166 AudioStreamMonitor* monitor_; | 176 AudioStreamMonitor* monitor_; |
167 | 177 |
168 private: | 178 private: |
(...skipping 17 matching lines...) Expand all Loading... |
186 }; | 196 }; |
187 | 197 |
188 // Tests that AudioStreamMonitor is polling while it has a | 198 // Tests that AudioStreamMonitor is polling while it has a |
189 // ReadPowerAndClipCallback, and is not polling at other times. | 199 // ReadPowerAndClipCallback, and is not polling at other times. |
190 TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) { | 200 TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) { |
191 if (!power_level_monitoring_available()) | 201 if (!power_level_monitoring_available()) |
192 return; | 202 return; |
193 | 203 |
194 EXPECT_FALSE(monitor_->WasRecentlyAudible()); | 204 EXPECT_FALSE(monitor_->WasRecentlyAudible()); |
195 ExpectNotCurrentlyAudible(); | 205 ExpectNotCurrentlyAudible(); |
196 ExpectIsPolling(kRenderProcessId, kStreamId, false); | 206 ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, false); |
197 | 207 |
198 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); | 208 StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, |
| 209 CreatePollCallback(kStreamId)); |
199 EXPECT_FALSE(monitor_->WasRecentlyAudible()); | 210 EXPECT_FALSE(monitor_->WasRecentlyAudible()); |
200 ExpectNotCurrentlyAudible(); | 211 ExpectNotCurrentlyAudible(); |
201 ExpectIsPolling(kRenderProcessId, kStreamId, true); | 212 ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); |
202 | 213 |
203 StopMonitoring(kRenderProcessId, kStreamId); | 214 StopMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); |
204 EXPECT_FALSE(monitor_->WasRecentlyAudible()); | 215 EXPECT_FALSE(monitor_->WasRecentlyAudible()); |
205 ExpectNotCurrentlyAudible(); | 216 ExpectNotCurrentlyAudible(); |
206 ExpectIsPolling(kRenderProcessId, kStreamId, false); | 217 ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, false); |
207 } | 218 } |
208 | 219 |
209 // Tests that AudioStreamMonitor debounces the power level readings it's taking, | 220 // Tests that AudioStreamMonitor debounces the power level readings it's taking, |
210 // which could be fluctuating rapidly between the audible versus silence | 221 // which could be fluctuating rapidly between the audible versus silence |
211 // threshold. See comments in audio_stream_monitor.h for expected behavior. | 222 // threshold. See comments in audio_stream_monitor.h for expected behavior. |
212 TEST_F(AudioStreamMonitorTest, | 223 TEST_F(AudioStreamMonitorTest, |
213 ImpulsesKeepIndicatorOnUntilHoldingPeriodHasPassed) { | 224 ImpulsesKeepIndicatorOnUntilHoldingPeriodHasPassed) { |
214 if (!power_level_monitoring_available()) | 225 if (!power_level_monitoring_available()) |
215 return; | 226 return; |
216 | 227 |
217 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); | 228 StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, |
| 229 CreatePollCallback(kStreamId)); |
218 | 230 |
219 // Expect WebContents will get one call form AudioStreamMonitor to toggle the | 231 // Expect WebContents will get one call form AudioStreamMonitor to toggle the |
220 // indicator on upon the very first poll. | 232 // indicator on upon the very first poll. |
221 ExpectRecentlyAudibleChangeNotification(true); | 233 ExpectRecentlyAudibleChangeNotification(true); |
222 | 234 |
223 // Loop, each time testing a slightly longer period of polled silence. The | 235 // Loop, each time testing a slightly longer period of polled silence. The |
224 // recently audible state should not change while the currently audible one | 236 // recently audible state should not change while the currently audible one |
225 // should. | 237 // should. |
226 int num_silence_polls = 1; | 238 int num_silence_polls = 1; |
227 base::TimeTicks last_blurt_time; | 239 base::TimeTicks last_blurt_time; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 AdvanceClock(one_polling_interval()); | 274 AdvanceClock(one_polling_interval()); |
263 } | 275 } |
264 } | 276 } |
265 | 277 |
266 // Tests that the AudioStreamMonitor correctly processes the blurts from two | 278 // Tests that the AudioStreamMonitor correctly processes the blurts from two |
267 // different streams in the same tab. | 279 // different streams in the same tab. |
268 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) { | 280 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) { |
269 if (!power_level_monitoring_available()) | 281 if (!power_level_monitoring_available()) |
270 return; | 282 return; |
271 | 283 |
272 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); | 284 StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, |
273 StartMonitoring( | 285 CreatePollCallback(kStreamId)); |
274 kRenderProcessId, kAnotherStreamId, CreatePollCallback(kAnotherStreamId)); | 286 StartMonitoring(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId, |
| 287 CreatePollCallback(kAnotherStreamId)); |
275 | 288 |
276 base::TimeTicks last_blurt_time; | 289 base::TimeTicks last_blurt_time; |
277 ExpectTabWasRecentlyAudible(false, last_blurt_time); | 290 ExpectTabWasRecentlyAudible(false, last_blurt_time); |
278 ExpectNotCurrentlyAudible(); | 291 ExpectNotCurrentlyAudible(); |
279 | 292 |
280 // Measure audible sound from the first stream and silence from the second. | 293 // Measure audible sound from the first stream and silence from the second. |
281 // The tab becomes audible. | 294 // The tab becomes audible. |
282 ExpectRecentlyAudibleChangeNotification(true); | 295 ExpectRecentlyAudibleChangeNotification(true); |
283 ExpectCurrentlyAudibleChangeNotification(true); | 296 ExpectCurrentlyAudibleChangeNotification(true); |
284 | 297 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 // silent. | 361 // silent. |
349 for (int i = 0; i < 100; ++i) { | 362 for (int i = 0; i < 100; ++i) { |
350 AdvanceClock(one_polling_interval()); | 363 AdvanceClock(one_polling_interval()); |
351 SimulatePollTimerFired(); | 364 SimulatePollTimerFired(); |
352 ExpectTabWasRecentlyAudible(false, last_blurt_time); | 365 ExpectTabWasRecentlyAudible(false, last_blurt_time); |
353 ExpectNotCurrentlyAudible(); | 366 ExpectNotCurrentlyAudible(); |
354 } | 367 } |
355 } | 368 } |
356 | 369 |
357 TEST_F(AudioStreamMonitorTest, MultipleRendererProcesses) { | 370 TEST_F(AudioStreamMonitorTest, MultipleRendererProcesses) { |
358 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); | 371 StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, |
359 StartMonitoring( | 372 CreatePollCallback(kStreamId)); |
360 kAnotherRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); | 373 StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, |
361 ExpectIsPolling(kRenderProcessId, kStreamId, true); | 374 CreatePollCallback(kStreamId)); |
362 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true); | 375 ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); |
363 StopMonitoring(kAnotherRenderProcessId, kStreamId); | 376 ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); |
364 ExpectIsPolling(kRenderProcessId, kStreamId, true); | 377 StopMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId); |
365 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, false); | 378 ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); |
| 379 ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, false); |
366 } | 380 } |
367 | 381 |
368 TEST_F(AudioStreamMonitorTest, RenderProcessGone) { | 382 TEST_F(AudioStreamMonitorTest, RenderProcessGone) { |
369 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); | 383 StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, |
370 StartMonitoring(kAnotherRenderProcessId, kStreamId, | |
371 CreatePollCallback(kStreamId)); | 384 CreatePollCallback(kStreamId)); |
372 ExpectIsPolling(kRenderProcessId, kStreamId, true); | 385 StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, |
373 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true); | 386 CreatePollCallback(kStreamId)); |
| 387 ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); |
| 388 ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); |
374 monitor_->RenderProcessGone(kRenderProcessId); | 389 monitor_->RenderProcessGone(kRenderProcessId); |
375 ExpectIsPolling(kRenderProcessId, kStreamId, false); | 390 ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, false); |
376 if (!power_level_monitoring_available()) | 391 if (!power_level_monitoring_available()) |
377 ExpectCurrentlyAudibleChangeNotification(false); | 392 ExpectCurrentlyAudibleChangeNotification(false); |
378 monitor_->RenderProcessGone(kAnotherRenderProcessId); | 393 monitor_->RenderProcessGone(kAnotherRenderProcessId); |
379 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, false); | 394 ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, false); |
380 } | 395 } |
381 | 396 |
382 TEST_F(AudioStreamMonitorTest, NoPowerLevelMonitoring) { | 397 TEST_F(AudioStreamMonitorTest, NoPowerLevelMonitoring) { |
383 if (power_level_monitoring_available()) | 398 if (power_level_monitoring_available()) |
384 return; | 399 return; |
385 | 400 |
386 ExpectNotCurrentlyAudible(); | 401 ExpectNotCurrentlyAudible(); |
387 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); | 402 StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, |
388 ExpectIsCurrentlyAudible(); | |
389 ExpectIsPolling(kRenderProcessId, kStreamId, true); | |
390 | |
391 StartMonitoring(kAnotherRenderProcessId, kStreamId, | |
392 CreatePollCallback(kStreamId)); | 403 CreatePollCallback(kStreamId)); |
393 ExpectIsCurrentlyAudible(); | 404 ExpectIsCurrentlyAudible(); |
394 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true); | 405 ExpectIsPolling(kRenderProcessId, kRenderFrameId, kStreamId, true); |
395 | 406 |
396 StopMonitoring(kRenderProcessId, kStreamId); | 407 StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, |
| 408 CreatePollCallback(kStreamId)); |
397 ExpectIsCurrentlyAudible(); | 409 ExpectIsCurrentlyAudible(); |
398 StopMonitoring(kAnotherRenderProcessId, kStreamId); | 410 ExpectIsPolling(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); |
| 411 |
| 412 StopMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); |
| 413 ExpectIsCurrentlyAudible(); |
| 414 StopMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId); |
399 ExpectNotCurrentlyAudible(); | 415 ExpectNotCurrentlyAudible(); |
400 } | 416 } |
401 | 417 |
402 } // namespace content | 418 } // namespace content |
OLD | NEW |