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