Home | History | Annotate | Download | only in cras
      1 // Copyright 2013 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.
      4 
      5 #include <string>
      6 
      7 #include "base/synchronization/waitable_event.h"
      8 #include "base/test/test_timeouts.h"
      9 #include "base/time/time.h"
     10 #include "media/audio/cras/audio_manager_cras.h"
     11 #include "media/audio/cras/cras_unified.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using testing::_;
     16 using testing::DoAll;
     17 using testing::InvokeWithoutArgs;
     18 using testing::Return;
     19 using testing::SetArgumentPointee;
     20 using testing::StrictMock;
     21 
     22 namespace media {
     23 
     24 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
     25  public:
     26   MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus,
     27                                AudioBuffersState buffers_state));
     28   MOCK_METHOD3(OnMoreIOData, int(AudioBus* source,
     29                                  AudioBus* dest,
     30                                  AudioBuffersState buffers_state));
     31   MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
     32 };
     33 
     34 class MockAudioManagerCras : public AudioManagerCras {
     35  public:
     36   MOCK_METHOD0(Init, void());
     37   MOCK_METHOD0(HasAudioOutputDevices, bool());
     38   MOCK_METHOD0(HasAudioInputDevices, bool());
     39   MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*(
     40       const AudioParameters& params));
     41   MOCK_METHOD1(MakeLowLatencyOutputStream, AudioOutputStream*(
     42       const AudioParameters& params));
     43   MOCK_METHOD2(MakeLinearOutputStream, AudioInputStream*(
     44       const AudioParameters& params, const std::string& device_id));
     45   MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*(
     46       const AudioParameters& params, const std::string& device_id));
     47 
     48   // We need to override this function in order to skip the checking the number
     49   // of active output streams. It is because the number of active streams
     50   // is managed inside MakeAudioOutputStream, and we don't use
     51   // MakeAudioOutputStream to create the stream in the tests.
     52   virtual void ReleaseOutputStream(AudioOutputStream* stream) OVERRIDE {
     53     DCHECK(stream);
     54     delete stream;
     55   }
     56 };
     57 
     58 class CrasUnifiedStreamTest : public testing::Test {
     59  protected:
     60   CrasUnifiedStreamTest() {
     61     mock_manager_.reset(new StrictMock<MockAudioManagerCras>());
     62   }
     63 
     64   virtual ~CrasUnifiedStreamTest() {
     65   }
     66 
     67   CrasUnifiedStream* CreateStream(ChannelLayout layout) {
     68     return CreateStream(layout, kTestFramesPerPacket);
     69   }
     70 
     71   CrasUnifiedStream* CreateStream(ChannelLayout layout,
     72                                  int32 samples_per_packet) {
     73     AudioParameters params(kTestFormat, layout, kTestSampleRate,
     74                            kTestBitsPerSample, samples_per_packet);
     75     return new CrasUnifiedStream(params, mock_manager_.get());
     76   }
     77 
     78   MockAudioManagerCras& mock_manager() {
     79     return *(mock_manager_.get());
     80   }
     81 
     82   static const ChannelLayout kTestChannelLayout;
     83   static const int kTestSampleRate;
     84   static const int kTestBitsPerSample;
     85   static const AudioParameters::Format kTestFormat;
     86   static const uint32 kTestFramesPerPacket;
     87 
     88   scoped_ptr<StrictMock<MockAudioManagerCras> > mock_manager_;
     89 
     90  private:
     91   DISALLOW_COPY_AND_ASSIGN(CrasUnifiedStreamTest);
     92 };
     93 
     94 const ChannelLayout CrasUnifiedStreamTest::kTestChannelLayout =
     95     CHANNEL_LAYOUT_STEREO;
     96 const int CrasUnifiedStreamTest::kTestSampleRate =
     97     AudioParameters::kAudioCDSampleRate;
     98 const int CrasUnifiedStreamTest::kTestBitsPerSample = 16;
     99 const AudioParameters::Format CrasUnifiedStreamTest::kTestFormat =
    100     AudioParameters::AUDIO_PCM_LINEAR;
    101 const uint32 CrasUnifiedStreamTest::kTestFramesPerPacket = 1000;
    102 
    103 TEST_F(CrasUnifiedStreamTest, ConstructedState) {
    104   // Should support mono.
    105   CrasUnifiedStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
    106   test_stream->Close();
    107 
    108   // Should support stereo.
    109   test_stream = CreateStream(CHANNEL_LAYOUT_SURROUND);
    110   EXPECT_TRUE(test_stream->Open());
    111   test_stream->Close();
    112 
    113   // Bad bits per sample.
    114   AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout,
    115                                  kTestSampleRate, kTestBitsPerSample - 1,
    116                                  kTestFramesPerPacket);
    117   test_stream = new CrasUnifiedStream(bad_bps_params, mock_manager_.get());
    118   EXPECT_FALSE(test_stream->Open());
    119   test_stream->Close();
    120 
    121   // Bad sample rate.
    122   AudioParameters bad_rate_params(kTestFormat, kTestChannelLayout,
    123                                   0, kTestBitsPerSample, kTestFramesPerPacket);
    124   test_stream = new CrasUnifiedStream(bad_rate_params, mock_manager_.get());
    125   EXPECT_FALSE(test_stream->Open());
    126   test_stream->Close();
    127 
    128   // Check that Mono works too.
    129   test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
    130   ASSERT_TRUE(test_stream->Open());
    131   test_stream->Close();
    132 }
    133 
    134 TEST_F(CrasUnifiedStreamTest, RenderFrames) {
    135   CrasUnifiedStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
    136   MockAudioSourceCallback mock_callback;
    137 
    138   ASSERT_TRUE(test_stream->Open());
    139 
    140   base::WaitableEvent event(false, false);
    141 
    142   EXPECT_CALL(mock_callback, OnMoreData(_, _))
    143       .WillRepeatedly(DoAll(
    144           InvokeWithoutArgs(&event, &base::WaitableEvent::Signal),
    145                             Return(kTestFramesPerPacket)));
    146 
    147   test_stream->Start(&mock_callback);
    148 
    149   // Wait for samples to be captured.
    150   EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout()));
    151 
    152   test_stream->Stop();
    153 
    154   test_stream->Close();
    155 }
    156 
    157 }  // namespace media
    158