OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "base/bind.h" |
| 6 #include "base/bind_helpers.h" |
5 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/message_loop_proxy.h" |
6 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
7 #include "media/audio/audio_manager.h" | 10 #include "media/audio/audio_manager.h" |
8 #include "media/audio/simple_sources.h" | 11 #include "media/audio/simple_sources.h" |
9 #include "media/audio/virtual_audio_input_stream.h" | 12 #include "media/audio/virtual_audio_input_stream.h" |
10 #include "media/audio/virtual_audio_output_stream.h" | 13 #include "media/audio/virtual_audio_output_stream.h" |
11 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
13 | 16 |
14 using ::testing::_; | 17 using ::testing::_; |
15 | 18 |
16 namespace media { | 19 namespace media { |
17 | 20 |
18 class MockVirtualAudioInputStream : public VirtualAudioInputStream { | 21 class MockVirtualAudioInputStream : public VirtualAudioInputStream { |
19 public: | 22 public: |
20 MockVirtualAudioInputStream(AudioManagerBase* manager, | 23 MockVirtualAudioInputStream(const AudioParameters& params, |
21 AudioParameters params, | 24 base::MessageLoopProxy* message_loop, |
22 base::MessageLoopProxy* message_loop) | 25 const AfterCloseCallback& after_close_cb) |
23 : VirtualAudioInputStream(manager, params, message_loop) {} | 26 : VirtualAudioInputStream(params, message_loop, after_close_cb) {} |
24 ~MockVirtualAudioInputStream() {} | 27 ~MockVirtualAudioInputStream() {} |
25 | 28 |
26 MOCK_METHOD2(AddOutputStream, void(VirtualAudioOutputStream* stream, | 29 MOCK_METHOD2(AddOutputStream, void(VirtualAudioOutputStream* stream, |
27 const AudioParameters& output_params)); | 30 const AudioParameters& output_params)); |
28 MOCK_METHOD2(RemoveOutputStream, void(VirtualAudioOutputStream* stream, | 31 MOCK_METHOD2(RemoveOutputStream, void(VirtualAudioOutputStream* stream, |
29 const AudioParameters& output_params)); | 32 const AudioParameters& output_params)); |
30 | 33 |
31 private: | 34 private: |
32 DISALLOW_COPY_AND_ASSIGN(MockVirtualAudioInputStream); | 35 DISALLOW_COPY_AND_ASSIGN(MockVirtualAudioInputStream); |
33 }; | 36 }; |
34 | 37 |
35 class MockAudioDeviceListener : public AudioManager::AudioDeviceListener { | 38 class MockAudioDeviceListener : public AudioManager::AudioDeviceListener { |
36 public: | 39 public: |
37 MOCK_METHOD0(OnDeviceChange, void()); | 40 MOCK_METHOD0(OnDeviceChange, void()); |
38 }; | 41 }; |
39 | 42 |
40 class VirtualAudioOutputStreamTest : public testing::Test { | 43 class VirtualAudioOutputStreamTest : public testing::Test { |
41 public: | 44 public: |
| 45 VirtualAudioOutputStreamTest() |
| 46 : audio_manager_(AudioManager::Create()) {} |
| 47 |
| 48 scoped_refptr<base::MessageLoopProxy> audio_message_loop() const { |
| 49 return audio_manager_->GetMessageLoop(); |
| 50 } |
| 51 |
42 void ListenAndCreateVirtualOnAudioThread( | 52 void ListenAndCreateVirtualOnAudioThread( |
43 AudioManager* manager, AudioManager::AudioDeviceListener* listener) { | 53 AudioManager::AudioDeviceListener* listener) { |
44 manager->AddOutputDeviceChangeListener(listener); | 54 audio_manager_->AddOutputDeviceChangeListener(listener); |
45 | 55 |
46 AudioParameters params( | 56 AudioParameters params( |
47 AudioParameters::AUDIO_VIRTUAL, CHANNEL_LAYOUT_MONO, 8000, 8, 128); | 57 AudioParameters::AUDIO_VIRTUAL, CHANNEL_LAYOUT_MONO, 8000, 8, 128); |
48 AudioInputStream* stream = manager->MakeAudioInputStream(params, "1"); | 58 AudioInputStream* stream = |
49 stream->Close(); | 59 audio_manager_->MakeAudioInputStream(params, "1"); |
50 signal_.Signal(); | 60 stream->Open(); |
| 61 stream->Close(); // AudioManager deletes |stream|. |
51 } | 62 } |
52 | 63 |
53 void RemoveListenerOnAudioThread( | 64 void RemoveListenerOnAudioThread( |
54 AudioManager* manager, AudioManager::AudioDeviceListener* listener) { | 65 AudioManager::AudioDeviceListener* listener) { |
55 manager->RemoveOutputDeviceChangeListener(listener); | 66 audio_manager_->RemoveOutputDeviceChangeListener(listener); |
56 signal_.Signal(); | |
57 } | 67 } |
58 | 68 |
59 protected: | 69 void SyncWithAudioThread() { |
60 VirtualAudioOutputStreamTest() : signal_(false, false) {} | 70 base::WaitableEvent done(false, false); |
61 | 71 audio_message_loop()->PostTask( |
62 base::WaitableEvent signal_; | 72 FROM_HERE, base::Bind(&base::WaitableEvent::Signal, |
| 73 base::Unretained(&done))); |
| 74 done.Wait(); |
| 75 } |
63 | 76 |
64 private: | 77 private: |
| 78 scoped_ptr<AudioManager> audio_manager_; |
| 79 |
65 DISALLOW_COPY_AND_ASSIGN(VirtualAudioOutputStreamTest); | 80 DISALLOW_COPY_AND_ASSIGN(VirtualAudioOutputStreamTest); |
66 }; | 81 }; |
67 | 82 |
68 TEST_F(VirtualAudioOutputStreamTest, StartStopStartStop) { | 83 TEST_F(VirtualAudioOutputStreamTest, StartStopStartStop) { |
69 scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); | 84 static const int kCycles = 3; |
70 | |
71 MessageLoop message_loop; | |
72 | 85 |
73 AudioParameters params( | 86 AudioParameters params( |
74 AudioParameters::AUDIO_VIRTUAL, CHANNEL_LAYOUT_MONO, 8000, 8, 128); | 87 AudioParameters::AUDIO_VIRTUAL, CHANNEL_LAYOUT_MONO, 8000, 8, 128); |
75 AudioParameters output_params( | 88 AudioParameters output_params( |
76 AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, 8000, 8, 128); | 89 AudioParameters::AUDIO_FAKE, CHANNEL_LAYOUT_MONO, 8000, 8, 128); |
77 | 90 |
78 MockVirtualAudioInputStream input_stream( | 91 MockVirtualAudioInputStream* const input_stream = |
79 static_cast<AudioManagerBase*>(audio_manager.get()), | 92 new MockVirtualAudioInputStream( |
80 params, | 93 params, audio_message_loop(), |
81 message_loop.message_loop_proxy()); | 94 base::Bind(&base::DeletePointer<VirtualAudioInputStream>)); |
| 95 audio_message_loop()->PostTask( |
| 96 FROM_HERE, base::Bind( |
| 97 base::IgnoreResult(&MockVirtualAudioInputStream::Open), |
| 98 base::Unretained(input_stream))); |
82 | 99 |
83 EXPECT_CALL(input_stream, AddOutputStream(_, _)).Times(2); | 100 VirtualAudioOutputStream* const output_stream = |
84 EXPECT_CALL(input_stream, RemoveOutputStream(_, _)).Times(2); | 101 new VirtualAudioOutputStream( |
| 102 output_params, audio_message_loop(), input_stream, |
| 103 base::Bind(&base::DeletePointer<VirtualAudioOutputStream>)); |
85 | 104 |
86 scoped_ptr<VirtualAudioOutputStream> output_stream( | 105 EXPECT_CALL(*input_stream, AddOutputStream(output_stream, _)) |
87 VirtualAudioOutputStream::MakeStream( | 106 .Times(kCycles); |
88 static_cast<AudioManagerBase*>(audio_manager.get()), | 107 EXPECT_CALL(*input_stream, RemoveOutputStream(output_stream, _)) |
89 output_params, | 108 .Times(kCycles); |
90 message_loop.message_loop_proxy(), | |
91 &input_stream)); | |
92 | 109 |
| 110 audio_message_loop()->PostTask( |
| 111 FROM_HERE, base::Bind(base::IgnoreResult(&VirtualAudioOutputStream::Open), |
| 112 base::Unretained(output_stream))); |
93 SineWaveAudioSource source(CHANNEL_LAYOUT_STEREO, 200.0, 128); | 113 SineWaveAudioSource source(CHANNEL_LAYOUT_STEREO, 200.0, 128); |
94 output_stream->Start(&source); | 114 for (int i = 0; i < kCycles; ++i) { |
95 output_stream->Stop(); | 115 audio_message_loop()->PostTask( |
96 output_stream->Start(&source); | 116 FROM_HERE, base::Bind(&VirtualAudioOutputStream::Start, |
97 output_stream->Stop(); | 117 base::Unretained(output_stream), |
98 // Can't Close() here because we didn't create this output stream is not owned | 118 &source)); |
99 // by the audio manager. | 119 audio_message_loop()->PostTask( |
| 120 FROM_HERE, base::Bind(&VirtualAudioOutputStream::Stop, |
| 121 base::Unretained(output_stream))); |
| 122 } |
| 123 audio_message_loop()->PostTask( |
| 124 FROM_HERE, base::Bind(&VirtualAudioOutputStream::Close, |
| 125 base::Unretained(output_stream))); |
| 126 |
| 127 audio_message_loop()->PostTask( |
| 128 FROM_HERE, base::Bind(&MockVirtualAudioInputStream::Close, |
| 129 base::Unretained(input_stream))); |
| 130 |
| 131 SyncWithAudioThread(); |
100 } | 132 } |
101 | 133 |
102 // Tests that we get notifications to reattach output streams when we create a | 134 // Tests that we get notifications to reattach output streams when we create a |
103 // VirtualAudioInputStream. | 135 // VirtualAudioInputStream. |
104 TEST_F(VirtualAudioOutputStreamTest, OutputStreamsNotified) { | 136 TEST_F(VirtualAudioOutputStreamTest, OutputStreamsNotified) { |
105 scoped_ptr<AudioManager> audio_manager(AudioManager::Create()); | |
106 | |
107 MockAudioDeviceListener mock_listener; | 137 MockAudioDeviceListener mock_listener; |
108 EXPECT_CALL(mock_listener, OnDeviceChange()).Times(2); | 138 EXPECT_CALL(mock_listener, OnDeviceChange()).Times(2); |
109 | 139 |
110 audio_manager->GetMessageLoop()->PostTask( | 140 audio_message_loop()->PostTask( |
111 FROM_HERE, base::Bind( | 141 FROM_HERE, base::Bind( |
112 &VirtualAudioOutputStreamTest::ListenAndCreateVirtualOnAudioThread, | 142 &VirtualAudioOutputStreamTest::ListenAndCreateVirtualOnAudioThread, |
113 base::Unretained(this), | 143 base::Unretained(this), |
114 audio_manager.get(), | |
115 &mock_listener)); | 144 &mock_listener)); |
116 | 145 |
117 signal_.Wait(); | 146 SyncWithAudioThread(); |
118 | 147 |
119 audio_manager->GetMessageLoop()->PostTask( | 148 audio_message_loop()->PostTask( |
120 FROM_HERE, base::Bind( | 149 FROM_HERE, base::Bind( |
121 &VirtualAudioOutputStreamTest::RemoveListenerOnAudioThread, | 150 &VirtualAudioOutputStreamTest::RemoveListenerOnAudioThread, |
122 base::Unretained(this), | 151 base::Unretained(this), |
123 audio_manager.get(), | |
124 &mock_listener)); | 152 &mock_listener)); |
125 | 153 |
126 signal_.Wait(); | 154 SyncWithAudioThread(); |
127 } | 155 } |
128 | 156 |
129 } // namespace media | 157 } // namespace media |
OLD | NEW |