2 * Copyright (C) 2014-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
11 #include "ServiceBroker.h"
12 #include "cores/AudioEngine/Engines/ActiveAE/ActiveAE.h"
13 #include "utils/log.h"
15 #include "platform/win32/CharsetConverter.h"
16 #include "platform/win32/powermanagement/Win32PowerSyscall.h"
18 #include <mmdeviceapi.h>
19 #include <wrl/client.h>
21 using KODI::PLATFORM::WINDOWS::FromW
;
23 class CMMNotificationClient
: public IMMNotificationClient
26 Microsoft::WRL::ComPtr
<IMMDeviceEnumerator
> _pEnumerator
;
30 CMMNotificationClient() : _cRef(1), _pEnumerator(nullptr)
34 ~CMMNotificationClient() = default;
36 // IUnknown methods -- AddRef, Release, and QueryInterface
38 ULONG STDMETHODCALLTYPE
AddRef()
40 return InterlockedIncrement(&_cRef
);
43 ULONG STDMETHODCALLTYPE
Release()
45 ULONG ulRef
= InterlockedDecrement(&_cRef
);
53 HRESULT STDMETHODCALLTYPE
QueryInterface(const IID
& riid
, void **ppvInterface
)
55 if (IID_IUnknown
== riid
)
58 *ppvInterface
= (IUnknown
*)this;
60 else if (__uuidof(IMMNotificationClient
) == riid
)
63 *ppvInterface
= (IMMNotificationClient
*)this;
67 *ppvInterface
= nullptr;
73 // Callback methods for device-event notifications.
75 HRESULT STDMETHODCALLTYPE
OnDefaultDeviceChanged(EDataFlow flow
, ERole role
, LPCWSTR pwstrDeviceId
)
77 // if the default device changes this function is called four times.
78 // therefore we call CServiceBroker::GetActiveAE()->DeviceChange() only for one role.
79 std::string pszFlow
= "?????";
80 std::string pszRole
= "?????";
98 pszRole
= "eMultimedia";
100 case eCommunications
:
101 pszRole
= "eCommunications";
106 CLog::Log(LOGDEBUG
, "{}: New default device: flow = {}, role = {}", __FUNCTION__
, pszFlow
,
111 HRESULT STDMETHODCALLTYPE
OnDeviceAdded(LPCWSTR pwstrDeviceId
)
113 CLog::Log(LOGDEBUG
, "{}: Added device: {}", __FUNCTION__
, FromW(pwstrDeviceId
));
118 HRESULT STDMETHODCALLTYPE
OnDeviceRemoved(LPCWSTR pwstrDeviceId
)
120 CLog::Log(LOGDEBUG
, "{}: Removed device: {}", __FUNCTION__
, FromW(pwstrDeviceId
));
125 HRESULT STDMETHODCALLTYPE
OnDeviceStateChanged(LPCWSTR pwstrDeviceId
, DWORD dwNewState
)
127 std::string pszState
= "?????";
131 case DEVICE_STATE_ACTIVE
:
134 case DEVICE_STATE_DISABLED
:
135 pszState
= "DISABLED";
137 case DEVICE_STATE_NOTPRESENT
:
138 pszState
= "NOTPRESENT";
140 case DEVICE_STATE_UNPLUGGED
:
141 pszState
= "UNPLUGGED";
144 CLog::Log(LOGDEBUG
, "{}: New device state is DEVICE_STATE_{}", __FUNCTION__
, pszState
);
149 HRESULT STDMETHODCALLTYPE
OnPropertyValueChanged(LPCWSTR pwstrDeviceId
, const PROPERTYKEY key
)
152 "{}: Changed device property of {} is "
153 "({:08x}-{:04x}-{:04x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x})#{}",
154 __FUNCTION__
, FromW(pwstrDeviceId
), key
.fmtid
.Data1
, key
.fmtid
.Data2
, key
.fmtid
.Data3
,
155 key
.fmtid
.Data4
[0], key
.fmtid
.Data4
[1], key
.fmtid
.Data4
[2], key
.fmtid
.Data4
[3],
156 key
.fmtid
.Data4
[4], key
.fmtid
.Data4
[5], key
.fmtid
.Data4
[6], key
.fmtid
.Data4
[7],
161 void STDMETHODCALLTYPE
NotifyAE()
163 if(!CWin32PowerSyscall::IsSuspending())
164 CServiceBroker::GetActiveAE()->DeviceChange();