| Index: media/audio/audio_output_proxy_unittest.cc
|
| ===================================================================
|
| --- media/audio/audio_output_proxy_unittest.cc (revision 132979)
|
| +++ media/audio/audio_output_proxy_unittest.cc (working copy)
|
| @@ -2,10 +2,13 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include <string>
|
| +
|
| #include "base/message_loop.h"
|
| #include "base/message_loop_proxy.h"
|
| #include "base/threading/platform_thread.h"
|
| -#include "media/audio/audio_output_dispatcher.h"
|
| +#include "media/audio/audio_output_dispatcher_impl.h"
|
| +#include "media/audio/audio_output_mixer.h"
|
| #include "media/audio/audio_output_proxy.h"
|
| #include "media/audio/audio_manager.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| @@ -88,7 +91,7 @@
|
|
|
| virtual void TearDown() {
|
| // All paused proxies should have been closed at this point.
|
| - EXPECT_EQ(0u, dispatcher_->paused_proxies_);
|
| + EXPECT_EQ(0u, dispatcher_impl_->paused_proxies_);
|
|
|
| // This is necessary to free all proxy objects that have been
|
| // closed by the test.
|
| @@ -98,42 +101,166 @@
|
| void InitDispatcher(base::TimeDelta close_delay) {
|
| AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
|
| CHANNEL_LAYOUT_STEREO, 44100, 16, 1024);
|
| - dispatcher_ = new AudioOutputDispatcher(&manager(), params, close_delay);
|
| + dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(),
|
| + params,
|
| + close_delay);
|
| + mixer_ = new AudioOutputMixer(&manager(), params, close_delay);
|
|
|
| // Necessary to know how long the dispatcher will wait before posting
|
| // StopStreamTask.
|
| - pause_delay_ = dispatcher_->pause_delay_;
|
| + pause_delay_ = dispatcher_impl_->pause_delay_;
|
| }
|
|
|
| MockAudioManager& manager() {
|
| return manager_;
|
| }
|
|
|
| + // Wait for the close timer to fire.
|
| + void WaitForCloseTimer(const int timer_delay_ms) {
|
| + message_loop_.RunAllPending(); // OpenTask() may reset the timer.
|
| + base::PlatformThread::Sleep(
|
| + base::TimeDelta::FromMilliseconds(timer_delay_ms) * 2);
|
| + message_loop_.RunAllPending();
|
| + }
|
| +
|
| + // Methods that do actual tests.
|
| + void OpenAndClose(AudioOutputDispatcher* dispatcher) {
|
| + MockAudioOutputStream stream;
|
| +
|
| + EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| + .WillOnce(Return(&stream));
|
| + EXPECT_CALL(stream, Open())
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(stream, Close())
|
| + .Times(1);
|
| +
|
| + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
|
| + EXPECT_TRUE(proxy->Open());
|
| + proxy->Close();
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| + }
|
| +
|
| + // Create a stream, and then calls Start() and Stop().
|
| + void StartAndStop(AudioOutputDispatcher* dispatcher) {
|
| + MockAudioOutputStream stream;
|
| +
|
| + EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| + .WillOnce(Return(&stream));
|
| + EXPECT_CALL(stream, Open())
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(stream, Start(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, SetVolume(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Stop())
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Close())
|
| + .Times(1);
|
| +
|
| + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
|
| + EXPECT_TRUE(proxy->Open());
|
| +
|
| + proxy->Start(&callback_);
|
| + proxy->Stop();
|
| +
|
| + proxy->Close();
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| + }
|
| +
|
| + // Verify that the stream is closed after Stop is called.
|
| + void CloseAfterStop(AudioOutputDispatcher* dispatcher) {
|
| + MockAudioOutputStream stream;
|
| +
|
| + EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| + .WillOnce(Return(&stream));
|
| + EXPECT_CALL(stream, Open())
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(stream, Start(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, SetVolume(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Stop())
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Close())
|
| + .Times(1);
|
| +
|
| + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
|
| + EXPECT_TRUE(proxy->Open());
|
| +
|
| + proxy->Start(&callback_);
|
| + proxy->Stop();
|
| +
|
| + // Wait for StopStream() to post StopStreamTask().
|
| + base::PlatformThread::Sleep(pause_delay_ * 2);
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| +
|
| + // Verify expectation before calling Close().
|
| + Mock::VerifyAndClear(&stream);
|
| +
|
| + proxy->Close();
|
| + }
|
| +
|
| + // Create two streams, but don't start them. Only one device must be open.
|
| + void TwoStreams(AudioOutputDispatcher* dispatcher) {
|
| + MockAudioOutputStream stream;
|
| +
|
| + EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| + .WillOnce(Return(&stream));
|
| + EXPECT_CALL(stream, Open())
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(stream, Close())
|
| + .Times(1);
|
| +
|
| + AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher);
|
| + AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher);
|
| + EXPECT_TRUE(proxy1->Open());
|
| + EXPECT_TRUE(proxy2->Open());
|
| + proxy1->Close();
|
| + proxy2->Close();
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| + }
|
| +
|
| + // Open() method failed.
|
| + void OpenFailed(AudioOutputDispatcher* dispatcher) {
|
| + MockAudioOutputStream stream;
|
| +
|
| + EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| + .WillOnce(Return(&stream));
|
| + EXPECT_CALL(stream, Open())
|
| + .WillOnce(Return(false));
|
| + EXPECT_CALL(stream, Close())
|
| + .Times(1);
|
| +
|
| + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher);
|
| + EXPECT_FALSE(proxy->Open());
|
| + proxy->Close();
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| + }
|
| +
|
| MessageLoop message_loop_;
|
| - scoped_refptr<AudioOutputDispatcher> dispatcher_;
|
| + scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_;
|
| + scoped_refptr<AudioOutputMixer> mixer_;
|
| base::TimeDelta pause_delay_;
|
| MockAudioManager manager_;
|
| MockAudioSourceCallback callback_;
|
| };
|
|
|
| TEST_F(AudioOutputProxyTest, CreateAndClose) {
|
| - AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_);
|
| + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
|
| proxy->Close();
|
| }
|
|
|
| +TEST_F(AudioOutputProxyTest, CreateAndClose_Mixer) {
|
| + AudioOutputProxy* proxy = new AudioOutputProxy(mixer_);
|
| + proxy->Close();
|
| +}
|
| +
|
| TEST_F(AudioOutputProxyTest, OpenAndClose) {
|
| - MockAudioOutputStream stream;
|
| + OpenAndClose(dispatcher_impl_);
|
| +}
|
|
|
| - EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| - .WillOnce(Return(&stream));
|
| - EXPECT_CALL(stream, Open())
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(stream, Close())
|
| - .Times(1);
|
| -
|
| - AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_);
|
| - EXPECT_TRUE(proxy->Open());
|
| - proxy->Close();
|
| +TEST_F(AudioOutputProxyTest, OpenAndClose_Mixer) {
|
| + OpenAndClose(mixer_);
|
| }
|
|
|
| // Create a stream, and verify that it is closed after kTestCloseDelayMs.
|
| @@ -148,7 +275,7 @@
|
| EXPECT_CALL(stream, Close())
|
| .Times(1);
|
|
|
| - AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_);
|
| + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
|
| EXPECT_TRUE(proxy->Open());
|
|
|
| // Simulate a delay.
|
| @@ -162,87 +289,28 @@
|
| proxy->Close();
|
| }
|
|
|
| -// Create a stream, and then calls Start() and Stop().
|
| TEST_F(AudioOutputProxyTest, StartAndStop) {
|
| - MockAudioOutputStream stream;
|
| + StartAndStop(dispatcher_impl_);
|
| +}
|
|
|
| - EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| - .WillOnce(Return(&stream));
|
| - EXPECT_CALL(stream, Open())
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(stream, Start(_))
|
| - .Times(1);
|
| - EXPECT_CALL(stream, SetVolume(_))
|
| - .Times(1);
|
| - EXPECT_CALL(stream, Stop())
|
| - .Times(1);
|
| - EXPECT_CALL(stream, Close())
|
| - .Times(1);
|
| -
|
| - AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_);
|
| - EXPECT_TRUE(proxy->Open());
|
| -
|
| - proxy->Start(&callback_);
|
| - proxy->Stop();
|
| -
|
| - proxy->Close();
|
| +TEST_F(AudioOutputProxyTest, StartAndStop_Mixer) {
|
| + StartAndStop(mixer_);
|
| }
|
|
|
| -// Verify that the stream is closed after Stop is called.
|
| TEST_F(AudioOutputProxyTest, CloseAfterStop) {
|
| - MockAudioOutputStream stream;
|
| + CloseAfterStop(dispatcher_impl_);
|
| +}
|
|
|
| - EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| - .WillOnce(Return(&stream));
|
| - EXPECT_CALL(stream, Open())
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(stream, Start(_))
|
| - .Times(1);
|
| - EXPECT_CALL(stream, SetVolume(_))
|
| - .Times(1);
|
| - EXPECT_CALL(stream, Stop())
|
| - .Times(1);
|
| - EXPECT_CALL(stream, Close())
|
| - .Times(1);
|
| -
|
| - AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_);
|
| - EXPECT_TRUE(proxy->Open());
|
| -
|
| - proxy->Start(&callback_);
|
| - proxy->Stop();
|
| -
|
| - // Wait for StreamStopped() to post StopStreamTask().
|
| - base::PlatformThread::Sleep(pause_delay_ * 2);
|
| - message_loop_.RunAllPending();
|
| -
|
| - // Wait for the close timer to fire.
|
| - base::PlatformThread::Sleep(
|
| - base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2);
|
| - message_loop_.RunAllPending();
|
| -
|
| - // Verify expectation before calling Close().
|
| - Mock::VerifyAndClear(&stream);
|
| -
|
| - proxy->Close();
|
| +TEST_F(AudioOutputProxyTest, CloseAfterStop_Mixer) {
|
| + CloseAfterStop(mixer_);
|
| }
|
|
|
| -// Create two streams, but don't start them. Only one device must be open.
|
| TEST_F(AudioOutputProxyTest, TwoStreams) {
|
| - MockAudioOutputStream stream;
|
| + TwoStreams(dispatcher_impl_);
|
| +}
|
|
|
| - EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| - .WillOnce(Return(&stream));
|
| - EXPECT_CALL(stream, Open())
|
| - .WillOnce(Return(true));
|
| - EXPECT_CALL(stream, Close())
|
| - .Times(1);
|
| -
|
| - AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_);
|
| - AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_);
|
| - EXPECT_TRUE(proxy1->Open());
|
| - EXPECT_TRUE(proxy2->Open());
|
| - proxy1->Close();
|
| - proxy2->Close();
|
| +TEST_F(AudioOutputProxyTest, TwoStreams_Mixer) {
|
| + TwoStreams(mixer_);
|
| }
|
|
|
| // Two streams: verify that second stream is allocated when the first
|
| @@ -273,8 +341,8 @@
|
| EXPECT_CALL(stream2, Close())
|
| .Times(1);
|
|
|
| - AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_);
|
| - AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_);
|
| + AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_impl_);
|
| + AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_impl_);
|
| EXPECT_TRUE(proxy1->Open());
|
| EXPECT_TRUE(proxy2->Open());
|
|
|
| @@ -286,6 +354,39 @@
|
| proxy2->Close();
|
| }
|
|
|
| +// Two streams: verify that only one device will be created.
|
| +TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying_Mixer) {
|
| + MockAudioOutputStream stream;
|
| +
|
| + InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
|
| +
|
| + EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| + .WillOnce(Return(&stream));
|
| +
|
| + EXPECT_CALL(stream, Open())
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(stream, Start(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, SetVolume(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Stop())
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Close())
|
| + .Times(1);
|
| +
|
| + AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_);
|
| + AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_);
|
| + EXPECT_TRUE(proxy1->Open());
|
| + EXPECT_TRUE(proxy2->Open());
|
| +
|
| + proxy1->Start(&callback_);
|
| + proxy1->Stop();
|
| +
|
| + proxy1->Close();
|
| + proxy2->Close();
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| +}
|
| +
|
| // Two streams, both are playing. Dispatcher should not open a third stream.
|
| TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) {
|
| MockAudioOutputStream stream1;
|
| @@ -319,8 +420,8 @@
|
| EXPECT_CALL(stream2, Close())
|
| .Times(1);
|
|
|
| - AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_);
|
| - AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_);
|
| + AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher_impl_);
|
| + AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher_impl_);
|
| EXPECT_TRUE(proxy1->Open());
|
| EXPECT_TRUE(proxy2->Open());
|
|
|
| @@ -333,22 +434,49 @@
|
| proxy2->Close();
|
| }
|
|
|
| -// Open() method failed.
|
| -TEST_F(AudioOutputProxyTest, OpenFailed) {
|
| +// Two streams, both are playing. Still have to use single device.
|
| +TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying_Mixer) {
|
| MockAudioOutputStream stream;
|
|
|
| + InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs));
|
| +
|
| EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| .WillOnce(Return(&stream));
|
| +
|
| EXPECT_CALL(stream, Open())
|
| - .WillOnce(Return(false));
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(stream, Start(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, SetVolume(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Stop())
|
| + .Times(1);
|
| EXPECT_CALL(stream, Close())
|
| .Times(1);
|
|
|
| - AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_);
|
| - EXPECT_FALSE(proxy->Open());
|
| - proxy->Close();
|
| + AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_);
|
| + AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_);
|
| + EXPECT_TRUE(proxy1->Open());
|
| + EXPECT_TRUE(proxy2->Open());
|
| +
|
| + proxy1->Start(&callback_);
|
| + proxy2->Start(&callback_);
|
| + proxy1->Stop();
|
| + proxy2->Stop();
|
| +
|
| + proxy1->Close();
|
| + proxy2->Close();
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| }
|
|
|
| +TEST_F(AudioOutputProxyTest, OpenFailed) {
|
| + OpenFailed(dispatcher_impl_);
|
| +}
|
| +
|
| +TEST_F(AudioOutputProxyTest, OpenFailed_Mixer) {
|
| + OpenFailed(mixer_);
|
| +}
|
| +
|
| // Start() method failed.
|
| TEST_F(AudioOutputProxyTest, StartFailed) {
|
| MockAudioOutputStream stream;
|
| @@ -360,7 +488,7 @@
|
| EXPECT_CALL(stream, Close())
|
| .Times(1);
|
|
|
| - AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_);
|
| + AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_);
|
| EXPECT_TRUE(proxy->Open());
|
|
|
| // Simulate a delay.
|
| @@ -385,4 +513,48 @@
|
| proxy->Close();
|
| }
|
|
|
| +// Start() method failed.
|
| +TEST_F(AudioOutputProxyTest, StartFailed_Mixer) {
|
| + MockAudioOutputStream stream;
|
| +
|
| + EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| + .WillOnce(Return(&stream));
|
| + EXPECT_CALL(stream, Open())
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(stream, Close())
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Start(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, SetVolume(_))
|
| + .Times(1);
|
| + EXPECT_CALL(stream, Stop())
|
| + .Times(1);
|
| +
|
| + AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_);
|
| + AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_);
|
| + EXPECT_TRUE(proxy1->Open());
|
| + EXPECT_TRUE(proxy2->Open());
|
| + proxy1->Start(&callback_);
|
| + proxy1->Stop();
|
| + proxy1->Close();
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| +
|
| + // Verify expectation before continueing.
|
| + Mock::VerifyAndClear(&stream);
|
| +
|
| + // |stream| is closed at this point. Start() should reopen it again.
|
| + EXPECT_CALL(manager(), MakeAudioOutputStream(_))
|
| + .WillOnce(Return(reinterpret_cast<AudioOutputStream*>(NULL)));
|
| +
|
| + EXPECT_CALL(callback_, OnError(_, _))
|
| + .Times(1);
|
| +
|
| + proxy2->Start(&callback_);
|
| +
|
| + Mock::VerifyAndClear(&callback_);
|
| +
|
| + proxy2->Close();
|
| + WaitForCloseTimer(kTestCloseDelayMs);
|
| +}
|
| +
|
| } // namespace media
|
|
|