diff options
author | satish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-10 22:41:21 +0000 |
---|---|---|
committer | satish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-10 22:41:21 +0000 |
commit | 557d4e83efbdae5bd4fa8564f5db9b03bb9d691c (patch) | |
tree | 8c95528cf8a740ca325a933b810b09cf53b7935c /media/audio | |
parent | 3355fbdbc15c9d66cc5d74004f8cdc243afa4054 (diff) | |
download | chromium_src-557d4e83efbdae5bd4fa8564f5db9b03bb9d691c.zip chromium_src-557d4e83efbdae5bd4fa8564f5db9b03bb9d691c.tar.gz chromium_src-557d4e83efbdae5bd4fa8564f5db9b03bb9d691c.tar.bz2 |
Allow unit tests to use a mock audio input controller.
This is modelled after chrome/common/net/test_url_fetcher_factory.h. Using this mock unit tests can stub out the audio recording part and test the consumer of the audio data.
I have also added a new media_test_support target to media.gyp, this will be used in subsequent CLs for testing speech input code.
BUG=none
TEST=none, this code will get used in future unit tests
Review URL: http://codereview.chromium.org/3148003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55627 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r-- | media/audio/audio_input_controller.cc | 8 | ||||
-rw-r--r-- | media/audio/audio_input_controller.h | 30 | ||||
-rw-r--r-- | media/audio/test_audio_input_controller_factory.cc | 44 | ||||
-rw-r--r-- | media/audio/test_audio_input_controller_factory.h | 100 |
4 files changed, 179 insertions, 3 deletions
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc index f94c0042..d64fb70 100644 --- a/media/audio/audio_input_controller.cc +++ b/media/audio/audio_input_controller.cc @@ -15,6 +15,9 @@ const int kMaxSamplesPerPacket = kMaxSampleRate; namespace media { +// static +AudioInputController::Factory* AudioInputController::factory_ = NULL; + AudioInputController::AudioInputController(EventHandler* handler) : handler_(handler), stream_(NULL), @@ -40,6 +43,11 @@ scoped_refptr<AudioInputController> AudioInputController::Create( (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) return NULL; + if (factory_) { + return factory_->Create(event_handler, format, channels, sample_rate, + bits_per_sample, samples_per_packet); + } + scoped_refptr<AudioInputController> controller = new AudioInputController( event_handler); diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h index 27b3a54..a00e2bc 100644 --- a/media/audio/audio_input_controller.h +++ b/media/audio/audio_input_controller.h @@ -49,6 +49,21 @@ class AudioInputController : uint32 size) = 0; }; + // AudioInputController::Create uses the currently registered Factory to + // create the AudioInputController. Factory is intended for testing. + class Factory { + public: + virtual AudioInputController* Create(EventHandler* event_handler, + AudioManager::Format format, + int channels, + int sample_rate, + int bits_per_sample, + int samples_per_packet) = 0; + + protected: + virtual ~Factory() {} + }; + virtual ~AudioInputController(); // Factory method for creating an AudioInputController. @@ -63,8 +78,15 @@ class AudioInputController : int bits_per_sample, // Number of bits per sample. int samples_per_packet); // Size of the hardware buffer. + // Sets the factory used by the static method Create. AudioInputController + // does not take ownership of |factory|. A value of NULL results in an + // AudioInputController being created directly. +#if defined(UNIT_TEST) + static void set_factory(Factory* factory) { factory_ = factory; } +#endif + // Starts recording in this audio input stream. - void Record(); + virtual void Record(); // Closes the audio input stream and shutdown the audio input controller // thread. This method returns only after all operations are completed. This @@ -72,7 +94,7 @@ class AudioInputController : // // It is safe to call this method more than once. Calls after the first one // will have no effect. - void Close(); + virtual void Close(); /////////////////////////////////////////////////////////////////////////// // AudioInputCallback methods. @@ -80,7 +102,7 @@ class AudioInputController : virtual void OnClose(AudioInputStream* stream); virtual void OnError(AudioInputStream* stream, int code); - private: + protected: // Internal state of the source. enum State { kEmpty, @@ -113,6 +135,8 @@ class AudioInputController : // The audio input controller thread that this object runs on. base::Thread thread_; + static Factory* factory_; + DISALLOW_COPY_AND_ASSIGN(AudioInputController); }; diff --git a/media/audio/test_audio_input_controller_factory.cc b/media/audio/test_audio_input_controller_factory.cc new file mode 100644 index 0000000..c56afd8 --- /dev/null +++ b/media/audio/test_audio_input_controller_factory.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/audio/test_audio_input_controller_factory.h" +#include "media/audio/audio_io.h" + +namespace media { + +TestAudioInputController::TestAudioInputController( + TestAudioInputControllerFactory* factory, EventHandler* event_handler) + : AudioInputController(event_handler), + factory_(factory), + event_handler_(event_handler) { +} + +TestAudioInputController::~TestAudioInputController() { + // Inform the factory so that it allows creating new instances in future. + factory_->OnTestAudioInputControllerDestroyed(this); +} + +TestAudioInputControllerFactory::TestAudioInputControllerFactory() + : controller_(NULL) { +} + +AudioInputController* TestAudioInputControllerFactory::Create( + AudioInputController::EventHandler* event_handler, + AudioManager::Format format, + int channels, + int sample_rate, + int bits_per_sample, + int samples_per_packet) { + DCHECK(!controller_); // Only one test instance managed at a time. + controller_ = new TestAudioInputController(this, event_handler); + return controller_; +} + +void TestAudioInputControllerFactory::OnTestAudioInputControllerDestroyed( + TestAudioInputController* controller) { + DCHECK(controller_ == controller); + controller_ = NULL; +} + +} // namespace media diff --git a/media/audio/test_audio_input_controller_factory.h b/media/audio/test_audio_input_controller_factory.h new file mode 100644 index 0000000..bd8f7b9 --- /dev/null +++ b/media/audio/test_audio_input_controller_factory.h @@ -0,0 +1,100 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_AUDIO_TEST_AUDIO_INPUT_CONTROLLER_FACTORY_H_ +#define MEDIA_AUDIO_TEST_AUDIO_INPUT_CONTROLLER_FACTORY_H_ +#pragma once + +#include "media/audio/audio_input_controller.h" + +namespace media { + +class TestAudioInputControllerFactory; + +// TestAudioInputController and TestAudioInputControllerFactory are used for +// testing consumers of AudioInputController. TestAudioInputControllerFactory +// is a AudioInputController::Factory that creates TestAudioInputControllers. +// +// TestAudioInputController::Record and Close are overriden to do nothing. It is +// expected that you'll grab the EventHandler from the TestAudioInputController +// and invoke the callback methods when appropriate. In this way it's easy to +// mock a AudioInputController. +// +// Typical usage: +// // Create and register factory. +// TestAudioInputControllerFactory factory; +// AudioInputController::set_factory(&factory); +// +// // Do something that triggers creation of an AudioInputController. +// TestAudioInputController* controller = factory.last_controller(); +// DCHECK(controller); +// +// // Notify event handler with whatever data you want. +// controller->event_handler()->OnCreated(...); +// +// // Do something that triggers AudioInputController::Record to be called. +// controller->event_handler()->OnData(...); +// controller->event_handler()->OnError(...); +// +// // Make sure consumer of AudioInputController does the right thing. +// ... +// // Reset factory. +// AudioInputController::set_factory(NULL); + +class TestAudioInputController : public AudioInputController { + public: + TestAudioInputController(TestAudioInputControllerFactory* factory, + EventHandler* event_handler); + virtual ~TestAudioInputController(); + + // Returns the event handler installed on the AudioInputController. + EventHandler* event_handler() const { return event_handler_; } + + // Overriden to do nothing. It is assumed the caller will notify the event + // handler with recorded data and other events. + virtual void Record() {} + virtual void Close() {} + + private: + // These are not owned by us and expected to be valid for this object's + // lifetime. + TestAudioInputControllerFactory* factory_; + EventHandler* event_handler_; + + DISALLOW_COPY_AND_ASSIGN(TestAudioInputController); +}; + +// Simple AudioInputController::Factory method that creates +// TestAudioInputControllers. +class TestAudioInputControllerFactory : public AudioInputController::Factory { + public: + TestAudioInputControllerFactory(); + + // AudioInputController::Factory methods. + AudioInputController* Create( + AudioInputController::EventHandler* event_handler, + AudioManager::Format format, + int channels, + int sample_rate, + int bits_per_sample, + int samples_per_packet); + + TestAudioInputController* controller() const { return controller_; } + + private: + friend class TestAudioInputController; + + // Invoked by a TestAudioInputController when it gets destroyed. + void OnTestAudioInputControllerDestroyed( + TestAudioInputController* controller); + + // The caller of Create owns this object. + TestAudioInputController* controller_; + + DISALLOW_COPY_AND_ASSIGN(TestAudioInputControllerFactory); +}; + +} // namespace media + +#endif // MEDIA_AUDIO_TEST_AUDIO_INPUT_CONTROLLER_FACTORY_H_ |