Home | History | Annotate | Download | only in audio
      1 // Copyright (c) 2012 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 "base/basictypes.h"
      6 #include "base/bind.h"
      7 #include "base/message_loop/message_loop.h"
      8 #include "base/synchronization/waitable_event.h"
      9 #include "base/test/test_timeouts.h"
     10 #include "media/audio/audio_input_controller.h"
     11 #include "media/audio/audio_manager_base.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using ::testing::_;
     16 using ::testing::AtLeast;
     17 using ::testing::Exactly;
     18 using ::testing::InvokeWithoutArgs;
     19 using ::testing::NotNull;
     20 
     21 namespace media {
     22 
     23 static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
     24 static const int kBitsPerSample = 16;
     25 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
     26 static const int kSamplesPerPacket = kSampleRate / 10;
     27 
     28 // Posts base::MessageLoop::QuitClosure() on specified message loop.
     29 ACTION_P(QuitMessageLoop, loop_or_proxy) {
     30   loop_or_proxy->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
     31 }
     32 
     33 // Posts base::MessageLoop::QuitClosure() on specified message loop after a
     34 // certain number of calls given by |limit|.
     35 ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop_or_proxy) {
     36   if (++*count >= limit) {
     37     loop_or_proxy->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
     38   }
     39 }
     40 
     41 // Closes AudioOutputController synchronously.
     42 static void CloseAudioController(AudioInputController* controller) {
     43   controller->Close(base::MessageLoop::QuitClosure());
     44   base::MessageLoop::current()->Run();
     45 }
     46 
     47 class MockAudioInputControllerEventHandler
     48     : public AudioInputController::EventHandler {
     49  public:
     50   MockAudioInputControllerEventHandler() {}
     51 
     52   MOCK_METHOD1(OnCreated, void(AudioInputController* controller));
     53   MOCK_METHOD1(OnRecording, void(AudioInputController* controller));
     54   MOCK_METHOD2(OnError, void(AudioInputController* controller,
     55                              AudioInputController::ErrorCode error_code));
     56   MOCK_METHOD2(OnData,
     57                void(AudioInputController* controller, const AudioBus* data));
     58   MOCK_METHOD2(OnLog,
     59                void(AudioInputController* controller,
     60                     const std::string& message));
     61 
     62  private:
     63   DISALLOW_COPY_AND_ASSIGN(MockAudioInputControllerEventHandler);
     64 };
     65 
     66 // Test fixture.
     67 class AudioInputControllerTest : public testing::Test {
     68  public:
     69   AudioInputControllerTest() {}
     70   virtual ~AudioInputControllerTest() {}
     71 
     72  protected:
     73   base::MessageLoop message_loop_;
     74 
     75  private:
     76   DISALLOW_COPY_AND_ASSIGN(AudioInputControllerTest);
     77 };
     78 
     79 // Test AudioInputController for create and close without recording audio.
     80 TEST_F(AudioInputControllerTest, CreateAndClose) {
     81   MockAudioInputControllerEventHandler event_handler;
     82 
     83   // OnCreated() will be posted once.
     84   EXPECT_CALL(event_handler, OnCreated(NotNull()))
     85       .WillOnce(QuitMessageLoop(&message_loop_));
     86 
     87   scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
     88   AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
     89                          kSampleRate, kBitsPerSample, kSamplesPerPacket);
     90 
     91   scoped_refptr<AudioInputController> controller =
     92       AudioInputController::Create(audio_manager.get(),
     93                                    &event_handler,
     94                                    params,
     95                                    AudioManagerBase::kDefaultDeviceId,
     96                                    NULL);
     97   ASSERT_TRUE(controller.get());
     98 
     99   // Wait for OnCreated() to fire.
    100   message_loop_.Run();
    101 
    102   // Close the AudioInputController synchronously.
    103   CloseAudioController(controller.get());
    104 }
    105 
    106 // Test a normal call sequence of create, record and close.
    107 TEST_F(AudioInputControllerTest, RecordAndClose) {
    108   MockAudioInputControllerEventHandler event_handler;
    109   int count = 0;
    110 
    111   // OnCreated() will be called once.
    112   EXPECT_CALL(event_handler, OnCreated(NotNull()))
    113       .Times(Exactly(1));
    114 
    115   // OnRecording() will be called only once.
    116   EXPECT_CALL(event_handler, OnRecording(NotNull()))
    117       .Times(Exactly(1));
    118 
    119   // OnData() shall be called ten times.
    120   EXPECT_CALL(event_handler, OnData(NotNull(), NotNull()))
    121       .Times(AtLeast(10))
    122       .WillRepeatedly(CheckCountAndPostQuitTask(
    123           &count, 10, message_loop_.message_loop_proxy()));
    124 
    125   scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
    126   AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
    127                          kSampleRate, kBitsPerSample, kSamplesPerPacket);
    128 
    129   // Creating the AudioInputController should render an OnCreated() call.
    130   scoped_refptr<AudioInputController> controller =
    131       AudioInputController::Create(audio_manager.get(),
    132                                    &event_handler,
    133                                    params,
    134                                    AudioManagerBase::kDefaultDeviceId,
    135                                    NULL);
    136   ASSERT_TRUE(controller.get());
    137 
    138   // Start recording and trigger one OnRecording() call.
    139   controller->Record();
    140 
    141   // Record and wait until ten OnData() callbacks are received.
    142   message_loop_.Run();
    143 
    144   // Close the AudioInputController synchronously.
    145   CloseAudioController(controller.get());
    146 }
    147 
    148 // Test that the AudioInputController reports an error when the input stream
    149 // stops. This can happen when the underlying audio layer stops feeding data as
    150 // a result of a removed microphone device.
    151 // Disabled due to crbug.com/357569 and crbug.com/357501.
    152 // TODO(henrika): Remove the test when the timer workaround has been removed.
    153 TEST_F(AudioInputControllerTest, DISABLED_RecordAndError) {
    154   MockAudioInputControllerEventHandler event_handler;
    155   int count = 0;
    156 
    157   // OnCreated() will be called once.
    158   EXPECT_CALL(event_handler, OnCreated(NotNull()))
    159       .Times(Exactly(1));
    160 
    161   // OnRecording() will be called only once.
    162   EXPECT_CALL(event_handler, OnRecording(NotNull()))
    163       .Times(Exactly(1));
    164 
    165   // OnData() shall be called ten times.
    166   EXPECT_CALL(event_handler, OnData(NotNull(), NotNull()))
    167       .Times(AtLeast(10))
    168       .WillRepeatedly(CheckCountAndPostQuitTask(
    169           &count, 10, message_loop_.message_loop_proxy()));
    170 
    171   // OnError() will be called after the data stream stops while the
    172   // controller is in a recording state.
    173   EXPECT_CALL(event_handler, OnError(NotNull(),
    174                                      AudioInputController::NO_DATA_ERROR))
    175       .Times(Exactly(1))
    176       .WillOnce(QuitMessageLoop(&message_loop_));
    177 
    178   scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
    179   AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
    180                          kSampleRate, kBitsPerSample, kSamplesPerPacket);
    181 
    182   // Creating the AudioInputController should render an OnCreated() call.
    183   scoped_refptr<AudioInputController> controller =
    184       AudioInputController::Create(audio_manager.get(),
    185                                    &event_handler,
    186                                    params,
    187                                    AudioManagerBase::kDefaultDeviceId,
    188                                    NULL);
    189   ASSERT_TRUE(controller.get());
    190 
    191   // Start recording and trigger one OnRecording() call.
    192   controller->Record();
    193 
    194   // Record and wait until ten OnData() callbacks are received.
    195   message_loop_.Run();
    196 
    197   // Stop the stream and verify that OnError() is posted.
    198   AudioInputStream* stream = controller->stream_for_testing();
    199   stream->Stop();
    200   message_loop_.Run();
    201 
    202   // Close the AudioInputController synchronously.
    203   CloseAudioController(controller.get());
    204 }
    205 
    206 // Test that AudioInputController rejects insanely large packet sizes.
    207 TEST_F(AudioInputControllerTest, SamplesPerPacketTooLarge) {
    208   // Create an audio device with a very large packet size.
    209   MockAudioInputControllerEventHandler event_handler;
    210 
    211   // OnCreated() shall not be called in this test.
    212   EXPECT_CALL(event_handler, OnCreated(NotNull()))
    213     .Times(Exactly(0));
    214 
    215   scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
    216   AudioParameters params(AudioParameters::AUDIO_FAKE,
    217                          kChannelLayout,
    218                          kSampleRate,
    219                          kBitsPerSample,
    220                          kSamplesPerPacket * 1000);
    221   scoped_refptr<AudioInputController> controller =
    222       AudioInputController::Create(audio_manager.get(),
    223                                    &event_handler,
    224                                    params,
    225                                    AudioManagerBase::kDefaultDeviceId,
    226                                    NULL);
    227   ASSERT_FALSE(controller.get());
    228 }
    229 
    230 // Test calling AudioInputController::Close multiple times.
    231 TEST_F(AudioInputControllerTest, CloseTwice) {
    232   MockAudioInputControllerEventHandler event_handler;
    233 
    234   // OnRecording() will be called only once.
    235   EXPECT_CALL(event_handler, OnCreated(NotNull()));
    236 
    237   // OnRecording() will be called only once.
    238   EXPECT_CALL(event_handler, OnRecording(NotNull()))
    239       .Times(Exactly(1));
    240 
    241   scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
    242   AudioParameters params(AudioParameters::AUDIO_FAKE,
    243                          kChannelLayout,
    244                          kSampleRate,
    245                          kBitsPerSample,
    246                          kSamplesPerPacket);
    247   scoped_refptr<AudioInputController> controller =
    248       AudioInputController::Create(audio_manager.get(),
    249                                    &event_handler,
    250                                    params,
    251                                    AudioManagerBase::kDefaultDeviceId,
    252                                    NULL);
    253   ASSERT_TRUE(controller.get());
    254 
    255   controller->Record();
    256 
    257   controller->Close(base::MessageLoop::QuitClosure());
    258   base::MessageLoop::current()->Run();
    259 
    260   controller->Close(base::MessageLoop::QuitClosure());
    261   base::MessageLoop::current()->Run();
    262 }
    263 
    264 }  // namespace media
    265