[Android] Add ps_ext tool for tools-friendly cpu/mem/proc stats.
[chromium-blink-merge.git] / media / audio / audio_output_controller_unittest.cc
blob288acd97201356acecb732cf7e46f9d606cf27ce
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_METHOD2(OnPowerMeasured, void(float power_dbfs, bool clipped));
43 MOCK_METHOD0(OnPaused, void());
44 MOCK_METHOD0(OnError, void());
45 MOCK_METHOD2(OnDeviceChange, void(int new_buffer_size, int new_sample_rate));
47 private:
48 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
51 class MockAudioOutputControllerSyncReader
52 : public AudioOutputController::SyncReader {
53 public:
54 MockAudioOutputControllerSyncReader() {}
56 MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
57 MOCK_METHOD2(Read, void(const AudioBus* source, AudioBus* dest));
58 MOCK_METHOD0(Close, void());
60 private:
61 DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
64 class MockAudioOutputStream : public AudioOutputStream {
65 public:
66 MOCK_METHOD0(Open, bool());
67 MOCK_METHOD1(Start, void(AudioSourceCallback* callback));
68 MOCK_METHOD0(Stop, void());
69 MOCK_METHOD1(SetVolume, void(double volume));
70 MOCK_METHOD1(GetVolume, void(double* volume));
71 MOCK_METHOD0(Close, void());
73 // Set/get the callback passed to Start().
74 AudioSourceCallback* callback() const { return callback_; }
75 void SetCallback(AudioSourceCallback* asc) { callback_ = asc; }
77 private:
78 AudioSourceCallback* callback_;
81 ACTION_P(SignalEvent, event) {
82 event->Signal();
85 static const float kBufferNonZeroData = 1.0f;
86 ACTION(PopulateBuffer) {
87 arg1->Zero();
88 // Note: To confirm the buffer will be populated in these tests, it's
89 // sufficient that only the first float in channel 0 is set to the value.
90 arg1->channel(0)[0] = kBufferNonZeroData;
93 class AudioOutputControllerTest : public testing::Test {
94 public:
95 AudioOutputControllerTest()
96 : audio_manager_(AudioManager::CreateForTesting()),
97 create_event_(false, false),
98 play_event_(false, false),
99 read_event_(false, false),
100 pause_event_(false, false) {
103 virtual ~AudioOutputControllerTest() {
106 protected:
107 void Create(int samples_per_packet) {
108 EXPECT_FALSE(create_event_.IsSignaled());
109 EXPECT_FALSE(play_event_.IsSignaled());
110 EXPECT_FALSE(read_event_.IsSignaled());
111 EXPECT_FALSE(pause_event_.IsSignaled());
113 params_ = AudioParameters(
114 AudioParameters::AUDIO_FAKE, kChannelLayout,
115 kSampleRate, kBitsPerSample, samples_per_packet);
117 if (params_.IsValid()) {
118 EXPECT_CALL(mock_event_handler_, OnCreated())
119 .WillOnce(SignalEvent(&create_event_));
122 controller_ = AudioOutputController::Create(
123 audio_manager_.get(), &mock_event_handler_, params_, std::string(),
124 std::string(), &mock_sync_reader_);
125 if (controller_.get())
126 controller_->SetVolume(kTestVolume);
128 EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
131 void Play() {
132 // Expect the event handler to receive one OnPlaying() call and one or more
133 // OnPowerMeasured() calls.
134 EXPECT_CALL(mock_event_handler_, OnPlaying())
135 .WillOnce(SignalEvent(&play_event_));
136 #if defined(AUDIO_POWER_MONITORING)
137 EXPECT_CALL(mock_event_handler_, OnPowerMeasured(_, false))
138 .Times(AtLeast(1));
139 #endif
141 // During playback, the mock pretends to provide audio data rendered and
142 // sent from the render process.
143 EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
144 .Times(AtLeast(1));
145 EXPECT_CALL(mock_sync_reader_, Read(_, _))
146 .WillRepeatedly(DoAll(PopulateBuffer(),
147 SignalEvent(&read_event_)));
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_->GetTaskRunner()->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 SwitchDevice(bool diverting) {
220 if (!diverting) {
221 // Expect the current stream to close and a new stream to start
222 // playing if not diverting. When diverting, nothing happens
223 // until diverting is stopped.
224 EXPECT_CALL(mock_event_handler_, OnPlaying())
225 .WillOnce(SignalEvent(&play_event_));
228 controller_->SwitchOutputDevice(AudioManagerBase::kDefaultDeviceName,
229 base::Bind(&base::DoNothing));
232 void Close() {
233 EXPECT_CALL(mock_sync_reader_, Close());
235 controller_->Close(base::MessageLoop::QuitClosure());
236 base::MessageLoop::current()->Run();
239 // These help make test sequences more readable.
240 void DivertNeverPlaying() { Divert(false, 0); }
241 void DivertWillEventuallyBeTwicePlayed() { Divert(false, 2); }
242 void DivertWhilePlaying() { Divert(true, 1); }
243 void RevertWasNotPlaying() { Revert(false); }
244 void RevertWhilePlaying() { Revert(true); }
246 // These synchronize the main thread with key events taking place on other
247 // threads.
248 void WaitForCreate() { create_event_.Wait(); }
249 void WaitForPlay() { play_event_.Wait(); }
250 void WaitForReads() {
251 // Note: Arbitrarily chosen, but more iterations causes tests to take
252 // significantly more time.
253 static const int kNumIterations = 3;
254 for (int i = 0; i < kNumIterations; ++i) {
255 read_event_.Wait();
258 void WaitForPause() { pause_event_.Wait(); }
260 private:
261 base::MessageLoopForIO message_loop_;
262 scoped_ptr<AudioManager> audio_manager_;
263 MockAudioOutputControllerEventHandler mock_event_handler_;
264 MockAudioOutputControllerSyncReader mock_sync_reader_;
265 MockAudioOutputStream mock_stream_;
266 base::WaitableEvent create_event_;
267 base::WaitableEvent play_event_;
268 base::WaitableEvent read_event_;
269 base::WaitableEvent pause_event_;
270 AudioParameters params_;
271 scoped_refptr<AudioOutputController> controller_;
273 DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
276 TEST_F(AudioOutputControllerTest, CreateAndClose) {
277 Create(kSamplesPerPacket);
278 Close();
281 TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
282 Create(kSamplesPerPacket * 1000);
285 TEST_F(AudioOutputControllerTest, PlayAndClose) {
286 Create(kSamplesPerPacket);
287 WaitForCreate();
288 Play();
289 WaitForPlay();
290 WaitForReads();
291 Close();
294 TEST_F(AudioOutputControllerTest, PlayPauseClose) {
295 Create(kSamplesPerPacket);
296 WaitForCreate();
297 Play();
298 WaitForPlay();
299 WaitForReads();
300 Pause();
301 WaitForPause();
302 Close();
305 TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
306 Create(kSamplesPerPacket);
307 WaitForCreate();
308 Play();
309 WaitForPlay();
310 WaitForReads();
311 Pause();
312 WaitForPause();
313 Play();
314 WaitForPlay();
315 Close();
318 TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
319 Create(kSamplesPerPacket);
320 WaitForCreate();
321 Play();
322 WaitForPlay();
323 WaitForReads();
324 ChangeDevice();
325 WaitForPlay();
326 WaitForReads();
327 Close();
330 TEST_F(AudioOutputControllerTest, PlaySwitchDeviceClose) {
331 Create(kSamplesPerPacket);
332 WaitForCreate();
333 Play();
334 WaitForPlay();
335 WaitForReads();
336 SwitchDevice(false);
337 WaitForPlay();
338 WaitForReads();
339 Close();
342 TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
343 Create(kSamplesPerPacket);
344 WaitForCreate();
345 Play();
346 WaitForPlay();
347 WaitForReads();
348 DivertWhilePlaying();
349 WaitForPlay();
350 ReadDivertedAudioData();
351 RevertWhilePlaying();
352 WaitForPlay();
353 WaitForReads();
354 Close();
357 TEST_F(AudioOutputControllerTest, PlayDivertSwitchDeviceRevertClose) {
358 Create(kSamplesPerPacket);
359 WaitForCreate();
360 Play();
361 WaitForPlay();
362 WaitForReads();
363 DivertWhilePlaying();
364 WaitForPlay();
365 SwitchDevice(true);
366 ReadDivertedAudioData();
367 RevertWhilePlaying();
368 WaitForPlay();
369 WaitForReads();
370 Close();
373 TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
374 Create(kSamplesPerPacket);
375 WaitForCreate();
376 Play();
377 WaitForPlay();
378 WaitForReads();
379 DivertWhilePlaying();
380 WaitForPlay();
381 ReadDivertedAudioData();
382 RevertWhilePlaying();
383 WaitForPlay();
384 WaitForReads();
385 DivertWhilePlaying();
386 WaitForPlay();
387 ReadDivertedAudioData();
388 RevertWhilePlaying();
389 WaitForPlay();
390 WaitForReads();
391 Close();
394 TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
395 Create(kSamplesPerPacket);
396 WaitForCreate();
397 DivertWillEventuallyBeTwicePlayed();
398 Play();
399 WaitForPlay();
400 ReadDivertedAudioData();
401 Pause();
402 WaitForPause();
403 Play();
404 WaitForPlay();
405 ReadDivertedAudioData();
406 RevertWhilePlaying();
407 WaitForPlay();
408 WaitForReads();
409 Close();
412 TEST_F(AudioOutputControllerTest, DivertRevertClose) {
413 Create(kSamplesPerPacket);
414 WaitForCreate();
415 DivertNeverPlaying();
416 RevertWasNotPlaying();
417 Close();
420 } // namespace media