[SystemVolumePlugin][MacOS] Send data about default audio device

This commit is contained in:
Art Pinch 2020-12-07 10:55:01 +03:00 committed by Simon Redman
parent 0c5e2c50e0
commit dc7ce7f01f
2 changed files with 60 additions and 1 deletions

View file

@ -33,6 +33,8 @@ public:
float volume(); float volume();
void setMuted(bool muted); void setMuted(bool muted);
bool isMuted(); bool isMuted();
void setDefault(bool enabled);
bool isDefault();
void updateType(); void updateType();
}; };
@ -79,6 +81,12 @@ static const AudioObjectPropertyAddress kAudioMasterDataSourcePropertyAddress =
kAudioObjectPropertyElementMaster kAudioObjectPropertyElementMaster
}; };
static const AudioObjectPropertyAddress kAudioDefaultOutputDevicePropertyAddress = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
OSStatus onVolumeChanged(AudioObjectID object, UInt32 numAddresses, const AudioObjectPropertyAddress addresses[], void *context) OSStatus onVolumeChanged(AudioObjectID object, UInt32 numAddresses, const AudioObjectPropertyAddress addresses[], void *context)
{ {
Q_UNUSED(object); Q_UNUSED(object);
@ -101,6 +109,17 @@ OSStatus onMutedChanged(AudioObjectID object, UInt32 numAddresses, const AudioOb
return noErr; return noErr;
} }
OSStatus onDefaultChanged(AudioObjectID object, UInt32 numAddresses, const AudioObjectPropertyAddress addresses[], void *context)
{
Q_UNUSED(object);
Q_UNUSED(addresses);
Q_UNUSED(numAddresses);
SystemvolumePlugin *plugin = (SystemvolumePlugin*)context;
plugin->sendSinkList();
return noErr;
}
OSStatus onOutputSourceChanged(AudioObjectID object, UInt32 numAddresses, const AudioObjectPropertyAddress addresses[], void *context) OSStatus onOutputSourceChanged(AudioObjectID object, UInt32 numAddresses, const AudioObjectPropertyAddress addresses[], void *context)
{ {
Q_UNUSED(object); Q_UNUSED(object);
@ -112,6 +131,16 @@ OSStatus onOutputSourceChanged(AudioObjectID object, UInt32 numAddresses, const
return noErr; return noErr;
} }
AudioObjectID getDefaultOutputDeviceId() {
AudioObjectID dataSourceId;
UInt32 size = sizeof(dataSourceId);
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &kAudioDefaultOutputDevicePropertyAddress, 0, NULL, &size, &dataSourceId);
if (result != noErr)
return kAudioDeviceUnknown;
return dataSourceId;
}
UInt32 getDeviceSourceId(AudioObjectID deviceId) { UInt32 getDeviceSourceId(AudioObjectID deviceId) {
UInt32 dataSourceId; UInt32 dataSourceId;
UInt32 size = sizeof(dataSourceId); UInt32 size = sizeof(dataSourceId);
@ -202,6 +231,11 @@ SystemvolumePlugin::SystemvolumePlugin(QObject* parent, const QVariantList& args
: KdeConnectPlugin(parent, args), m_sinksMap() : KdeConnectPlugin(parent, args), m_sinksMap()
{} {}
SystemvolumePlugin::~SystemvolumePlugin()
{
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &kAudioDefaultOutputDevicePropertyAddress, &onDefaultChanged, (void *)this);
}
bool SystemvolumePlugin::receivePacket(const NetworkPacket& np) bool SystemvolumePlugin::receivePacket(const NetworkPacket& np)
{ {
if (np.has(QStringLiteral("requestSinks"))) { if (np.has(QStringLiteral("requestSinks"))) {
@ -260,7 +294,8 @@ void SystemvolumePlugin::sendSinkList()
{QStringLiteral("muted"), audioDevice->isMuted()}, {QStringLiteral("muted"), audioDevice->isMuted()},
{QStringLiteral("description"), audioDevice->m_description}, {QStringLiteral("description"), audioDevice->m_description},
{QStringLiteral("volume"), audioDevice->volume() * 100}, {QStringLiteral("volume"), audioDevice->volume() * 100},
{QStringLiteral("maxVolume"), 100} {QStringLiteral("maxVolume"), 100},
{QStringLiteral("enabled"), audioDevice->isDefault()}
}; };
array.append(sinkObject); array.append(sinkObject);
@ -275,6 +310,7 @@ void SystemvolumePlugin::sendSinkList()
void SystemvolumePlugin::connected() void SystemvolumePlugin::connected()
{ {
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &kAudioDefaultOutputDevicePropertyAddress, &onDefaultChanged, (void *)this);
sendSinkList(); sendSinkList();
} }
@ -369,6 +405,22 @@ void MacOSCoreAudioDevice::setMuted(bool muted)
} }
} }
void MacOSCoreAudioDevice::setDefault(bool enabled)
{
if (!enabled) return;
if (m_deviceId == kAudioObjectUnknown) {
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to set an Unknown Device as default output";
return;
}
OSStatus result = AudioObjectSetPropertyData(kAudioObjectSystemObject, &kAudioDefaultOutputDevicePropertyAddress, 0, NULL, sizeof(m_deviceId), &m_deviceId);
if (result != noErr) {
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to set default state of Device" << m_deviceId;
}
}
float MacOSCoreAudioDevice::volume() float MacOSCoreAudioDevice::volume()
{ {
OSStatus result; OSStatus result;
@ -412,6 +464,11 @@ bool MacOSCoreAudioDevice::isMuted()
return muted == 1; return muted == 1;
} }
bool MacOSCoreAudioDevice::isDefault() {
AudioObjectID defaultDeviceId = getDefaultOutputDeviceId();
return m_deviceId == defaultDeviceId;
}
void MacOSCoreAudioDevice::updateType() void MacOSCoreAudioDevice::updateType()
{ {
// Try to get volume from left channel to check if it's a stereo device // Try to get volume from left channel to check if it's a stereo device

View file

@ -25,6 +25,8 @@ class Q_DECL_EXPORT SystemvolumePlugin : public KdeConnectPlugin
public: public:
explicit SystemvolumePlugin(QObject *parent, const QVariantList &args); explicit SystemvolumePlugin(QObject *parent, const QVariantList &args);
~SystemvolumePlugin();
bool receivePacket(const NetworkPacket& np) override; bool receivePacket(const NetworkPacket& np) override;
void connected() override; void connected() override;
void sendSinkList(); void sendSinkList();