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"
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"
21 using ::testing::AtLeast
;
22 using ::testing::DoAll
;
23 using ::testing::Invoke
;
24 using ::testing::NotNull
;
25 using ::testing::Return
;
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
{
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
));
47 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler
);
50 class MockAudioOutputControllerSyncReader
51 : public AudioOutputController::SyncReader
{
53 MockAudioOutputControllerSyncReader() {}
55 MOCK_METHOD1(UpdatePendingBytes
, void(uint32 bytes
));
56 MOCK_METHOD1(Read
, void(AudioBus
* dest
));
57 MOCK_METHOD0(Close
, void());
60 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader
);
63 class MockAudioOutputStream
: public AudioOutputStream
{
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
; }
77 AudioSourceCallback
* callback_
;
80 ACTION_P(SignalEvent
, event
) {
84 static const float kBufferNonZeroData
= 1.0f
;
85 ACTION(PopulateBuffer
) {
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
{
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
{}
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(),
123 if (controller_
.get())
124 controller_
->SetVolume(kTestVolume
);
126 EXPECT_EQ(params_
.IsValid(), controller_
.get() != NULL
);
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(_
))
138 EXPECT_CALL(mock_sync_reader_
, Read(_
))
139 .WillRepeatedly(DoAll(PopulateBuffer(),
140 SignalEvent(&read_event_
)));
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()
155 EXPECT_CALL(mock_event_handler_
, OnPlaying())
156 .WillOnce(SignalEvent(&play_event_
));
157 EXPECT_CALL(mock_event_handler_
, OnPaused())
160 // Simulate a device change event to AudioOutputController from the
162 audio_manager_
->GetTaskRunner()->PostTask(
164 base::Bind(&AudioOutputController::OnDeviceChange
, controller_
));
167 void Divert(bool was_playing
, int num_times_to_be_started
) {
169 // Expect the handler to receive one OnPlaying() call as a result of the
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
)
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
) {
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
) {
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
));
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
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
) {
251 void WaitForPause() { pause_event_
.Wait(); }
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
);
274 TEST_F(AudioOutputControllerTest
, HardwareBufferTooLarge
) {
275 Create(kSamplesPerPacket
* 1000);
278 TEST_F(AudioOutputControllerTest
, PlayAndClose
) {
279 Create(kSamplesPerPacket
);
287 TEST_F(AudioOutputControllerTest
, PlayPauseClose
) {
288 Create(kSamplesPerPacket
);
298 TEST_F(AudioOutputControllerTest
, PlayPausePlayClose
) {
299 Create(kSamplesPerPacket
);
311 TEST_F(AudioOutputControllerTest
, PlayDeviceChangeClose
) {
312 Create(kSamplesPerPacket
);
323 TEST_F(AudioOutputControllerTest
, PlaySwitchDeviceClose
) {
324 Create(kSamplesPerPacket
);
335 TEST_F(AudioOutputControllerTest
, PlayDivertRevertClose
) {
336 Create(kSamplesPerPacket
);
341 DivertWhilePlaying();
343 ReadDivertedAudioData();
344 RevertWhilePlaying();
350 TEST_F(AudioOutputControllerTest
, PlayDivertSwitchDeviceRevertClose
) {
351 Create(kSamplesPerPacket
);
356 DivertWhilePlaying();
359 ReadDivertedAudioData();
360 RevertWhilePlaying();
366 TEST_F(AudioOutputControllerTest
, PlayDivertRevertDivertRevertClose
) {
367 Create(kSamplesPerPacket
);
372 DivertWhilePlaying();
374 ReadDivertedAudioData();
375 RevertWhilePlaying();
378 DivertWhilePlaying();
380 ReadDivertedAudioData();
381 RevertWhilePlaying();
387 TEST_F(AudioOutputControllerTest
, DivertPlayPausePlayRevertClose
) {
388 Create(kSamplesPerPacket
);
390 DivertWillEventuallyBeTwicePlayed();
393 ReadDivertedAudioData();
398 ReadDivertedAudioData();
399 RevertWhilePlaying();
405 TEST_F(AudioOutputControllerTest
, DivertRevertClose
) {
406 Create(kSamplesPerPacket
);
408 DivertNeverPlaying();
409 RevertWasNotPlaying();