summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authorsatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-10 22:41:21 +0000
committersatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-10 22:41:21 +0000
commit557d4e83efbdae5bd4fa8564f5db9b03bb9d691c (patch)
tree8c95528cf8a740ca325a933b810b09cf53b7935c /media/audio
parent3355fbdbc15c9d66cc5d74004f8cdc243afa4054 (diff)
downloadchromium_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.cc8
-rw-r--r--media/audio/audio_input_controller.h30
-rw-r--r--media/audio/test_audio_input_controller_factory.cc44
-rw-r--r--media/audio/test_audio_input_controller_factory.h100
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_