core_audio_util_win_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 "base/memory/scoped_ptr.h" 6#include "base/synchronization/waitable_event.h" 7#include "base/win/scoped_com_initializer.h" 8#include "media/audio/win/core_audio_util_win.h" 9#include "testing/gmock/include/gmock/gmock.h" 10#include "testing/gtest/include/gtest/gtest.h" 11 12using base::win::ScopedCOMInitializer; 13 14namespace media { 15 16class CoreAudioUtilWinTest : public ::testing::Test { 17 protected: 18 // The test runs on a COM thread in the multithreaded apartment (MTA). 19 // If we don't initialize the COM library on a thread before using COM, 20 // all function calls will return CO_E_NOTINITIALIZED. 21 CoreAudioUtilWinTest() 22 : com_init_(ScopedCOMInitializer::kMTA) { 23 DCHECK(com_init_.succeeded()); 24 } 25 virtual ~CoreAudioUtilWinTest() {} 26 27 bool CanRunAudioTest() { 28 bool core_audio = CoreAudioUtil::IsSupported(); 29 if (!core_audio) 30 return false; 31 int capture_devices = CoreAudioUtil::NumberOfActiveDevices(eCapture); 32 int render_devices = CoreAudioUtil::NumberOfActiveDevices(eRender); 33 return ((capture_devices > 0) && (render_devices > 0)); 34 } 35 36 ScopedCOMInitializer com_init_; 37}; 38 39TEST_F(CoreAudioUtilWinTest, NumberOfActiveDevices) { 40 if (!CanRunAudioTest()) 41 return; 42 43 int render_devices = CoreAudioUtil::NumberOfActiveDevices(eRender); 44 EXPECT_GT(render_devices, 0); 45 int capture_devices = CoreAudioUtil::NumberOfActiveDevices(eCapture); 46 EXPECT_GT(capture_devices, 0); 47 int total_devices = CoreAudioUtil::NumberOfActiveDevices(eAll); 48 EXPECT_EQ(total_devices, render_devices + capture_devices); 49} 50 51TEST_F(CoreAudioUtilWinTest, CreateDeviceEnumerator) { 52 if (!CanRunAudioTest()) 53 return; 54 55 ScopedComPtr<IMMDeviceEnumerator> enumerator = 56 CoreAudioUtil::CreateDeviceEnumerator(); 57 EXPECT_TRUE(enumerator); 58} 59 60TEST_F(CoreAudioUtilWinTest, CreateDefaultDevice) { 61 if (!CanRunAudioTest()) 62 return; 63 64 struct { 65 EDataFlow flow; 66 ERole role; 67 } data[] = { 68 {eRender, eConsole}, 69 {eRender, eCommunications}, 70 {eRender, eMultimedia}, 71 {eCapture, eConsole}, 72 {eCapture, eCommunications}, 73 {eCapture, eMultimedia} 74 }; 75 76 // Create default devices for all flow/role combinations above. 77 ScopedComPtr<IMMDevice> audio_device; 78 for (int i = 0; i < arraysize(data); ++i) { 79 audio_device = 80 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); 81 EXPECT_TRUE(audio_device); 82 EXPECT_EQ(data[i].flow, CoreAudioUtil::GetDataFlow(audio_device)); 83 } 84 85 // Only eRender and eCapture are allowed as flow parameter. 86 audio_device = CoreAudioUtil::CreateDefaultDevice(eAll, eConsole); 87 EXPECT_FALSE(audio_device); 88} 89 90TEST_F(CoreAudioUtilWinTest, CreateDevice) { 91 if (!CanRunAudioTest()) 92 return; 93 94 // Get name and ID of default device used for playback. 95 ScopedComPtr<IMMDevice> default_render_device = 96 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); 97 AudioDeviceName default_render_name; 98 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDeviceName(default_render_device, 99 &default_render_name))); 100 101 // Use the uniqe ID as input to CreateDevice() and create a corresponding 102 // IMMDevice. 103 ScopedComPtr<IMMDevice> audio_device = 104 CoreAudioUtil::CreateDevice(default_render_name.unique_id); 105 EXPECT_TRUE(audio_device); 106 107 // Verify that the two IMMDevice interfaces represents the same endpoint 108 // by comparing their unique IDs. 109 AudioDeviceName device_name; 110 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDeviceName(audio_device, 111 &device_name))); 112 EXPECT_EQ(default_render_name.unique_id, device_name.unique_id); 113} 114 115TEST_F(CoreAudioUtilWinTest, GetDefaultDeviceName) { 116 if (!CanRunAudioTest()) 117 return; 118 119 struct { 120 EDataFlow flow; 121 ERole role; 122 } data[] = { 123 {eRender, eConsole}, 124 {eRender, eCommunications}, 125 {eCapture, eConsole}, 126 {eCapture, eCommunications} 127 }; 128 129 // Get name and ID of default devices for all flow/role combinations above. 130 ScopedComPtr<IMMDevice> audio_device; 131 AudioDeviceName device_name; 132 for (int i = 0; i < arraysize(data); ++i) { 133 audio_device = 134 CoreAudioUtil::CreateDefaultDevice(data[i].flow, data[i].role); 135 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDeviceName(audio_device, 136 &device_name))); 137 EXPECT_FALSE(device_name.device_name.empty()); 138 EXPECT_FALSE(device_name.unique_id.empty()); 139 } 140} 141 142TEST_F(CoreAudioUtilWinTest, GetFriendlyName) { 143 if (!CanRunAudioTest()) 144 return; 145 146 // Get name and ID of default device used for recording. 147 ScopedComPtr<IMMDevice> audio_device = 148 CoreAudioUtil::CreateDefaultDevice(eCapture, eConsole); 149 AudioDeviceName device_name; 150 HRESULT hr = CoreAudioUtil::GetDeviceName(audio_device, &device_name); 151 EXPECT_TRUE(SUCCEEDED(hr)); 152 153 // Use unique ID as input to GetFriendlyName() and compare the result 154 // with the already obtained friendly name for the default capture device. 155 std::string friendly_name = CoreAudioUtil::GetFriendlyName( 156 device_name.unique_id); 157 EXPECT_EQ(friendly_name, device_name.device_name); 158 159 // Same test as above but for playback. 160 audio_device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); 161 hr = CoreAudioUtil::GetDeviceName(audio_device, &device_name); 162 EXPECT_TRUE(SUCCEEDED(hr)); 163 friendly_name = CoreAudioUtil::GetFriendlyName(device_name.unique_id); 164 EXPECT_EQ(friendly_name, device_name.device_name); 165} 166 167TEST_F(CoreAudioUtilWinTest, DeviceIsDefault) { 168 if (!CanRunAudioTest()) 169 return; 170 171 // Verify that the default render device is correctly identified as a 172 // default device. 173 ScopedComPtr<IMMDevice> audio_device = 174 CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); 175 AudioDeviceName name; 176 EXPECT_TRUE(SUCCEEDED(CoreAudioUtil::GetDeviceName(audio_device, &name))); 177 const std::string id = name.unique_id; 178 EXPECT_TRUE(CoreAudioUtil::DeviceIsDefault(eRender, eConsole, id)); 179 EXPECT_FALSE(CoreAudioUtil::DeviceIsDefault(eCapture, eConsole, id)); 180} 181 182TEST_F(CoreAudioUtilWinTest, CreateClient) { 183 if (!CanRunAudioTest()) 184 return; 185 186 EDataFlow data[] = {eRender, eCapture}; 187 ScopedComPtr<IMMDevice> device; 188 189 for (int i = 0; i < arraysize(data); ++i) { 190 device = CoreAudioUtil::CreateDefaultDevice(data[i], eConsole); 191 EXPECT_TRUE(device); 192 EXPECT_EQ(data[i], CoreAudioUtil::GetDataFlow(device)); 193 } 194} 195 196} // namespace media 197