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