| Index: media/audio/win/core_audio_util_win_unittest.cc
|
| diff --git a/media/audio/win/core_audio_util_win_unittest.cc b/media/audio/win/core_audio_util_win_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9b9eda2ca25b19e10a9c162062d6317fb143ab5a
|
| --- /dev/null
|
| +++ b/media/audio/win/core_audio_util_win_unittest.cc
|
| @@ -0,0 +1,223 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| +#include "base/win/scoped_com_initializer.h"
|
| +#include "media/audio/win/core_audio_util_win.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using base::win::ScopedCOMInitializer;
|
| +
|
| +namespace media {
|
| +namespace win {
|
| +
|
| +class CoreAudioUtilWinTest : public ::testing::Test {
|
| + protected:
|
| + // The test runs on a COM thread in a multithread apartment (MTA).
|
| + // If we don't initialize the COM library on a thread before using COM,
|
| + // all function calls will return CO_E_NOTINITIALIZED.
|
| + CoreAudioUtilWinTest()
|
| + : com_init_(ScopedCOMInitializer::kMTA) {}
|
| + virtual ~CoreAudioUtilWinTest() {}
|
| +
|
| + bool CanRunAudioTest() {
|
| + bool core_audio = CoreAudioIsSupported();
|
| + int capture_devices = NumberOfActiveAudioDevices(eCapture);
|
| + int render_devices = NumberOfActiveAudioDevices(eRender);
|
| + return (core_audio && (capture_devices > 0) && (render_devices > 0));
|
| + }
|
| +
|
| + ScopedCOMInitializer com_init_;
|
| +};
|
| +
|
| +// --- MMdevice
|
| +
|
| +TEST_F(CoreAudioUtilWinTest, NumberOfActiveAudioDevices) {
|
| + if (!CanRunAudioTest())
|
| + return;
|
| +
|
| + int render_devices = NumberOfActiveAudioDevices(eRender);
|
| + EXPECT_GT(render_devices, 0);
|
| + int capture_devices = NumberOfActiveAudioDevices(eCapture);
|
| + EXPECT_GT(capture_devices, 0);
|
| + int total_devices = NumberOfActiveAudioDevices(eAll);
|
| + EXPECT_EQ(total_devices, render_devices + capture_devices);
|
| +}
|
| +
|
| +TEST_F(CoreAudioUtilWinTest, CreateDeviceEnumerator) {
|
| + if (!CanRunAudioTest())
|
| + return;
|
| +
|
| + ScopedComPtr<IMMDeviceEnumerator> enumerator = CreateDeviceEnumerator();
|
| + EXPECT_TRUE(enumerator);
|
| + enumerator = CreateDeviceEnumerator();
|
| + EXPECT_TRUE(enumerator);
|
| + enumerator.Release();
|
| + EXPECT_FALSE(enumerator);
|
| + enumerator = CreateDeviceEnumerator();
|
| + EXPECT_TRUE(enumerator);
|
| +}
|
| +
|
| +TEST_F(CoreAudioUtilWinTest, CreateDefaultAudioDevice) {
|
| + if (!CanRunAudioTest())
|
| + return;
|
| +
|
| + // Verify all device roles for playback endpoints.
|
| + ScopedComPtr<IMMDevice> audio_device =
|
| + CreateDefaultAudioDevice(eRender, eConsole);
|
| + EXPECT_TRUE(audio_device);
|
| + EXPECT_EQ(eRender, GetDataFlow(audio_device));
|
| + CreateDefaultAudioDevice(eRender, eCommunications);
|
| + EXPECT_TRUE(audio_device);
|
| + CreateDefaultAudioDevice(eRender, eMultimedia);
|
| + EXPECT_TRUE(audio_device);
|
| + CreateDefaultAudioDevice(eRender, eCommunications);
|
| +
|
| + // Verify all device roles for recording endpoints.
|
| + audio_device = CreateDefaultAudioDevice(eCapture, eConsole);
|
| + EXPECT_TRUE(audio_device);
|
| + EXPECT_EQ(eCapture, GetDataFlow(audio_device));
|
| + audio_device = CreateDefaultAudioDevice(eCapture, eCommunications);
|
| + EXPECT_TRUE(audio_device);
|
| + EXPECT_EQ(eCapture, GetDataFlow(audio_device));
|
| + audio_device = CreateDefaultAudioDevice(eCapture, eMultimedia);
|
| + EXPECT_TRUE(audio_device);
|
| + EXPECT_EQ(eCapture, GetDataFlow(audio_device));
|
| +
|
| + // Only eRender and eCapture are allowed as flow parameter.
|
| + audio_device = CreateDefaultAudioDevice(eAll, eConsole);
|
| + EXPECT_FALSE(audio_device);
|
| + EXPECT_EQ(eAll, GetDataFlow(audio_device));
|
| +}
|
| +
|
| +TEST_F(CoreAudioUtilWinTest, CreateAudioDevice) {
|
| + if (!CanRunAudioTest())
|
| + return;
|
| +
|
| + // Get name and ID of default device used for playback.
|
| + ScopedComPtr<IMMDevice> default_render_device =
|
| + CreateDefaultAudioDevice(eRender, eConsole);
|
| + AudioDeviceName default_render_name;
|
| + HRESULT hr = GetAudioDeviceName(default_render_device, &default_render_name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| +
|
| + // Use the uniqe ID as input to CreateAudioDevice() and create a
|
| + // corresponding IMMDevice.
|
| + ScopedComPtr<IMMDevice> audio_device =
|
| + CreateAudioDevice(default_render_name.unique_id);
|
| + EXPECT_TRUE(audio_device);
|
| +
|
| + // Verify that the two IMMDevice interfaces represents the same endpoint
|
| + // by comparing their unique IDs.
|
| + AudioDeviceName device_name;
|
| + hr = GetAudioDeviceName(audio_device, &device_name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| + EXPECT_STREQ(default_render_name.unique_id.c_str(),
|
| + device_name.unique_id.c_str());
|
| +}
|
| +
|
| +TEST_F(CoreAudioUtilWinTest, GetDefaultAudioDeviceName) {
|
| + if (!CanRunAudioTest())
|
| + return;
|
| +
|
| + // Get name and ID of default device used for playback.
|
| + ScopedComPtr<IMMDevice> audio_device =
|
| + CreateDefaultAudioDevice(eRender, eConsole);
|
| + AudioDeviceName device_name;
|
| + HRESULT hr = GetAudioDeviceName(audio_device, &device_name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| + EXPECT_FALSE(device_name.device_name.empty());
|
| + EXPECT_FALSE(device_name.unique_id.empty());
|
| +
|
| +
|
| + // Get name and ID of default communication device used for playback.
|
| + audio_device = CreateDefaultAudioDevice(eRender, eCommunications);
|
| + hr = GetAudioDeviceName(audio_device, &device_name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| + EXPECT_FALSE(device_name.device_name.empty());
|
| + EXPECT_FALSE(device_name.unique_id.empty());
|
| +
|
| + // Get name and ID of default device used for recording.
|
| + audio_device = CreateDefaultAudioDevice(eCapture, eConsole);
|
| + hr = GetAudioDeviceName(audio_device, &device_name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| + EXPECT_FALSE(device_name.device_name.empty());
|
| + EXPECT_FALSE(device_name.unique_id.empty());
|
| +
|
| + // Get name and ID of default communication device used for recording.
|
| + audio_device = CreateDefaultAudioDevice(eCapture, eCommunications);
|
| + hr = GetAudioDeviceName(audio_device, &device_name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| + EXPECT_FALSE(device_name.device_name.empty());
|
| + EXPECT_FALSE(device_name.unique_id.empty());
|
| +}
|
| +
|
| +TEST_F(CoreAudioUtilWinTest, GetFriendlyName) {
|
| + if (!CanRunAudioTest())
|
| + return;
|
| +
|
| + // Get name and ID of default device used for recording.
|
| + ScopedComPtr<IMMDevice> audio_device =
|
| + CreateDefaultAudioDevice(eCapture, eConsole);
|
| + AudioDeviceName device_name;
|
| + HRESULT hr = GetAudioDeviceName(audio_device, &device_name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| +
|
| + // Use unique ID as input to GetFriendlyName() and compare the result
|
| + // with the already obtained friendly name for the default capture device.
|
| + std::string friendly_name = GetFriendlyName(device_name.unique_id);
|
| + EXPECT_STREQ(friendly_name.c_str(), device_name.device_name.c_str());
|
| +
|
| + // Same test as above but for playback.
|
| + audio_device = CreateDefaultAudioDevice(eRender, eConsole);
|
| + hr = GetAudioDeviceName(audio_device, &device_name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| + friendly_name = GetFriendlyName(device_name.unique_id);
|
| + EXPECT_STREQ(friendly_name.c_str(), device_name.device_name.c_str());
|
| +}
|
| +
|
| +TEST_F(CoreAudioUtilWinTest, IsDeviceDefault) {
|
| + if (!CanRunAudioTest())
|
| + return;
|
| +
|
| + // Verify that the default render device is correctly identified as a
|
| + // default device.
|
| + ScopedComPtr<IMMDevice> audio_device =
|
| + CreateDefaultAudioDevice(eRender, eConsole);
|
| + AudioDeviceName name;
|
| + HRESULT hr = GetAudioDeviceName(audio_device, &name);
|
| + EXPECT_TRUE(SUCCEEDED(hr));
|
| + EXPECT_TRUE(IsDeviceDefault(eRender, eConsole, name.unique_id));
|
| + EXPECT_FALSE(IsDeviceDefault(eCapture, eConsole, name.unique_id));
|
| +
|
| + // If more than one active render device exists, one must be default and
|
| + // the other default communication.
|
| + if (NumberOfActiveAudioDevices(eRender) > 1) {
|
| + EXPECT_FALSE(IsDeviceDefault(eRender, eCommunications, name.unique_id));
|
| + }
|
| +}
|
| +
|
| +// --- WASAPI
|
| +
|
| +TEST_F(CoreAudioUtilWinTest, CreateAudioClient) {
|
| + if (!CanRunAudioTest())
|
| + return;
|
| +
|
| + // Create an audio client for the default render device.
|
| + ScopedComPtr<IMMDevice> device = CreateDefaultAudioDevice(eRender, eConsole);
|
| + EXPECT_EQ(eRender, GetDataFlow(device));
|
| + ScopedComPtr<IAudioClient> client = CreateAudioClient(device);
|
| + EXPECT_TRUE(client);
|
| +
|
| + // Create an audio client for the default capture device.
|
| + device = CreateDefaultAudioDevice(eCapture, eConsole);
|
| + EXPECT_EQ(eCapture, GetDataFlow(device));
|
| + client = CreateAudioClient(device);
|
| + EXPECT_TRUE(client);
|
| +}
|
| +
|
| +} // namespace win
|
| +} // namespace media
|
|
|