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 |