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.
6 #include "base/environment.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/message_loop.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "media/audio/audio_output_controller.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 // TODO(vrk): These tests need to be rewritten! (crbug.com/112500)
18 using ::testing::AtLeast
;
19 using ::testing::DoAll
;
20 using ::testing::Exactly
;
21 using ::testing::InvokeWithoutArgs
;
22 using ::testing::NotNull
;
23 using ::testing::Return
;
27 static const int kSampleRate
= AudioParameters::kAudioCDSampleRate
;
28 static const int kBitsPerSample
= 16;
29 static const ChannelLayout kChannelLayout
= CHANNEL_LAYOUT_STEREO
;
30 static const int kSamplesPerPacket
= kSampleRate
/ 10;
31 static const int kHardwareBufferSize
= kSamplesPerPacket
*
32 ChannelLayoutToChannelCount(kChannelLayout
) * kBitsPerSample
/ 8;
34 class MockAudioOutputControllerEventHandler
35 : public AudioOutputController::EventHandler
{
37 MockAudioOutputControllerEventHandler() {}
39 MOCK_METHOD1(OnCreated
, void(AudioOutputController
* controller
));
40 MOCK_METHOD1(OnPlaying
, void(AudioOutputController
* controller
));
41 MOCK_METHOD1(OnPaused
, void(AudioOutputController
* controller
));
42 MOCK_METHOD2(OnError
, void(AudioOutputController
* controller
,
46 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler
);
49 class MockAudioOutputControllerSyncReader
50 : public AudioOutputController::SyncReader
{
52 MockAudioOutputControllerSyncReader() {}
54 MOCK_METHOD1(UpdatePendingBytes
, void(uint32 bytes
));
55 MOCK_METHOD2(Read
, int(AudioBus
* source
, AudioBus
* dest
));
56 MOCK_METHOD0(Close
, void());
57 MOCK_METHOD0(DataReady
, bool());
60 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader
);
63 ACTION_P(SignalEvent
, event
) {
67 // Custom action to clear a memory buffer.
72 // Closes AudioOutputController synchronously.
73 static void CloseAudioController(AudioOutputController
* controller
) {
74 controller
->Close(MessageLoop::QuitClosure());
75 MessageLoop::current()->Run();
78 class AudioOutputControllerTest
: public testing::Test
{
80 AudioOutputControllerTest() {}
81 virtual ~AudioOutputControllerTest() {}
84 MessageLoopForIO message_loop_
;
87 DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest
);
90 TEST_F(AudioOutputControllerTest
, CreateAndClose
) {
91 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
92 if (!audio_manager
->HasAudioOutputDevices())
95 MockAudioOutputControllerEventHandler event_handler
;
97 EXPECT_CALL(event_handler
, OnCreated(NotNull()))
100 MockAudioOutputControllerSyncReader sync_reader
;
101 EXPECT_CALL(sync_reader
, Close());
103 AudioParameters
params(AudioParameters::AUDIO_PCM_LINEAR
, kChannelLayout
,
104 kSampleRate
, kBitsPerSample
, kSamplesPerPacket
);
105 scoped_refptr
<AudioOutputController
> controller
=
106 AudioOutputController::Create(
107 audio_manager
.get(), &event_handler
, params
, &sync_reader
);
108 ASSERT_TRUE(controller
.get());
110 // Close the controller immediately.
111 CloseAudioController(controller
);
114 TEST_F(AudioOutputControllerTest
, PlayPauseClose
) {
115 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
116 if (!audio_manager
->HasAudioOutputDevices())
119 MockAudioOutputControllerEventHandler event_handler
;
120 base::WaitableEvent
event(false, false);
121 base::WaitableEvent
pause_event(false, false);
123 // If OnCreated is called then signal the event.
124 EXPECT_CALL(event_handler
, OnCreated(NotNull()))
125 .WillOnce(InvokeWithoutArgs(&event
, &base::WaitableEvent::Signal
));
127 // OnPlaying() will be called only once.
128 EXPECT_CALL(event_handler
, OnPlaying(NotNull()));
130 MockAudioOutputControllerSyncReader sync_reader
;
131 EXPECT_CALL(sync_reader
, UpdatePendingBytes(_
))
133 EXPECT_CALL(sync_reader
, Read(_
, _
))
134 .WillRepeatedly(DoAll(ClearBuffer(), SignalEvent(&event
),
136 EXPECT_CALL(sync_reader
, DataReady())
137 .WillRepeatedly(Return(true));
138 EXPECT_CALL(event_handler
, OnPaused(NotNull()))
139 .WillOnce(InvokeWithoutArgs(&pause_event
, &base::WaitableEvent::Signal
));
140 EXPECT_CALL(sync_reader
, Close());
142 AudioParameters
params(AudioParameters::AUDIO_PCM_LINEAR
, kChannelLayout
,
143 kSampleRate
, kBitsPerSample
, kSamplesPerPacket
);
144 scoped_refptr
<AudioOutputController
> controller
=
145 AudioOutputController::Create(
146 audio_manager
.get(), &event_handler
, params
, &sync_reader
);
147 ASSERT_TRUE(controller
.get());
149 // Wait for OnCreated() to be called.
152 ASSERT_FALSE(pause_event
.IsSignaled());
157 // Now stop the controller.
158 CloseAudioController(controller
);
161 TEST_F(AudioOutputControllerTest
, HardwareBufferTooLarge
) {
162 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
163 if (!audio_manager
->HasAudioOutputDevices())
166 // Create an audio device with a very large hardware buffer size.
167 MockAudioOutputControllerEventHandler event_handler
;
169 MockAudioOutputControllerSyncReader sync_reader
;
170 AudioParameters
params(AudioParameters::AUDIO_PCM_LINEAR
, kChannelLayout
,
171 kSampleRate
, kBitsPerSample
,
172 kSamplesPerPacket
* 1000);
173 scoped_refptr
<AudioOutputController
> controller
=
174 AudioOutputController::Create(
175 audio_manager
.get(), &event_handler
, params
, &sync_reader
);
177 // Use assert because we don't stop the device and assume we can't
179 ASSERT_FALSE(controller
);
182 TEST_F(AudioOutputControllerTest
, PlayPausePlayClose
) {
183 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
184 if (!audio_manager
->HasAudioOutputDevices())
187 MockAudioOutputControllerEventHandler event_handler
;
188 base::WaitableEvent
event(false, false);
189 EXPECT_CALL(event_handler
, OnCreated(NotNull()))
190 .WillOnce(InvokeWithoutArgs(&event
, &base::WaitableEvent::Signal
));
192 // OnPlaying() will be called only once.
193 base::WaitableEvent
play_event(false, false);
194 EXPECT_CALL(event_handler
, OnPlaying(NotNull()))
195 .WillOnce(InvokeWithoutArgs(&play_event
, &base::WaitableEvent::Signal
));
197 // OnPaused() should never be called since the pause during kStarting is
198 // dropped when the second play comes in.
199 EXPECT_CALL(event_handler
, OnPaused(NotNull()))
202 MockAudioOutputControllerSyncReader sync_reader
;
203 EXPECT_CALL(sync_reader
, UpdatePendingBytes(_
))
205 EXPECT_CALL(sync_reader
, Read(_
, _
))
206 .WillRepeatedly(DoAll(ClearBuffer(), SignalEvent(&event
), Return(4)));
207 EXPECT_CALL(sync_reader
, DataReady())
208 .WillRepeatedly(Return(true));
209 EXPECT_CALL(sync_reader
, Close());
211 AudioParameters
params(AudioParameters::AUDIO_PCM_LINEAR
, kChannelLayout
,
212 kSampleRate
, kBitsPerSample
, kSamplesPerPacket
);
213 scoped_refptr
<AudioOutputController
> controller
=
214 AudioOutputController::Create(
215 audio_manager
.get(), &event_handler
, params
, &sync_reader
);
216 ASSERT_TRUE(controller
.get());
218 // Wait for OnCreated() to be called.
221 ASSERT_FALSE(play_event
.IsSignaled());
227 // Now stop the controller.
228 CloseAudioController(controller
);
231 // Ensure state change events are handled.
232 TEST_F(AudioOutputControllerTest
, PlayStateChangeClose
) {
233 scoped_ptr
<AudioManager
> audio_manager(AudioManager::Create());
234 if (!audio_manager
->HasAudioOutputDevices())
237 MockAudioOutputControllerEventHandler event_handler
;
238 base::WaitableEvent
event(false, false);
239 EXPECT_CALL(event_handler
, OnCreated(NotNull()))
240 .WillOnce(InvokeWithoutArgs(&event
, &base::WaitableEvent::Signal
));
242 // OnPlaying() will be called once normally and once after being recreated.
243 base::WaitableEvent
play_event(false, false);
244 EXPECT_CALL(event_handler
, OnPlaying(NotNull()))
246 .WillRepeatedly(InvokeWithoutArgs(
247 &play_event
, &base::WaitableEvent::Signal
));
249 // OnPaused() should not be called during the state change event.
250 EXPECT_CALL(event_handler
, OnPaused(NotNull()))
253 MockAudioOutputControllerSyncReader sync_reader
;
254 EXPECT_CALL(sync_reader
, UpdatePendingBytes(_
))
256 EXPECT_CALL(sync_reader
, Read(_
, _
))
257 .WillRepeatedly(DoAll(ClearBuffer(), SignalEvent(&event
), Return(4)));
258 EXPECT_CALL(sync_reader
, DataReady())
259 .WillRepeatedly(Return(true));
260 EXPECT_CALL(sync_reader
, Close());
262 AudioParameters
params(AudioParameters::AUDIO_PCM_LINEAR
, kChannelLayout
,
263 kSampleRate
, kBitsPerSample
, kSamplesPerPacket
);
264 scoped_refptr
<AudioOutputController
> controller
=
265 AudioOutputController::Create(
266 audio_manager
.get(), &event_handler
, params
, &sync_reader
);
267 ASSERT_TRUE(controller
.get());
269 // Wait for OnCreated() to be called.
272 ASSERT_FALSE(play_event
.IsSignaled());
276 // Force a state change and wait for the stream to come back to playing state.
278 audio_manager
->GetMessageLoop()->PostTask(FROM_HERE
,
279 base::Bind(&AudioOutputController::OnDeviceChange
, controller
));
282 // Now stop the controller.
283 CloseAudioController(controller
);