Delete chrome.mediaGalleriesPrivate because the functionality unique to it has since...
[chromium-blink-merge.git] / media / audio / audio_output_controller_unittest.cc
blobd15889886a47c915aa6ed878ee1466d343d3e39b
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 ~AudioOutputControllerTest() override {}
104 protected:
105 void Create(int samples_per_packet) {
106 EXPECT_FALSE(create_event_.IsSignaled());
107 EXPECT_FALSE(play_event_.IsSignaled());
108 EXPECT_FALSE(read_event_.IsSignaled());
109 EXPECT_FALSE(pause_event_.IsSignaled());
111 params_ = AudioParameters(
112 AudioParameters::AUDIO_FAKE, kChannelLayout,
113 kSampleRate, kBitsPerSample, samples_per_packet);
115 if (params_.IsValid()) {
116 EXPECT_CALL(mock_event_handler_, OnCreated())
117 .WillOnce(SignalEvent(&create_event_));
120 controller_ = AudioOutputController::Create(
121 audio_manager_.get(), &mock_event_handler_, params_, std::string(),
122 &mock_sync_reader_);
123 if (controller_.get())
124 controller_->SetVolume(kTestVolume);
126 EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
129 void Play() {
130 // Expect the event handler to receive one OnPlaying() call.
131 EXPECT_CALL(mock_event_handler_, OnPlaying())
132 .WillOnce(SignalEvent(&play_event_));
134 // During playback, the mock pretends to provide audio data rendered and
135 // sent from the render process.
136 EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
137 .Times(AtLeast(1));
138 EXPECT_CALL(mock_sync_reader_, Read(_))
139 .WillRepeatedly(DoAll(PopulateBuffer(),
140 SignalEvent(&read_event_)));
141 controller_->Play();
144 void Pause() {
145 // Expect the event handler to receive one OnPaused() call.
146 EXPECT_CALL(mock_event_handler_, OnPaused())
147 .WillOnce(SignalEvent(&pause_event_));
149 controller_->Pause();
152 void ChangeDevice() {
153 // Expect the event handler to receive one OnPaying() call and no OnPaused()
154 // call.
155 EXPECT_CALL(mock_event_handler_, OnPlaying())
156 .WillOnce(SignalEvent(&play_event_));
157 EXPECT_CALL(mock_event_handler_, OnPaused())
158 .Times(0);
160 // Simulate a device change event to AudioOutputController from the
161 // AudioManager.
162 audio_manager_->GetTaskRunner()->PostTask(
163 FROM_HERE,
164 base::Bind(&AudioOutputController::OnDeviceChange, controller_));
167 void Divert(bool was_playing, int num_times_to_be_started) {
168 if (was_playing) {
169 // Expect the handler to receive one OnPlaying() call as a result of the
170 // stream switching.
171 EXPECT_CALL(mock_event_handler_, OnPlaying())
172 .WillOnce(SignalEvent(&play_event_));
175 EXPECT_CALL(mock_stream_, Open())
176 .WillOnce(Return(true));
177 EXPECT_CALL(mock_stream_, SetVolume(kTestVolume));
178 if (num_times_to_be_started > 0) {
179 EXPECT_CALL(mock_stream_, Start(NotNull()))
180 .Times(num_times_to_be_started)
181 .WillRepeatedly(
182 Invoke(&mock_stream_, &MockAudioOutputStream::SetCallback));
183 EXPECT_CALL(mock_stream_, Stop())
184 .Times(num_times_to_be_started);
187 controller_->StartDiverting(&mock_stream_);
190 void ReadDivertedAudioData() {
191 scoped_ptr<AudioBus> dest = AudioBus::Create(params_);
192 ASSERT_TRUE(!!mock_stream_.callback());
193 const int frames_read =
194 mock_stream_.callback()->OnMoreData(dest.get(), 0);
195 EXPECT_LT(0, frames_read);
196 EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
199 void Revert(bool was_playing) {
200 if (was_playing) {
201 // Expect the handler to receive one OnPlaying() call as a result of the
202 // stream switching back.
203 EXPECT_CALL(mock_event_handler_, OnPlaying())
204 .WillOnce(SignalEvent(&play_event_));
207 EXPECT_CALL(mock_stream_, Close());
209 controller_->StopDiverting();
212 void SwitchDevice(bool diverting) {
213 if (!diverting) {
214 // Expect the current stream to close and a new stream to start
215 // playing if not diverting. When diverting, nothing happens
216 // until diverting is stopped.
217 EXPECT_CALL(mock_event_handler_, OnPlaying())
218 .WillOnce(SignalEvent(&play_event_));
221 controller_->SwitchOutputDevice(AudioManagerBase::kDefaultDeviceName,
222 base::Bind(&base::DoNothing));
225 void Close() {
226 EXPECT_CALL(mock_sync_reader_, Close());
228 controller_->Close(base::MessageLoop::QuitClosure());
229 base::MessageLoop::current()->Run();
232 // These help make test sequences more readable.
233 void DivertNeverPlaying() { Divert(false, 0); }
234 void DivertWillEventuallyBeTwicePlayed() { Divert(false, 2); }
235 void DivertWhilePlaying() { Divert(true, 1); }
236 void RevertWasNotPlaying() { Revert(false); }
237 void RevertWhilePlaying() { Revert(true); }
239 // These synchronize the main thread with key events taking place on other
240 // threads.
241 void WaitForCreate() { create_event_.Wait(); }
242 void WaitForPlay() { play_event_.Wait(); }
243 void WaitForReads() {
244 // Note: Arbitrarily chosen, but more iterations causes tests to take
245 // significantly more time.
246 static const int kNumIterations = 3;
247 for (int i = 0; i < kNumIterations; ++i) {
248 read_event_.Wait();
251 void WaitForPause() { pause_event_.Wait(); }
253 private:
254 base::MessageLoopForIO message_loop_;
255 scoped_ptr<AudioManager> audio_manager_;
256 MockAudioOutputControllerEventHandler mock_event_handler_;
257 MockAudioOutputControllerSyncReader mock_sync_reader_;
258 MockAudioOutputStream mock_stream_;
259 base::WaitableEvent create_event_;
260 base::WaitableEvent play_event_;
261 base::WaitableEvent read_event_;
262 base::WaitableEvent pause_event_;
263 AudioParameters params_;
264 scoped_refptr<AudioOutputController> controller_;
266 DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
269 TEST_F(AudioOutputControllerTest, CreateAndClose) {
270 Create(kSamplesPerPacket);
271 Close();
274 TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
275 Create(kSamplesPerPacket * 1000);
278 TEST_F(AudioOutputControllerTest, PlayAndClose) {
279 Create(kSamplesPerPacket);
280 WaitForCreate();
281 Play();
282 WaitForPlay();
283 WaitForReads();
284 Close();
287 TEST_F(AudioOutputControllerTest, PlayPauseClose) {
288 Create(kSamplesPerPacket);
289 WaitForCreate();
290 Play();
291 WaitForPlay();
292 WaitForReads();
293 Pause();
294 WaitForPause();
295 Close();
298 TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
299 Create(kSamplesPerPacket);
300 WaitForCreate();
301 Play();
302 WaitForPlay();
303 WaitForReads();
304 Pause();
305 WaitForPause();
306 Play();
307 WaitForPlay();
308 Close();
311 TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
312 Create(kSamplesPerPacket);
313 WaitForCreate();
314 Play();
315 WaitForPlay();
316 WaitForReads();
317 ChangeDevice();
318 WaitForPlay();
319 WaitForReads();
320 Close();
323 TEST_F(AudioOutputControllerTest, PlaySwitchDeviceClose) {
324 Create(kSamplesPerPacket);
325 WaitForCreate();
326 Play();
327 WaitForPlay();
328 WaitForReads();
329 SwitchDevice(false);
330 WaitForPlay();
331 WaitForReads();
332 Close();
335 TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
336 Create(kSamplesPerPacket);
337 WaitForCreate();
338 Play();
339 WaitForPlay();
340 WaitForReads();
341 DivertWhilePlaying();
342 WaitForPlay();
343 ReadDivertedAudioData();
344 RevertWhilePlaying();
345 WaitForPlay();
346 WaitForReads();
347 Close();
350 TEST_F(AudioOutputControllerTest, PlayDivertSwitchDeviceRevertClose) {
351 Create(kSamplesPerPacket);
352 WaitForCreate();
353 Play();
354 WaitForPlay();
355 WaitForReads();
356 DivertWhilePlaying();
357 WaitForPlay();
358 SwitchDevice(true);
359 ReadDivertedAudioData();
360 RevertWhilePlaying();
361 WaitForPlay();
362 WaitForReads();
363 Close();
366 TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
367 Create(kSamplesPerPacket);
368 WaitForCreate();
369 Play();
370 WaitForPlay();
371 WaitForReads();
372 DivertWhilePlaying();
373 WaitForPlay();
374 ReadDivertedAudioData();
375 RevertWhilePlaying();
376 WaitForPlay();
377 WaitForReads();
378 DivertWhilePlaying();
379 WaitForPlay();
380 ReadDivertedAudioData();
381 RevertWhilePlaying();
382 WaitForPlay();
383 WaitForReads();
384 Close();
387 TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
388 Create(kSamplesPerPacket);
389 WaitForCreate();
390 DivertWillEventuallyBeTwicePlayed();
391 Play();
392 WaitForPlay();
393 ReadDivertedAudioData();
394 Pause();
395 WaitForPause();
396 Play();
397 WaitForPlay();
398 ReadDivertedAudioData();
399 RevertWhilePlaying();
400 WaitForPlay();
401 WaitForReads();
402 Close();
405 TEST_F(AudioOutputControllerTest, DivertRevertClose) {
406 Create(kSamplesPerPacket);
407 WaitForCreate();
408 DivertNeverPlaying();
409 RevertWasNotPlaying();
410 Close();
413 } // namespace media