summaryrefslogtreecommitdiffstats
path: root/media/audio/linux/cras_output_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'media/audio/linux/cras_output_unittest.cc')
-rw-r--r--media/audio/linux/cras_output_unittest.cc216
1 files changed, 216 insertions, 0 deletions
diff --git a/media/audio/linux/cras_output_unittest.cc b/media/audio/linux/cras_output_unittest.cc
new file mode 100644
index 0000000..7f6e06b
--- /dev/null
+++ b/media/audio/linux/cras_output_unittest.cc
@@ -0,0 +1,216 @@
+// Copyright (c) 2012 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 "media/audio/linux/audio_manager_linux.h"
+#include "media/audio/linux/cras_output.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Return;
+using testing::SetArgumentPointee;
+using testing::StrictMock;
+
+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 MockAudioManagerLinux : public AudioManagerLinux {
+ public:
+ MOCK_METHOD0(Init, void());
+ MOCK_METHOD0(HasAudioOutputDevices, bool());
+ MOCK_METHOD0(HasAudioInputDevices, bool());
+ MOCK_METHOD0(MuteAll, void());
+ MOCK_METHOD0(UnMuteAll, void());
+ MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*(
+ const AudioParameters& params));
+ MOCK_METHOD1(MakeLowLatencyOutputStream, AudioOutputStream*(
+ const AudioParameters& params));
+ MOCK_METHOD2(MakeLinearOutputStream, AudioInputStream*(
+ const AudioParameters& params, const std::string& device_id));
+ MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*(
+ const AudioParameters& params, const std::string& device_id));
+
+ // We need to override this function in order to skip the checking the number
+ // of active output streams. It is because the number of active streams
+ // is managed inside MakeAudioOutputStream, and we don't use
+ // MakeAudioOutputStream to create the stream in the tests.
+ virtual void ReleaseOutputStream(AudioOutputStream* stream) OVERRIDE {
+ DCHECK(stream);
+ delete stream;
+ }
+
+ // We don't mock this method since all tests will do the same thing
+ // and use the current message loop.
+ virtual scoped_refptr<base::MessageLoopProxy> GetMessageLoop() OVERRIDE {
+ return MessageLoop::current()->message_loop_proxy();
+ }
+};
+
+class CrasOutputStreamTest : public testing::Test {
+ protected:
+ CrasOutputStreamTest() {
+ mock_manager_.reset(new StrictMock<MockAudioManagerLinux>());
+ }
+
+ virtual ~CrasOutputStreamTest() {
+ }
+
+ CrasOutputStream* CreateStream(ChannelLayout layout) {
+ return CreateStream(layout, kTestFramesPerPacket);
+ }
+
+ CrasOutputStream* CreateStream(ChannelLayout layout,
+ int32 samples_per_packet) {
+ AudioParameters params(kTestFormat, layout, kTestSampleRate,
+ kTestBitsPerSample, samples_per_packet);
+ return new CrasOutputStream(params,
+ mock_manager_.get());
+ }
+
+ MockAudioManagerLinux& mock_manager() {
+ return *(mock_manager_.get());
+ }
+
+ static const ChannelLayout kTestChannelLayout;
+ static const int kTestSampleRate;
+ static const int kTestBitsPerSample;
+ static const int kTestBytesPerFrame;
+ static const AudioParameters::Format kTestFormat;
+ static const uint32 kTestFramesPerPacket;
+ static const uint32 kTestPacketSize;
+ static struct cras_audio_format* const kFakeAudioFormat;
+ static struct cras_stream_params* const kFakeStreamParams;
+ static struct cras_client* const kFakeClient;
+
+ scoped_ptr<StrictMock<MockAudioManagerLinux> > mock_manager_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CrasOutputStreamTest);
+};
+
+const ChannelLayout CrasOutputStreamTest::kTestChannelLayout =
+ CHANNEL_LAYOUT_STEREO;
+const int CrasOutputStreamTest::kTestSampleRate =
+ AudioParameters::kAudioCDSampleRate;
+const int CrasOutputStreamTest::kTestBitsPerSample = 16;
+const int CrasOutputStreamTest::kTestBytesPerFrame =
+ CrasOutputStreamTest::kTestBitsPerSample / 8 *
+ ChannelLayoutToChannelCount(CrasOutputStreamTest::kTestChannelLayout);
+const AudioParameters::Format CrasOutputStreamTest::kTestFormat =
+ AudioParameters::AUDIO_PCM_LINEAR;
+const uint32 CrasOutputStreamTest::kTestFramesPerPacket = 1000;
+const uint32 CrasOutputStreamTest::kTestPacketSize =
+ CrasOutputStreamTest::kTestFramesPerPacket *
+ CrasOutputStreamTest::kTestBytesPerFrame;
+struct cras_audio_format* const CrasOutputStreamTest::kFakeAudioFormat =
+ reinterpret_cast<struct cras_audio_format*>(1);
+struct cras_stream_params* const CrasOutputStreamTest::kFakeStreamParams =
+ reinterpret_cast<struct cras_stream_params*>(1);
+struct cras_client* const CrasOutputStreamTest::kFakeClient =
+ reinterpret_cast<struct cras_client*>(1);
+
+TEST_F(CrasOutputStreamTest, ConstructedState) {
+ // Should support mono.
+ CrasOutputStream *test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
+ EXPECT_EQ(CrasOutputStream::kCreated, test_stream->state());
+ test_stream->Close();
+
+ // Should support stereo.
+ test_stream = CreateStream(CHANNEL_LAYOUT_SURROUND);
+ EXPECT_EQ(CrasOutputStream::kCreated, test_stream->state());
+ test_stream->Close();
+
+ // Bad bits per sample.
+ AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout,
+ kTestSampleRate, kTestBitsPerSample - 1,
+ kTestFramesPerPacket);
+ test_stream = new CrasOutputStream(bad_bps_params, mock_manager_.get());
+ EXPECT_EQ(CrasOutputStream::kInError, test_stream->state());
+ test_stream->Close();
+
+ // Bad format.
+ AudioParameters bad_format_params(AudioParameters::AUDIO_LAST_FORMAT,
+ kTestChannelLayout, kTestSampleRate,
+ kTestBitsPerSample, kTestFramesPerPacket);
+ test_stream = new CrasOutputStream(bad_format_params, mock_manager_.get());
+ EXPECT_EQ(CrasOutputStream::kInError, test_stream->state());
+ test_stream->Close();
+
+ // Bad sample rate.
+ AudioParameters bad_rate_params(kTestFormat, kTestChannelLayout,
+ 0, kTestBitsPerSample, kTestFramesPerPacket);
+ test_stream = new CrasOutputStream(bad_rate_params, mock_manager_.get());
+ EXPECT_EQ(CrasOutputStream::kInError, test_stream->state());
+ test_stream->Close();
+}
+
+TEST_F(CrasOutputStreamTest, OpenClose) {
+ CrasOutputStream *test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
+ // Open the stream.
+ ASSERT_TRUE(test_stream->Open());
+ EXPECT_EQ(CrasOutputStream::kIsOpened, test_stream->state());
+
+ // Close the stream.
+ test_stream->Close();
+}
+
+TEST_F(CrasOutputStreamTest, StartFailBeforeOpen) {
+ CrasOutputStream *test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
+ MockAudioSourceCallback mock_callback;
+
+ test_stream->Start(&mock_callback);
+ EXPECT_EQ(CrasOutputStream::kInError, test_stream->state());
+}
+
+TEST_F(CrasOutputStreamTest, StartStop) {
+ CrasOutputStream *test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
+ MockAudioSourceCallback mock_callback;
+
+ // Open the stream.
+ ASSERT_TRUE(test_stream->Open());
+ EXPECT_EQ(CrasOutputStream::kIsOpened, test_stream->state());
+
+ // Start.
+ test_stream->Start(&mock_callback);
+ EXPECT_EQ(CrasOutputStream::kIsPlaying, test_stream->state());
+
+ // Stop.
+ test_stream->Stop();
+ EXPECT_EQ(CrasOutputStream::kIsStopped, test_stream->state());
+
+ // Close the stream.
+ test_stream->Close();
+}
+
+TEST_F(CrasOutputStreamTest, RenderFrames) {
+ CrasOutputStream *test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
+ MockAudioSourceCallback mock_callback;
+ const uint32 amount_rendered_return = 2048;
+
+ // Open the stream.
+ ASSERT_TRUE(test_stream->Open());
+ EXPECT_EQ(CrasOutputStream::kIsOpened, test_stream->state());
+
+ // Render Callback.
+ EXPECT_CALL(mock_callback, OnMoreData(test_stream, _,
+ kTestFramesPerPacket * kTestBytesPerFrame, _))
+ .WillRepeatedly(Return(amount_rendered_return));
+
+ // Start.
+ test_stream->Start(&mock_callback);
+ EXPECT_EQ(CrasOutputStream::kIsPlaying, test_stream->state());
+
+ // Stop.
+ test_stream->Stop();
+ EXPECT_EQ(CrasOutputStream::kIsStopped, test_stream->state());
+
+ // Close the stream.
+ test_stream->Close();
+}