1// Copyright 2014 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 "ash/system/win/audio/tray_audio_delegate_win.h" 6 7#include <audiopolicy.h> 8#include <cmath> 9 10#include "media/audio/win/core_audio_util_win.h" 11 12using base::win::ScopedComPtr; 13 14namespace { 15 16// Volume value which should be considered as muted in range [0, 100]. 17const int kMuteThresholdPercent = 1; 18 19// Lowest volume which is considered to be audible in the range [0, 100]. 20const int kDefaultUnmuteVolumePercent = 4; 21 22} // namespace 23 24namespace ash { 25namespace system { 26 27void TrayAudioDelegateWin::AdjustOutputVolumeToAudibleLevel() { 28 if (GetOutputVolumeLevel() <= kMuteThresholdPercent) 29 SetOutputVolumeLevel(kDefaultUnmuteVolumePercent); 30} 31 32int TrayAudioDelegateWin::GetOutputDefaultVolumeMuteLevel() { 33 return kMuteThresholdPercent; 34} 35 36int TrayAudioDelegateWin::GetOutputVolumeLevel() { 37 ScopedComPtr<ISimpleAudioVolume> volume_control = 38 CreateDefaultVolumeControl(); 39 if (!volume_control) 40 return 0; 41 42 float level = 0.0f; 43 if (FAILED(volume_control->GetMasterVolume(&level))) 44 return 0; 45 46 // MSVC prior to 2013 doesn't have a round function. The below code is not 47 // conformant to C99 round(), but since we know that 0 <= level <= 100, it 48 // should be ok. 49 return static_cast<int>(level + 0.5); 50} 51 52int TrayAudioDelegateWin::GetActiveOutputDeviceIconId() { 53 return kNoAudioDeviceIcon; 54} 55 56bool TrayAudioDelegateWin::HasAlternativeSources() { 57 return false; 58} 59 60bool TrayAudioDelegateWin::IsOutputAudioMuted() { 61 ScopedComPtr<ISimpleAudioVolume> volume_control = 62 CreateDefaultVolumeControl(); 63 64 if (!volume_control) 65 return false; 66 67 BOOL mute = FALSE; 68 if (FAILED(volume_control->GetMute(&mute))) 69 return false; 70 71 return !!mute; 72} 73 74void TrayAudioDelegateWin::SetOutputAudioIsMuted(bool is_muted) { 75 ScopedComPtr<ISimpleAudioVolume> volume_control = 76 CreateDefaultVolumeControl(); 77 78 if (!volume_control) 79 return; 80 81 volume_control->SetMute(is_muted, NULL); 82} 83 84void TrayAudioDelegateWin::SetOutputVolumeLevel(int level) { 85 ScopedComPtr<ISimpleAudioVolume> volume_control = 86 CreateDefaultVolumeControl(); 87 88 if (!volume_control) 89 return; 90 91 float volume_level = static_cast<float>(level) / 100.0f; 92 volume_control->SetMasterVolume(volume_level, NULL); 93} 94 95ScopedComPtr<ISimpleAudioVolume> 96TrayAudioDelegateWin::CreateDefaultVolumeControl() { 97 ScopedComPtr<ISimpleAudioVolume> volume_control; 98 ScopedComPtr<IAudioSessionManager> session_manager; 99 100 ScopedComPtr<IMMDevice> device = 101 media::CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); 102 if (!device || 103 FAILED(device->Activate(__uuidof(IAudioSessionManager), CLSCTX_ALL, NULL, 104 session_manager.ReceiveVoid()))) { 105 return volume_control; 106 } 107 108 session_manager->GetSimpleAudioVolume(NULL, FALSE, 109 volume_control.Receive()); 110 111 return volume_control; 112} 113 114} // namespace system 115} // namespace ash 116