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

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

Issue 478543003: Use AudioStreamMonitor to control power save blocking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Simplify OS_CHROMEOS exclusions. Created 6 years, 3 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 | Annotate | Revision Log
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 "chrome/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"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/test/simple_test_tick_clock.h" 13 #include "base/test/simple_test_tick_clock.h"
14 #include "chrome/test/base/testing_profile.h" 14 #include "content/browser/web_contents/web_contents_impl.h"
15 #include "content/public/browser/invalidate_type.h" 15 #include "content/public/browser/invalidate_type.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/browser/web_contents_delegate.h" 16 #include "content/public/browser/web_contents_delegate.h"
18 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "content/public/test/test_renderer_host.h"
19 #include "media/audio/audio_power_monitor.h" 18 #include "media/audio/audio_power_monitor.h"
20 #include "testing/gmock/include/gmock/gmock.h" 19 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
22 21
23 using ::testing::InvokeWithoutArgs; 22 using ::testing::InvokeWithoutArgs;
24 23
24 namespace content {
25
25 namespace { 26 namespace {
26 27
28 const int kRenderProcessId = 1;
29 const int kAnotherRenderProcessId = 2;
27 const int kStreamId = 3; 30 const int kStreamId = 3;
28 const int kAnotherStreamId = 6; 31 const int kAnotherStreamId = 6;
29 32
30 // Used to confirm audio indicator state changes occur at the correct times. 33 // Used to confirm audio indicator state changes occur at the correct times.
31 class MockWebContentsDelegate : public content::WebContentsDelegate { 34 class MockWebContentsDelegate : public WebContentsDelegate {
32 public: 35 public:
33 MOCK_METHOD2(NavigationStateChanged, 36 MOCK_METHOD2(NavigationStateChanged,
34 void(const content::WebContents* source, 37 void(const WebContents* source, InvalidateTypes changed_flags));
35 content::InvalidateTypes changed_flags));
36 }; 38 };
37 39
38 } // namespace 40 } // namespace
39 41
40 class AudioStreamMonitorTest : public testing::Test { 42 class AudioStreamMonitorTest : public RenderViewHostTestHarness {
41 public: 43 public:
42 AudioStreamMonitorTest() { 44 AudioStreamMonitorTest() {
43 // Start |clock_| at non-zero. 45 // Start |clock_| at non-zero.
44 clock_.Advance(base::TimeDelta::FromSeconds(1000000)); 46 clock_.Advance(base::TimeDelta::FromSeconds(1000000));
45
46 // Create a WebContents instance and set it to use our mock delegate.
47 web_contents_.reset(content::WebContents::Create(
48 content::WebContents::CreateParams(&profile_, NULL)));
49 web_contents_->SetDelegate(&mock_web_contents_delegate_);
50
51 // Create an AudioStreamMonitor instance whose lifecycle is tied to that of
52 // |web_contents_|, and override its clock with the test clock.
53 AudioStreamMonitor::CreateForWebContents(web_contents_.get());
54 CHECK(audio_stream_monitor());
55 const_cast<base::TickClock*&>(audio_stream_monitor()->clock_) = &clock_;
56 } 47 }
57 48
58 AudioStreamMonitor* audio_stream_monitor() { 49 virtual void SetUp() OVERRIDE {
59 return AudioStreamMonitor::FromWebContents(web_contents_.get()); 50 RenderViewHostTestHarness::SetUp();
51
52 WebContentsImpl* web_contents = reinterpret_cast<WebContentsImpl*>(
53 RenderViewHostTestHarness::web_contents());
54 web_contents->SetDelegate(&mock_web_contents_delegate_);
55 monitor_ = web_contents->audio_stream_monitor();
56 const_cast<base::TickClock*&>(monitor_->clock_) = &clock_;
60 } 57 }
61 58
62 base::TimeTicks GetTestClockTime() { return clock_.NowTicks(); } 59 base::TimeTicks GetTestClockTime() { return clock_.NowTicks(); }
63 60
64 void AdvanceClock(const base::TimeDelta& delta) { clock_.Advance(delta); } 61 void AdvanceClock(const base::TimeDelta& delta) { clock_.Advance(delta); }
65 62
66 AudioStreamMonitor::ReadPowerAndClipCallback CreatePollCallback( 63 AudioStreamMonitor::ReadPowerAndClipCallback CreatePollCallback(
67 int stream_id) { 64 int stream_id) {
68 return base::Bind( 65 return base::Bind(
69 &AudioStreamMonitorTest::ReadPower, base::Unretained(this), stream_id); 66 &AudioStreamMonitorTest::ReadPower, base::Unretained(this), stream_id);
70 } 67 }
71 68
72 void SetStreamPower(int stream_id, float power) { 69 void SetStreamPower(int stream_id, float power) {
73 current_power_[stream_id] = power; 70 current_power_[stream_id] = power;
74 } 71 }
75 72
76 void SimulatePollTimerFired() { audio_stream_monitor()->Poll(); } 73 void SimulatePollTimerFired() { monitor_->Poll(); }
77 74
78 void SimulateOffTimerFired() { audio_stream_monitor()->MaybeToggle(); } 75 void SimulateOffTimerFired() { monitor_->MaybeToggle(); }
79 76
80 void ExpectIsPolling(int stream_id, bool is_polling) { 77 void ExpectIsPolling(int render_process_id, int stream_id, bool is_polling) {
81 AudioStreamMonitor* const monitor = audio_stream_monitor(); 78 const AudioStreamMonitor::StreamID key(render_process_id, stream_id);
82 EXPECT_EQ(is_polling, 79 EXPECT_EQ(
83 monitor->poll_callbacks_.find(stream_id) != 80 is_polling,
84 monitor->poll_callbacks_.end()); 81 monitor_->poll_callbacks_.find(key) != monitor_->poll_callbacks_.end());
85 EXPECT_EQ(!monitor->poll_callbacks_.empty(), 82 EXPECT_EQ(!monitor_->poll_callbacks_.empty(),
86 monitor->poll_timer_.IsRunning()); 83 monitor_->poll_timer_.IsRunning());
87 } 84 }
88 85
89 void ExpectTabWasRecentlyAudible(bool was_audible, 86 void ExpectTabWasRecentlyAudible(bool was_audible,
90 const base::TimeTicks& last_blurt_time) { 87 const base::TimeTicks& last_blurt_time) {
91 AudioStreamMonitor* const monitor = audio_stream_monitor(); 88 EXPECT_EQ(was_audible, monitor_->was_recently_audible_);
92 EXPECT_EQ(was_audible, monitor->was_recently_audible_); 89 EXPECT_EQ(last_blurt_time, monitor_->last_blurt_time_);
93 EXPECT_EQ(last_blurt_time, monitor->last_blurt_time_); 90 EXPECT_EQ(monitor_->was_recently_audible_,
94 EXPECT_EQ(monitor->was_recently_audible_, monitor->off_timer_.IsRunning()); 91 monitor_->off_timer_.IsRunning());
95 } 92 }
96 93
97 void ExpectWebContentsWillBeNotifiedOnce(bool should_be_audible) { 94 void ExpectWebContentsWillBeNotifiedOnce(bool should_be_audible) {
98 EXPECT_CALL(mock_web_contents_delegate_, 95 EXPECT_CALL(
99 NavigationStateChanged(web_contents_.get(), 96 mock_web_contents_delegate_,
100 content::INVALIDATE_TYPE_TAB)) 97 NavigationStateChanged(RenderViewHostTestHarness::web_contents(),
98 INVALIDATE_TYPE_TAB))
101 .WillOnce(InvokeWithoutArgs( 99 .WillOnce(InvokeWithoutArgs(
102 this, 100 this,
103 should_be_audible 101 should_be_audible
104 ? &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOn 102 ? &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOn
105 : &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOff)) 103 : &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOff))
106 .RetiresOnSaturation(); 104 .RetiresOnSaturation();
107 } 105 }
108 106
109 static base::TimeDelta one_polling_interval() { 107 static base::TimeDelta one_polling_interval() {
110 return base::TimeDelta::FromSeconds(1) / 108 return base::TimeDelta::FromSeconds(1) /
111 AudioStreamMonitor::kPowerMeasurementsPerSecond; 109 AudioStreamMonitor::kPowerMeasurementsPerSecond;
112 } 110 }
113 111
114 static base::TimeDelta holding_period() { 112 static base::TimeDelta holding_period() {
115 return base::TimeDelta::FromMilliseconds( 113 return base::TimeDelta::FromMilliseconds(
116 AudioStreamMonitor::kHoldOnMilliseconds); 114 AudioStreamMonitor::kHoldOnMilliseconds);
117 } 115 }
118 116
117 void StartMonitoring(
118 int render_process_id,
119 int stream_id,
120 const AudioStreamMonitor::ReadPowerAndClipCallback& callback) {
121 monitor_->StartMonitoringStreamOnUIThread(
122 render_process_id, stream_id, callback);
123 }
124
125 void StopMonitoring(int render_process_id, int stream_id) {
126 monitor_->StopMonitoringStreamOnUIThread(render_process_id, stream_id);
127 }
128
129 protected:
130 AudioStreamMonitor* monitor_;
131
119 private: 132 private:
120 std::pair<float, bool> ReadPower(int stream_id) { 133 std::pair<float, bool> ReadPower(int stream_id) {
121 return std::make_pair(current_power_[stream_id], false); 134 return std::make_pair(current_power_[stream_id], false);
122 } 135 }
123 136
124 void ExpectIsNotifyingForToggleOn() { 137 void ExpectIsNotifyingForToggleOn() {
125 EXPECT_TRUE(audio_stream_monitor()->WasRecentlyAudible()); 138 EXPECT_TRUE(monitor_->WasRecentlyAudible());
126 } 139 }
127 140
128 void ExpectIsNotifyingForToggleOff() { 141 void ExpectIsNotifyingForToggleOff() {
129 EXPECT_FALSE(audio_stream_monitor()->WasRecentlyAudible()); 142 EXPECT_FALSE(monitor_->WasRecentlyAudible());
130 } 143 }
131 144
132 content::TestBrowserThreadBundle browser_thread_bundle_;
133 TestingProfile profile_;
134 MockWebContentsDelegate mock_web_contents_delegate_; 145 MockWebContentsDelegate mock_web_contents_delegate_;
135 base::SimpleTestTickClock clock_; 146 base::SimpleTestTickClock clock_;
136 std::map<int, float> current_power_; 147 std::map<int, float> current_power_;
137 scoped_ptr<content::WebContents> web_contents_;
138 148
139 DISALLOW_COPY_AND_ASSIGN(AudioStreamMonitorTest); 149 DISALLOW_COPY_AND_ASSIGN(AudioStreamMonitorTest);
140 }; 150 };
141 151
142 // Tests that AudioStreamMonitor is polling while it has a 152 // Tests that AudioStreamMonitor is polling while it has a
143 // ReadPowerAndClipCallback, and is not polling at other times. 153 // ReadPowerAndClipCallback, and is not polling at other times.
144 TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) { 154 TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) {
145 EXPECT_FALSE(audio_stream_monitor()->WasRecentlyAudible()); 155 EXPECT_FALSE(monitor_->WasRecentlyAudible());
146 ExpectIsPolling(kStreamId, false); 156 ExpectIsPolling(kRenderProcessId, kStreamId, false);
147 157
148 audio_stream_monitor()->StartMonitoringStream(kStreamId, 158 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
149 CreatePollCallback(kStreamId)); 159 EXPECT_FALSE(monitor_->WasRecentlyAudible());
150 EXPECT_FALSE(audio_stream_monitor()->WasRecentlyAudible()); 160 ExpectIsPolling(kRenderProcessId, kStreamId, true);
151 ExpectIsPolling(kStreamId, true);
152 161
153 audio_stream_monitor()->StopMonitoringStream(kStreamId); 162 StopMonitoring(kRenderProcessId, kStreamId);
154 EXPECT_FALSE(audio_stream_monitor()->WasRecentlyAudible()); 163 EXPECT_FALSE(monitor_->WasRecentlyAudible());
155 ExpectIsPolling(kStreamId, false); 164 ExpectIsPolling(kRenderProcessId, kStreamId, false);
156 } 165 }
157 166
158 // Tests that AudioStreamMonitor debounces the power level readings it's taking, 167 // Tests that AudioStreamMonitor debounces the power level readings it's taking,
159 // which could be fluctuating rapidly between the audible versus silence 168 // which could be fluctuating rapidly between the audible versus silence
160 // threshold. See comments in audio_stream_monitor.h for expected behavior. 169 // threshold. See comments in audio_stream_monitor.h for expected behavior.
161 TEST_F(AudioStreamMonitorTest, 170 TEST_F(AudioStreamMonitorTest,
162 ImpulsesKeepIndicatorOnUntilHoldingPeriodHasPassed) { 171 ImpulsesKeepIndicatorOnUntilHoldingPeriodHasPassed) {
163 audio_stream_monitor()->StartMonitoringStream(kStreamId, 172 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
164 CreatePollCallback(kStreamId));
165 173
166 // Expect WebContents will get one call form AudioStreamMonitor to toggle the 174 // Expect WebContents will get one call form AudioStreamMonitor to toggle the
167 // indicator on upon the very first poll. 175 // indicator on upon the very first poll.
168 ExpectWebContentsWillBeNotifiedOnce(true); 176 ExpectWebContentsWillBeNotifiedOnce(true);
169 177
170 // Loop, each time testing a slightly longer period of polled silence. The 178 // Loop, each time testing a slightly longer period of polled silence. The
171 // indicator should remain on throughout. 179 // indicator should remain on throughout.
172 int num_silence_polls = 0; 180 int num_silence_polls = 0;
173 base::TimeTicks last_blurt_time; 181 base::TimeTicks last_blurt_time;
174 do { 182 do {
(...skipping 26 matching lines...) Expand all
201 for (int i = 0; i < 10; ++i) { 209 for (int i = 0; i < 10; ++i) {
202 SimulateOffTimerFired(); 210 SimulateOffTimerFired();
203 ExpectTabWasRecentlyAudible(false, last_blurt_time); 211 ExpectTabWasRecentlyAudible(false, last_blurt_time);
204 AdvanceClock(one_polling_interval()); 212 AdvanceClock(one_polling_interval());
205 } 213 }
206 } 214 }
207 215
208 // Tests that the AudioStreamMonitor correctly processes the blurts from two 216 // Tests that the AudioStreamMonitor correctly processes the blurts from two
209 // different streams in the same tab. 217 // different streams in the same tab.
210 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) { 218 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) {
211 audio_stream_monitor()->StartMonitoringStream(kStreamId, 219 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
212 CreatePollCallback(kStreamId)); 220 StartMonitoring(
213 audio_stream_monitor()->StartMonitoringStream( 221 kRenderProcessId, kAnotherStreamId, CreatePollCallback(kAnotherStreamId));
214 kAnotherStreamId,
215 CreatePollCallback(kAnotherStreamId));
216 222
217 base::TimeTicks last_blurt_time; 223 base::TimeTicks last_blurt_time;
218 ExpectTabWasRecentlyAudible(false, last_blurt_time); 224 ExpectTabWasRecentlyAudible(false, last_blurt_time);
219 225
220 // Measure audible sound from the first stream and silence from the second. 226 // Measure audible sound from the first stream and silence from the second.
221 // The indicator turns on (i.e., tab was recently audible). 227 // The indicator turns on (i.e., tab was recently audible).
222 ExpectWebContentsWillBeNotifiedOnce(true); 228 ExpectWebContentsWillBeNotifiedOnce(true);
223 SetStreamPower(kStreamId, media::AudioPowerMonitor::max_power()); 229 SetStreamPower(kStreamId, media::AudioPowerMonitor::max_power());
224 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power()); 230 SetStreamPower(kAnotherStreamId, media::AudioPowerMonitor::zero_power());
225 last_blurt_time = GetTestClockTime(); 231 last_blurt_time = GetTestClockTime();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 ExpectTabWasRecentlyAudible(false, last_blurt_time); 275 ExpectTabWasRecentlyAudible(false, last_blurt_time);
270 276
271 // Polling should not turn the indicator back while both streams are remaining 277 // Polling should not turn the indicator back while both streams are remaining
272 // silent. 278 // silent.
273 for (int i = 0; i < 100; ++i) { 279 for (int i = 0; i < 100; ++i) {
274 AdvanceClock(one_polling_interval()); 280 AdvanceClock(one_polling_interval());
275 SimulatePollTimerFired(); 281 SimulatePollTimerFired();
276 ExpectTabWasRecentlyAudible(false, last_blurt_time); 282 ExpectTabWasRecentlyAudible(false, last_blurt_time);
277 } 283 }
278 } 284 }
285
286 TEST_F(AudioStreamMonitorTest, MultipleRendererProcesses) {
287 StartMonitoring(kRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
288 StartMonitoring(
289 kAnotherRenderProcessId, kStreamId, CreatePollCallback(kStreamId));
290 ExpectIsPolling(kRenderProcessId, kStreamId, true);
291 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, true);
292 StopMonitoring(kAnotherRenderProcessId, kStreamId);
293 ExpectIsPolling(kRenderProcessId, kStreamId, true);
294 ExpectIsPolling(kAnotherRenderProcessId, kStreamId, false);
295 }
296
297 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/audio_stream_monitor.cc ('k') | content/browser/renderer_host/media/audio_renderer_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698