Index: media/audio/audio_output_controller_unittest.cc |
diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc |
index fe29ce59af3f969a10191e1b5742cbe64acfd389..bd665fd9b7be072fa0a91beaed60cd8da516f076 100644 |
--- a/media/audio/audio_output_controller_unittest.cc |
+++ b/media/audio/audio_output_controller_unittest.cc |
@@ -9,6 +9,7 @@ |
#include "base/message_loop.h" |
#include "base/synchronization/waitable_event.h" |
#include "media/audio/audio_output_controller.h" |
+#include "media/audio/virtual_audio_input_stream.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -77,11 +78,20 @@ static void CloseAudioController(AudioOutputController* controller) { |
class AudioOutputControllerTest : public testing::Test { |
public: |
- AudioOutputControllerTest() {} |
+ AudioOutputControllerTest() : done_(false, false) {} |
virtual ~AudioOutputControllerTest() {} |
+ void EndTestVirtualAudioTest(int callbacks) { |
+ stream_->Stop(); |
+ stream_->Close(); |
+ |
+ done_.Signal(); |
+ } |
+ |
protected: |
+ AudioInputStream* stream_; |
MessageLoopForIO message_loop_; |
+ base::WaitableEvent done_; |
private: |
DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest); |
@@ -283,4 +293,74 @@ TEST_F(AudioOutputControllerTest, PlayStateChangeClose) { |
CloseAudioController(controller); |
} |
+// Tests that we detach an existing audio stream and re-attach them as virtual |
+// output streams when a VirtualAudioInputStream is created. |
+TEST_F(AudioOutputControllerTest, VirtualStreamsTriggerDeviceChange) { |
+ scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); |
+ if (!audio_manager->HasAudioOutputDevices()) |
+ return; |
+ |
+ MockAudioOutputControllerEventHandler event_handler; |
+ base::WaitableEvent event(false, false); |
+ EXPECT_CALL(event_handler, OnCreated(NotNull())) |
+ .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); |
+ |
+ // OnPlaying() will be called once normally and once after being recreated. |
+ base::WaitableEvent play_event(false, false); |
+ EXPECT_CALL(event_handler, OnPlaying(NotNull())) |
+ .Times(2) |
+ .WillRepeatedly(InvokeWithoutArgs( |
+ &play_event, &base::WaitableEvent::Signal)); |
+ |
+ // OnPaused() should not be called during the state change event. |
+ EXPECT_CALL(event_handler, OnPaused(NotNull())) |
+ .Times(0); |
+ |
+ MockAudioOutputControllerSyncReader sync_reader; |
+ EXPECT_CALL(sync_reader, UpdatePendingBytes(_)) |
+ .Times(AtLeast(1)); |
+ EXPECT_CALL(sync_reader, Read(_, _)) |
+ .WillRepeatedly(DoAll(ClearBuffer(), SignalEvent(&event), Return(4))); |
+ EXPECT_CALL(sync_reader, DataReady()) |
+ .WillRepeatedly(Return(true)); |
+ EXPECT_CALL(sync_reader, Close()); |
+ |
+ AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, |
+ kSampleRate, kBitsPerSample, kSamplesPerPacket); |
+ scoped_refptr<AudioOutputController> controller = |
+ AudioOutputController::Create( |
+ audio_manager.get(), &event_handler, params, &sync_reader); |
+ ASSERT_TRUE(controller.get()); |
+ |
+ // Wait for OnCreated() to be called. |
+ event.Wait(); |
+ |
+ ASSERT_FALSE(play_event.IsSignaled()); |
+ controller->Play(); |
+ play_event.Wait(); |
+ |
+ play_event.Reset(); |
+ |
+ // Create a new VirtualAudioInputStream and expect another play event and |
+ // the existing output stream to be recreated as a VirtualAudiOutputStream and |
+ // attached. |
+ stream_ = audio_manager->MakeAudioInputStream( |
+ AudioParameters(AudioParameters::AUDIO_MIRROR_BROWSER, |
+ CHANNEL_LAYOUT_MONO, 8000, 8, 128), "1"); |
+ |
+ play_event.Wait(); |
+ EXPECT_EQ(1u, |
+ static_cast<VirtualAudioInputStream*>(stream_)->converters_.size()); |
+ |
+ int callbacks = 0; |
+ audio_manager->GetMessageLoop()->PostTask(FROM_HERE, base::Bind( |
+ &AudioOutputControllerTest::EndTestVirtualAudioTest, |
+ base::Unretained(this), |
+ callbacks)); |
+ done_.Wait(); |
+ |
+ // Now stop the controller. |
+ CloseAudioController(controller); |
+} |
+ |
} // namespace media |