Fixed example in MessageLoop::ReleaseSoon comment
[chromium-blink-merge.git] / media / audio / audio_input_volume_unittest.cc
blobe89d106f7edfc5ebb13ca6fcbe07dbabbe074af5
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
3 // found in the LICENSE file.
5 #include <cmath>
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "media/audio/audio_io.h"
10 #include "media/audio/audio_manager_base.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 #if defined(OS_WIN)
14 #include "base/win/scoped_com_initializer.h"
15 #include "media/audio/win/core_audio_util_win.h"
16 #endif
18 namespace media {
20 double GetVolumeAfterSetVolumeOnLinux(AudioInputStream* ais,
21 double target_volume) {
22 // SetVolume() is asynchronous on Linux, we need to keep trying until
23 // the SetVolume() operation is done.
24 static const int kTimesToRun = 10;
25 double volume = 0.0;
26 for (int i = 0; i < kTimesToRun; ++i) {
27 volume = ais->GetVolume();
28 if (volume == target_volume)
29 break;
31 // Sleep 100ms to wait for the operation.
32 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
35 return volume;
38 class AudioInputVolumeTest : public ::testing::Test {
39 protected:
40 AudioInputVolumeTest()
41 : audio_manager_(AudioManager::CreateForTesting())
42 #if defined(OS_WIN)
43 , com_init_(base::win::ScopedCOMInitializer::kMTA)
44 #endif
48 bool CanRunAudioTests() {
49 #if defined(OS_WIN)
50 // TODO(henrika): add support for volume control on Windows XP as well.
51 // For now, we might as well signal false already here to avoid running
52 // these tests on Windows XP.
53 if (!CoreAudioUtil::IsSupported())
54 return false;
55 #endif
56 if (!audio_manager_)
57 return false;
59 return audio_manager_->HasAudioInputDevices();
62 // Helper method which checks if the stream has volume support.
63 bool HasDeviceVolumeControl(AudioInputStream* stream) {
64 if (!stream)
65 return false;
67 return (stream->GetMaxVolume() != 0.0);
70 AudioInputStream* CreateAndOpenStream(const std::string& device_id) {
71 const AudioParameters& params =
72 audio_manager_->GetInputStreamParameters(device_id);
73 AudioInputStream* ais = audio_manager_->MakeAudioInputStream(
74 params, device_id);
75 EXPECT_TRUE(NULL != ais);
77 #if defined(OS_LINUX) || defined(OS_OPENBSD)
78 // Some linux devices do not support our settings, we may fail to open
79 // those devices.
80 if (!ais->Open()) {
81 // Default device should always be able to be opened.
82 EXPECT_TRUE(AudioManagerBase::kDefaultDeviceId != device_id);
83 ais->Close();
84 ais = NULL;
86 #elif defined(OS_WIN) || defined(OS_MACOSX)
87 EXPECT_TRUE(ais->Open());
88 #endif
90 return ais;
93 scoped_ptr<AudioManager> audio_manager_;
95 #if defined(OS_WIN)
96 base::win::ScopedCOMInitializer com_init_;
97 #endif
100 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
101 // Currently failing on linux ARM bot: http://crbug/238490
102 #define MAYBE_InputVolumeTest DISABLED_InputVolumeTest
103 #else
104 #define MAYBE_InputVolumeTest InputVolumeTest
105 #endif
107 TEST_F(AudioInputVolumeTest, MAYBE_InputVolumeTest) {
108 if (!CanRunAudioTests())
109 return;
111 // Retrieve a list of all available input devices.
112 AudioDeviceNames device_names;
113 audio_manager_->GetAudioInputDeviceNames(&device_names);
114 if (device_names.empty()) {
115 LOG(WARNING) << "Could not find any available input device";
116 return;
119 // Scan all available input devices and repeat the same test for all of them.
120 for (AudioDeviceNames::const_iterator it = device_names.begin();
121 it != device_names.end();
122 ++it) {
123 AudioInputStream* ais = CreateAndOpenStream(it->unique_id);
124 if (!ais) {
125 DLOG(WARNING) << "Failed to open stream for device " << it->unique_id;
126 continue;
129 if (!HasDeviceVolumeControl(ais)) {
130 DLOG(WARNING) << "Device: " << it->unique_id
131 << ", does not have volume control.";
132 ais->Close();
133 continue;
136 double max_volume = ais->GetMaxVolume();
137 EXPECT_GT(max_volume, 0.0);
139 // Store the current input-device volume level.
140 double original_volume = ais->GetVolume();
141 EXPECT_GE(original_volume, 0.0);
142 #if defined(OS_WIN) || defined(OS_MACOSX)
143 // Note that |original_volume| can be higher than |max_volume| on Linux.
144 EXPECT_LE(original_volume, max_volume);
145 #endif
147 // Set the volume to the maxiumum level..
148 ais->SetVolume(max_volume);
149 double current_volume = ais->GetVolume();
150 EXPECT_EQ(max_volume, current_volume);
152 // Set the volume to the mininum level (=0).
153 double new_volume = 0.0;
154 ais->SetVolume(new_volume);
155 #if defined(OS_LINUX)
156 current_volume = GetVolumeAfterSetVolumeOnLinux(ais, new_volume);
157 #else
158 current_volume = ais->GetVolume();
159 #endif
160 EXPECT_EQ(new_volume, current_volume);
162 // Set the volume to the mid level (50% of max).
163 // Verify that the absolute error is small enough.
164 new_volume = max_volume / 2;
165 ais->SetVolume(new_volume);
166 #if defined(OS_LINUX)
167 current_volume = GetVolumeAfterSetVolumeOnLinux(ais, new_volume);
168 #else
169 current_volume = ais->GetVolume();
170 #endif
171 EXPECT_LT(current_volume, max_volume);
172 EXPECT_GT(current_volume, 0);
173 EXPECT_NEAR(current_volume, new_volume, 0.25 * max_volume);
175 // Restores the volume to the original value.
176 ais->SetVolume(original_volume);
177 current_volume = ais->GetVolume();
178 EXPECT_EQ(original_volume, current_volume);
180 ais->Close();
184 } // namespace media