Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: media/audio/audio_manager_unittest.cc

Issue 1806313003: Pass task runners to AudioManager constructor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: DCHECK -> CHECK Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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" 5 #include "base/bind.h"
6 #include "base/environment.h" 6 #include "base/environment.h"
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h"
9 #include "base/synchronization/waitable_event.h" 10 #include "base/synchronization/waitable_event.h"
11 #include "base/test/test_message_loop.h"
12 #include "base/thread_task_runner_handle.h"
10 #include "build/build_config.h" 13 #include "build/build_config.h"
11 #include "media/audio/audio_manager.h" 14 #include "media/audio/audio_manager.h"
12 #include "media/audio/audio_manager_base.h" 15 #include "media/audio/audio_manager_base.h"
13 #include "media/audio/audio_output_proxy.h" 16 #include "media/audio/audio_output_proxy.h"
14 #include "media/audio/audio_unittest_util.h" 17 #include "media/audio/audio_unittest_util.h"
15 #include "media/audio/fake_audio_log_factory.h" 18 #include "media/audio/fake_audio_log_factory.h"
16 #include "media/audio/fake_audio_manager.h" 19 #include "media/audio/fake_audio_manager.h"
17 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
18 21
19 #if defined(USE_ALSA) 22 #if defined(USE_ALSA)
20 #include "media/audio/alsa/audio_manager_alsa.h" 23 #include "media/audio/alsa/audio_manager_alsa.h"
21 #endif // defined(USE_ALSA) 24 #endif // defined(USE_ALSA)
22 25
23 #if defined(OS_WIN) 26 #if defined(OS_WIN)
24 #include "base/win/scoped_com_initializer.h" 27 #include "base/win/scoped_com_initializer.h"
25 #include "media/audio/win/audio_manager_win.h" 28 #include "media/audio/win/audio_manager_win.h"
26 #include "media/audio/win/wavein_input_win.h" 29 #include "media/audio/win/wavein_input_win.h"
27 #endif 30 #endif
28 31
29 #if defined(USE_PULSEAUDIO) 32 #if defined(USE_PULSEAUDIO)
30 #include "media/audio/pulse/audio_manager_pulse.h" 33 #include "media/audio/pulse/audio_manager_pulse.h"
31 #endif // defined(USE_PULSEAUDIO) 34 #endif // defined(USE_PULSEAUDIO)
32 35
33 namespace media { 36 namespace media {
34 37
38 namespace {
39 template <typename T>
40 struct TestAudioManagerFactory {
41 static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) {
42 return ScopedAudioManagerPtr(new T(base::ThreadTaskRunnerHandle::Get(),
43 base::ThreadTaskRunnerHandle::Get(),
44 audio_log_factory));
45 };
tommi (sloooow) - chröme 2016/04/13 07:31:51 remove semicolon (here and below)
alokp 2016/04/17 16:55:19 Done.
46 };
47
48 #if defined(USE_PULSEAUDIO)
49 template <>
50 struct TestAudioManagerFactory<AudioManagerPulse> {
51 static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) {
52 std::unique_ptr<AudioManagerPulse, AudioManagerDeleter> manager(
53 new AudioManagerPulse(base::ThreadTaskRunnerHandle::Get(),
54 base::ThreadTaskRunnerHandle::Get(),
55 audio_log_factory));
56 if (!manager->Init())
57 manager.reset();
58 return std::move(manager);
59 };
60 };
61 #endif // defined(USE_PULSEAUDIO)
62
63 template <>
64 struct TestAudioManagerFactory<std::nullptr_t> {
65 static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) {
66 return AudioManager::Create(base::ThreadTaskRunnerHandle::Get(),
67 base::ThreadTaskRunnerHandle::Get(), nullptr,
68 audio_log_factory);
69 };
70 };
71 } // namespace
72
35 // Test fixture which allows us to override the default enumeration API on 73 // Test fixture which allows us to override the default enumeration API on
36 // Windows. 74 // Windows.
37 class AudioManagerTest : public ::testing::Test { 75 class AudioManagerTest : public ::testing::Test {
38 public: 76 public:
39 void HandleDefaultDeviceIDsTest() { 77 void HandleDefaultDeviceIDsTest() {
40 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, 78 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
41 CHANNEL_LAYOUT_STEREO, 48000, 16, 2048); 79 CHANNEL_LAYOUT_STEREO, 48000, 16, 2048);
42 80
43 // Create a stream with the default device id "". 81 // Create a stream with the default device id "".
44 AudioOutputStream* stream = 82 AudioOutputStream* stream =
(...skipping 25 matching lines...) Expand all
70 *params = audio_manager_->GetDefaultOutputStreamParameters(); 108 *params = audio_manager_->GetDefaultOutputStreamParameters();
71 } 109 }
72 110
73 void GetAssociatedOutputDeviceID(const std::string& input_device_id, 111 void GetAssociatedOutputDeviceID(const std::string& input_device_id,
74 std::string* output_device_id) { 112 std::string* output_device_id) {
75 *output_device_id = 113 *output_device_id =
76 audio_manager_->GetAssociatedOutputDeviceID(input_device_id); 114 audio_manager_->GetAssociatedOutputDeviceID(input_device_id);
77 } 115 }
78 116
79 protected: 117 protected:
80 AudioManagerTest() : audio_manager_(AudioManager::CreateForTesting()) { 118 AudioManagerTest() { CreateAudioManagerForTesting(); }
81 // Wait for audio thread initialization to complete. Otherwise the 119 ~AudioManagerTest() override {}
82 // enumeration type may not have been set yet.
83 base::WaitableEvent event(false, false);
84 audio_manager_->GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
85 &base::WaitableEvent::Signal, base::Unretained(&event)));
86 event.Wait();
87 }
88 120
89 #if defined(OS_WIN) 121 #if defined(OS_WIN)
90 bool SetMMDeviceEnumeration() { 122 bool SetMMDeviceEnumeration() {
91 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get()); 123 AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
92 // Windows Wave is used as default if Windows XP was detected => 124 // Windows Wave is used as default if Windows XP was detected =>
93 // return false since MMDevice is not supported on XP. 125 // return false since MMDevice is not supported on XP.
94 if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration) 126 if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
95 return false; 127 return false;
96 128
97 amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration); 129 amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 ++it; 174 ++it;
143 } 175 }
144 } else { 176 } else {
145 // Log a warning so we can see the status on the build bots. No need to 177 // Log a warning so we can see the status on the build bots. No need to
146 // break the test though since this does successfully test the code and 178 // break the test though since this does successfully test the code and
147 // some failure cases. 179 // some failure cases.
148 LOG(WARNING) << "No input devices detected"; 180 LOG(WARNING) << "No input devices detected";
149 } 181 }
150 } 182 }
151 183
152 void HasInputDevicesAvailable(bool* has_devices) { 184 bool InputDevicesAvailable() {
153 *has_devices = audio_manager_->HasAudioInputDevices(); 185 return audio_manager_->HasAudioInputDevices();
186 }
187 bool OutputDevicesAvailable() {
188 return audio_manager_->HasAudioOutputDevices();
154 } 189 }
155 190
156 void HasOutputDevicesAvailable(bool* has_devices) { 191 template <typename T = std::nullptr_t>
157 *has_devices = audio_manager_->HasAudioOutputDevices();
158 }
159
160 bool InputDevicesAvailable() {
161 bool has_devices = false;
162 RunOnAudioThread(base::Bind(&AudioManagerTest::HasInputDevicesAvailable,
163 base::Unretained(this), &has_devices));
164 return has_devices;
165 }
166
167 bool OutputDevicesAvailable() {
168 bool has_devices = false;
169 RunOnAudioThread(base::Bind(&AudioManagerTest::HasOutputDevicesAvailable,
170 base::Unretained(this), &has_devices));
171 return has_devices;
172 }
173
174 #if defined(USE_ALSA) || defined(USE_PULSEAUDIO)
175 template <class T>
176 void CreateAudioManagerForTesting() { 192 void CreateAudioManagerForTesting() {
177 // Only one AudioManager may exist at a time, so destroy the one we're 193 // Only one AudioManager may exist at a time, so destroy the one we're
178 // currently holding before creating a new one. 194 // currently holding before creating a new one.
195 // Flush the message loop to run any shutdown tasks posted by AudioManager.
179 audio_manager_.reset(); 196 audio_manager_.reset();
180 audio_manager_.reset(T::Create(&fake_audio_log_factory_)); 197 base::RunLoop().RunUntilIdle();
181 }
182 #endif
183 198
184 // Synchronously runs the provided callback/closure on the audio thread. 199 audio_manager_ =
185 void RunOnAudioThread(const base::Closure& closure) { 200 TestAudioManagerFactory<T>::Create(&fake_audio_log_factory_);
186 if (!audio_manager_->GetTaskRunner()->BelongsToCurrentThread()) { 201 // A few AudioManager implementations post initialization tasks to
187 base::WaitableEvent event(false, false); 202 // audio thread. Flush the thread to ensure that |audio_manager_| is
188 audio_manager_->GetTaskRunner()->PostTask( 203 // initialized and ready to use before returning from this function.
189 FROM_HERE, 204 // TODO(alokp): We should perhaps do this in AudioManager::Create().
190 base::Bind(&AudioManagerTest::RunOnAudioThreadImpl, 205 base::RunLoop().RunUntilIdle();
191 base::Unretained(this),
192 closure,
193 &event));
194 event.Wait();
195 } else {
196 closure.Run();
197 }
198 } 206 }
199 207
200 void RunOnAudioThreadImpl(const base::Closure& closure, 208 base::TestMessageLoop message_loop_;
201 base::WaitableEvent* event) {
202 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
203 closure.Run();
204 event->Signal();
205 }
206
207 FakeAudioLogFactory fake_audio_log_factory_; 209 FakeAudioLogFactory fake_audio_log_factory_;
208 scoped_ptr<AudioManager> audio_manager_; 210 ScopedAudioManagerPtr audio_manager_;
209 }; 211 };
210 212
211 TEST_F(AudioManagerTest, HandleDefaultDeviceIDs) { 213 TEST_F(AudioManagerTest, HandleDefaultDeviceIDs) {
212 // Use a fake manager so we can makeup device ids, this will still use the 214 // Use a fake manager so we can makeup device ids, this will still use the
213 // AudioManagerBase code. 215 // AudioManagerBase code.
214 audio_manager_.reset(new FakeAudioManager(&fake_audio_log_factory_)); 216 CreateAudioManagerForTesting<FakeAudioManager>();
215 RunOnAudioThread(base::Bind(&AudioManagerTest::HandleDefaultDeviceIDsTest, 217 HandleDefaultDeviceIDsTest();
216 base::Unretained(this))); 218 base::RunLoop().RunUntilIdle();
217 } 219 }
218 220
219 // Test that devices can be enumerated. 221 // Test that devices can be enumerated.
220 TEST_F(AudioManagerTest, EnumerateInputDevices) { 222 TEST_F(AudioManagerTest, EnumerateInputDevices) {
221 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable()); 223 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
222 224
223 AudioDeviceNames device_names; 225 AudioDeviceNames device_names;
224 RunOnAudioThread( 226 audio_manager_->GetAudioInputDeviceNames(&device_names);
225 base::Bind(&AudioManager::GetAudioInputDeviceNames,
226 base::Unretained(audio_manager_.get()),
227 &device_names));
228 CheckDeviceNames(device_names); 227 CheckDeviceNames(device_names);
229 } 228 }
230 229
231 // Test that devices can be enumerated. 230 // Test that devices can be enumerated.
232 TEST_F(AudioManagerTest, EnumerateOutputDevices) { 231 TEST_F(AudioManagerTest, EnumerateOutputDevices) {
233 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable()); 232 ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
234 233
235 AudioDeviceNames device_names; 234 AudioDeviceNames device_names;
236 RunOnAudioThread( 235 audio_manager_->GetAudioOutputDeviceNames(&device_names);
237 base::Bind(&AudioManager::GetAudioOutputDeviceNames,
238 base::Unretained(audio_manager_.get()),
239 &device_names));
240 CheckDeviceNames(device_names); 236 CheckDeviceNames(device_names);
241 } 237 }
242 238
243 // Run additional tests for Windows since enumeration can be done using 239 // Run additional tests for Windows since enumeration can be done using
244 // two different APIs. MMDevice is default for Vista and higher and Wave 240 // two different APIs. MMDevice is default for Vista and higher and Wave
245 // is default for XP and lower. 241 // is default for XP and lower.
246 #if defined(OS_WIN) 242 #if defined(OS_WIN)
247 243
248 // Override default enumeration API and force usage of Windows MMDevice. 244 // Override default enumeration API and force usage of Windows MMDevice.
249 // This test will only run on Windows Vista and higher. 245 // This test will only run on Windows Vista and higher.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 audio_manager_->GetAudioOutputDeviceNames(&device_names); 392 audio_manager_->GetAudioOutputDeviceNames(&device_names);
397 CheckDeviceNames(device_names); 393 CheckDeviceNames(device_names);
398 } 394 }
399 #endif // defined(USE_ALSA) 395 #endif // defined(USE_ALSA)
400 396
401 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) { 397 TEST_F(AudioManagerTest, GetDefaultOutputStreamParameters) {
402 #if defined(OS_WIN) || defined(OS_MACOSX) 398 #if defined(OS_WIN) || defined(OS_MACOSX)
403 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable()); 399 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
404 400
405 AudioParameters params; 401 AudioParameters params;
406 RunOnAudioThread( 402 GetDefaultOutputStreamParameters(&params);
407 base::Bind(&AudioManagerTest::GetDefaultOutputStreamParameters,
408 base::Unretained(this), &params));
409 EXPECT_TRUE(params.IsValid()); 403 EXPECT_TRUE(params.IsValid());
410 #endif // defined(OS_WIN) || defined(OS_MACOSX) 404 #endif // defined(OS_WIN) || defined(OS_MACOSX)
411 } 405 }
412 406
413 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) { 407 TEST_F(AudioManagerTest, GetAssociatedOutputDeviceID) {
414 #if defined(OS_WIN) || defined(OS_MACOSX) 408 #if defined(OS_WIN) || defined(OS_MACOSX)
415 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable() && OutputDevicesAvailable()); 409 ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable() && OutputDevicesAvailable());
416 410
417 AudioDeviceNames device_names; 411 AudioDeviceNames device_names;
418 RunOnAudioThread(base::Bind(&AudioManager::GetAudioInputDeviceNames, 412 audio_manager_->GetAudioInputDeviceNames(&device_names);
419 base::Unretained(audio_manager_.get()),
420 &device_names));
421 bool found_an_associated_device = false; 413 bool found_an_associated_device = false;
422 for (AudioDeviceNames::iterator it = device_names.begin(); 414 for (AudioDeviceNames::iterator it = device_names.begin();
423 it != device_names.end(); 415 it != device_names.end();
424 ++it) { 416 ++it) {
425 EXPECT_FALSE(it->unique_id.empty()); 417 EXPECT_FALSE(it->unique_id.empty());
426 EXPECT_FALSE(it->device_name.empty()); 418 EXPECT_FALSE(it->device_name.empty());
427 std::string output_device_id; 419 std::string output_device_id;
428 RunOnAudioThread(base::Bind(&AudioManagerTest::GetAssociatedOutputDeviceID, 420 GetAssociatedOutputDeviceID(it->unique_id, &output_device_id);
429 base::Unretained(this), it->unique_id,
430 &output_device_id));
431 if (!output_device_id.empty()) { 421 if (!output_device_id.empty()) {
432 DVLOG(2) << it->unique_id << " matches with " << output_device_id; 422 DVLOG(2) << it->unique_id << " matches with " << output_device_id;
433 found_an_associated_device = true; 423 found_an_associated_device = true;
434 } 424 }
435 } 425 }
436 426
437 EXPECT_TRUE(found_an_associated_device); 427 EXPECT_TRUE(found_an_associated_device);
438 #endif // defined(OS_WIN) || defined(OS_MACOSX) 428 #endif // defined(OS_WIN) || defined(OS_MACOSX)
439 } 429 }
440 430
441 } // namespace media 431 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698