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

Side by Side Diff: content/browser/media/audio_stream_monitor_unittest.cc

Issue 1591453005: Add metrics regarding concurrent audible tabs in Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: user action and tick Created 4 years, 11 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 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 <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 } 86 }
87 87
88 void ExpectTabWasRecentlyAudible(bool was_audible, 88 void ExpectTabWasRecentlyAudible(bool was_audible,
89 const base::TimeTicks& last_blurt_time) { 89 const base::TimeTicks& last_blurt_time) {
90 EXPECT_EQ(was_audible, monitor_->was_recently_audible_); 90 EXPECT_EQ(was_audible, monitor_->was_recently_audible_);
91 EXPECT_EQ(last_blurt_time, monitor_->last_blurt_time_); 91 EXPECT_EQ(last_blurt_time, monitor_->last_blurt_time_);
92 EXPECT_EQ(monitor_->was_recently_audible_, 92 EXPECT_EQ(monitor_->was_recently_audible_,
93 monitor_->off_timer_.IsRunning()); 93 monitor_->off_timer_.IsRunning());
94 } 94 }
95 95
96 void ExpectWebContentsWillBeNotifiedOnce(bool should_be_audible) { 96 void ExpectIsCurrentlyAudible() const {
97 EXPECT_TRUE(monitor_->IsCurrentlyAudible());
98 }
99
100 void ExpectNotCurrentlyAudible() const {
101 EXPECT_FALSE(monitor_->IsCurrentlyAudible());
102 }
103
104 void ExpectRecentlyAudbileChangeNotification(bool new_recently_audible) {
DaleCurtis 2016/01/19 19:32:57 Audible
mlamouri (slow - plz ping) 2016/01/19 19:55:10 Done.
97 EXPECT_CALL( 105 EXPECT_CALL(
98 mock_web_contents_delegate_, 106 mock_web_contents_delegate_,
99 NavigationStateChanged(RenderViewHostTestHarness::web_contents(), 107 NavigationStateChanged(RenderViewHostTestHarness::web_contents(),
100 INVALIDATE_TYPE_TAB)) 108 INVALIDATE_TYPE_TAB))
101 .WillOnce(InvokeWithoutArgs( 109 .WillOnce(InvokeWithoutArgs(
102 this, 110 this,
103 should_be_audible 111 new_recently_audible
104 ? &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOn 112 ? &AudioStreamMonitorTest::ExpectWasRecentlyAudible
105 : &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOff)) 113 : &AudioStreamMonitorTest::ExpectNotRecentlyAudible))
106 .RetiresOnSaturation(); 114 .RetiresOnSaturation();
107 } 115 }
108 116
117 void ExpectCurrentlyAudbileChangeNotification(bool new_audible) {
DaleCurtis 2016/01/19 19:32:57 Audible
mlamouri (slow - plz ping) 2016/01/19 19:55:10 Done.
118 EXPECT_CALL(
119 mock_web_contents_delegate_,
120 NavigationStateChanged(RenderViewHostTestHarness::web_contents(),
121 INVALIDATE_TYPE_TAB))
122 .WillOnce(InvokeWithoutArgs(
123 this,
124 new_audible
125 ? &AudioStreamMonitorTest::ExpectIsCurrentlyAudible
126 : &AudioStreamMonitorTest::ExpectNotCurrentlyAudible))
127 .RetiresOnSaturation();
128 }
129
109 static base::TimeDelta one_polling_interval() { 130 static base::TimeDelta one_polling_interval() {
110 return base::TimeDelta::FromSeconds(1) / 131 return base::TimeDelta::FromSeconds(1) /
111 static_cast<int>(AudioStreamMonitor::kPowerMeasurementsPerSecond); 132 static_cast<int>(AudioStreamMonitor::kPowerMeasurementsPerSecond);
112 } 133 }
113 134
114 static base::TimeDelta holding_period() { 135 static base::TimeDelta holding_period() {
115 return base::TimeDelta::FromMilliseconds( 136 return base::TimeDelta::FromMilliseconds(
116 AudioStreamMonitor::kHoldOnMilliseconds); 137 AudioStreamMonitor::kHoldOnMilliseconds);
117 } 138 }
118 139
(...skipping 10 matching lines...) Expand all
129 } 150 }
130 151
131 protected: 152 protected:
132 AudioStreamMonitor* monitor_; 153 AudioStreamMonitor* monitor_;
133 154
134 private: 155 private:
135 std::pair<float, bool> ReadPower(int stream_id) { 156 std::pair<float, bool> ReadPower(int stream_id) {
136 return std::make_pair(current_power_[stream_id], false); 157 return std::make_pair(current_power_[stream_id], false);
137 } 158 }
138 159
139 void ExpectIsNotifyingForToggleOn() { 160 void ExpectWasRecentlyAudible() const {
140 EXPECT_TRUE(monitor_->WasRecentlyAudible()); 161 EXPECT_TRUE(monitor_->WasRecentlyAudible());
141 } 162 }
142 163
143 void ExpectIsNotifyingForToggleOff() { 164 void ExpectNotRecentlyAudible() const {
144 EXPECT_FALSE(monitor_->WasRecentlyAudible()); 165 EXPECT_FALSE(monitor_->WasRecentlyAudible());
145 } 166 }
146 167
147 MockWebContentsDelegate mock_web_contents_delegate_; 168 MockWebContentsDelegate mock_web_contents_delegate_;
148 base::SimpleTestTickClock clock_; 169 base::SimpleTestTickClock clock_;
149 std::map<int, float> current_power_; 170 std::map<int, float> current_power_;
150 171
151 DISALLOW_COPY_AND_ASSIGN(AudioStreamMonitorTest); 172 DISALLOW_COPY_AND_ASSIGN(AudioStreamMonitorTest);
152 }; 173 };
153 174
154 // Tests that AudioStreamMonitor is polling while it has a 175 // Tests that AudioStreamMonitor is polling while it has a
155 // ReadPowerAndClipCallback, and is not polling at other times. 176 // ReadPowerAndClipCallback, and is not polling at other times.
156 TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) { 177 TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) {
157 EXPECT_FALSE(monitor_->WasRecentlyAudible()); 178 EXPECT_FALSE(monitor_->WasRecentlyAudible());
179 ExpectNotCurrentlyAudible();
158 ExpectIsPolling(kRenderProcessId, kStreamId, false); 180 ExpectIsPolling(kRenderProcessId, kStreamId, false);
159 181
160 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); 182 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
161 EXPECT_FALSE(monitor_->WasRecentlyAudible()); 183 EXPECT_FALSE(monitor_->WasRecentlyAudible());
184 ExpectNotCurrentlyAudible();
162 ExpectIsPolling(kRenderProcessId, kStreamId, true); 185 ExpectIsPolling(kRenderProcessId, kStreamId, true);
163 186
164 StopMonitoring(kRenderProcessId, kStreamId); 187 StopMonitoring(kRenderProcessId, kStreamId);
165 EXPECT_FALSE(monitor_->WasRecentlyAudible()); 188 EXPECT_FALSE(monitor_->WasRecentlyAudible());
189 ExpectNotCurrentlyAudible();
166 ExpectIsPolling(kRenderProcessId, kStreamId, false); 190 ExpectIsPolling(kRenderProcessId, kStreamId, false);
167 } 191 }
168 192
169 // Tests that AudioStreamMonitor debounces the power level readings it's taking, 193 // Tests that AudioStreamMonitor debounces the power level readings it's taking,
170 // which could be fluctuating rapidly between the audible versus silence 194 // which could be fluctuating rapidly between the audible versus silence
171 // threshold. See comments in audio_stream_monitor.h for expected behavior. 195 // threshold. See comments in audio_stream_monitor.h for expected behavior.
172 TEST_F(AudioStreamMonitorTest, 196 TEST_F(AudioStreamMonitorTest,
173 ImpulsesKeepIndicatorOnUntilHoldingPeriodHasPassed) { 197 ImpulsesKeepIndicatorOnUntilHoldingPeriodHasPassed) {
174 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); 198 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
175 199
176 // Expect WebContents will get one call form AudioStreamMonitor to toggle the 200 // Expect WebContents will get one call form AudioStreamMonitor to toggle the
177 // indicator on upon the very first poll. 201 // indicator on upon the very first poll.
178 ExpectWebContentsWillBeNotifiedOnce(true); 202 ExpectRecentlyAudbileChangeNotification(true);
179 203
180 // Loop, each time testing a slightly longer period of polled silence. The 204 // Loop, each time testing a slightly longer period of polled silence. The
181 // indicator should remain on throughout. 205 // recently audible state should not change while the currently audible one
182 int num_silence_polls = 0; 206 // should.
207 int num_silence_polls = 1;
183 base::TimeTicks last_blurt_time; 208 base::TimeTicks last_blurt_time;
184 do { 209 do {
210 ExpectCurrentlyAudbileChangeNotification(true);
211
185 // Poll an audible signal, and expect tab indicator state is on. 212 // Poll an audible signal, and expect tab indicator state is on.
186 SetStreamPower(kStreamId, media::AudioPowerMonitor::max_power()); 213 SetStreamPower(kStreamId, media::AudioPowerMonitor::max_power());
187 last_blurt_time = GetTestClockTime(); 214 last_blurt_time = GetTestClockTime();
188 SimulatePollTimerFired(); 215 SimulatePollTimerFired();
189 ExpectTabWasRecentlyAudible(true, last_blurt_time); 216 ExpectTabWasRecentlyAudible(true, last_blurt_time);
190 AdvanceClock(one_polling_interval()); 217 AdvanceClock(one_polling_interval());
191 218
219 ExpectCurrentlyAudbileChangeNotification(false);
220
192 // Poll a silent signal repeatedly, ensuring that the indicator is being 221 // Poll a silent signal repeatedly, ensuring that the indicator is being
193 // held on during the holding period. 222 // held on during the holding period.
194 SetStreamPower(kStreamId, media::AudioPowerMonitor::zero_power()); 223 SetStreamPower(kStreamId, media::AudioPowerMonitor::zero_power());
195 for (int i = 0; i < num_silence_polls; ++i) { 224 for (int i = 0; i < num_silence_polls; ++i) {
196 SimulatePollTimerFired(); 225 SimulatePollTimerFired();
197 ExpectTabWasRecentlyAudible(true, last_blurt_time); 226 ExpectTabWasRecentlyAudible(true, last_blurt_time);
198 // Note: Redundant off timer firings should not have any effect. 227 // Note: Redundant off timer firings should not have any effect.
199 SimulateOffTimerFired(); 228 SimulateOffTimerFired();
200 ExpectTabWasRecentlyAudible(true, last_blurt_time); 229 ExpectTabWasRecentlyAudible(true, last_blurt_time);
201 AdvanceClock(one_polling_interval()); 230 AdvanceClock(one_polling_interval());
202 } 231 }
203 232
204 ++num_silence_polls; 233 ++num_silence_polls;
205 } while (GetTestClockTime() < last_blurt_time + holding_period()); 234 } while (GetTestClockTime() < last_blurt_time + holding_period());
206 235
207 // At this point, the clock has just advanced to beyond the holding period, so 236 // At this point, the clock has just advanced to beyond the holding period, so
208 // the next firing of the off timer should turn off the tab indicator. Also, 237 // the next firing of the off timer should turn off the tab indicator. Also,
209 // make sure it stays off for several cycles thereafter. 238 // make sure it stays off for several cycles thereafter.
210 ExpectWebContentsWillBeNotifiedOnce(false); 239 ExpectRecentlyAudbileChangeNotification(false);
211 for (int i = 0; i < 10; ++i) { 240 for (int i = 0; i < 10; ++i) {
212 SimulateOffTimerFired(); 241 SimulateOffTimerFired();
213 ExpectTabWasRecentlyAudible(false, last_blurt_time); 242 ExpectTabWasRecentlyAudible(false, last_blurt_time);
214 AdvanceClock(one_polling_interval()); 243 AdvanceClock(one_polling_interval());
215 } 244 }
216 } 245 }
217 246
218 // Tests that the AudioStreamMonitor correctly processes the blurts from two 247 // Tests that the AudioStreamMonitor correctly processes the blurts from two
219 // different streams in the same tab. 248 // different streams in the same tab.
220 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) { 249 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) {
221 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); 250 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
222 StartMonitoring( 251 StartMonitoring(
223 kRenderProcessId, kAnotherStreamId, CreatePollCallback(kAnotherStreamId)); 252 kRenderProcessId, kAnotherStreamId, CreatePollCallback(kAnotherStreamId));
224 253
225 base::TimeTicks last_blurt_time; 254 base::TimeTicks last_blurt_time;
226 ExpectTabWasRecentlyAudible(false, last_blurt_time); 255 ExpectTabWasRecentlyAudible(false, last_blurt_time);
256 ExpectNotCurrentlyAudible();
227 257
228 // Measure audible sound from the first stream and silence from the second. 258 // Measure audible sound from the first stream and silence from the second.
229 // The indicator turns on (i.e., tab was recently audible). 259 // The tab becomes audible.
230 ExpectWebContentsWillBeNotifiedOnce(true); 260 ExpectRecentlyAudbileChangeNotification(true);
261 ExpectCurrentlyAudbileChangeNotification(true);
262
231 SetStreamPower(kStreamId, media::AudioPowerMonitor::max_power()); 263 SetStreamPower(kStreamId, media::AudioPowerMonitor::max_power());
232 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power()); 264 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power());
233 last_blurt_time = GetTestClockTime(); 265 last_blurt_time = GetTestClockTime();
234 SimulatePollTimerFired(); 266 SimulatePollTimerFired();
235 ExpectTabWasRecentlyAudible(true, last_blurt_time); 267 ExpectTabWasRecentlyAudible(true, last_blurt_time);
268 ExpectIsCurrentlyAudible();
236 269
237 // Halfway through the holding period, the second stream joins in. The 270 // Halfway through the holding period, the second stream joins in. The
238 // indicator stays on. 271 // indicator stays on.
239 AdvanceClock(holding_period() / 2); 272 AdvanceClock(holding_period() / 2);
240 SimulateOffTimerFired(); 273 SimulateOffTimerFired();
241 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::max_power()); 274 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::max_power());
242 last_blurt_time = GetTestClockTime(); 275 last_blurt_time = GetTestClockTime();
243 SimulatePollTimerFired(); // Restarts holding period. 276 SimulatePollTimerFired(); // Restarts holding period.
244 ExpectTabWasRecentlyAudible(true, last_blurt_time); 277 ExpectTabWasRecentlyAudible(true, last_blurt_time);
278 ExpectIsCurrentlyAudible();
245 279
246 // Now, measure silence from both streams. After an entire holding period 280 // Now, measure silence from both streams. After an entire holding period
247 // has passed (since the second stream joined in), the indicator should turn 281 // has passed (since the second stream joined in), the tab will no longer
248 // off. 282 // become audible nor recently audible.
249 ExpectWebContentsWillBeNotifiedOnce(false); 283 ExpectCurrentlyAudbileChangeNotification(false);
284 ExpectRecentlyAudbileChangeNotification(false);
285
250 AdvanceClock(holding_period()); 286 AdvanceClock(holding_period());
251 SimulateOffTimerFired(); 287 SimulateOffTimerFired();
252 SetStreamPower(kStreamId, media::AudioPowerMonitor::zero_power()); 288 SetStreamPower(kStreamId, media::AudioPowerMonitor::zero_power());
253 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power()); 289 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power());
254 SimulatePollTimerFired(); 290 SimulatePollTimerFired();
255 ExpectTabWasRecentlyAudible(false, last_blurt_time); 291 ExpectTabWasRecentlyAudible(false, last_blurt_time);
292 ExpectNotCurrentlyAudible();
256 293
257 // Now, measure silence from the first stream and audible sound from the 294 // Now, measure silence from the first stream and audible sound from the
258 // second. The indicator turns back on. 295 // second. The tab becomes audible again.
259 ExpectWebContentsWillBeNotifiedOnce(true); 296 ExpectRecentlyAudbileChangeNotification(true);
297 ExpectCurrentlyAudbileChangeNotification(true);
298
260 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::max_power()); 299 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::max_power());
261 last_blurt_time = GetTestClockTime(); 300 last_blurt_time = GetTestClockTime();
262 SimulatePollTimerFired(); 301 SimulatePollTimerFired();
263 ExpectTabWasRecentlyAudible(true, last_blurt_time); 302 ExpectTabWasRecentlyAudible(true, last_blurt_time);
303 ExpectIsCurrentlyAudible();
264 304
265 // From here onwards, both streams are silent. Halfway through the holding 305 // From here onwards, both streams are silent. Halfway through the holding
266 // period, the indicator should not have changed. 306 // period, the tab is no longer audible but stays as recently audible.
307 ExpectCurrentlyAudbileChangeNotification(false);
308
267 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power()); 309 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power());
268 AdvanceClock(holding_period() / 2); 310 AdvanceClock(holding_period() / 2);
269 SimulatePollTimerFired(); 311 SimulatePollTimerFired();
270 SimulateOffTimerFired(); 312 SimulateOffTimerFired();
271 ExpectTabWasRecentlyAudible(true, last_blurt_time); 313 ExpectTabWasRecentlyAudible(true, last_blurt_time);
314 ExpectNotCurrentlyAudible();
272 315
273 // Just past the holding period, the indicator should be turned off. 316 // Just past the holding period, the tab is no longer marked as recently
274 ExpectWebContentsWillBeNotifiedOnce(false); 317 // audible.
318 ExpectRecentlyAudbileChangeNotification(false);
319
275 AdvanceClock(holding_period() - (GetTestClockTime() - last_blurt_time)); 320 AdvanceClock(holding_period() - (GetTestClockTime() - last_blurt_time));
276 SimulateOffTimerFired(); 321 SimulateOffTimerFired();
277 ExpectTabWasRecentlyAudible(false, last_blurt_time); 322 ExpectTabWasRecentlyAudible(false, last_blurt_time);
323 ExpectNotCurrentlyAudible();
278 324
279 // Polling should not turn the indicator back while both streams are remaining 325 // Polling should not turn the indicator back while both streams are remaining
280 // silent. 326 // silent.
281 for (int i = 0; i < 100; ++i) { 327 for (int i = 0; i < 100; ++i) {
282 AdvanceClock(one_polling_interval()); 328 AdvanceClock(one_polling_interval());
283 SimulatePollTimerFired(); 329 SimulatePollTimerFired();
284 ExpectTabWasRecentlyAudible(false, last_blurt_time); 330 ExpectTabWasRecentlyAudible(false, last_blurt_time);
331 ExpectNotCurrentlyAudible();
285 } 332 }
286 } 333 }
287 334
288 TEST_F(AudioStreamMonitorTest, MultipleRendererProcesses) { 335 TEST_F(AudioStreamMonitorTest, MultipleRendererProcesses) {
289 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); 336 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
290 StartMonitoring( 337 StartMonitoring(
291 kAnotherRenderProcessId, kStreamId, CreatePollCallback(kStreamId)); 338 kAnotherRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
292 ExpectIsPolling(kRenderProcessId, kStreamId, true); 339 ExpectIsPolling(kRenderProcessId, kStreamId, true);
293 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true); 340 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true);
294 StopMonitoring(kAnotherRenderProcessId, kStreamId); 341 StopMonitoring(kAnotherRenderProcessId, kStreamId);
295 ExpectIsPolling(kRenderProcessId, kStreamId, true); 342 ExpectIsPolling(kRenderProcessId, kStreamId, true);
296 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, false); 343 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, false);
297 } 344 }
298 345
299 } // namespace content 346 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698