VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/VBoxMMNotificationClient.cpp@ 68683

Last change on this file since 68683 was 68683, checked in by vboxsync, 7 years ago

Audio: More code for audio endpoint (change) detection for Windows hosts.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.4 KB
Line 
1/* $Id: VBoxMMNotificationClient.cpp 68683 2017-09-06 15:26:32Z vboxsync $ */
2/** @file
3 * VBoxMMNotificationClient.cpp - Implementation of the IMMNotificationClient interface
4 * to detect audio endpoint changes.
5 */
6
7/*
8 * Copyright (C) 2017 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBoxMMNotificationClient.h"
20
21#include <iprt/win/windows.h>
22
23#pragma warning(push)
24#pragma warning(disable: 4201)
25#include <mmdeviceapi.h>
26#include <endpointvolume.h>
27#pragma warning(pop)
28
29#ifdef LOG_GROUP
30# undef LOG_GROUP
31#endif
32#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
33#include <VBox/log.h>
34
35VBoxMMNotificationClient::VBoxMMNotificationClient(void)
36 : m_fRegisteredClient(false)
37 , m_cRef(1)
38{
39}
40
41VBoxMMNotificationClient::~VBoxMMNotificationClient(void)
42{
43}
44
45void VBoxMMNotificationClient::Dispose(void)
46{
47 DetachFromEndpoint();
48
49 if (m_fRegisteredClient)
50 {
51 m_pEnum->UnregisterEndpointNotificationCallback(this);
52
53 m_fRegisteredClient = false;
54 }
55}
56
57HRESULT VBoxMMNotificationClient::Initialize(void)
58{
59 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), 0, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
60 (void **)&m_pEnum);
61 if (SUCCEEDED(hr))
62 {
63 hr = m_pEnum->RegisterEndpointNotificationCallback(this);
64 if (SUCCEEDED(hr))
65 {
66 hr = AttachToDefaultEndpoint();
67 }
68 }
69
70 LogFunc(("Returning %Rhrc\n", hr));
71 return hr;
72}
73
74int VBoxMMNotificationClient::RegisterCallback(PPDMDRVINS pDrvIns, PFNPDMHOSTAUDIOCALLBACK pfnCallback)
75{
76 this->m_pDrvIns = pDrvIns;
77 this->m_pfnCallback = pfnCallback;
78
79 return VINF_SUCCESS;
80}
81
82void VBoxMMNotificationClient::UnregisterCallback(void)
83{
84 this->m_pDrvIns = NULL;
85 this->m_pfnCallback = NULL;
86}
87
88HRESULT VBoxMMNotificationClient::AttachToDefaultEndpoint(void)
89{
90 return S_OK;
91}
92
93void VBoxMMNotificationClient::DetachFromEndpoint(void)
94{
95
96}
97
98STDMETHODIMP VBoxMMNotificationClient::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
99{
100 char *pszState = "unknown";
101
102 switch (dwNewState)
103 {
104 case DEVICE_STATE_ACTIVE:
105 pszState = "active";
106 break;
107 case DEVICE_STATE_DISABLED:
108 pszState = "disabled";
109 break;
110 case DEVICE_STATE_NOTPRESENT:
111 pszState = "not present";
112 break;
113 case DEVICE_STATE_UNPLUGGED:
114 pszState = "unplugged";
115 break;
116 default:
117 break;
118 }
119
120 LogRel2(("Audio: Device '%ls' has changed state to '%s'\n", pwstrDeviceId, pszState));
121
122#ifdef VBOX_WITH_AUDIO_CALLBACKS
123 AssertPtr(this->m_pDrvIns);
124 AssertPtr(this->m_pfnCallback);
125
126 if (this->m_pfnCallback)
127 /* Ignore rc */ this->m_pfnCallback(this->m_pDrvIns, PDMAUDIOBACKENDCBTYPE_DEVICES_CHANGED, NULL, 0);
128#endif
129
130 return S_OK;
131}
132
133STDMETHODIMP VBoxMMNotificationClient::OnDeviceAdded(LPCWSTR pwstrDeviceId)
134{
135 LogFunc(("%ls\n", pwstrDeviceId));
136 return S_OK;
137}
138
139STDMETHODIMP VBoxMMNotificationClient::OnDeviceRemoved(LPCWSTR pwstrDeviceId)
140{
141 LogFunc(("%ls\n", pwstrDeviceId));
142 return S_OK;
143}
144
145STDMETHODIMP VBoxMMNotificationClient::OnDefaultDeviceChanged(EDataFlow eFlow, ERole eRole, LPCWSTR pwstrDefaultDeviceId)
146{
147 RT_NOREF(eRole, pwstrDefaultDeviceId);
148
149 if (eFlow == eRender)
150 {
151
152 }
153
154 return S_OK;
155}
156
157STDMETHODIMP VBoxMMNotificationClient::QueryInterface(REFIID interfaceID, void **ppvInterface)
158{
159 const IID IID_IMMNotificationClient = __uuidof(IMMNotificationClient);
160
161 if ( IsEqualIID(interfaceID, IID_IUnknown)
162 || IsEqualIID(interfaceID, IID_IMMNotificationClient))
163 {
164 *ppvInterface = static_cast<IMMNotificationClient*>(this);
165 AddRef();
166 return S_OK;
167 }
168
169 *ppvInterface = NULL;
170 return E_NOINTERFACE;
171}
172
173STDMETHODIMP_(ULONG) VBoxMMNotificationClient::AddRef(void)
174{
175 return InterlockedIncrement(&m_cRef);
176}
177
178STDMETHODIMP_(ULONG) VBoxMMNotificationClient::Release(void)
179{
180 long lRef = InterlockedDecrement(&m_cRef);
181 if (lRef == 0)
182 delete this;
183
184 return lRef;
185}
186
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette