| Index: chromecast/media/audio/cast_audio_output_stream_unittest.cc
|
| diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
|
| index 67bf2952cce4d5a824a05e70083241d060a18da0..d529077e8516a87e775ca6919927ec85dae359cd 100644
|
| --- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc
|
| +++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
|
| @@ -10,9 +10,7 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/macros.h"
|
| -#include "base/run_loop.h"
|
| #include "base/synchronization/waitable_event.h"
|
| -#include "base/thread_task_runner_handle.h"
|
| #include "chromecast/base/metrics/cast_metrics_test_helper.h"
|
| #include "chromecast/media/audio/cast_audio_manager.h"
|
| #include "chromecast/media/base/media_message_loop.h"
|
| @@ -186,9 +184,8 @@
|
|
|
| class FakeAudioManager : public CastAudioManager {
|
| public:
|
| - FakeAudioManager(scoped_refptr<base::SingleThreadTaskRunner> task_runner)
|
| - : CastAudioManager(task_runner, task_runner, nullptr, nullptr),
|
| - media_pipeline_backend_(nullptr) {}
|
| + FakeAudioManager()
|
| + : CastAudioManager(nullptr, nullptr), media_pipeline_backend_(nullptr) {}
|
| ~FakeAudioManager() override {}
|
|
|
| // CastAudioManager overrides.
|
| @@ -234,9 +231,9 @@
|
| void SetUp() override {
|
| metrics::InitializeMetricsHelperForTesting();
|
|
|
| - audio_task_runner_ = base::ThreadTaskRunnerHandle::Get();
|
| + audio_manager_.reset(new FakeAudioManager);
|
| + audio_task_runner_ = audio_manager_->GetTaskRunner();
|
| backend_task_runner_ = media::MediaMessageLoop::GetTaskRunner();
|
| - audio_manager_.reset(new FakeAudioManager(audio_task_runner_));
|
| }
|
|
|
| void TearDown() override {
|
| @@ -259,68 +256,107 @@
|
|
|
| // Synchronous utility functions.
|
| ::media::AudioOutputStream* CreateStream() {
|
| - return audio_manager_->MakeAudioOutputStream(GetAudioParams(),
|
| - kDefaultDeviceId);
|
| + ::media::AudioOutputStream* stream = nullptr;
|
| +
|
| + base::WaitableEvent completion_event(false, false);
|
| + audio_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&CastAudioOutputStreamTest::CreateStreamOnAudioThread,
|
| + base::Unretained(this), GetAudioParams(), &stream,
|
| + &completion_event));
|
| + completion_event.Wait();
|
| +
|
| + return stream;
|
| }
|
| bool OpenStream(::media::AudioOutputStream* stream) {
|
| - bool success = stream->Open();
|
| + DCHECK(stream);
|
| +
|
| + bool success = false;
|
| + base::WaitableEvent completion_event(false, false);
|
| + audio_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&CastAudioOutputStreamTest::OpenStreamOnAudioThread,
|
| + base::Unretained(this), stream, &success,
|
| + &completion_event));
|
| + completion_event.Wait();
|
| +
|
| // Drain the backend task runner so that appropriate states are set on
|
| // the backend pipeline devices.
|
| RunUntilIdle(backend_task_runner_.get());
|
| return success;
|
| }
|
| void CloseStream(::media::AudioOutputStream* stream) {
|
| - stream->Close();
|
| + audio_task_runner_->PostTask(FROM_HERE,
|
| + base::Bind(&::media::AudioOutputStream::Close,
|
| + base::Unretained(stream)));
|
| + RunUntilIdle(audio_task_runner_.get());
|
| RunUntilIdle(backend_task_runner_.get());
|
| // Backend task runner may have posted more tasks to the audio task runner.
|
| // So we need to drain it once more.
|
| - message_loop_.RunUntilIdle();
|
| + RunUntilIdle(audio_task_runner_.get());
|
| }
|
| void StartStream(
|
| ::media::AudioOutputStream* stream,
|
| ::media::AudioOutputStream::AudioSourceCallback* source_callback) {
|
| - stream->Start(source_callback);
|
| - // Drain the audio task runner so that tasks posted by
|
| + audio_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&::media::AudioOutputStream::Start,
|
| + base::Unretained(stream), source_callback));
|
| + // Drain the audio task runner twice so that tasks posted by
|
| // media::AudioOutputStream::Start are run as well.
|
| - message_loop_.RunUntilIdle();
|
| + RunUntilIdle(audio_task_runner_.get());
|
| + RunUntilIdle(audio_task_runner_.get());
|
| // Drain the backend task runner so that appropriate states are set on
|
| // the backend pipeline devices.
|
| RunUntilIdle(backend_task_runner_.get());
|
| // Drain the audio task runner again to run the tasks posted by the
|
| // backend on audio task runner.
|
| - message_loop_.RunUntilIdle();
|
| + RunUntilIdle(audio_task_runner_.get());
|
| }
|
| void StopStream(::media::AudioOutputStream* stream) {
|
| - stream->Stop();
|
| + audio_task_runner_->PostTask(FROM_HERE,
|
| + base::Bind(&::media::AudioOutputStream::Stop,
|
| + base::Unretained(stream)));
|
| + RunUntilIdle(audio_task_runner_.get());
|
| // Drain the backend task runner so that appropriate states are set on
|
| // the backend pipeline devices.
|
| RunUntilIdle(backend_task_runner_.get());
|
| }
|
| void SetStreamVolume(::media::AudioOutputStream* stream, double volume) {
|
| - stream->SetVolume(volume);
|
| + audio_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&::media::AudioOutputStream::SetVolume,
|
| + base::Unretained(stream), volume));
|
| + RunUntilIdle(audio_task_runner_.get());
|
| // Drain the backend task runner so that appropriate states are set on
|
| // the backend pipeline devices.
|
| RunUntilIdle(backend_task_runner_.get());
|
| }
|
| double GetStreamVolume(::media::AudioOutputStream* stream) {
|
| double volume = 0.0;
|
| - stream->GetVolume(&volume);
|
| + audio_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&::media::AudioOutputStream::GetVolume,
|
| + base::Unretained(stream), &volume));
|
| + RunUntilIdle(audio_task_runner_.get());
|
| // No need to drain the backend task runner because getting the volume
|
| // does not involve posting any task to the backend.
|
| return volume;
|
| }
|
|
|
| - void RunAudioLoopFor(int frames) {
|
| - ::media::AudioParameters audio_params = GetAudioParams();
|
| - base::TimeDelta duration = audio_params.GetBufferDuration() * frames;
|
| -
|
| - base::RunLoop run_loop;
|
| - message_loop_.task_runner()->PostDelayedTask(
|
| - FROM_HERE, run_loop.QuitClosure(), duration);
|
| - run_loop.Run();
|
| - }
|
| -
|
| - base::MessageLoop message_loop_;
|
| + void CreateStreamOnAudioThread(const ::media::AudioParameters& audio_params,
|
| + ::media::AudioOutputStream** stream,
|
| + base::WaitableEvent* completion_event) {
|
| + DCHECK(audio_task_runner_->BelongsToCurrentThread());
|
| + *stream = audio_manager_->MakeAudioOutputStream(GetAudioParams(),
|
| + kDefaultDeviceId);
|
| + completion_event->Signal();
|
| + }
|
| + void OpenStreamOnAudioThread(::media::AudioOutputStream* stream,
|
| + bool* success,
|
| + base::WaitableEvent* completion_event) {
|
| + DCHECK(audio_task_runner_->BelongsToCurrentThread());
|
| + *success = stream->Open();
|
| + completion_event->Signal();
|
| + }
|
| +
|
| std::unique_ptr<FakeAudioManager> audio_manager_;
|
| scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_;
|
| scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner_;
|
| @@ -440,7 +476,6 @@
|
| std::unique_ptr<FakeAudioSourceCallback> source_callback(
|
| new FakeAudioSourceCallback);
|
| StartStream(stream, source_callback.get());
|
| - RunAudioLoopFor(2);
|
| StopStream(stream);
|
|
|
| // Verify that the stream pushed frames to the backend.
|
| @@ -483,7 +518,10 @@
|
|
|
| // Sleep for a few frames and verify that more frames were not pushed
|
| // because the backend device was busy.
|
| - RunAudioLoopFor(5);
|
| + ::media::AudioParameters audio_params = GetAudioParams();
|
| + base::TimeDelta pause = audio_params.GetBufferDuration() * 5;
|
| + base::PlatformThread::Sleep(pause);
|
| + RunUntilIdle(audio_task_runner_.get());
|
| RunUntilIdle(backend_task_runner_.get());
|
| EXPECT_EQ(1u, audio_decoder->pushed_buffer_count());
|
|
|
| @@ -494,7 +532,9 @@
|
| base::Bind(&FakeAudioDecoder::set_pipeline_status,
|
| base::Unretained(audio_decoder),
|
| FakeAudioDecoder::PIPELINE_STATUS_OK));
|
| - RunAudioLoopFor(5);
|
| +
|
| + base::PlatformThread::Sleep(pause);
|
| + RunUntilIdle(audio_task_runner_.get());
|
| RunUntilIdle(backend_task_runner_.get());
|
| EXPECT_LT(1u, audio_decoder->pushed_buffer_count());
|
| EXPECT_FALSE(source_callback->error());
|
| @@ -515,7 +555,6 @@
|
| std::unique_ptr<FakeAudioSourceCallback> source_callback(
|
| new FakeAudioSourceCallback);
|
| StartStream(stream, source_callback.get());
|
| - RunAudioLoopFor(2);
|
|
|
| // Make sure that AudioOutputStream attempted to push the initial frame.
|
| EXPECT_LT(0u, audio_decoder->pushed_buffer_count());
|
| @@ -539,7 +578,6 @@
|
| std::unique_ptr<FakeAudioSourceCallback> source_callback(
|
| new FakeAudioSourceCallback);
|
| StartStream(stream, source_callback.get());
|
| - RunAudioLoopFor(5);
|
|
|
| // Make sure that one frame was pushed.
|
| EXPECT_EQ(1u, audio_decoder->pushed_buffer_count());
|
| @@ -552,7 +590,7 @@
|
| base::Unretained(audio_decoder),
|
| FakeAudioDecoder::PIPELINE_STATUS_OK));
|
|
|
| - RunAudioLoopFor(5);
|
| + RunUntilIdle(audio_task_runner_.get());
|
| RunUntilIdle(backend_task_runner_.get());
|
| // AudioOutputStream must report error to source callback.
|
| EXPECT_TRUE(source_callback->error());
|
| @@ -587,11 +625,16 @@
|
|
|
| std::unique_ptr<FakeAudioSourceCallback> source_callback(
|
| new FakeAudioSourceCallback);
|
| - stream->Start(source_callback.get());
|
| - RunAudioLoopFor(2);
|
| - stream->Stop();
|
| - stream->Start(source_callback.get());
|
| - RunAudioLoopFor(2);
|
| + audio_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&::media::AudioOutputStream::Start,
|
| + base::Unretained(stream), source_callback.get()));
|
| + audio_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&::media::AudioOutputStream::Stop, base::Unretained(stream)));
|
| + audio_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&::media::AudioOutputStream::Start,
|
| + base::Unretained(stream), source_callback.get()));
|
| + RunUntilIdle(audio_task_runner_.get());
|
| RunUntilIdle(backend_task_runner_.get());
|
|
|
| FakeAudioDecoder* audio_device = GetAudio();
|
|
|