summaryrefslogtreecommitdiffstats
path: root/media/audio/virtual_audio_input_stream_unittest.cc
diff options
context:
space:
mode:
authormiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-15 23:24:26 +0000
committermiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-15 23:24:26 +0000
commit4451e7a22d8264f53fd2d2f62a6c5dbacbe1e69f (patch)
tree901ee492ff8b6a97f2fdfffc397d2f50835710e5 /media/audio/virtual_audio_input_stream_unittest.cc
parent5a8bb129afab85ae5f0922fccadfbe8bee0eebcf (diff)
downloadchromium_src-4451e7a22d8264f53fd2d2f62a6c5dbacbe1e69f.zip
chromium_src-4451e7a22d8264f53fd2d2f62a6c5dbacbe1e69f.tar.gz
chromium_src-4451e7a22d8264f53fd2d2f62a6c5dbacbe1e69f.tar.bz2
Bug fix: Bypass dispatcher output stream caching scheme for virtual output streams in AudioManagerBase.
Reworked unit tests in virtual_audio_input_stream_unittest.cc, and confirmed the VirtualAudioInputStreamTest.PausedOutputStreamReconnectsToRealDevice test crashes without the bug fix in audio_manager_base.cc. BUG=167920 TEST=Run media_unittests --gtest_filter='VirtualAudioInputStreamTest.*' Review URL: https://chromiumcodereview.appspot.com/11778085 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177008 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/virtual_audio_input_stream_unittest.cc')
-rw-r--r--media/audio/virtual_audio_input_stream_unittest.cc557
1 files changed, 314 insertions, 243 deletions
diff --git a/media/audio/virtual_audio_input_stream_unittest.cc b/media/audio/virtual_audio_input_stream_unittest.cc
index b47b814..93b4b01 100644
--- a/media/audio/virtual_audio_input_stream_unittest.cc
+++ b/media/audio/virtual_audio_input_stream_unittest.cc
@@ -2,321 +2,392 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <vector>
+#include <list>
#include "base/message_loop.h"
+#include "base/rand_util.h"
#include "base/synchronization/waitable_event.h"
+#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "media/audio/simple_sources.h"
#include "media/audio/virtual_audio_input_stream.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using ::testing::_;
+using ::testing::AtLeast;
+using ::testing::InvokeWithoutArgs;
+using ::testing::NotNull;
+
namespace media {
+namespace {
+
class MockInputCallback : public AudioInputStream::AudioInputCallback {
public:
- MockInputCallback() {}
- virtual void OnData(AudioInputStream* stream, const uint8* data,
- uint32 size, uint32 hardware_delay_bytes,
- double volume) {}
- virtual void OnClose(AudioInputStream* stream) {}
- virtual void OnError(AudioInputStream* stream, int code) {}
+ MockInputCallback()
+ : data_pushed_(false, false) {
+ ON_CALL(*this, OnData(_, _, _, _, _))
+ .WillByDefault(InvokeWithoutArgs(&data_pushed_,
+ &base::WaitableEvent::Signal));
+ }
+
+ virtual ~MockInputCallback() {}
+
+ MOCK_METHOD5(OnData, void(AudioInputStream* stream, const uint8* data,
+ uint32 size, uint32 hardware_delay_bytes,
+ double volume));
+ MOCK_METHOD1(OnClose, void(AudioInputStream* stream));
+ MOCK_METHOD2(OnError, void(AudioInputStream* stream, int code));
+
+ void WaitForDataPushes() {
+ for (int i = 0; i < 3; ++i) {
+ data_pushed_.Wait();
+ }
+ }
private:
+ base::WaitableEvent data_pushed_;
+
DISALLOW_COPY_AND_ASSIGN(MockInputCallback);
};
-class VirtualAudioInputStreamTest : public testing::Test {
+class TestAudioSource : public SineWaveAudioSource {
+ public:
+ TestAudioSource()
+ : SineWaveAudioSource(CHANNEL_LAYOUT_STEREO, 200.0, 8000.0),
+ data_pulled_(false, false) {}
+
+ virtual ~TestAudioSource() {}
+
+ virtual int OnMoreData(AudioBus* audio_bus,
+ AudioBuffersState audio_buffers) OVERRIDE {
+ const int ret = SineWaveAudioSource::OnMoreData(audio_bus, audio_buffers);
+ data_pulled_.Signal();
+ return ret;
+ }
+
+ virtual int OnMoreIOData(AudioBus* source,
+ AudioBus* dest,
+ AudioBuffersState audio_buffers) OVERRIDE {
+ const int ret =
+ SineWaveAudioSource::OnMoreIOData(source, dest, audio_buffers);
+ data_pulled_.Signal();
+ return ret;
+ }
+
+ void WaitForDataPulls() {
+ for (int i = 0; i < 3; ++i) {
+ data_pulled_.Wait();
+ }
+ }
+
+ private:
+ base::WaitableEvent data_pulled_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestAudioSource);
+};
+
+} // namespace
+
+class VirtualAudioInputStreamTest
+ : public testing::Test,
+ public AudioManager::AudioDeviceListener {
public:
VirtualAudioInputStreamTest()
: audio_manager_(AudioManager::Create()),
- params_(
- AudioParameters::AUDIO_VIRTUAL,CHANNEL_LAYOUT_MONO, 8000, 8, 128),
- output_params_(
- AudioParameters::AUDIO_FAKE, CHANNEL_LAYOUT_MONO, 8000, 8, 128),
+ params_(AudioParameters::AUDIO_VIRTUAL, CHANNEL_LAYOUT_STEREO, 8000, 8,
+ 10),
+ output_params_(AudioParameters::AUDIO_FAKE, CHANNEL_LAYOUT_STEREO, 8000,
+ 8, 10),
stream_(NULL),
- source_(CHANNEL_LAYOUT_STEREO, 200.0, 128),
- done_(false, false) {
+ closed_stream_(false, false) {
+ audio_manager_->GetMessageLoop()->PostTask(
+ FROM_HERE,
+ base::Bind(&AudioManager::AddOutputDeviceChangeListener,
+ base::Unretained(audio_manager_.get()),
+ this));
+ }
+
+ ~VirtualAudioInputStreamTest() {
+ audio_manager_->GetMessageLoop()->PostTask(
+ FROM_HERE,
+ base::Bind(&AudioManager::RemoveOutputDeviceChangeListener,
+ base::Unretained(audio_manager_.get()),
+ this));
+
+ SyncWithAudioThread();
+
+ DCHECK(output_streams_.empty());
+ DCHECK(stopped_output_streams_.empty());
}
- void CreateAndOpenVirtualAudioInputStream() {
+ void Create() {
stream_ = static_cast<VirtualAudioInputStream*>(
audio_manager_->MakeAudioInputStream(params_, "1"));
ASSERT_TRUE(!!stream_);
stream_->Open();
}
- void StartStreamAndRunTestsOnAudioThread(int num_output_streams,
- int num_callback_iterations,
- int num_streams_removed_per_round,
- int num_expected_source_callbacks) {
- ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
- CreateAndOpenVirtualAudioInputStream();
+ void Start() {
+ EXPECT_CALL(input_callback_, OnClose(_));
+ EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _, _))
+ .Times(AtLeast(1));
+
+ ASSERT_TRUE(!!stream_);
stream_->Start(&input_callback_);
- AddStreamsAndDoCallbacks(num_output_streams,
- num_callback_iterations,
- num_streams_removed_per_round,
- num_expected_source_callbacks);
}
- void AddStreamsAndDoCallbacks(int num_output_streams,
- int num_callback_iterations,
- int num_streams_removed_per_round,
- int num_expected_source_callbacks) {
- ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
+ void CreateAndStartOneOutputStream() {
+ AudioOutputStream* const output_stream =
+ audio_manager_->MakeAudioOutputStreamProxy(output_params_);
+ ASSERT_TRUE(!!output_stream);
+ output_streams_.push_back(output_stream);
- for (int i = 0; i < num_output_streams; ++i) {
- AudioOutputStream* output_stream =
- audio_manager_->MakeAudioOutputStream(output_params_);
- DCHECK(output_stream);
- output_streams_.push_back(output_stream);
+ output_stream->Open();
+ output_stream->Start(&source_);
+ }
- output_stream->Open();
- output_stream->Start(&source_);
- }
+ void Stop() {
+ ASSERT_TRUE(!!stream_);
+ stream_->Stop();
+ }
- if (num_output_streams == 0 && num_streams_removed_per_round > 0) {
- AudioOutputStream* output_stream = output_streams_.back();
- output_streams_.pop_back();
- output_stream->Stop();
- output_stream->Close();
- }
+ void Close() {
+ ASSERT_TRUE(!!stream_);
+ stream_->Close();
+ stream_ = NULL;
+ closed_stream_.Signal();
+ }
- if (num_callback_iterations > 0) {
- // Force the next callback to be immediate.
- stream_->buffer_duration_ms_ = base::TimeDelta();
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(
- &VirtualAudioInputStreamTest::AddStreamsAndDoCallbacks,
- base::Unretained(this),
- 0,
- --num_callback_iterations,
- num_streams_removed_per_round,
- num_expected_source_callbacks));
- } else {
- // Finish the test.
- EXPECT_EQ(num_expected_source_callbacks, source_.callbacks());
- EXPECT_EQ(0, source_.errors());
-
- for (std::vector<AudioOutputStream*>::iterator it =
- output_streams_.begin(); it != output_streams_.end(); ++it)
- (*it)->Stop();
-
- stream_->Stop();
-
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::EndTest,
- base::Unretained(this)));
+ void WaitForDataPulls() {
+ const int count = output_streams_.size();
+ for (int i = 0; i < count; ++i) {
+ source_.WaitForDataPulls();
}
}
- void OpenAndCloseOnAudioThread() {
- ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
- CreateAndOpenVirtualAudioInputStream();
-
- // Create 2 output streams, which we just open and close without starting.
- const int num_output_stream = 2;
+ void WaitForDataPushes() {
+ input_callback_.WaitForDataPushes();
+ }
- for (int i = 0; i < num_output_stream; ++i) {
- AudioOutputStream* output_stream =
- audio_manager_->MakeAudioOutputStream(output_params_);
- DCHECK(output_stream);
- output_streams_.push_back(output_stream);
+ void WaitUntilClosed() {
+ closed_stream_.Wait();
+ }
- output_stream->Open();
- }
+ void StopAndCloseOneOutputStream() {
+ ASSERT_TRUE(!output_streams_.empty());
+ AudioOutputStream* const output_stream = output_streams_.front();
+ ASSERT_TRUE(!!output_stream);
+ output_streams_.pop_front();
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::EndTest,
- base::Unretained(this)));
+ output_stream->Stop();
+ output_stream->Close();
}
- void StartStopOnAudioThread(int num_output_streams,
- int num_callback_iterations,
- int num_expected_source_callbacks) {
- ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
- CreateAndOpenVirtualAudioInputStream();
- stream_->Start(&input_callback_);
- StartStopCallback(true, num_output_streams, num_callback_iterations,
- num_expected_source_callbacks);
+ void StopFirstOutputStream() {
+ ASSERT_TRUE(!output_streams_.empty());
+ AudioOutputStream* const output_stream = output_streams_.front();
+ ASSERT_TRUE(!!output_stream);
+ output_streams_.pop_front();
+ output_stream->Stop();
+ stopped_output_streams_.push_back(output_stream);
}
- void StartStopCallback(bool init,
- int num_output_streams,
- int num_callback_iterations,
- int num_expected_source_callbacks) {
- ASSERT_TRUE(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
-
- if (init) {
- for (int i = 0; i < num_output_streams; ++i) {
- AudioOutputStream* output_stream =
- audio_manager_->MakeAudioOutputStream(output_params_);
- DCHECK(output_stream);
- output_streams_.push_back(output_stream);
-
- output_stream->Open();
- output_stream->Start(&source_);
- }
-
- // Start with an odd iteration number so we call Stop() first below.
- DCHECK_NE(0, num_callback_iterations % 2);
- }
-
- // Start or stop half the streams.
- for (int i = 0; i < num_output_streams / 2; ++i) {
- if (num_callback_iterations % 2 != 0)
- output_streams_[i]->Stop();
- else
- output_streams_[i]->Start(&source_);
+ void StopSomeOutputStreams() {
+ ASSERT_LE(1, static_cast<int>(output_streams_.size()));
+ for (int remaning = base::RandInt(1, output_streams_.size() - 1);
+ remaning > 0; --remaning) {
+ StopFirstOutputStream();
}
+ }
- if (num_callback_iterations > 0) {
- // Force the next callback to be immediate.
- stream_->buffer_duration_ms_ = base::TimeDelta::FromMilliseconds(0);
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(
- &VirtualAudioInputStreamTest::StartStopCallback,
- base::Unretained(this),
- false,
- num_output_streams,
- --num_callback_iterations,
- num_expected_source_callbacks));
- } else {
- // Finish the test.
- EXPECT_EQ(num_expected_source_callbacks, source_.callbacks());
- EXPECT_EQ(0, source_.errors());
-
- for (std::vector<AudioOutputStream*>::iterator it =
- output_streams_.begin(); it != output_streams_.end(); ++it)
- (*it)->Stop();
-
- stream_->Stop();
-
- audio_manager_->GetMessageLoop()->PostTask(FROM_HERE,
- base::Bind(&VirtualAudioInputStreamTest::EndTest,
- base::Unretained(this)));
+ void RestartAllStoppedOutputStreams() {
+ typedef std::list<AudioOutputStream*>::const_iterator ConstIter;
+ for (ConstIter it = stopped_output_streams_.begin();
+ it != stopped_output_streams_.end(); ++it) {
+ (*it)->Start(&source_);
+ output_streams_.push_back(*it);
}
+ stopped_output_streams_.clear();
}
- void EndTest() {
- for (std::vector<AudioOutputStream*>::iterator it =
- output_streams_.begin(); it != output_streams_.end(); ++it)
- (*it)->Close();
+ AudioManager* audio_manager() const { return audio_manager_.get(); }
- stream_->Close();
+ private:
+ virtual void OnDeviceChange() OVERRIDE {
+ audio_manager_->RemoveOutputDeviceChangeListener(this);
+
+ // Simulate each AudioOutputController closing and re-opening a stream, in
+ // turn.
+ for (int remaining = output_streams_.size(); remaining > 0; --remaining) {
+ StopAndCloseOneOutputStream();
+ CreateAndStartOneOutputStream();
+ }
+ for (int remaining = stopped_output_streams_.size(); remaining > 0;
+ --remaining) {
+ AudioOutputStream* stream = stopped_output_streams_.front();
+ stopped_output_streams_.pop_front();
+ stream->Close();
+
+ stream = audio_manager_->MakeAudioOutputStreamProxy(output_params_);
+ ASSERT_TRUE(!!stream);
+ stopped_output_streams_.push_back(stream);
+ stream->Open();
+ }
+
+ audio_manager_->AddOutputDeviceChangeListener(this);
+ }
- done_.Signal();
+ void SyncWithAudioThread() {
+ base::WaitableEvent done(false, false);
+ audio_manager_->GetMessageLoop()->PostTask(
+ FROM_HERE,
+ base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
+ done.Wait();
}
- protected:
- scoped_ptr<AudioManager> audio_manager_;
- AudioParameters params_;
- AudioParameters output_params_;
+ const scoped_ptr<AudioManager> audio_manager_;
+ const AudioParameters params_;
+ const AudioParameters output_params_;
+
VirtualAudioInputStream* stream_;
MockInputCallback input_callback_;
- std::vector<AudioOutputStream*> output_streams_;
- SineWaveAudioSource source_;
- base::WaitableEvent done_;
+ base::WaitableEvent closed_stream_;
+
+ std::list<AudioOutputStream*> output_streams_;
+ std::list<AudioOutputStream*> stopped_output_streams_;
+ TestAudioSource source_;
- private:
DISALLOW_COPY_AND_ASSIGN(VirtualAudioInputStreamTest);
};
-TEST_F(VirtualAudioInputStreamTest, AttachAndDriveSingleStream) {
- const int num_output_streams = 1;
- const int num_callback_iterations = 1;
- const int num_streams_removed_per_round = 0;
- const int num_expected_source_callbacks = 1;
-
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(
- &VirtualAudioInputStreamTest::StartStreamAndRunTestsOnAudioThread,
- base::Unretained(this),
- num_output_streams,
- num_callback_iterations,
- num_streams_removed_per_round,
- num_expected_source_callbacks));
-
- done_.Wait();
-}
+#define RUN_ON_AUDIO_THREAD(method) \
+ audio_manager()->GetMessageLoop()->PostTask( \
+ FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::method, \
+ base::Unretained(this)))
-TEST_F(VirtualAudioInputStreamTest, AttachAndDriveMultipleStreams) {
- const int num_output_streams = 5;
- const int num_callback_iterations = 5;
- const int num_streams_removed_per_round = 0;
- const int num_expected_source_callbacks = 25;
-
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(
- &VirtualAudioInputStreamTest::StartStreamAndRunTestsOnAudioThread,
- base::Unretained(this),
- num_output_streams,
- num_callback_iterations,
- num_streams_removed_per_round,
- num_expected_source_callbacks));
-
- done_.Wait();
+// Creates and closes and VirtualAudioInputStream.
+TEST_F(VirtualAudioInputStreamTest, CreateAndClose) {
+ RUN_ON_AUDIO_THREAD(Create);
+ RUN_ON_AUDIO_THREAD(Close);
+ WaitUntilClosed();
}
-TEST_F(VirtualAudioInputStreamTest, AttachAndRemoveStreams) {
- const int num_output_streams = 8;
- const int num_callback_iterations = 5;
- const int num_streams_removed_per_round = 1;
- const int num_expected_source_callbacks = 8 + 7 + 6 + 5 + 4;
-
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(
- &VirtualAudioInputStreamTest::StartStreamAndRunTestsOnAudioThread,
- base::Unretained(this),
- num_output_streams,
- num_callback_iterations,
- num_streams_removed_per_round,
- num_expected_source_callbacks));
-
- done_.Wait();
+// Tests a session where one output is created and destroyed within.
+TEST_F(VirtualAudioInputStreamTest, SingleOutputWithinSession) {
+ RUN_ON_AUDIO_THREAD(Create);
+ RUN_ON_AUDIO_THREAD(Start);
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ WaitForDataPulls(); // Confirm data is being pulled (rendered).
+ WaitForDataPushes(); // Confirm mirrored data is being pushed.
+ RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
+ RUN_ON_AUDIO_THREAD(Stop);
+ RUN_ON_AUDIO_THREAD(Close);
+ WaitUntilClosed();
}
-// Opens/closes a VirtualAudioInputStream and a number of attached
-// VirtualAudioOutputStreams without calling Start()/Stop().
-TEST_F(VirtualAudioInputStreamTest, OpenAndClose) {
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(
- &VirtualAudioInputStreamTest::OpenAndCloseOnAudioThread,
- base::Unretained(this)));
-
- done_.Wait();
+// Tests a session where one output existed before and afterwards.
+TEST_F(VirtualAudioInputStreamTest, SingleLongLivedOutput) {
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ WaitForDataPulls(); // Confirm data is flowing out before the session.
+ RUN_ON_AUDIO_THREAD(Create);
+ RUN_ON_AUDIO_THREAD(Start);
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(Stop);
+ RUN_ON_AUDIO_THREAD(Close);
+ WaitUntilClosed();
+ WaitForDataPulls(); // Confirm data is still flowing out.
+ RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
}
-// Creates and closes and VirtualAudioInputStream.
-TEST_F(VirtualAudioInputStreamTest, CreateAndClose) {
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(
- &VirtualAudioInputStreamTest::CreateAndOpenVirtualAudioInputStream,
- base::Unretained(this)));
+TEST_F(VirtualAudioInputStreamTest, SingleOutputPausedWithinSession) {
+ RUN_ON_AUDIO_THREAD(Create);
+ RUN_ON_AUDIO_THREAD(Start);
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ WaitForDataPulls();
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(StopFirstOutputStream);
+ RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams);
+ WaitForDataPulls();
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
+ RUN_ON_AUDIO_THREAD(Stop);
+ RUN_ON_AUDIO_THREAD(Close);
+ WaitUntilClosed();
+}
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(&VirtualAudioInputStreamTest::EndTest,
- base::Unretained(this)));
+TEST_F(VirtualAudioInputStreamTest, OutputStreamsReconnectToRealDevices) {
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ WaitForDataPulls();
+ RUN_ON_AUDIO_THREAD(Create);
+ RUN_ON_AUDIO_THREAD(Start);
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ WaitForDataPulls();
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(Stop);
+ RUN_ON_AUDIO_THREAD(Close);
+ WaitUntilClosed();
+ WaitForDataPulls();
+ RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
+ RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
+}
- done_.Wait();
+TEST_F(VirtualAudioInputStreamTest, PausedOutputStreamReconnectsToRealDevice) {
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ WaitForDataPulls();
+ RUN_ON_AUDIO_THREAD(Create);
+ RUN_ON_AUDIO_THREAD(Start);
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ WaitForDataPulls();
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(StopFirstOutputStream);
+ WaitForDataPulls();
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(Stop);
+ RUN_ON_AUDIO_THREAD(Close);
+ WaitUntilClosed();
+ WaitForDataPulls();
+ RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams);
+ WaitForDataPulls();
+ RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
+ RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
}
-// Starts and stops VirtualAudioOutputStreams while attached to a
-// VirtualAudioInputStream.
-TEST_F(VirtualAudioInputStreamTest, AttachAndStartStopStreams) {
- const int num_output_streams = 4;
- const int num_callback_iterations = 5;
- const int num_expected_source_callbacks = 2 + 4 + 2 + 4 + 2;
-
- audio_manager_->GetMessageLoop()->PostTask(
- FROM_HERE, base::Bind(
- &VirtualAudioInputStreamTest::StartStopOnAudioThread,
- base::Unretained(this),
- num_output_streams,
- num_callback_iterations,
- num_expected_source_callbacks));
-
- done_.Wait();
+// A combination of all of the above tests with many output streams.
+TEST_F(VirtualAudioInputStreamTest, ComprehensiveTest) {
+ static const int kNumOutputs = 8;
+ static const int kPauseIterations = 5;
+
+ for (int i = 0; i < kNumOutputs / 2; ++i) {
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ }
+ WaitForDataPulls();
+ RUN_ON_AUDIO_THREAD(Create);
+ RUN_ON_AUDIO_THREAD(Start);
+ WaitForDataPushes();
+ for (int i = 0; i < kNumOutputs / 2; ++i) {
+ RUN_ON_AUDIO_THREAD(CreateAndStartOneOutputStream);
+ }
+ WaitForDataPulls();
+ WaitForDataPushes();
+ for (int i = 0; i < kPauseIterations; ++i) {
+ RUN_ON_AUDIO_THREAD(StopSomeOutputStreams);
+ WaitForDataPulls();
+ WaitForDataPushes();
+ RUN_ON_AUDIO_THREAD(RestartAllStoppedOutputStreams);
+ WaitForDataPulls();
+ WaitForDataPushes();
+ }
+ RUN_ON_AUDIO_THREAD(Stop);
+ RUN_ON_AUDIO_THREAD(Close);
+ WaitUntilClosed();
+ WaitForDataPulls();
+ for (int i = 0; i < kNumOutputs; ++i) {
+ RUN_ON_AUDIO_THREAD(StopAndCloseOneOutputStream);
+ }
}
} // namespace media