Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / audio / audio_output_controller_unittest.cc
blob3e9229da9ba51e9be912f25b309a50f26a5e7bfa
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());
45 private:
46 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
49 class MockAudioOutputControllerSyncReader
50 : public AudioOutputController::SyncReader {
51 public:
52 MockAudioOutputControllerSyncReader() {}
54 MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
55 MOCK_METHOD1(Read, void(AudioBus* dest));
56 MOCK_METHOD0(Close, void());
58 private:
59 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
62 class MockAudioOutputStream : public AudioOutputStream {
63 public:
64 MOCK_METHOD0(Open, bool());
65 MOCK_METHOD1(Start, void(AudioSourceCallback* callback));
66 MOCK_METHOD0(Stop, void());
67 MOCK_METHOD1(SetVolume, void(double volume));
68 MOCK_METHOD1(GetVolume, void(double* volume));
69 MOCK_METHOD0(Close, void());
71 // Set/get the callback passed to Start().
72 AudioSourceCallback* callback() const { return callback_; }
73 void SetCallback(AudioSourceCallback* asc) { callback_ = asc; }
75 private:
76 AudioSourceCallback* callback_;
79 ACTION_P(SignalEvent, event) {
80 event->Signal();
83 static const float kBufferNonZeroData = 1.0f;
84 ACTION(PopulateBuffer) {
85 arg0->Zero();
86 // Note: To confirm the buffer will be populated in these tests, it's
87 // sufficient that only the first float in channel 0 is set to the value.
88 arg0->channel(0)[0] = kBufferNonZeroData;
91 class AudioOutputControllerTest : public testing::Test {
92 public:
93 AudioOutputControllerTest()
94 : audio_manager_(AudioManager::CreateForTesting()),
95 create_event_(false, false),
96 play_event_(false, false),
97 read_event_(false, false),
98 pause_event_(false, false) {
101 ~AudioOutputControllerTest() override {}
103 protected:
104 void Create(int samples_per_packet) {
105 EXPECT_FALSE(create_event_.IsSignaled());
106 EXPECT_FALSE(play_event_.IsSignaled());
107 EXPECT_FALSE(read_event_.IsSignaled());
108 EXPECT_FALSE(pause_event_.IsSignaled());
110 params_ = AudioParameters(
111 AudioParameters::AUDIO_FAKE, kChannelLayout,
112 kSampleRate, kBitsPerSample, samples_per_packet);
114 if (params_.IsValid()) {
115 EXPECT_CALL(mock_event_handler_, OnCreated())
116 .WillOnce(SignalEvent(&create_event_));
119 controller_ = AudioOutputController::Create(
120 audio_manager_.get(), &mock_event_handler_, params_, std::string(),
121 &mock_sync_reader_);
122 if (controller_.get())
123 controller_->SetVolume(kTestVolume);
125 EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
128 void Play() {
129 // Expect the event handler to receive one OnPlaying() call.
130 EXPECT_CALL(mock_event_handler_, OnPlaying())
131 .WillOnce(SignalEvent(&play_event_));
133 // During playback, the mock pretends to provide audio data rendered and
134 // sent from the render process.
135 EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
136 .Times(AtLeast(1));
137 EXPECT_CALL(mock_sync_reader_, Read(_))
138 .WillRepeatedly(DoAll(PopulateBuffer(),
139 SignalEvent(&read_event_)));
140 controller_->Play();
143 void Pause() {
144 // Expect the event handler to receive one OnPaused() call.
145 EXPECT_CALL(mock_event_handler_, OnPaused())
146 .WillOnce(SignalEvent(&pause_event_));
148 controller_->Pause();
151 void ChangeDevice() {
152 // Expect the event handler to receive one OnPaying() call and no OnPaused()
153 // call.
154 EXPECT_CALL(mock_event_handler_, OnPlaying())
155 .WillOnce(SignalEvent(&play_event_));
156 EXPECT_CALL(mock_event_handler_, OnPaused())
157 .Times(0);
159 // Simulate a device change event to AudioOutputController from the
160 // AudioManager.
161 audio_manager_->GetTaskRunner()->PostTask(
162 FROM_HERE,
163 base::Bind(&AudioOutputController::OnDeviceChange, controller_));
166 void Divert(bool was_playing, int num_times_to_be_started) {
167 if (was_playing) {
168 // Expect the handler to receive one OnPlaying() call as a result of the
169 // stream switching.
170 EXPECT_CALL(mock_event_handler_, OnPlaying())
171 .WillOnce(SignalEvent(&play_event_));
174 EXPECT_CALL(mock_stream_, Open())
175 .WillOnce(Return(true));
176 EXPECT_CALL(mock_stream_, SetVolume(kTestVolume));
177 if (num_times_to_be_started > 0) {
178 EXPECT_CALL(mock_stream_, Start(NotNull()))
179 .Times(num_times_to_be_started)
180 .WillRepeatedly(
181 Invoke(&mock_stream_, &MockAudioOutputStream::SetCallback));
182 EXPECT_CALL(mock_stream_, Stop())
183 .Times(num_times_to_be_started);
186 controller_->StartDiverting(&mock_stream_);
189 void ReadDivertedAudioData() {
190 scoped_ptr<AudioBus> dest = AudioBus::Create(params_);
191 ASSERT_TRUE(mock_stream_.callback());
192 const int frames_read =
193 mock_stream_.callback()->OnMoreData(dest.get(), 0);
194 EXPECT_LT(0, frames_read);
195 EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
198 void Revert(bool was_playing) {
199 if (was_playing) {
200 // Expect the handler to receive one OnPlaying() call as a result of the
201 // stream switching back.
202 EXPECT_CALL(mock_event_handler_, OnPlaying())
203 .WillOnce(SignalEvent(&play_event_));
206 EXPECT_CALL(mock_stream_, Close());
208 controller_->StopDiverting();
211 void SwitchDevice(bool diverting) {
212 if (!diverting) {
213 // Expect the current stream to close and a new stream to start
214 // playing if not diverting. When diverting, nothing happens
215 // until diverting is stopped.
216 EXPECT_CALL(mock_event_handler_, OnPlaying())
217 .WillOnce(SignalEvent(&play_event_));
220 controller_->SwitchOutputDevice(AudioManagerBase::kDefaultDeviceName,
221 base::Bind(&base::DoNothing));
224 void Close() {
225 EXPECT_CALL(mock_sync_reader_, Close());
227 controller_->Close(base::MessageLoop::QuitClosure());
228 base::MessageLoop::current()->Run();
231 // These help make test sequences more readable.
232 void DivertNeverPlaying() { Divert(false, 0); }
233 void DivertWillEventuallyBeTwicePlayed() { Divert(false, 2); }
234 void DivertWhilePlaying() { Divert(true, 1); }
235 void RevertWasNotPlaying() { Revert(false); }
236 void RevertWhilePlaying() { Revert(true); }
238 // These synchronize the main thread with key events taking place on other
239 // threads.
240 void WaitForCreate() { create_event_.Wait(); }
241 void WaitForPlay() { play_event_.Wait(); }
242 void WaitForReads() {
243 // Note: Arbitrarily chosen, but more iterations causes tests to take
244 // significantly more time.
245 static const int kNumIterations = 3;
246 for (int i = 0; i < kNumIterations; ++i) {
247 read_event_.Wait();
250 void WaitForPause() { pause_event_.Wait(); }
252 private:
253 base::MessageLoopForIO message_loop_;
254 scoped_ptr<AudioManager> audio_manager_;
255 MockAudioOutputControllerEventHandler mock_event_handler_;
256 MockAudioOutputControllerSyncReader mock_sync_reader_;
257 MockAudioOutputStream mock_stream_;
258 base::WaitableEvent create_event_;
259 base::WaitableEvent play_event_;
260 base::WaitableEvent read_event_;
261 base::WaitableEvent pause_event_;
262 AudioParameters params_;
263 scoped_refptr<AudioOutputController> controller_;
265 DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
268 TEST_F(AudioOutputControllerTest, CreateAndClose) {
269 Create(kSamplesPerPacket);
270 Close();
273 TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
274 Create(kSamplesPerPacket * 1000);
277 TEST_F(AudioOutputControllerTest, PlayAndClose) {
278 Create(kSamplesPerPacket);
279 WaitForCreate();
280 Play();
281 WaitForPlay();
282 WaitForReads();
283 Close();
286 TEST_F(AudioOutputControllerTest, PlayPauseClose) {
287 Create(kSamplesPerPacket);
288 WaitForCreate();
289 Play();
290 WaitForPlay();
291 WaitForReads();
292 Pause();
293 WaitForPause();
294 Close();
297 TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
298 Create(kSamplesPerPacket);
299 WaitForCreate();
300 Play();
301 WaitForPlay();
302 WaitForReads();
303 Pause();
304 WaitForPause();
305 Play();
306 WaitForPlay();
307 Close();
310 TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
311 Create(kSamplesPerPacket);
312 WaitForCreate();
313 Play();
314 WaitForPlay();
315 WaitForReads();
316 ChangeDevice();
317 WaitForPlay();
318 WaitForReads();
319 Close();
322 TEST_F(AudioOutputControllerTest, PlaySwitchDeviceClose) {
323 Create(kSamplesPerPacket);
324 WaitForCreate();
325 Play();
326 WaitForPlay();
327 WaitForReads();
328 SwitchDevice(false);
329 WaitForPlay();
330 WaitForReads();
331 Close();
334 TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
335 Create(kSamplesPerPacket);
336 WaitForCreate();
337 Play();
338 WaitForPlay();
339 WaitForReads();
340 DivertWhilePlaying();
341 WaitForPlay();
342 ReadDivertedAudioData();
343 RevertWhilePlaying();
344 WaitForPlay();
345 WaitForReads();
346 Close();
349 TEST_F(AudioOutputControllerTest, PlayDivertSwitchDeviceRevertClose) {
350 Create(kSamplesPerPacket);
351 WaitForCreate();
352 Play();
353 WaitForPlay();
354 WaitForReads();
355 DivertWhilePlaying();
356 WaitForPlay();
357 SwitchDevice(true);
358 ReadDivertedAudioData();
359 RevertWhilePlaying();
360 WaitForPlay();
361 WaitForReads();
362 Close();
365 TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
366 Create(kSamplesPerPacket);
367 WaitForCreate();
368 Play();
369 WaitForPlay();
370 WaitForReads();
371 DivertWhilePlaying();
372 WaitForPlay();
373 ReadDivertedAudioData();
374 RevertWhilePlaying();
375 WaitForPlay();
376 WaitForReads();
377 DivertWhilePlaying();
378 WaitForPlay();
379 ReadDivertedAudioData();
380 RevertWhilePlaying();
381 WaitForPlay();
382 WaitForReads();
383 Close();
386 TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
387 Create(kSamplesPerPacket);
388 WaitForCreate();
389 DivertWillEventuallyBeTwicePlayed();
390 Play();
391 WaitForPlay();
392 ReadDivertedAudioData();
393 Pause();
394 WaitForPause();
395 Play();
396 WaitForPlay();
397 ReadDivertedAudioData();
398 RevertWhilePlaying();
399 WaitForPlay();
400 WaitForReads();
401 Close();
404 TEST_F(AudioOutputControllerTest, DivertRevertClose) {
405 Create(kSamplesPerPacket);
406 WaitForCreate();
407 DivertNeverPlaying();
408 RevertWasNotPlaying();
409 Close();
412 } // namespace media