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

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: Move it with style! 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"
15 #include "content/public/browser/invalidate_type.h" 14 #include "content/public/browser/invalidate_type.h"
16 #include "content/public/browser/web_contents.h" 15 #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
27 const int kStreamId = 3; 28 const int kStreamId = 3;
28 const int kAnotherStreamId = 6; 29 const int kAnotherStreamId = 6;
29 30
30 // Used to confirm audio indicator state changes occur at the correct times. 31 // Used to confirm audio indicator state changes occur at the correct times.
31 class MockWebContentsDelegate : public content::WebContentsDelegate { 32 class MockWebContentsDelegate : public WebContentsDelegate {
32 public: 33 public:
33 MOCK_METHOD2(NavigationStateChanged, 34 MOCK_METHOD2(NavigationStateChanged,
34 void(const content::WebContents* source, 35 void(const WebContents* source, InvalidateTypes changed_flags));
35 content::InvalidateTypes changed_flags));
36 }; 36 };
37 37
38 } // namespace 38 } // namespace
39 39
40 class AudioStreamMonitorTest : public testing::Test { 40 class AudioStreamMonitorTest : public RenderViewHostTestHarness {
41 public: 41 public:
42 AudioStreamMonitorTest() { 42 AudioStreamMonitorTest() {
43 // Start |clock_| at non-zero. 43 // Start |clock_| at non-zero.
44 clock_.Advance(base::TimeDelta::FromSeconds(1000000)); 44 clock_.Advance(base::TimeDelta::FromSeconds(1000000));
45 }
45 46
46 // Create a WebContents instance and set it to use our mock delegate. 47 virtual void SetUp() OVERRIDE {
47 web_contents_.reset(content::WebContents::Create( 48 RenderViewHostTestHarness::SetUp();
48 content::WebContents::CreateParams(&profile_, NULL))); 49
49 web_contents_->SetDelegate(&mock_web_contents_delegate_); 50 WebContents* web_contents = RenderViewHostTestHarness::web_contents();
51 web_contents->SetDelegate(&mock_web_contents_delegate_);
50 52
51 // Create an AudioStreamMonitor instance whose lifecycle is tied to that of 53 // Create an AudioStreamMonitor instance whose lifecycle is tied to that of
52 // |web_contents_|, and override its clock with the test clock. 54 // |web_contents_|, and override its clock with the test clock.
53 AudioStreamMonitor::CreateForWebContents(web_contents_.get()); 55 AudioStreamMonitor::CreateForWebContents(web_contents);
54 CHECK(audio_stream_monitor()); 56 monitor_ = AudioStreamMonitor::FromWebContents(web_contents);
55 const_cast<base::TickClock*&>(audio_stream_monitor()->clock_) = &clock_; 57 CHECK(monitor_);
56 } 58 const_cast<base::TickClock*&>(monitor_->clock_) = &clock_;
57
58 AudioStreamMonitor* audio_stream_monitor() {
59 return AudioStreamMonitor::FromWebContents(web_contents_.get());
60 } 59 }
61 60
62 base::TimeTicks GetTestClockTime() { return clock_.NowTicks(); } 61 base::TimeTicks GetTestClockTime() { return clock_.NowTicks(); }
63 62
64 void AdvanceClock(const base::TimeDelta& delta) { clock_.Advance(delta); } 63 void AdvanceClock(const base::TimeDelta& delta) { clock_.Advance(delta); }
65 64
66 AudioStreamMonitor::ReadPowerAndClipCallback CreatePollCallback( 65 AudioStreamMonitor::ReadPowerAndClipCallback CreatePollCallback(
67 int stream_id) { 66 int stream_id) {
68 return base::Bind( 67 return base::Bind(
69 &AudioStreamMonitorTest::ReadPower, base::Unretained(this), stream_id); 68 &AudioStreamMonitorTest::ReadPower, base::Unretained(this), stream_id);
70 } 69 }
71 70
72 void SetStreamPower(int stream_id, float power) { 71 void SetStreamPower(int stream_id, float power) {
73 current_power_[stream_id] = power; 72 current_power_[stream_id] = power;
74 } 73 }
75 74
76 void SimulatePollTimerFired() { audio_stream_monitor()->Poll(); } 75 void SimulatePollTimerFired() { monitor_->Poll(); }
77 76
78 void SimulateOffTimerFired() { audio_stream_monitor()->MaybeToggle(); } 77 void SimulateOffTimerFired() { monitor_->MaybeToggle(); }
79 78
80 void ExpectIsPolling(int stream_id, bool is_polling) { 79 void ExpectIsPolling(int stream_id, bool is_polling) {
81 AudioStreamMonitor* const monitor = audio_stream_monitor();
82 EXPECT_EQ(is_polling, 80 EXPECT_EQ(is_polling,
83 monitor->poll_callbacks_.find(stream_id) != 81 monitor_->poll_callbacks_.find(stream_id) !=
84 monitor->poll_callbacks_.end()); 82 monitor_->poll_callbacks_.end());
85 EXPECT_EQ(!monitor->poll_callbacks_.empty(), 83 EXPECT_EQ(!monitor_->poll_callbacks_.empty(),
86 monitor->poll_timer_.IsRunning()); 84 monitor_->poll_timer_.IsRunning());
87 } 85 }
88 86
89 void ExpectTabWasRecentlyAudible(bool was_audible, 87 void ExpectTabWasRecentlyAudible(bool was_audible,
90 const base::TimeTicks& last_blurt_time) { 88 const base::TimeTicks& last_blurt_time) {
91 AudioStreamMonitor* const monitor = audio_stream_monitor(); 89 EXPECT_EQ(was_audible, monitor_->was_recently_audible_);
92 EXPECT_EQ(was_audible, monitor->was_recently_audible_); 90 EXPECT_EQ(last_blurt_time, monitor_->last_blurt_time_);
93 EXPECT_EQ(last_blurt_time, monitor->last_blurt_time_); 91 EXPECT_EQ(monitor_->was_recently_audible_,
94 EXPECT_EQ(monitor->was_recently_audible_, monitor->off_timer_.IsRunning()); 92 monitor_->off_timer_.IsRunning());
93 const bool have_blocker = monitor_->blocker_;
94 EXPECT_EQ(have_blocker, monitor_->off_timer_.IsRunning());
95 } 95 }
96 96
97 void ExpectWebContentsWillBeNotifiedOnce(bool should_be_audible) { 97 void ExpectWebContentsWillBeNotifiedOnce(bool should_be_audible) {
98 EXPECT_CALL(mock_web_contents_delegate_, 98 EXPECT_CALL(
99 NavigationStateChanged(web_contents_.get(), 99 mock_web_contents_delegate_,
100 content::INVALIDATE_TYPE_TAB)) 100 NavigationStateChanged(RenderViewHostTestHarness::web_contents(),
101 INVALIDATE_TYPE_TAB))
101 .WillOnce(InvokeWithoutArgs( 102 .WillOnce(InvokeWithoutArgs(
102 this, 103 this,
103 should_be_audible 104 should_be_audible
104 ? &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOn 105 ? &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOn
105 : &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOff)) 106 : &AudioStreamMonitorTest::ExpectIsNotifyingForToggleOff))
106 .RetiresOnSaturation(); 107 .RetiresOnSaturation();
107 } 108 }
108 109
109 static base::TimeDelta one_polling_interval() { 110 static base::TimeDelta one_polling_interval() {
110 return base::TimeDelta::FromSeconds(1) / 111 return base::TimeDelta::FromSeconds(1) /
111 AudioStreamMonitor::kPowerMeasurementsPerSecond; 112 AudioStreamMonitor::kPowerMeasurementsPerSecond;
112 } 113 }
113 114
114 static base::TimeDelta holding_period() { 115 static base::TimeDelta holding_period() {
115 return base::TimeDelta::FromMilliseconds( 116 return base::TimeDelta::FromMilliseconds(
116 AudioStreamMonitor::kHoldOnMilliseconds); 117 AudioStreamMonitor::kHoldOnMilliseconds);
117 } 118 }
118 119
120 void StartMonitoring(
121 int stream_id,
122 const AudioStreamMonitor::ReadPowerAndClipCallback& callback) {
123 monitor_->StartMonitoringStreamOnUIThread(stream_id, callback);
124 }
125
126 void StopMonitoring(int stream_id) {
127 monitor_->StopMonitoringStreamOnUIThread(stream_id);
128 }
129
130 protected:
131 AudioStreamMonitor* monitor_;
132
119 private: 133 private:
120 std::pair<float, bool> ReadPower(int stream_id) { 134 std::pair<float, bool> ReadPower(int stream_id) {
121 return std::make_pair(current_power_[stream_id], false); 135 return std::make_pair(current_power_[stream_id], false);
122 } 136 }
123 137
124 void ExpectIsNotifyingForToggleOn() { 138 void ExpectIsNotifyingForToggleOn() {
125 EXPECT_TRUE(audio_stream_monitor()->WasRecentlyAudible()); 139 EXPECT_TRUE(monitor_->WasRecentlyAudible());
126 } 140 }
127 141
128 void ExpectIsNotifyingForToggleOff() { 142 void ExpectIsNotifyingForToggleOff() {
129 EXPECT_FALSE(audio_stream_monitor()->WasRecentlyAudible()); 143 EXPECT_FALSE(monitor_->WasRecentlyAudible());
130 } 144 }
131 145
132 content::TestBrowserThreadBundle browser_thread_bundle_;
133 TestingProfile profile_;
134 MockWebContentsDelegate mock_web_contents_delegate_; 146 MockWebContentsDelegate mock_web_contents_delegate_;
135 base::SimpleTestTickClock clock_; 147 base::SimpleTestTickClock clock_;
136 std::map<int, float> current_power_; 148 std::map<int, float> current_power_;
137 scoped_ptr<content::WebContents> web_contents_;
138 149
139 DISALLOW_COPY_AND_ASSIGN(AudioStreamMonitorTest); 150 DISALLOW_COPY_AND_ASSIGN(AudioStreamMonitorTest);
140 }; 151 };
141 152
142 // Tests that AudioStreamMonitor is polling while it has a 153 // Tests that AudioStreamMonitor is polling while it has a
143 // ReadPowerAndClipCallback, and is not polling at other times. 154 // ReadPowerAndClipCallback, and is not polling at other times.
144 TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) { 155 TEST_F(AudioStreamMonitorTest, PollsWhenProvidedACallback) {
145 EXPECT_FALSE(audio_stream_monitor()->WasRecentlyAudible()); 156 EXPECT_FALSE(monitor_->WasRecentlyAudible());
146 ExpectIsPolling(kStreamId, false); 157 ExpectIsPolling(kStreamId, false);
147 158
148 audio_stream_monitor()->StartMonitoringStream(kStreamId, 159 StartMonitoring(kStreamId, CreatePollCallback(kStreamId));
149 CreatePollCallback(kStreamId)); 160 EXPECT_FALSE(monitor_->WasRecentlyAudible());
150 EXPECT_FALSE(audio_stream_monitor()->WasRecentlyAudible());
151 ExpectIsPolling(kStreamId, true); 161 ExpectIsPolling(kStreamId, true);
152 162
153 audio_stream_monitor()->StopMonitoringStream(kStreamId); 163 StopMonitoring(kStreamId);
154 EXPECT_FALSE(audio_stream_monitor()->WasRecentlyAudible()); 164 EXPECT_FALSE(monitor_->WasRecentlyAudible());
155 ExpectIsPolling(kStreamId, false); 165 ExpectIsPolling(kStreamId, false);
156 } 166 }
157 167
158 // Tests that AudioStreamMonitor debounces the power level readings it's taking, 168 // Tests that AudioStreamMonitor debounces the power level readings it's taking,
159 // which could be fluctuating rapidly between the audible versus silence 169 // which could be fluctuating rapidly between the audible versus silence
160 // threshold. See comments in audio_stream_monitor.h for expected behavior. 170 // threshold. See comments in audio_stream_monitor.h for expected behavior.
161 TEST_F(AudioStreamMonitorTest, 171 TEST_F(AudioStreamMonitorTest,
162 ImpulsesKeepIndicatorOnUntilHoldingPeriodHasPassed) { 172 ImpulsesKeepIndicatorOnUntilHoldingPeriodHasPassed) {
163 audio_stream_monitor()->StartMonitoringStream(kStreamId, 173 StartMonitoring(kStreamId, CreatePollCallback(kStreamId));
164 CreatePollCallback(kStreamId));
165 174
166 // Expect WebContents will get one call form AudioStreamMonitor to toggle the 175 // Expect WebContents will get one call form AudioStreamMonitor to toggle the
167 // indicator on upon the very first poll. 176 // indicator on upon the very first poll.
168 ExpectWebContentsWillBeNotifiedOnce(true); 177 ExpectWebContentsWillBeNotifiedOnce(true);
169 178
170 // Loop, each time testing a slightly longer period of polled silence. The 179 // Loop, each time testing a slightly longer period of polled silence. The
171 // indicator should remain on throughout. 180 // indicator should remain on throughout.
172 int num_silence_polls = 0; 181 int num_silence_polls = 0;
173 base::TimeTicks last_blurt_time; 182 base::TimeTicks last_blurt_time;
174 do { 183 do {
(...skipping 26 matching lines...) Expand all
201 for (int i = 0; i < 10; ++i) { 210 for (int i = 0; i < 10; ++i) {
202 SimulateOffTimerFired(); 211 SimulateOffTimerFired();
203 ExpectTabWasRecentlyAudible(false, last_blurt_time); 212 ExpectTabWasRecentlyAudible(false, last_blurt_time);
204 AdvanceClock(one_polling_interval()); 213 AdvanceClock(one_polling_interval());
205 } 214 }
206 } 215 }
207 216
208 // Tests that the AudioStreamMonitor correctly processes the blurts from two 217 // Tests that the AudioStreamMonitor correctly processes the blurts from two
209 // different streams in the same tab. 218 // different streams in the same tab.
210 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) { 219 TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamsBlurting) {
211 audio_stream_monitor()->StartMonitoringStream(kStreamId, 220 StartMonitoring(kStreamId, CreatePollCallback(kStreamId));
212 CreatePollCallback(kStreamId)); 221 StartMonitoring(kAnotherStreamId, CreatePollCallback(kAnotherStreamId));
213 audio_stream_monitor()->StartMonitoringStream(
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 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698