File indexing completed on 2025-04-27 04:36:17
0001 /** 0002 * SPDX-FileCopyrightText: 2017 Nicolas Fella <nicolas.fella@gmx.de> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "systemvolumeplugin-pulse.h" 0008 0009 #include <KPluginFactory> 0010 0011 #include <QDebug> 0012 #include <QJsonArray> 0013 #include <QJsonDocument> 0014 #include <QJsonObject> 0015 #include <QProcess> 0016 0017 #include <core/device.h> 0018 0019 #include "plugin_systemvolume_debug.h" 0020 #include <PulseAudioQt/Context> 0021 #include <PulseAudioQt/Sink> 0022 0023 K_PLUGIN_CLASS_WITH_JSON(SystemvolumePlugin, "kdeconnect_systemvolume.json") 0024 0025 SystemvolumePlugin::SystemvolumePlugin(QObject *parent, const QVariantList &args) 0026 : KdeConnectPlugin(parent, args) 0027 , sinksMap() 0028 { 0029 } 0030 0031 void SystemvolumePlugin::receivePacket(const NetworkPacket &np) 0032 { 0033 if (!PulseAudioQt::Context::instance()->isValid()) 0034 return; 0035 0036 if (np.has(QStringLiteral("requestSinks"))) { 0037 sendSinkList(); 0038 } else { 0039 QString name = np.get<QString>(QStringLiteral("name")); 0040 0041 PulseAudioQt::Sink *sink = sinksMap.value(name); 0042 if (sink) { 0043 if (np.has(QStringLiteral("volume"))) { 0044 int volume = np.get<int>(QStringLiteral("volume")); 0045 sink->setVolume(volume); 0046 sink->setMuted(false); 0047 } 0048 if (np.has(QStringLiteral("muted"))) { 0049 sink->setMuted(np.get<bool>(QStringLiteral("muted"))); 0050 } 0051 if (np.has(QStringLiteral("enabled"))) { 0052 sink->setDefault(np.get<bool>(QStringLiteral("enabled"))); 0053 } 0054 } 0055 } 0056 } 0057 0058 void SystemvolumePlugin::sendSinkList() 0059 { 0060 QJsonDocument document; 0061 QJsonArray array; 0062 0063 sinksMap.clear(); 0064 0065 const auto sinks = PulseAudioQt::Context::instance()->sinks(); 0066 for (PulseAudioQt::Sink *sink : sinks) { 0067 sinksMap.insert(sink->name(), sink); 0068 0069 connect(sink, &PulseAudioQt::Sink::volumeChanged, this, [this, sink] { 0070 NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME); 0071 np.set<int>(QStringLiteral("volume"), sink->volume()); 0072 np.set<QString>(QStringLiteral("name"), sink->name()); 0073 sendPacket(np); 0074 }); 0075 0076 connect(sink, &PulseAudioQt::Sink::mutedChanged, this, [this, sink] { 0077 NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME); 0078 np.set<bool>(QStringLiteral("muted"), sink->isMuted()); 0079 np.set<QString>(QStringLiteral("name"), sink->name()); 0080 sendPacket(np); 0081 }); 0082 0083 connect(sink, &PulseAudioQt::Sink::defaultChanged, this, [this, sink] { 0084 NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME); 0085 np.set<bool>(QStringLiteral("enabled"), sink->isDefault()); 0086 np.set<QString>(QStringLiteral("name"), sink->name()); 0087 sendPacket(np); 0088 }); 0089 0090 QJsonObject sinkObject{{QStringLiteral("name"), sink->name()}, 0091 {QStringLiteral("muted"), sink->isMuted()}, 0092 {QStringLiteral("description"), sink->description()}, 0093 {QStringLiteral("volume"), sink->volume()}, 0094 {QStringLiteral("maxVolume"), PulseAudioQt::normalVolume()}, 0095 {QStringLiteral("enabled"), sink->isDefault()}}; 0096 0097 array.append(sinkObject); 0098 } 0099 0100 document.setArray(array); 0101 0102 NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME); 0103 np.set<QJsonDocument>(QStringLiteral("sinkList"), document); 0104 sendPacket(np); 0105 } 0106 0107 void SystemvolumePlugin::connected() 0108 { 0109 connect(PulseAudioQt::Context::instance(), &PulseAudioQt::Context::sinkAdded, this, [this] { 0110 sendSinkList(); 0111 }); 0112 0113 connect(PulseAudioQt::Context::instance(), &PulseAudioQt::Context::sinkRemoved, this, [this] { 0114 sendSinkList(); 0115 }); 0116 0117 const auto sinks = PulseAudioQt::Context::instance()->sinks(); 0118 for (PulseAudioQt::Sink *sink : sinks) { 0119 sinksMap.insert(sink->name(), sink); 0120 } 0121 } 0122 0123 #include "moc_systemvolumeplugin-pulse.cpp" 0124 #include "systemvolumeplugin-pulse.moc"