Chromium Code Reviews| 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 688a940bfbc11d0dc13390ac0bde8ec295f688d3..49e6de42e22ea753e896295b8b0d6627349d0e6d 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" |
| @@ -421,16 +422,18 @@ 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()) { |
| + // Wait for the AudioManager to finish any initialization on the audio loop. |
| + base::RunLoop().RunUntilIdle(); |
|
tommi (sloooow) - chröme
2014/01/31 14:06:59
what exactly is it that happens during this loop?
henrika (OOO until Aug 14)
2014/01/31 14:19:05
Sorry, my bad. Copied from test that Dale had just
DaleCurtis
2014/01/31 19:18:12
This is only needed on platforms which post initia
|
| } |
| - virtual void TearDown() {} |
| + virtual ~AudioAndroidOutputTest() { |
| + base::RunLoop().RunUntilIdle(); |
|
tommi (sloooow) - chröme
2014/01/31 14:06:59
add a comment for why we need this?
henrika (OOO until Aug 14)
2014/01/31 14:19:05
Will remove.
|
| + } |
| + protected: |
| AudioManager* audio_manager() { return audio_manager_.get(); } |
| base::MessageLoopForUI* loop() { return loop_.get(); } |
| @@ -508,9 +511,11 @@ std::vector<bool> RunAudioRecordInputPathTests() { |
| class AudioAndroidInputTest : public AudioAndroidOutputTest, |
| public testing::WithParamInterface<bool> { |
| public: |
| - AudioAndroidInputTest() {} |
| + AudioAndroidInputTest() : audio_input_stream_(NULL) {} |
| protected: |
| + AudioInputStream* ais() { return audio_input_stream_; } |
|
tommi (sloooow) - chröme
2014/01/31 14:06:59
I would keep audio_input_stream() in the spirit of
henrika (OOO until Aug 14)
2014/01/31 14:19:05
Will fix.
|
| + |
| AudioParameters GetInputStreamParameters() { |
| AudioParameters input_params = audio_manager()->GetInputStreamParameters( |
| AudioManagerBase::kDefaultDeviceId); |
| @@ -528,32 +533,58 @@ 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(ais(), NotNull(), params.GetBytesPerBuffer(), _, _)) |
| .Times(AtLeast(num_callbacks)) |
| .WillRepeatedly( |
| CheckCountAndPostQuitTask(&count, num_callbacks, loop())); |
| - EXPECT_CALL(sink, OnError(stream)).Times(0); |
| + EXPECT_CALL(sink, OnError(ais())).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); |
| @@ -567,8 +598,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(ais()->Open()); |
| + ais()->Start(source); |
| + } |
| + |
| + void StopAndClose() { |
| + DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread()); |
| + ais()->Stop(); |
| + ais()->Close(); |
| + } |
| + |
| + void OpenAndClose() { |
| + DCHECK(audio_manager()->GetTaskRunner()->BelongsToCurrentThread()); |
| + EXPECT_TRUE(ais()->Open()); |
| + ais()->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); |
| }; |
| @@ -599,6 +678,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; |
| @@ -619,10 +701,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(ais()))); |
| } |
| // Ensure that a default output stream can be created and closed. |
| @@ -640,11 +722,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. |
| @@ -659,18 +738,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(), |
| @@ -748,9 +824,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(), |
| @@ -760,12 +834,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 |