Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / media / audio / audio_input_volume_unittest.cc
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.
4
5 #include <cmath>
6
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"
12
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
17
18 namespace media {
19
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;
30
31     // Sleep 100ms to wait for the operation.
32     base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
33   }
34
35   return volume;
36 }
37
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
45   {
46   }
47
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;
58
59     return audio_manager_->HasAudioInputDevices();
60   }
61
62   // Helper method which checks if the stream has volume support.
63   bool HasDeviceVolumeControl(AudioInputStream* stream) {
64     if (!stream)
65       return false;
66
67     return (stream->GetMaxVolume() != 0.0);
68   }
69
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);
76
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;
85     }
86 #elif defined(OS_WIN) || defined(OS_MACOSX)
87     EXPECT_TRUE(ais->Open());
88 #endif
89
90     return ais;
91   }
92
93   scoped_ptr<AudioManager> audio_manager_;
94
95 #if defined(OS_WIN)
96   base::win::ScopedCOMInitializer com_init_;
97 #endif
98 };
99
100 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
101 // Currently failing on linux ARM bot: http://crbug/238490
102 // Also flaky on x86_64: http://crbug/236936
103 #define MAYBE_InputVolumeTest DISABLED_InputVolumeTest
104 #else
105 #define MAYBE_InputVolumeTest InputVolumeTest
106 #endif
107
108 TEST_F(AudioInputVolumeTest, MAYBE_InputVolumeTest) {
109   if (!CanRunAudioTests())
110     return;
111
112   // Retrieve a list of all available input devices.
113   AudioDeviceNames device_names;
114   audio_manager_->GetAudioInputDeviceNames(&device_names);
115   if (device_names.empty()) {
116     LOG(WARNING) << "Could not find any available input device";
117     return;
118   }
119
120   // Scan all available input devices and repeat the same test for all of them.
121   for (AudioDeviceNames::const_iterator it = device_names.begin();
122        it != device_names.end();
123        ++it) {
124     AudioInputStream* ais = CreateAndOpenStream(it->unique_id);
125     if (!ais) {
126       DLOG(WARNING) << "Failed to open stream for device " << it->unique_id;
127       continue;
128     }
129
130     if (!HasDeviceVolumeControl(ais)) {
131       DLOG(WARNING) << "Device: " << it->unique_id
132                     << ", does not have volume control.";
133       ais->Close();
134       continue;
135     }
136
137     double max_volume = ais->GetMaxVolume();
138     EXPECT_GT(max_volume, 0.0);
139
140     // Store the current input-device volume level.
141     double original_volume = ais->GetVolume();
142     EXPECT_GE(original_volume, 0.0);
143 #if defined(OS_WIN) || defined(OS_MACOSX)
144     // Note that |original_volume| can be higher than |max_volume| on Linux.
145     EXPECT_LE(original_volume, max_volume);
146 #endif
147
148     // Set the volume to the maxiumum level..
149     ais->SetVolume(max_volume);
150     double current_volume = ais->GetVolume();
151     EXPECT_EQ(max_volume, current_volume);
152
153     // Set the volume to the minimum level (=0).
154     double new_volume = 0.0;
155     ais->SetVolume(new_volume);
156 #if defined(OS_LINUX)
157     current_volume = GetVolumeAfterSetVolumeOnLinux(ais, new_volume);
158 #else
159     current_volume = ais->GetVolume();
160 #endif
161     EXPECT_EQ(new_volume, current_volume);
162
163     // Set the volume to the mid level (50% of max).
164     // Verify that the absolute error is small enough.
165     new_volume = max_volume / 2;
166     ais->SetVolume(new_volume);
167 #if defined(OS_LINUX)
168     current_volume = GetVolumeAfterSetVolumeOnLinux(ais, new_volume);
169 #else
170     current_volume = ais->GetVolume();
171 #endif
172     EXPECT_LT(current_volume, max_volume);
173     EXPECT_GT(current_volume, 0);
174     EXPECT_NEAR(current_volume, new_volume, 0.25 * max_volume);
175
176     // Restores the volume to the original value.
177     ais->SetVolume(original_volume);
178     current_volume = ais->GetVolume();
179     EXPECT_EQ(original_volume, current_volume);
180
181     ais->Close();
182   }
183 }
184
185 }  // namespace media