cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / media / audio / audio_output_controller_unittest.cc
blob128cc07716f2822767bf4fca70acdb5ee1c3f431
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_output_controller.h"
14 #include "media/audio/audio_parameters.h"
15 #include "media/base/audio_bus.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using ::testing::_;
20 using ::testing::AtLeast;
21 using ::testing::DoAll;
22 using ::testing::Invoke;
23 using ::testing::NotNull;
24 using ::testing::Return;
26 namespace media {
28 static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
29 static const int kBitsPerSample = 16;
30 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
31 static const int kSamplesPerPacket = kSampleRate / 100;
32 static const int kHardwareBufferSize = kSamplesPerPacket *
33 ChannelLayoutToChannelCount(kChannelLayout) * kBitsPerSample / 8;
34 static const double kTestVolume = 0.25;
36 class MockAudioOutputControllerEventHandler
37 : public AudioOutputController::EventHandler {
38 public:
39 MockAudioOutputControllerEventHandler() {}
41 MOCK_METHOD0(OnCreated, void());
42 MOCK_METHOD0(OnPlaying, void());
43 MOCK_METHOD2(OnPowerMeasured, void(float power_dbfs, bool clipped));
44 MOCK_METHOD0(OnPaused, void());
45 MOCK_METHOD0(OnError, void());
46 MOCK_METHOD2(OnDeviceChange, void(int new_buffer_size, int new_sample_rate));
48 private:
49 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
52 class MockAudioOutputControllerSyncReader
53 : public AudioOutputController::SyncReader {
54 public:
55 MockAudioOutputControllerSyncReader() {}
57 MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
58 MOCK_METHOD3(Read, int(bool block, const AudioBus* source, AudioBus* dest));
59 MOCK_METHOD0(Close, void());
61 private:
62 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
65 class MockAudioOutputStream : public AudioOutputStream {
66 public:
67 MOCK_METHOD0(Open, bool());
68 MOCK_METHOD1(Start, void(AudioSourceCallback* callback));
69 MOCK_METHOD0(Stop, void());
70 MOCK_METHOD1(SetVolume, void(double volume));
71 MOCK_METHOD1(GetVolume, void(double* volume));
72 MOCK_METHOD0(Close, void());
74 // Set/get the callback passed to Start().
75 AudioSourceCallback* callback() const { return callback_; }
76 void SetCallback(AudioSourceCallback* asc) { callback_ = asc; }
78 private:
79 AudioSourceCallback* callback_;
82 ACTION_P(SignalEvent, event) {
83 event->Signal();
86 static const float kBufferNonZeroData = 1.0f;
87 ACTION(PopulateBuffer) {
88 arg2->Zero();
89 // Note: To confirm the buffer will be populated in these tests, it's
90 // sufficient that only the first float in channel 0 is set to the value.
91 arg2->channel(0)[0] = kBufferNonZeroData;
94 class AudioOutputControllerTest : public testing::Test {
95 public:
96 AudioOutputControllerTest()
97 : audio_manager_(AudioManager::Create()),
98 create_event_(false, false),
99 play_event_(false, false),
100 read_event_(false, false),
101 pause_event_(false, false) {
104 virtual ~AudioOutputControllerTest() {
107 protected:
108 void Create(int samples_per_packet) {
109 EXPECT_FALSE(create_event_.IsSignaled());
110 EXPECT_FALSE(play_event_.IsSignaled());
111 EXPECT_FALSE(read_event_.IsSignaled());
112 EXPECT_FALSE(pause_event_.IsSignaled());
114 params_ = AudioParameters(
115 AudioParameters::AUDIO_FAKE, kChannelLayout,
116 kSampleRate, kBitsPerSample, samples_per_packet);
118 if (params_.IsValid()) {
119 EXPECT_CALL(mock_event_handler_, OnCreated())
120 .WillOnce(SignalEvent(&create_event_));
123 controller_ = AudioOutputController::Create(
124 audio_manager_.get(), &mock_event_handler_, params_, std::string(),
125 &mock_sync_reader_);
126 if (controller_.get())
127 controller_->SetVolume(kTestVolume);
129 EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
132 void Play() {
133 // Expect the event handler to receive one OnPlaying() call and one or more
134 // OnPowerMeasured() calls.
135 EXPECT_CALL(mock_event_handler_, OnPlaying())
136 .WillOnce(SignalEvent(&play_event_));
137 EXPECT_CALL(mock_event_handler_, OnPowerMeasured(_, false))
138 .Times(AtLeast(1));
140 // During playback, the mock pretends to provide audio data rendered and
141 // sent from the render process.
142 EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
143 .Times(AtLeast(1));
144 EXPECT_CALL(mock_sync_reader_, Read(_, _, _))
145 .WillRepeatedly(DoAll(PopulateBuffer(),
146 SignalEvent(&read_event_),
147 Return(params_.frames_per_buffer())));
148 controller_->Play();
151 void Pause() {
152 // Expect the event handler to receive one OnPaused() call.
153 EXPECT_CALL(mock_event_handler_, OnPaused())
154 .WillOnce(SignalEvent(&pause_event_));
156 controller_->Pause();
159 void ChangeDevice() {
160 // Expect the event handler to receive one OnPaying() call and no OnPaused()
161 // call.
162 EXPECT_CALL(mock_event_handler_, OnPlaying())
163 .WillOnce(SignalEvent(&play_event_));
164 EXPECT_CALL(mock_event_handler_, OnPaused())
165 .Times(0);
167 // Simulate a device change event to AudioOutputController from the
168 // AudioManager.
169 audio_manager_->GetMessageLoop()->PostTask(
170 FROM_HERE,
171 base::Bind(&AudioOutputController::OnDeviceChange, controller_));
174 void Divert(bool was_playing, int num_times_to_be_started) {
175 if (was_playing) {
176 // Expect the handler to receive one OnPlaying() call as a result of the
177 // stream switching.
178 EXPECT_CALL(mock_event_handler_, OnPlaying())
179 .WillOnce(SignalEvent(&play_event_));
182 EXPECT_CALL(mock_stream_, Open())
183 .WillOnce(Return(true));
184 EXPECT_CALL(mock_stream_, SetVolume(kTestVolume));
185 if (num_times_to_be_started > 0) {
186 EXPECT_CALL(mock_stream_, Start(NotNull()))
187 .Times(num_times_to_be_started)
188 .WillRepeatedly(
189 Invoke(&mock_stream_, &MockAudioOutputStream::SetCallback));
190 EXPECT_CALL(mock_stream_, Stop())
191 .Times(num_times_to_be_started);
194 controller_->StartDiverting(&mock_stream_);
197 void ReadDivertedAudioData() {
198 scoped_ptr<AudioBus> dest = AudioBus::Create(params_);
199 ASSERT_TRUE(!!mock_stream_.callback());
200 const int frames_read =
201 mock_stream_.callback()->OnMoreData(dest.get(), AudioBuffersState());
202 EXPECT_LT(0, frames_read);
203 EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
206 void Revert(bool was_playing) {
207 if (was_playing) {
208 // Expect the handler to receive one OnPlaying() call as a result of the
209 // stream switching back.
210 EXPECT_CALL(mock_event_handler_, OnPlaying())
211 .WillOnce(SignalEvent(&play_event_));
214 EXPECT_CALL(mock_stream_, Close());
216 controller_->StopDiverting();
219 void Close() {
220 EXPECT_CALL(mock_sync_reader_, Close());
222 controller_->Close(base::MessageLoop::QuitClosure());
223 base::MessageLoop::current()->Run();
226 // These help make test sequences more readable.
227 void DivertNeverPlaying() { Divert(false, 0); }
228 void DivertWillEventuallyBeTwicePlayed() { Divert(false, 2); }
229 void DivertWhilePlaying() { Divert(true, 1); }
230 void RevertWasNotPlaying() { Revert(false); }
231 void RevertWhilePlaying() { Revert(true); }
233 // These synchronize the main thread with key events taking place on other
234 // threads.
235 void WaitForCreate() { create_event_.Wait(); }
236 void WaitForPlay() { play_event_.Wait(); }
237 void WaitForReads() {
238 // Note: Arbitrarily chosen, but more iterations causes tests to take
239 // significantly more time.
240 static const int kNumIterations = 3;
241 for (int i = 0; i < kNumIterations; ++i) {
242 read_event_.Wait();
245 void WaitForPause() { pause_event_.Wait(); }
247 private:
248 base::MessageLoopForIO message_loop_;
249 scoped_ptr<AudioManager> audio_manager_;
250 MockAudioOutputControllerEventHandler mock_event_handler_;
251 MockAudioOutputControllerSyncReader mock_sync_reader_;
252 MockAudioOutputStream mock_stream_;
253 base::WaitableEvent create_event_;
254 base::WaitableEvent play_event_;
255 base::WaitableEvent read_event_;
256 base::WaitableEvent pause_event_;
257 AudioParameters params_;
258 scoped_refptr<AudioOutputController> controller_;
260 DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
263 TEST_F(AudioOutputControllerTest, CreateAndClose) {
264 Create(kSamplesPerPacket);
265 Close();
268 TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
269 Create(kSamplesPerPacket * 1000);
272 TEST_F(AudioOutputControllerTest, PlayAndClose) {
273 Create(kSamplesPerPacket);
274 WaitForCreate();
275 Play();
276 WaitForPlay();
277 WaitForReads();
278 Close();
281 TEST_F(AudioOutputControllerTest, PlayPauseClose) {
282 Create(kSamplesPerPacket);
283 WaitForCreate();
284 Play();
285 WaitForPlay();
286 WaitForReads();
287 Pause();
288 WaitForPause();
289 Close();
292 TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
293 Create(kSamplesPerPacket);
294 WaitForCreate();
295 Play();
296 WaitForPlay();
297 WaitForReads();
298 Pause();
299 WaitForPause();
300 Play();
301 WaitForPlay();
302 Close();
305 TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
306 Create(kSamplesPerPacket);
307 WaitForCreate();
308 Play();
309 WaitForPlay();
310 WaitForReads();
311 ChangeDevice();
312 WaitForPlay();
313 WaitForReads();
314 Close();
317 TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
318 Create(kSamplesPerPacket);
319 WaitForCreate();
320 Play();
321 WaitForPlay();
322 WaitForReads();
323 DivertWhilePlaying();
324 WaitForPlay();
325 ReadDivertedAudioData();
326 RevertWhilePlaying();
327 WaitForPlay();
328 WaitForReads();
329 Close();
332 TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
333 Create(kSamplesPerPacket);
334 WaitForCreate();
335 Play();
336 WaitForPlay();
337 WaitForReads();
338 DivertWhilePlaying();
339 WaitForPlay();
340 ReadDivertedAudioData();
341 RevertWhilePlaying();
342 WaitForPlay();
343 WaitForReads();
344 DivertWhilePlaying();
345 WaitForPlay();
346 ReadDivertedAudioData();
347 RevertWhilePlaying();
348 WaitForPlay();
349 WaitForReads();
350 Close();
353 TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
354 Create(kSamplesPerPacket);
355 WaitForCreate();
356 DivertWillEventuallyBeTwicePlayed();
357 Play();
358 WaitForPlay();
359 ReadDivertedAudioData();
360 Pause();
361 WaitForPause();
362 Play();
363 WaitForPlay();
364 ReadDivertedAudioData();
365 RevertWhilePlaying();
366 WaitForPlay();
367 WaitForReads();
368 Close();
371 TEST_F(AudioOutputControllerTest, DivertRevertClose) {
372 Create(kSamplesPerPacket);
373 WaitForCreate();
374 DivertNeverPlaying();
375 RevertWasNotPlaying();
376 Close();
379 } // namespace media