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