diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-24 22:22:46 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-24 22:22:46 +0000 |
commit | e667807890b931d41a4529165bedef5203382bbd (patch) | |
tree | 1ac7430f2e9cd9d6000fdc8fbff28d17c42ad3c6 /media/audio/audio_output_proxy_unittest.cc | |
parent | c78a2fa648c28bd7874df7b65962975bea027ea0 (diff) | |
download | chromium_src-e667807890b931d41a4529165bedef5203382bbd.zip chromium_src-e667807890b931d41a4529165bedef5203382bbd.tar.gz chromium_src-e667807890b931d41a4529165bedef5203382bbd.tar.bz2 |
Implemented AudioOutputProxy.
AudioOutputProxy implements AudioOutputStream interface, but opens
audio device only when audio is playing.
BUG=39825
TEST=Unittests.
Review URL: http://codereview.chromium.org/5158003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67327 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/audio_output_proxy_unittest.cc')
-rw-r--r-- | media/audio/audio_output_proxy_unittest.cc | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc new file mode 100644 index 0000000..efc164c --- /dev/null +++ b/media/audio/audio_output_proxy_unittest.cc @@ -0,0 +1,353 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/message_loop.h" +#include "base/platform_thread.h" +#include "media/audio/audio_output_dispatcher.h" +#include "media/audio/audio_output_proxy.h" +#include "media/audio/audio_manager.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::Mock; +using ::testing::Return; + +namespace { +const int kTestCloseDelayMs = 100; + +// Used in the test where we don't want a stream to be closed unexpectedly. +const int kTestBigCloseDelayMs = 1000 * 1000; +} // namespace + +class MockAudioOutputStream : public AudioOutputStream { + public: + MockAudioOutputStream() {} + + MOCK_METHOD0(Open, bool()); + MOCK_METHOD1(Start, void(AudioSourceCallback* callback)); + MOCK_METHOD0(Stop, void()); + MOCK_METHOD1(SetVolume, void(double volume)); + MOCK_METHOD1(GetVolume, void(double* volume)); + MOCK_METHOD0(Close, void()); +}; + +class MockAudioManager : public AudioManager { + public: + MockAudioManager() { }; + + MOCK_METHOD0(Init, void()); + MOCK_METHOD0(HasAudioOutputDevices, bool()); + MOCK_METHOD0(HasAudioInputDevices, bool()); + MOCK_METHOD0(GetAudioInputDeviceModel, string16()); + MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*( + AudioParameters params)); + MOCK_METHOD1(MakeAudioOutputStreamProxy, AudioOutputStream*( + const AudioParameters& params)); + MOCK_METHOD1(MakeAudioInputStream, AudioInputStream*( + AudioParameters params)); + MOCK_METHOD0(MuteAll, void()); + MOCK_METHOD0(UnMuteAll, void()); + MOCK_METHOD0(GetMessageLoop, MessageLoop*()); +}; + +class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { + public: + MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, + uint8* dest, uint32 max_size, + AudioBuffersState buffers_state)); + MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); +}; + +class AudioOutputProxyTest : public testing::Test { + protected: + virtual void SetUp() { + EXPECT_CALL(manager_, GetMessageLoop()) + .WillRepeatedly(Return(&message_loop_)); + InitDispatcher(kTestCloseDelayMs); + } + + virtual void TearDown() { + // All paused proxies should have been closed at this point. + EXPECT_EQ(0u, dispatcher_->paused_proxies_); + + // This is necessary to free all proxy objects that have been + // closed by the test. + message_loop_.RunAllPending(); + } + + void InitDispatcher(int close_delay_ms) { + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, 2, 44100, + 16, 1024); + dispatcher_ = new AudioOutputDispatcher(&manager_, params, close_delay_ms); + } + + MessageLoop message_loop_; + scoped_refptr<AudioOutputDispatcher> dispatcher_; + MockAudioManager manager_; + MockAudioSourceCallback callback_; +}; + +TEST_F(AudioOutputProxyTest, CreateAndClose) { + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); + proxy->Close(); +} + +TEST_F(AudioOutputProxyTest, OpenAndClose) { + MockAudioOutputStream stream; + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream)); + EXPECT_CALL(stream, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream, Close()) + .Times(1); + + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); + EXPECT_TRUE(proxy->Open()); + proxy->Close(); +} + +// Create a stream, and verify that it is closed after kTestCloseDelayMs. +// if it doesn't start playing. +TEST_F(AudioOutputProxyTest, CreateAndWait) { + MockAudioOutputStream stream; + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream)); + EXPECT_CALL(stream, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream, Close()) + .Times(1); + + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); + EXPECT_TRUE(proxy->Open()); + + // Simulate a delay. + PlatformThread::Sleep(kTestCloseDelayMs * 2); + message_loop_.RunAllPending(); + + // Verify expectation before calling Close(). + Mock::VerifyAndClear(&stream); + + proxy->Close(); +} + +// Create a stream, and then calls Start() and Stop(). +TEST_F(AudioOutputProxyTest, StartAndStop) { + MockAudioOutputStream stream; + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream)); + EXPECT_CALL(stream, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream, Start(_)) + .Times(1); + EXPECT_CALL(stream, SetVolume(_)) + .Times(1); + EXPECT_CALL(stream, Stop()) + .Times(1); + EXPECT_CALL(stream, Close()) + .Times(1); + + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); + EXPECT_TRUE(proxy->Open()); + + proxy->Start(&callback_); + proxy->Stop(); + + proxy->Close(); +} + +// Verify that the stream is closed after Stop is called. +TEST_F(AudioOutputProxyTest, CloseAfterStop) { + MockAudioOutputStream stream; + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream)); + EXPECT_CALL(stream, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream, Start(_)) + .Times(1); + EXPECT_CALL(stream, SetVolume(_)) + .Times(1); + EXPECT_CALL(stream, Stop()) + .Times(1); + EXPECT_CALL(stream, Close()) + .Times(1); + + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); + EXPECT_TRUE(proxy->Open()); + + proxy->Start(&callback_); + proxy->Stop(); + + // Simulate a delay. + message_loop_.RunAllPending(); + PlatformThread::Sleep(kTestCloseDelayMs * 10); + message_loop_.RunAllPending(); + + // Verify expectation before calling Close(). + Mock::VerifyAndClear(&stream); + + proxy->Close(); +} + +// Create two streams, but don't start them. Only one device must be open. +TEST_F(AudioOutputProxyTest, TwoStreams) { + MockAudioOutputStream stream; + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream)); + EXPECT_CALL(stream, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream, Close()) + .Times(1); + + AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); + AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); + EXPECT_TRUE(proxy1->Open()); + EXPECT_TRUE(proxy2->Open()); + proxy1->Close(); + proxy2->Close(); +} + +// Two streams: verify that second stream is allocated when the first +// starts playing. +TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) { + MockAudioOutputStream stream1; + MockAudioOutputStream stream2; + + InitDispatcher(kTestBigCloseDelayMs); + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream1)) + .WillOnce(Return(&stream2)); + + EXPECT_CALL(stream1, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream1, Start(_)) + .Times(1); + EXPECT_CALL(stream1, SetVolume(_)) + .Times(1); + EXPECT_CALL(stream1, Stop()) + .Times(1); + EXPECT_CALL(stream1, Close()) + .Times(1); + + EXPECT_CALL(stream2, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream2, Close()) + .Times(1); + + AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); + AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); + EXPECT_TRUE(proxy1->Open()); + EXPECT_TRUE(proxy2->Open()); + + proxy1->Start(&callback_); + message_loop_.RunAllPending(); + proxy1->Stop(); + + proxy1->Close(); + proxy2->Close(); +} + +// Two streams, both are playing. Dispatcher should not open a third stream. +TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { + MockAudioOutputStream stream1; + MockAudioOutputStream stream2; + + InitDispatcher(kTestBigCloseDelayMs); + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream1)) + .WillOnce(Return(&stream2)); + + EXPECT_CALL(stream1, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream1, Start(_)) + .Times(1); + EXPECT_CALL(stream1, SetVolume(_)) + .Times(1); + EXPECT_CALL(stream1, Stop()) + .Times(1); + EXPECT_CALL(stream1, Close()) + .Times(1); + + EXPECT_CALL(stream2, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream2, Start(_)) + .Times(1); + EXPECT_CALL(stream2, SetVolume(_)) + .Times(1); + EXPECT_CALL(stream2, Stop()) + .Times(1); + EXPECT_CALL(stream2, Close()) + .Times(1); + + AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_); + AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_); + EXPECT_TRUE(proxy1->Open()); + EXPECT_TRUE(proxy2->Open()); + + proxy1->Start(&callback_); + proxy2->Start(&callback_); + proxy1->Stop(); + proxy2->Stop(); + + proxy1->Close(); + proxy2->Close(); +} + +// Open() method failed. +TEST_F(AudioOutputProxyTest, OpenFailed) { + MockAudioOutputStream stream; + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream)); + EXPECT_CALL(stream, Open()) + .WillOnce(Return(false)); + EXPECT_CALL(stream, Close()) + .Times(1); + + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); + EXPECT_FALSE(proxy->Open()); + proxy->Close(); +} + +// Start() method failed. +TEST_F(AudioOutputProxyTest, StartFailed) { + MockAudioOutputStream stream; + + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(&stream)); + EXPECT_CALL(stream, Open()) + .WillOnce(Return(true)); + EXPECT_CALL(stream, Close()) + .Times(1); + + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_); + EXPECT_TRUE(proxy->Open()); + + // Simulate a delay. + PlatformThread::Sleep(kTestCloseDelayMs); + message_loop_.RunAllPending(); + + // Verify expectation before calling Close(). + Mock::VerifyAndClear(&stream); + + // |stream| is closed at this point. Start() should reopen it again. + EXPECT_CALL(manager_, MakeAudioOutputStream(_)) + .WillOnce(Return(reinterpret_cast<AudioOutputStream*>(NULL))); + + EXPECT_CALL(callback_, OnError(_, _)) + .Times(1); + + proxy->Start(&callback_); + + Mock::VerifyAndClear(&callback_); + + proxy->Close(); +} |