summaryrefslogtreecommitdiffstats
path: root/media/audio/audio_output_proxy_unittest.cc
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-24 22:22:46 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-24 22:22:46 +0000
commite667807890b931d41a4529165bedef5203382bbd (patch)
tree1ac7430f2e9cd9d6000fdc8fbff28d17c42ad3c6 /media/audio/audio_output_proxy_unittest.cc
parentc78a2fa648c28bd7874df7b65962975bea027ea0 (diff)
downloadchromium_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.cc353
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();
+}