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