15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_com_initializer.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_manager.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/win/audio_device_listener_win.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/win/core_audio_util_win.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::win::ScopedCOMInitializer; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kNoDevice[] = ""; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kFirstTestDevice[] = "test_device_0"; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kSecondTestDevice[] = "test_device_1"; 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioDeviceListenerWinTest : public testing::Test { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioDeviceListenerWinTest() 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : com_init_(ScopedCOMInitializer::kMTA) { 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CoreAudioUtil::IsSupported()) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_device_listener_.reset(new AudioDeviceListenerWin(base::Bind( 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AudioDeviceListenerWinTest::OnDeviceChange, base::Unretained(this)))); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Simulate a device change where no output devices are available. 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool SimulateNullDefaultOutputDeviceChange() { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output_device_listener_->OnDefaultDeviceChanged( 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<EDataFlow>(eConsole), static_cast<ERole>(eRender), 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL) == S_OK; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SimulateDefaultOutputDeviceChange(const char* new_device_id) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output_device_listener_->OnDefaultDeviceChanged( 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<EDataFlow>(eConsole), static_cast<ERole>(eRender), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ASCIIToWide(new_device_id).c_str()) == S_OK; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetOutputDeviceId(std::string new_device_id) { 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) output_device_listener_->default_render_device_id_ = new_device_id; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD0(OnDeviceChange, void()); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedCOMInitializer com_init_; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioDeviceListenerWin> output_device_listener_; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioDeviceListenerWinTest); 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Simulate a device change events and ensure we get the right callbacks. 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(AudioDeviceListenerWinTest, OutputDeviceChange) { 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!CoreAudioUtil::IsSupported()) 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetOutputDeviceId(kNoDevice); 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*this, OnDeviceChange()).Times(1); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(SimulateDefaultOutputDeviceChange(kFirstTestDevice)); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::Mock::VerifyAndClear(this); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnDeviceChange()).Times(1); 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(SimulateDefaultOutputDeviceChange(kSecondTestDevice)); 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The second device event should be ignored since the device id has not 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // changed. 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(SimulateDefaultOutputDeviceChange(kSecondTestDevice)); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that null output device changes don't crash. Simulates the situation 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where we have no output devices. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioDeviceListenerWinTest, NullOutputDeviceChange) { 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!CoreAudioUtil::IsSupported()) 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetOutputDeviceId(kNoDevice); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnDeviceChange()).Times(0); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(SimulateNullDefaultOutputDeviceChange()); 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) testing::Mock::VerifyAndClear(this); 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(*this, OnDeviceChange()).Times(1); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(SimulateDefaultOutputDeviceChange(kFirstTestDevice)); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::Mock::VerifyAndClear(this); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, OnDeviceChange()).Times(1); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(SimulateNullDefaultOutputDeviceChange()); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)