Index: media/audio/android/audio_android_unittest.cc |
diff --git a/media/audio/android/audio_android_unittest.cc b/media/audio/android/audio_android_unittest.cc |
index 91bf5d8461b663e21b9d0d652d5ffc3a379dd9cf..1f9a87b81cc3dc92ea78d5ed8bb2ab84fbf76a68 100644 |
--- a/media/audio/android/audio_android_unittest.cc |
+++ b/media/audio/android/audio_android_unittest.cc |
@@ -8,6 +8,7 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/message_loop/message_loop.h" |
#include "base/path_service.h" |
+#include "base/run_loop.h" |
#include "base/strings/stringprintf.h" |
#include "base/synchronization/lock.h" |
#include "base/synchronization/waitable_event.h" |
@@ -410,16 +411,15 @@ class FullDuplexAudioSinkSource |
// Test fixture class for tests which only exercise the output path. |
class AudioAndroidOutputTest : public testing::Test { |
public: |
- AudioAndroidOutputTest() {} |
- |
- protected: |
- virtual void SetUp() { |
- audio_manager_.reset(AudioManager::CreateForTesting()); |
- loop_.reset(new base::MessageLoopForUI()); |
+ AudioAndroidOutputTest() |
+ : loop_(new base::MessageLoopForUI()), |
+ audio_manager_(AudioManager::CreateForTesting()) { |
} |
- virtual void TearDown() {} |
+ virtual ~AudioAndroidOutputTest() { |
+ } |
+ protected: |
AudioManager* audio_manager() { return audio_manager_.get(); } |
base::MessageLoopForUI* loop() { return loop_.get(); } |
@@ -497,9 +497,11 @@ std::vector<bool> RunAudioRecordInputPathTests() { |
class AudioAndroidInputTest : public AudioAndroidOutputTest, |
public testing::WithParamInterface<bool> { |
public: |
- AudioAndroidInputTest() {} |
+ AudioAndroidInputTest() : audio_input_stream_(NULL) {} |
protected: |
+ AudioInputStream* audio_input_stream() { return audio_input_stream_; } |
+ |
AudioParameters GetInputStreamParameters() { |
AudioParameters input_params = audio_manager()->GetInputStreamParameters( |
AudioManagerBase::kDefaultDeviceId); |
@@ -517,32 +519,61 @@ class AudioAndroidInputTest : public AudioAndroidOutputTest, |
return params; |
} |
+ void MakeAISOnAudioThread(const AudioParameters& params) { |
+ RunOnAudioThread( |
+ base::Bind(&AudioAndroidInputTest::MakeInputStream, |
+ base::Unretained(this), |
+ params)); |
+ } |
+ |
+ void OpenAndCloseAISOnAudioThread() { |
+ RunOnAudioThread( |
+ base::Bind(&AudioAndroidInputTest::OpenAndClose, |
+ base::Unretained(this))); |
+ } |
+ |
+ void OpenAndStartAISOnAudioThread( |
+ AudioInputStream::AudioInputCallback* source) { |
+ RunOnAudioThread( |
+ base::Bind(&AudioAndroidInputTest::OpenAndStart, |
+ base::Unretained(this), |
+ source)); |
+ } |
+ |
+ void StopAndCloseAISOnAudioThread() { |
+ RunOnAudioThread( |
+ base::Bind(&AudioAndroidInputTest::StopAndClose, |
+ base::Unretained(this))); |
+ } |
+ |
void StartInputStreamCallbacks(const AudioParameters& params) { |
double expected_time_between_callbacks_ms = |
ExpectedTimeBetweenCallbacks(params); |
const int num_callbacks = |
(kCallbackTestTimeMs / expected_time_between_callbacks_ms); |
- AudioInputStream* stream = audio_manager()->MakeAudioInputStream( |
- params, AudioManagerBase::kDefaultDeviceId); |
- EXPECT_TRUE(stream); |
+ |
+ MakeAISOnAudioThread(params); |
int count = 0; |
MockAudioInputCallback sink; |
EXPECT_CALL(sink, |
- OnData(stream, NotNull(), params.GetBytesPerBuffer(), _, _)) |
+ OnData(audio_input_stream(), |
+ NotNull(), |
+ params. |
+ GetBytesPerBuffer(), _, _)) |
.Times(AtLeast(num_callbacks)) |
.WillRepeatedly( |
CheckCountAndPostQuitTask(&count, num_callbacks, loop())); |
- EXPECT_CALL(sink, OnError(stream)).Times(0); |
+ EXPECT_CALL(sink, OnError(audio_input_stream())).Times(0); |
+ |
+ OpenAndStartAISOnAudioThread(&sink); |
- EXPECT_TRUE(stream->Open()); |
- stream->Start(&sink); |
start_time_ = base::TimeTicks::Now(); |
loop()->Run(); |
end_time_ = base::TimeTicks::Now(); |
- stream->Stop(); |
- stream->Close(); |
+ |
+ StopAndCloseAISOnAudioThread(); |
double average_time_between_callbacks_ms = |
AverageTimeBetweenCallbacks(num_callbacks); |
@@ -556,8 +587,56 @@ class AudioAndroidInputTest : public AudioAndroidOutputTest, |
1.30 * expected_time_between_callbacks_ms); |
} |
+ void MakeInputStream(const AudioParameters& params) { |
+ DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread()); |
+ audio_input_stream_ = audio_manager()->MakeAudioInputStream( |
+ params, AudioManagerBase::kDefaultDeviceId); |
+ EXPECT_TRUE(audio_input_stream_); |
+ } |
+ |
+ void OpenAndStart(AudioInputStream::AudioInputCallback* source) { |
+ DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread()); |
+ EXPECT_TRUE(audio_input_stream()->Open()); |
+ audio_input_stream()->Start(source); |
+ } |
+ |
+ void StopAndClose() { |
+ DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread()); |
+ audio_input_stream()->Stop(); |
+ audio_input_stream()->Close(); |
+ } |
+ |
+ void OpenAndClose() { |
+ DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread()); |
+ EXPECT_TRUE(audio_input_stream()->Open()); |
+ audio_input_stream()->Close(); |
+ } |
+ |
+ // Synchronously runs the provided callback/closure on the audio thread. |
+ void RunOnAudioThread(const base::Closure& closure) { |
+ if (!audio_manager()->GetTaskRunner()->BelongsToCurrentThread()) { |
+ base::WaitableEvent event(false, false); |
+ audio_manager()->GetTaskRunner()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&AudioAndroidInputTest::RunOnAudioThreadImpl, |
+ base::Unretained(this), |
+ closure, |
+ &event)); |
+ event.Wait(); |
+ } else { |
+ closure.Run(); |
+ } |
+ } |
+ |
+ void RunOnAudioThreadImpl(const base::Closure& closure, |
+ base::WaitableEvent* event) { |
+ DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread()); |
+ closure.Run(); |
+ event->Signal(); |
+ } |
private: |
+ AudioInputStream* audio_input_stream_; |
DISALLOW_COPY_AND_ASSIGN(AudioAndroidInputTest); |
}; |
@@ -588,6 +667,9 @@ TEST_F(AudioAndroidOutputTest, IsAudioLowLatencySupported) { |
} |
// Verify input device enumeration. |
+// GetAudioInputDeviceNames() is mainly called from a dedicated device thread |
+// in Chrome but perform the test on the main thread here. The call will be |
+// sent to the audio thread in AudioManagerAndroid::GetAudioInputDeviceNames(). |
TEST_F(AudioAndroidInputTest, GetAudioInputDeviceNames) { |
if (!audio_manager()->HasAudioInputDevices()) |
return; |
@@ -608,10 +690,10 @@ TEST_F(AudioAndroidOutputTest, GetAudioOutputDeviceNames) { |
// Ensure that a default input stream can be created and closed. |
TEST_P(AudioAndroidInputTest, CreateAndCloseInputStream) { |
AudioParameters params = GetInputStreamParameters(); |
- AudioInputStream* ais = audio_manager()->MakeAudioInputStream( |
- params, AudioManagerBase::kDefaultDeviceId); |
- EXPECT_TRUE(ais); |
- ais->Close(); |
+ MakeAISOnAudioThread(params); |
+ RunOnAudioThread( |
+ base::Bind(&AudioInputStream::Close, |
+ base::Unretained(audio_input_stream()))); |
} |
// Ensure that a default output stream can be created and closed. |
@@ -629,11 +711,8 @@ TEST_F(AudioAndroidOutputTest, CreateAndCloseOutputStream) { |
// Ensure that a default input stream can be opened and closed. |
TEST_P(AudioAndroidInputTest, OpenAndCloseInputStream) { |
AudioParameters params = GetInputStreamParameters(); |
- AudioInputStream* ais = audio_manager()->MakeAudioInputStream( |
- params, AudioManagerBase::kDefaultDeviceId); |
- EXPECT_TRUE(ais); |
- EXPECT_TRUE(ais->Open()); |
- ais->Close(); |
+ MakeAISOnAudioThread(params); |
+ OpenAndCloseAISOnAudioThread(); |
} |
// Ensure that a default output stream can be opened and closed. |
@@ -648,18 +727,15 @@ TEST_F(AudioAndroidOutputTest, OpenAndCloseOutputStream) { |
// Start input streaming using default input parameters and ensure that the |
// callback sequence is sane. |
-// Disabled per crbug/337867 |
-TEST_P(AudioAndroidInputTest, DISABLED_StartInputStreamCallbacks) { |
- AudioParameters params = GetInputStreamParameters(); |
- StartInputStreamCallbacks(params); |
+TEST_P(AudioAndroidInputTest, StartInputStreamCallbacks) { |
+ AudioParameters native_params = GetInputStreamParameters(); |
+ StartInputStreamCallbacks(native_params); |
} |
// Start input streaming using non default input parameters and ensure that the |
// callback sequence is sane. The only change we make in this test is to select |
// a 10ms buffer size instead of the default size. |
-// TODO(henrika): possibly add support for more variations. |
-// Disabled per crbug/337867 |
-TEST_P(AudioAndroidInputTest, DISABLED_StartInputStreamCallbacksNonDefaultParameters) { |
+TEST_P(AudioAndroidInputTest, StartInputStreamCallbacksNonDefaultParameters) { |
AudioParameters native_params = GetInputStreamParameters(); |
AudioParameters params(native_params.format(), |
native_params.channel_layout(), |
@@ -737,9 +813,7 @@ TEST_F(AudioAndroidOutputTest, DISABLED_RunOutputStreamWithFileAsSource) { |
TEST_P(AudioAndroidInputTest, DISABLED_RunSimplexInputStreamWithFileAsSink) { |
AudioParameters params = GetInputStreamParameters(); |
VLOG(1) << params; |
- AudioInputStream* ais = audio_manager()->MakeAudioInputStream( |
- params, AudioManagerBase::kDefaultDeviceId); |
- EXPECT_TRUE(ais); |
+ MakeAISOnAudioThread(params); |
std::string file_name = base::StringPrintf("out_simplex_%d_%d_%d.pcm", |
params.sample_rate(), |
@@ -749,12 +823,10 @@ TEST_P(AudioAndroidInputTest, DISABLED_RunSimplexInputStreamWithFileAsSink) { |
base::WaitableEvent event(false, false); |
FileAudioSink sink(&event, params, file_name); |
- EXPECT_TRUE(ais->Open()); |
- ais->Start(&sink); |
+ OpenAndStartAISOnAudioThread(&sink); |
VLOG(0) << ">> Speak into the microphone to record audio..."; |
EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); |
- ais->Stop(); |
- ais->Close(); |
+ StopAndCloseAISOnAudioThread(); |
} |
// Same test as RunSimplexInputStreamWithFileAsSink but this time output |