#include "base/basictypes.h"
#include "base/bind.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "media/audio/audio_input_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Exactly;
using ::testing::InvokeWithoutArgs;
using ::testing::NotNull;
namespace media {
static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
static const int kBitsPerSample = 16;
static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
static const int kSamplesPerPacket = kSampleRate / 10;
ACTION_P(QuitMessageLoop, loop_or_proxy) {
loop_or_proxy->PostTask(FROM_HERE, MessageLoop::QuitClosure());
}
ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop_or_proxy) {
if (++*count >= limit) {
loop_or_proxy->PostTask(FROM_HERE, MessageLoop::QuitClosure());
}
}
static void CloseAudioController(AudioInputController* controller) {
controller->Close(MessageLoop::QuitClosure());
MessageLoop::current()->Run();
}
class MockAudioInputControllerEventHandler
: public AudioInputController::EventHandler {
public:
MockAudioInputControllerEventHandler() {}
MOCK_METHOD1(OnCreated, void(AudioInputController* controller));
MOCK_METHOD1(OnRecording, void(AudioInputController* controller));
MOCK_METHOD2(OnError, void(AudioInputController* controller, int error_code));
MOCK_METHOD3(OnData, void(AudioInputController* controller,
const uint8* data, uint32 size));
private:
DISALLOW_COPY_AND_ASSIGN(MockAudioInputControllerEventHandler);
};
class AudioInputControllerTest : public testing::Test {
public:
AudioInputControllerTest() {}
virtual ~AudioInputControllerTest() {}
protected:
MessageLoop message_loop_;
private:
DISALLOW_COPY_AND_ASSIGN(AudioInputControllerTest);
};
TEST_F(AudioInputControllerTest, CreateAndClose) {
MockAudioInputControllerEventHandler event_handler;
EXPECT_CALL(event_handler, OnCreated(NotNull()))
.WillOnce(QuitMessageLoop(&message_loop_));
scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannelLayout,
kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioInputController> controller =
AudioInputController::Create(audio_manager.get(), &event_handler, params);
ASSERT_TRUE(controller.get());
message_loop_.Run();
CloseAudioController(controller);
}
TEST_F(AudioInputControllerTest, RecordAndClose) {
MockAudioInputControllerEventHandler event_handler;
int count = 0;
EXPECT_CALL(event_handler, OnCreated(NotNull()))
.Times(Exactly(1));
EXPECT_CALL(event_handler, OnRecording(NotNull()))
.Times(Exactly(1));
EXPECT_CALL(event_handler, OnData(NotNull(), NotNull(), _))
.Times(AtLeast(10))
.WillRepeatedly(CheckCountAndPostQuitTask(&count, 10,
message_loop_.message_loop_proxy()));
scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannelLayout,
kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioInputController> controller =
AudioInputController::Create(audio_manager.get(), &event_handler, params);
ASSERT_TRUE(controller.get());
controller->Record();
message_loop_.Run();
CloseAudioController(controller);
}
TEST_F(AudioInputControllerTest, RecordAndError) {
MockAudioInputControllerEventHandler event_handler;
int count = 0;
EXPECT_CALL(event_handler, OnCreated(NotNull()))
.Times(Exactly(1));
EXPECT_CALL(event_handler, OnRecording(NotNull()))
.Times(Exactly(1));
EXPECT_CALL(event_handler, OnData(NotNull(), NotNull(), _))
.Times(AtLeast(10))
.WillRepeatedly(CheckCountAndPostQuitTask(&count, 10,
message_loop_.message_loop_proxy()));
EXPECT_CALL(event_handler, OnError(NotNull(), 0))
.Times(Exactly(1))
.WillOnce(QuitMessageLoop(&message_loop_));
scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannelLayout,
kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioInputController> controller =
AudioInputController::Create(audio_manager.get(), &event_handler, params);
ASSERT_TRUE(controller.get());
controller->Record();
message_loop_.Run();
AudioInputStream* stream = controller->stream_for_testing();
stream->Stop();
message_loop_.Run();
CloseAudioController(controller);
}
TEST_F(AudioInputControllerTest, SamplesPerPacketTooLarge) {
MockAudioInputControllerEventHandler event_handler;
EXPECT_CALL(event_handler, OnCreated(NotNull()))
.Times(Exactly(0));
scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannelLayout,
kSampleRate, kBitsPerSample, kSamplesPerPacket * 1000);
scoped_refptr<AudioInputController> controller =
AudioInputController::Create(audio_manager.get(), &event_handler, params);
ASSERT_FALSE(controller);
}
TEST_F(AudioInputControllerTest, CloseTwice) {
MockAudioInputControllerEventHandler event_handler;
EXPECT_CALL(event_handler, OnCreated(NotNull()));
EXPECT_CALL(event_handler, OnRecording(NotNull()))
.Times(Exactly(1));
scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannelLayout,
kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioInputController> controller =
AudioInputController::Create(audio_manager.get(), &event_handler, params);
ASSERT_TRUE(controller.get());
controller->Record();
controller->Close(MessageLoop::QuitClosure());
MessageLoop::current()->Run();
controller->Close(MessageLoop::QuitClosure());
MessageLoop::current()->Run();
}
}