| Index: media/audio/audio_output_proxy_unittest.cc
|
| diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5926dec6f62f959003b74491d69531989077cd3f
|
| --- /dev/null
|
| +++ b/media/audio/audio_output_proxy_unittest.cc
|
| @@ -0,0 +1,347 @@
|
| +// 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 = 100 * 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_METHOD1(MakeAudioOutputStream, AudioOutputStream*(
|
| + AudioParameters params));
|
| + MOCK_METHOD1(MakeAudioInputStream, AudioInputStream*(
|
| + AudioParameters params));
|
| + MOCK_METHOD0(MuteAll, void());
|
| + MOCK_METHOD0(UnMuteAll, void());
|
| + MOCK_METHOD1(MakeAudioOutputStreamProxy, AudioOutputStream*(
|
| + AudioParameters params));
|
| + 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_));
|
| + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, 2, 44100,
|
| + 16, 1024);
|
| + dispatcher_ = new AudioOutputDispatcher(&manager_, params);
|
| + dispatcher_->set_close_delay(
|
| + base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
|
| + }
|
| +
|
| + virtual void TearDown() {
|
| + // All paused proxies should have been destroyed at this point.
|
| + EXPECT_EQ(0, dispatcher_->paused_proxies_);
|
| + }
|
| +
|
| + 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);
|
| + 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.
|
| + PlatformThread::Sleep(kTestCloseDelayMs);
|
| + 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;
|
| +
|
| + dispatcher_->set_close_delay(
|
| + base::TimeDelta::FromMilliseconds(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;
|
| +
|
| + dispatcher_->set_close_delay(
|
| + base::TimeDelta::FromMilliseconds(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();
|
| +}
|
|
|