Fixed example in MessageLoop::ReleaseSoon comment
[chromium-blink-merge.git] / media / audio / audio_output_controller_unittest.cc
blob125763c9bfe24cc1657d42a8d2228cc9ec5f8184
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/environment.h"
8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "media/audio/audio_manager_base.h"
14 #include "media/audio/audio_output_controller.h"
15 #include "media/audio/audio_parameters.h"
16 #include "media/base/audio_bus.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using ::testing::_;
21 using ::testing::AtLeast;
22 using ::testing::DoAll;
23 using ::testing::Invoke;
24 using ::testing::NotNull;
25 using ::testing::Return;
27 namespace media {
29 static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
30 static const int kBitsPerSample = 16;
31 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
32 static const int kSamplesPerPacket = kSampleRate / 100;
33 static const double kTestVolume = 0.25;
35 class MockAudioOutputControllerEventHandler
36 : public AudioOutputController::EventHandler {
37 public:
38 MockAudioOutputControllerEventHandler() {}
40 MOCK_METHOD0(OnCreated, void());
41 MOCK_METHOD0(OnPlaying, void());
42 MOCK_METHOD0(OnPaused, void());
43 MOCK_METHOD0(OnError, void());
44 MOCK_METHOD2(OnDeviceChange, void(int new_buffer_size, int new_sample_rate));
46 private:
47 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
50 class MockAudioOutputControllerSyncReader
51 : public AudioOutputController::SyncReader {
52 public:
53 MockAudioOutputControllerSyncReader() {}
55 MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
56 MOCK_METHOD1(Read, void(AudioBus* dest));
57 MOCK_METHOD0(Close, void());
59 private:
60 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
63 class MockAudioOutputStream : public AudioOutputStream {
64 public:
65 MOCK_METHOD0(Open, bool());
66 MOCK_METHOD1(Start, void(AudioSourceCallback* callback));
67 MOCK_METHOD0(Stop, void());
68 MOCK_METHOD1(SetVolume, void(double volume));
69 MOCK_METHOD1(GetVolume, void(double* volume));
70 MOCK_METHOD0(Close, void());
72 // Set/get the callback passed to Start().
73 AudioSourceCallback* callback() const { return callback_; }
74 void SetCallback(AudioSourceCallback* asc) { callback_ = asc; }
76 private:
77 AudioSourceCallback* callback_;
80 ACTION_P(SignalEvent, event) {
81 event->Signal();
84 static const float kBufferNonZeroData = 1.0f;
85 ACTION(PopulateBuffer) {
86 arg0->Zero();
87 // Note: To confirm the buffer will be populated in these tests, it's
88 // sufficient that only the first float in channel 0 is set to the value.
89 arg0->channel(0)[0] = kBufferNonZeroData;
92 class AudioOutputControllerTest : public testing::Test {
93 public:
94 AudioOutputControllerTest()
95 : audio_manager_(AudioManager::CreateForTesting()),
96 create_event_(false, false),
97 play_event_(false, false),
98 read_event_(false, false),
99 pause_event_(false, false) {
102 virtual ~AudioOutputControllerTest() {
105 protected:
106 void Create(int samples_per_packet) {
107 EXPECT_FALSE(create_event_.IsSignaled());
108 EXPECT_FALSE(play_event_.IsSignaled());
109 EXPECT_FALSE(read_event_.IsSignaled());
110 EXPECT_FALSE(pause_event_.IsSignaled());
112 params_ = AudioParameters(
113 AudioParameters::AUDIO_FAKE, kChannelLayout,
114 kSampleRate, kBitsPerSample, samples_per_packet);
116 if (params_.IsValid()) {
117 EXPECT_CALL(mock_event_handler_, OnCreated())
118 .WillOnce(SignalEvent(&create_event_));
121 controller_ = AudioOutputController::Create(
122 audio_manager_.get(), &mock_event_handler_, params_, std::string(),
123 &mock_sync_reader_);
124 if (controller_.get())
125 controller_->SetVolume(kTestVolume);
127 EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
130 void Play() {
131 // Expect the event handler to receive one OnPlaying() call.
132 EXPECT_CALL(mock_event_handler_, OnPlaying())
133 .WillOnce(SignalEvent(&play_event_));
135 // During playback, the mock pretends to provide audio data rendered and
136 // sent from the render process.
137 EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
138 .Times(AtLeast(1));
139 EXPECT_CALL(mock_sync_reader_, Read(_))
140 .WillRepeatedly(DoAll(PopulateBuffer(),
141 SignalEvent(&read_event_)));
142 controller_->Play();
145 void Pause() {
146 // Expect the event handler to receive one OnPaused() call.
147 EXPECT_CALL(mock_event_handler_, OnPaused())
148 .WillOnce(SignalEvent(&pause_event_));
150 controller_->Pause();
153 void ChangeDevice() {
154 // Expect the event handler to receive one OnPaying() call and no OnPaused()
155 // call.
156 EXPECT_CALL(mock_event_handler_, OnPlaying())
157 .WillOnce(SignalEvent(&play_event_));
158 EXPECT_CALL(mock_event_handler_, OnPaused())
159 .Times(0);
161 // Simulate a device change event to AudioOutputController from the
162 // AudioManager.
163 audio_manager_->GetTaskRunner()->PostTask(
164 FROM_HERE,
165 base::Bind(&AudioOutputController::OnDeviceChange, controller_));
168 void Divert(bool was_playing, int num_times_to_be_started) {
169 if (was_playing) {
170 // Expect the handler to receive one OnPlaying() call as a result of the
171 // stream switching.
172 EXPECT_CALL(mock_event_handler_, OnPlaying())
173 .WillOnce(SignalEvent(&play_event_));
176 EXPECT_CALL(mock_stream_, Open())
177 .WillOnce(Return(true));
178 EXPECT_CALL(mock_stream_, SetVolume(kTestVolume));
179 if (num_times_to_be_started > 0) {
180 EXPECT_CALL(mock_stream_, Start(NotNull()))
181 .Times(num_times_to_be_started)
182 .WillRepeatedly(
183 Invoke(&mock_stream_, &MockAudioOutputStream::SetCallback));
184 EXPECT_CALL(mock_stream_, Stop())
185 .Times(num_times_to_be_started);
188 controller_->StartDiverting(&mock_stream_);
191 void ReadDivertedAudioData() {
192 scoped_ptr<AudioBus> dest = AudioBus::Create(params_);
193 ASSERT_TRUE(!!mock_stream_.callback());
194 const int frames_read =
195 mock_stream_.callback()->OnMoreData(dest.get(), AudioBuffersState());
196 EXPECT_LT(0, frames_read);
197 EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
200 void Revert(bool was_playing) {
201 if (was_playing) {
202 // Expect the handler to receive one OnPlaying() call as a result of the
203 // stream switching back.
204 EXPECT_CALL(mock_event_handler_, OnPlaying())
205 .WillOnce(SignalEvent(&play_event_));
208 EXPECT_CALL(mock_stream_, Close());
210 controller_->StopDiverting();
213 void SwitchDevice(bool diverting) {
214 if (!diverting) {
215 // Expect the current stream to close and a new stream to start
216 // playing if not diverting. When diverting, nothing happens
217 // until diverting is stopped.
218 EXPECT_CALL(mock_event_handler_, OnPlaying())
219 .WillOnce(SignalEvent(&play_event_));
222 controller_->SwitchOutputDevice(AudioManagerBase::kDefaultDeviceName,
223 base::Bind(&base::DoNothing));
226 void Close() {
227 EXPECT_CALL(mock_sync_reader_, Close());
229 controller_->Close(base::MessageLoop::QuitClosure());
230 base::MessageLoop::current()->Run();
233 // These help make test sequences more readable.
234 void DivertNeverPlaying() { Divert(false, 0); }
235 void DivertWillEventuallyBeTwicePlayed() { Divert(false, 2); }
236 void DivertWhilePlaying() { Divert(true, 1); }
237 void RevertWasNotPlaying() { Revert(false); }
238 void RevertWhilePlaying() { Revert(true); }
240 // These synchronize the main thread with key events taking place on other
241 // threads.
242 void WaitForCreate() { create_event_.Wait(); }
243 void WaitForPlay() { play_event_.Wait(); }
244 void WaitForReads() {
245 // Note: Arbitrarily chosen, but more iterations causes tests to take
246 // significantly more time.
247 static const int kNumIterations = 3;
248 for (int i = 0; i < kNumIterations; ++i) {
249 read_event_.Wait();
252 void WaitForPause() { pause_event_.Wait(); }
254 private:
255 base::MessageLoopForIO message_loop_;
256 scoped_ptr<AudioManager> audio_manager_;
257 MockAudioOutputControllerEventHandler mock_event_handler_;
258 MockAudioOutputControllerSyncReader mock_sync_reader_;
259 MockAudioOutputStream mock_stream_;
260 base::WaitableEvent create_event_;
261 base::WaitableEvent play_event_;
262 base::WaitableEvent read_event_;
263 base::WaitableEvent pause_event_;
264 AudioParameters params_;
265 scoped_refptr<AudioOutputController> controller_;
267 DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
270 TEST_F(AudioOutputControllerTest, CreateAndClose) {
271 Create(kSamplesPerPacket);
272 Close();
275 TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
276 Create(kSamplesPerPacket * 1000);
279 TEST_F(AudioOutputControllerTest, PlayAndClose) {
280 Create(kSamplesPerPacket);
281 WaitForCreate();
282 Play();
283 WaitForPlay();
284 WaitForReads();
285 Close();
288 TEST_F(AudioOutputControllerTest, PlayPauseClose) {
289 Create(kSamplesPerPacket);
290 WaitForCreate();
291 Play();
292 WaitForPlay();
293 WaitForReads();
294 Pause();
295 WaitForPause();
296 Close();
299 TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
300 Create(kSamplesPerPacket);
301 WaitForCreate();
302 Play();
303 WaitForPlay();
304 WaitForReads();
305 Pause();
306 WaitForPause();
307 Play();
308 WaitForPlay();
309 Close();
312 TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
313 Create(kSamplesPerPacket);
314 WaitForCreate();
315 Play();
316 WaitForPlay();
317 WaitForReads();
318 ChangeDevice();
319 WaitForPlay();
320 WaitForReads();
321 Close();
324 TEST_F(AudioOutputControllerTest, PlaySwitchDeviceClose) {
325 Create(kSamplesPerPacket);
326 WaitForCreate();
327 Play();
328 WaitForPlay();
329 WaitForReads();
330 SwitchDevice(false);
331 WaitForPlay();
332 WaitForReads();
333 Close();
336 TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
337 Create(kSamplesPerPacket);
338 WaitForCreate();
339 Play();
340 WaitForPlay();
341 WaitForReads();
342 DivertWhilePlaying();
343 WaitForPlay();
344 ReadDivertedAudioData();
345 RevertWhilePlaying();
346 WaitForPlay();
347 WaitForReads();
348 Close();
351 TEST_F(AudioOutputControllerTest, PlayDivertSwitchDeviceRevertClose) {
352 Create(kSamplesPerPacket);
353 WaitForCreate();
354 Play();
355 WaitForPlay();
356 WaitForReads();
357 DivertWhilePlaying();
358 WaitForPlay();
359 SwitchDevice(true);
360 ReadDivertedAudioData();
361 RevertWhilePlaying();
362 WaitForPlay();
363 WaitForReads();
364 Close();
367 TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
368 Create(kSamplesPerPacket);
369 WaitForCreate();
370 Play();
371 WaitForPlay();
372 WaitForReads();
373 DivertWhilePlaying();
374 WaitForPlay();
375 ReadDivertedAudioData();
376 RevertWhilePlaying();
377 WaitForPlay();
378 WaitForReads();
379 DivertWhilePlaying();
380 WaitForPlay();
381 ReadDivertedAudioData();
382 RevertWhilePlaying();
383 WaitForPlay();
384 WaitForReads();
385 Close();
388 TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
389 Create(kSamplesPerPacket);
390 WaitForCreate();
391 DivertWillEventuallyBeTwicePlayed();
392 Play();
393 WaitForPlay();
394 ReadDivertedAudioData();
395 Pause();
396 WaitForPause();
397 Play();
398 WaitForPlay();
399 ReadDivertedAudioData();
400 RevertWhilePlaying();
401 WaitForPlay();
402 WaitForReads();
403 Close();
406 TEST_F(AudioOutputControllerTest, DivertRevertClose) {
407 Create(kSamplesPerPacket);
408 WaitForCreate();
409 DivertNeverPlaying();
410 RevertWasNotPlaying();
411 Close();
414 } // namespace media