Improve D-Bus implementation on macOS

Better patch to replace !218.

- Auto and quick detection of previous D-Bus instance;
- Remove private D-Bus compile definition, only use it on macOS without an existing D-Bus instance;
- Safe reboot after crashes because the indicator is not relating on the kdeconnectd to run a D-Bus session;
- Safe exit after clicking on `Quit` in the systray.


More details in commit logs:

Only enable private D-Bus on macOS because the other platforms do not
need them.
The app should be able to easily detect the session bus from the env
DBUS_LAUNCHD_SESSION_BUS_SOCKET from launchd through launchctl.
Because https://gitlab.freedesktop.org/dbus/dbus/-/blob/master/dbus/dbus-sysdeps-unix.c#L4392
shows that it is the only probing method on macOS with launchd.

The D-Bus session bus can be easily found from launchd/launchctl
with DBUS_LAUNCHD_SESSION_BUS_SOCKET env. It can be an external one
(installed from HomeBrew) or an internal one (launched by a previous
instance followed by a crash).

The indicator helper on macOS can now automatically detect whether we can use a potentially
(with launchd/launchctl env set, or KDE Connect macOS
private_bus_address set) existed and usable session bus.
If previous bus is usable, just try to launch the kdeconnectd with us.
Otherwise, launch a private D-Bus daemon, export the launchd/launchctl
env, and run a kdeconnectd instance.

Everything works better and quicker now :)
This commit is contained in:
Weixuan Xiao 2022-04-12 05:40:03 +00:00
parent 81349acd82
commit f1843cb492
27 changed files with 118 additions and 222 deletions

View file

@ -115,11 +115,6 @@ if (NOT ZSH_AUTOCOMPLETE_DIR)
set(ZSH_AUTOCOMPLETE_DIR "${KDE_INSTALL_DATADIR}/zsh/site-functions") set(ZSH_AUTOCOMPLETE_DIR "${KDE_INSTALL_DATADIR}/zsh/site-functions")
endif() endif()
option(APPLE_IN_APP_BUNDLE "Use private dbus session for kdeconnect" OFF)
if(APPLE_IN_APP_BUNDLE)
add_compile_definitions(USE_PRIVATE_DBUS)
endif()
add_subdirectory(core) add_subdirectory(core)
add_subdirectory(plugins) add_subdirectory(plugins)
add_subdirectory(interfaces) add_subdirectory(interfaces)

View file

@ -158,7 +158,7 @@ int main(int argc, char** argv)
return int(devices.isEmpty()); return int(devices.isEmpty());
} else if(parser.isSet(QStringLiteral("refresh"))) { } else if(parser.isSet(QStringLiteral("refresh"))) {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect"), QStringLiteral("org.kde.kdeconnect.daemon"), QStringLiteral("forceOnNetworkChange")); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect"), QStringLiteral("org.kde.kdeconnect.daemon"), QStringLiteral("forceOnNetworkChange"));
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
} else { } else {
QString device = parser.value(QStringLiteral("device")); QString device = parser.value(QStringLiteral("device"));
@ -196,7 +196,7 @@ int main(int argc, char** argv)
QStringLiteral("org.kde.kdeconnect.device.share"), QStringLiteral("shareUrls")); QStringLiteral("org.kde.kdeconnect.device.share"), QStringLiteral("shareUrls"));
msg.setArguments(QVariantList() << QVariant(urls)); msg.setArguments(QVariantList() << QVariant(urls));
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
for (const QString& url : qAsConst(urls)) { for (const QString& url : qAsConst(urls)) {
QTextStream(stdout) << i18n("Shared %1", url) << endl; QTextStream(stdout) << i18n("Shared %1", url) << endl;
@ -204,7 +204,7 @@ int main(int argc, char** argv)
} else if (parser.isSet(QStringLiteral("share-text"))) { } else if (parser.isSet(QStringLiteral("share-text"))) {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device + QStringLiteral("/share"), QStringLiteral("org.kde.kdeconnect.device.share"), QStringLiteral("shareText")); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device + QStringLiteral("/share"), QStringLiteral("org.kde.kdeconnect.device.share"), QStringLiteral("shareText"));
msg.setArguments(QVariantList() << parser.value(QStringLiteral("share-text"))); msg.setArguments(QVariantList() << parser.value(QStringLiteral("share-text")));
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
QTextStream(stdout) << i18n("Shared text: %1", parser.value(QStringLiteral("share-text"))) << endl; QTextStream(stdout) << i18n("Shared text: %1", parser.value(QStringLiteral("share-text"))) << endl;
} else if (parser.isSet(QStringLiteral("lock")) || parser.isSet(QStringLiteral("unlock"))) { } else if (parser.isSet(QStringLiteral("lock")) || parser.isSet(QStringLiteral("unlock"))) {
LockDeviceDbusInterface iface(device); LockDeviceDbusInterface iface(device);
@ -257,7 +257,7 @@ int main(int argc, char** argv)
QString message = parser.value(QStringLiteral("ping-msg")); QString message = parser.value(QStringLiteral("ping-msg"));
msg.setArguments(QVariantList() << message); msg.setArguments(QVariantList() << message);
} }
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
} else if(parser.isSet(QStringLiteral("send-sms"))) { } else if(parser.isSet(QStringLiteral("send-sms"))) {
if (parser.isSet(QStringLiteral("destination"))) { if (parser.isSet(QStringLiteral("destination"))) {
qDBusRegisterMetaType<ConversationAddress>(); qDBusRegisterMetaType<ConversationAddress>();
@ -290,13 +290,13 @@ int main(int argc, char** argv)
} }
} else if(parser.isSet(QStringLiteral("ring"))) { } else if(parser.isSet(QStringLiteral("ring"))) {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device + QStringLiteral("/findmyphone"), QStringLiteral("org.kde.kdeconnect.device.findmyphone"), QStringLiteral("ring")); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device + QStringLiteral("/findmyphone"), QStringLiteral("org.kde.kdeconnect.device.findmyphone"), QStringLiteral("ring"));
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
} else if(parser.isSet(QStringLiteral("photo"))) { } else if(parser.isSet(QStringLiteral("photo"))) {
const QString fileName = parser.value(QStringLiteral("photo")); const QString fileName = parser.value(QStringLiteral("photo"));
if (!fileName.isEmpty()) { if (!fileName.isEmpty()) {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device + QStringLiteral("/photo"), QStringLiteral("org.kde.kdeconnect.device.photo"), QStringLiteral("requestPhoto")); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device + QStringLiteral("/photo"), QStringLiteral("org.kde.kdeconnect.device.photo"), QStringLiteral("requestPhoto"));
msg.setArguments({fileName}); msg.setArguments({fileName});
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
} else { } else {
QTextStream(stderr) << i18n("Please specify a filename for the photo") << endl; QTextStream(stderr) << i18n("Please specify a filename for the photo") << endl;
} }
@ -310,13 +310,13 @@ int main(int argc, char** argv)
while (!in.atEnd()) { while (!in.atEnd()) {
QByteArray line = in.readLine(); // sanitize to ASCII-codes > 31? QByteArray line = in.readLine(); // sanitize to ASCII-codes > 31?
msg.setArguments({QString::fromLatin1(line), -1, false, false, false}); msg.setArguments({QString::fromLatin1(line), -1, false, false, false});
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
} }
in.close(); in.close();
} }
} else { } else {
msg.setArguments({seq, -1, false, false, false}); msg.setArguments({seq, -1, false, false, false});
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
} }
} else if(parser.isSet(QStringLiteral("list-notifications"))) { } else if(parser.isSet(QStringLiteral("list-notifications"))) {
NotificationsModel notifications; NotificationsModel notifications;

View file

@ -82,8 +82,8 @@ void Daemon::init()
//Register on DBus //Register on DBus
qDBusRegisterMetaType< QMap<QString,QString> >(); qDBusRegisterMetaType< QMap<QString,QString> >();
DBusHelper::sessionBus().registerService(QStringLiteral("org.kde.kdeconnect")); QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kdeconnect"));
DBusHelper::sessionBus().registerObject(QStringLiteral("/modules/kdeconnect"), this, QDBusConnection::ExportScriptableContents); QDBusConnection::sessionBus().registerObject(QStringLiteral("/modules/kdeconnect"), this, QDBusConnection::ExportScriptableContents);
//Read remembered paired devices //Read remembered paired devices
const QStringList& list = KdeConnectConfig::instance().trustedDevices(); const QStringList& list = KdeConnectConfig::instance().trustedDevices();

View file

@ -24,7 +24,7 @@
namespace DBusHelper { namespace DBusHelper {
#ifdef USE_PRIVATE_DBUS #ifdef Q_OS_MAC
class DBusInstancePrivate class DBusInstancePrivate
{ {
public: public:
@ -46,17 +46,7 @@ void filterNonExportableCharacters(QString& s)
s.replace(regexp,QLatin1String("_")); s.replace(regexp,QLatin1String("_"));
} }
QDBusConnection sessionBus() #ifdef Q_OS_MAC
{
#ifdef USE_PRIVATE_DBUS
return QDBusConnection::connectToBus(KdeConnectConfig::instance().privateDBusAddress(),
QStringLiteral(KDECONNECT_PRIVATE_DBUS_NAME));
#else
return QDBusConnection::sessionBus();
#endif
}
#ifdef USE_PRIVATE_DBUS
void launchDBusDaemon() void launchDBusDaemon()
{ {
dbusInstance.launchDBusDaemon(); dbusInstance.launchDBusDaemon();
@ -68,7 +58,6 @@ void closeDBusDaemon()
dbusInstance.closeDBusDaemon(); dbusInstance.closeDBusDaemon();
} }
#ifdef Q_OS_MAC
void macosUnsetLaunchctlEnv() void macosUnsetLaunchctlEnv()
{ {
// Unset Launchd env // Unset Launchd env
@ -81,7 +70,6 @@ void macosUnsetLaunchctlEnv()
unsetLaunchdDBusEnv.start(); unsetLaunchdDBusEnv.start();
unsetLaunchdDBusEnv.waitForFinished(); unsetLaunchdDBusEnv.waitForFinished();
} }
#endif
void DBusInstancePrivate::launchDBusDaemon() void DBusInstancePrivate::launchDBusDaemon()
{ {
@ -147,9 +135,7 @@ void DBusInstancePrivate::closeDBusDaemon()
if (privateDBusAddressFile.exists()) privateDBusAddressFile.resize(0); if (privateDBusAddressFile.exists()) privateDBusAddressFile.resize(0);
#ifdef Q_OS_MAC
macosUnsetLaunchctlEnv(); macosUnsetLaunchctlEnv();
#endif
} }
} }

View file

@ -19,12 +19,9 @@
namespace DBusHelper { namespace DBusHelper {
void KDECONNECTCORE_EXPORT filterNonExportableCharacters(QString& s); void KDECONNECTCORE_EXPORT filterNonExportableCharacters(QString& s);
#ifdef USE_PRIVATE_DBUS #ifdef Q_OS_MAC
void KDECONNECTCORE_EXPORT launchDBusDaemon(); void KDECONNECTCORE_EXPORT launchDBusDaemon();
void KDECONNECTCORE_EXPORT closeDBusDaemon(); void KDECONNECTCORE_EXPORT closeDBusDaemon();
#endif
QDBusConnection KDECONNECTCORE_EXPORT sessionBus();
#ifdef Q_OS_MAC
void KDECONNECTCORE_EXPORT macosUnsetLaunchctlEnv(); void KDECONNECTCORE_EXPORT macosUnsetLaunchctlEnv();
#endif #endif
} }

View file

@ -74,7 +74,7 @@ Device::Device(QObject* parent, const QString& id)
d->m_deviceType = str2type(info.deviceType); d->m_deviceType = str2type(info.deviceType);
//Register in bus //Register in bus
DBusHelper::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
//Assume every plugin is supported until addLink is called and we can get the actual list //Assume every plugin is supported until addLink is called and we can get the actual list
d->m_allPlugins = PluginLoader::instance()->getPluginList().toSet(); d->m_allPlugins = PluginLoader::instance()->getPluginList().toSet();
@ -93,7 +93,7 @@ Device::Device(QObject* parent, const NetworkPacket& identityPacket, DeviceLink*
addLink(identityPacket, dl); addLink(identityPacket, dl);
//Register in bus //Register in bus
DBusHelper::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors);
connect(this, &Device::pairingError, this, &warn); connect(this, &Device::pairingError, this, &warn);
@ -186,7 +186,7 @@ void Device::reloadPlugins()
d->m_plugins = newPluginMap; d->m_plugins = newPluginMap;
d->m_pluginsByIncomingCapability = newPluginsByIncomingCapability; d->m_pluginsByIncomingCapability = newPluginsByIncomingCapability;
QDBusConnection bus = DBusHelper::sessionBus(); QDBusConnection bus = QDBusConnection::sessionBus();
for (KdeConnectPlugin* plugin : qAsConst(d->m_plugins)) { for (KdeConnectPlugin* plugin : qAsConst(d->m_plugins)) {
//TODO: see how it works in Android (only done once, when created) //TODO: see how it works in Android (only done once, when created)
plugin->connected(); plugin->connected();

View file

@ -39,7 +39,7 @@ struct KdeConnectConfigPrivate {
QSettings* m_config; QSettings* m_config;
QSettings* m_trustedDevices; QSettings* m_trustedDevices;
#ifdef USE_PRIVATE_DBUS #ifdef Q_OS_MAC
QString m_privateDBusAddress; // Private DBus Address cache QString m_privateDBusAddress; // Private DBus Address cache
#endif #endif
}; };
@ -362,7 +362,7 @@ void KdeConnectConfig::generateCertificate(const QString& certPath)
} }
} }
#ifdef USE_PRIVATE_DBUS #ifdef Q_OS_MAC
QString KdeConnectConfig::privateDBusAddressPath() QString KdeConnectConfig::privateDBusAddressPath()
{ {
return baseConfigDir().absoluteFilePath(QStringLiteral("private_dbus_address")); return baseConfigDir().absoluteFilePath(QStringLiteral("private_dbus_address"));

View file

@ -60,7 +60,7 @@ public:
QDir deviceConfigDir(const QString& deviceId); QDir deviceConfigDir(const QString& deviceId);
QDir pluginConfigDir(const QString& deviceId, const QString& pluginName); //Used by KdeConnectPluginConfig QDir pluginConfigDir(const QString& deviceId, const QString& pluginName); //Used by KdeConnectPluginConfig
#ifdef USE_PRIVATE_DBUS #ifdef Q_OS_MAC
/* /*
* Get private DBus Address when use private DBus * Get private DBus Address when use private DBus
*/ */

View file

@ -37,7 +37,7 @@ KdeConnectPluginConfig::KdeConnectPluginConfig(const QString& deviceId, const QS
d->m_config = new QSettings(d->m_configDir.absoluteFilePath(QStringLiteral("config")), QSettings::IniFormat); d->m_config = new QSettings(d->m_configDir.absoluteFilePath(QStringLiteral("config")), QSettings::IniFormat);
d->m_signal = QDBusMessage::createSignal(QStringLiteral("/kdeconnect/") + deviceId + QStringLiteral("/") + pluginName, QStringLiteral("org.kde.kdeconnect.config"), QStringLiteral("configChanged")); d->m_signal = QDBusMessage::createSignal(QStringLiteral("/kdeconnect/") + deviceId + QStringLiteral("/") + pluginName, QStringLiteral("org.kde.kdeconnect.config"), QStringLiteral("configChanged"));
DBusHelper::sessionBus().connect(QLatin1String(""), QStringLiteral("/kdeconnect/") + deviceId + QStringLiteral("/") + pluginName, QStringLiteral("org.kde.kdeconnect.config"), QStringLiteral("configChanged"), this, SLOT(slotConfigChanged())); QDBusConnection::sessionBus().connect(QLatin1String(""), QStringLiteral("/kdeconnect/") + deviceId + QStringLiteral("/") + pluginName, QStringLiteral("org.kde.kdeconnect.config"), QStringLiteral("configChanged"), this, SLOT(slotConfigChanged()));
} }
KdeConnectPluginConfig::~KdeConnectPluginConfig() KdeConnectPluginConfig::~KdeConnectPluginConfig()
@ -107,7 +107,7 @@ void KdeConnectPluginConfig::set(const QString& key, const QVariant& value)
{ {
d->m_config->setValue(key, value); d->m_config->setValue(key, value);
d->m_config->sync(); d->m_config->sync();
DBusHelper::sessionBus().send(d->m_signal); QDBusConnection::sessionBus().send(d->m_signal);
} }
void KdeConnectPluginConfig::setList(const QString& key, const QVariantList& list) void KdeConnectPluginConfig::setList(const QString& key, const QVariantList& list)
@ -119,7 +119,7 @@ void KdeConnectPluginConfig::setList(const QString& key, const QVariantList& lis
} }
d->m_config->endArray(); d->m_config->endArray();
d->m_config->sync(); d->m_config->sync();
DBusHelper::sessionBus().send(d->m_signal); QDBusConnection::sessionBus().send(d->m_signal);
} }
void KdeConnectPluginConfig::slotConfigChanged() void KdeConnectPluginConfig::slotConfigChanged()

View file

@ -24,7 +24,7 @@ void NotificationServerInfo::init()
{ {
QDBusMessage query = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("/org/freedesktop/Notifications"), QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("GetCapabilities")); QDBusMessage query = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("/org/freedesktop/Notifications"), QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("GetCapabilities"));
QDBusPendingReply<QStringList> reply = DBusHelper::sessionBus().asyncCall(query); QDBusPendingReply<QStringList> reply = QDBusConnection::sessionBus().asyncCall(query);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, reply, watcher] { connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, reply, watcher] {
watcher->deleteLater(); watcher->deleteLater();

View file

@ -141,23 +141,27 @@ int main(int argc, char* argv[])
KAboutData::setApplicationData(aboutData); KAboutData::setApplicationData(aboutData);
app.setQuitOnLastWindowClosed(false); app.setQuitOnLastWindowClosed(false);
#ifdef USE_PRIVATE_DBUS
DBusHelper::launchDBusDaemon();
#endif
QCommandLineParser parser; QCommandLineParser parser;
QCommandLineOption replaceOption({QStringLiteral("replace")}, i18n("Replace an existing instance")); QCommandLineOption replaceOption({QStringLiteral("replace")}, i18n("Replace an existing instance"));
parser.addOption(replaceOption); parser.addOption(replaceOption);
QCommandLineOption macosPrivateDBusOption({QStringLiteral("use-private-dbus")},
i18n("Launch a private D-Bus daemon with kdeconnectd (macOS test-purpose only)"));
parser.addOption(macosPrivateDBusOption);
aboutData.setupCommandLine(&parser); aboutData.setupCommandLine(&parser);
parser.process(app); parser.process(app);
#ifdef Q_OS_MAC
if (parser.isSet(macosPrivateDBusOption)) {
DBusHelper::launchDBusDaemon();
}
#endif
aboutData.processCommandLine(&parser); aboutData.processCommandLine(&parser);
if (parser.isSet(replaceOption)) { if (parser.isSet(replaceOption)) {
auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"),
QStringLiteral("/MainApplication"), QStringLiteral("/MainApplication"),
QStringLiteral("org.qtproject.Qt.QCoreApplication"), QStringLiteral("org.qtproject.Qt.QCoreApplication"),
QStringLiteral("quit")); QStringLiteral("quit"));
DBusHelper::sessionBus().call(message); //deliberately block until it's done, so we register the name after the app quits QDBusConnection::sessionBus().call(message); //deliberately block until it's done, so we register the name after the app quits
} }
KDBusService dbusService(KDBusService::Unique); KDBusService dbusService(KDBusService::Unique);

View file

@ -80,7 +80,7 @@ void SendFileItemAction::sendFile()
for (const QUrl& url : urls) { for (const QUrl& url : urls) {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/share"), QStringLiteral("org.kde.kdeconnect.device.share"), QStringLiteral("shareUrl")); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/share"), QStringLiteral("org.kde.kdeconnect.device.share"), QStringLiteral("shareUrl"));
msg.setArguments(QVariantList() << url.toString()); msg.setArguments(QVariantList() << url.toString());
DBusHelper::sessionBus().asyncCall(msg); QDBusConnection::sessionBus().asyncCall(msg);
} }
} }

View file

@ -68,7 +68,7 @@ DeviceIndicator::DeviceIndicator(DeviceDbusInterface* device)
connect(getPhoto, &QAction::triggered, this, [device](){ connect(getPhoto, &QAction::triggered, this, [device](){
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device->id() + QStringLiteral("/photo"), QStringLiteral("org.kde.kdeconnect.device.photo"), QStringLiteral("requestPhoto")); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device->id() + QStringLiteral("/photo"), QStringLiteral("org.kde.kdeconnect.device.photo"), QStringLiteral("requestPhoto"));
msg.setArguments({QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first() + QDateTime::currentDateTime().toString(QStringLiteral("/dd-MM-yy_hh-mm-ss.png"))}); msg.setArguments({QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first() + QDateTime::currentDateTime().toString(QStringLiteral("/dd-MM-yy_hh-mm-ss.png"))});
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
}); });
setWhenAvailable(device->hasPlugin(QStringLiteral("kdeconnect_photo")), [getPhoto](bool available) { getPhoto->setVisible(available); }, this); setWhenAvailable(device->hasPlugin(QStringLiteral("kdeconnect_photo")), [getPhoto](bool available) { getPhoto->setVisible(available); }, this);

View file

@ -20,6 +20,8 @@
#include "serviceregister_mac.h" #include "serviceregister_mac.h"
#include <kdeconnectconfig.h>
IndicatorHelper::IndicatorHelper() IndicatorHelper::IndicatorHelper()
{ {
registerServices(); registerServices();
@ -60,30 +62,33 @@ void IndicatorHelper::iconPathHook()
int IndicatorHelper::daemonHook(QProcess &kdeconnectd) int IndicatorHelper::daemonHook(QProcess &kdeconnectd)
{ {
#ifdef USE_PRIVATE_DBUS // This flag marks whether a session DBus daemon is installed and run
// Unset launchctl env, avoid block bool hasUsableSessionBus = true;
DBusHelper::macosUnsetLaunchctlEnv(); // Use another bus instance for detecting, avoid session bus cache in Qt
#endif if (!QDBusConnection::connectToBus(QDBusConnection::SessionBus,
QStringLiteral("kdeconnect-test-client")).isConnected()) {
qDebug() << "Default session bus not detected, will use private D-Bus.";
// Start kdeconnectd // Unset launchctl env and private dbus addr file, avoid block
m_splashScreen->showMessage(i18n("Launching daemon") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white); DBusHelper::macosUnsetLaunchctlEnv();
if (QFile::exists(QCoreApplication::applicationDirPath() + QStringLiteral("/kdeconnectd"))) { QFile privateDBusAddressFile(KdeConnectConfig::instance().privateDBusAddressPath());
kdeconnectd.startDetached(QCoreApplication::applicationDirPath() + QStringLiteral("/kdeconnectd")); if (privateDBusAddressFile.exists()) privateDBusAddressFile.resize(0);
} else if (QFile::exists(QString::fromLatin1(qgetenv("craftRoot")) + QStringLiteral("/../lib/libexec/kdeconnectd"))) {
kdeconnectd.startDetached(QString::fromLatin1(qgetenv("craftRoot")) + QStringLiteral("/../lib/libexec/kdeconnectd")); // Update session bus usability state
} else { hasUsableSessionBus = false;
QMessageBox::critical(nullptr, i18n("KDE Connect"),
i18n("Cannot find kdeconnectd"),
QMessageBox::Abort,
QMessageBox::Abort);
return -1;
} }
// Wait for dbus daemon env // Start daemon
QProcess getLaunchdDBusEnv; m_splashScreen->showMessage(i18n("Launching daemon") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);
m_splashScreen->showMessage(i18n("Waiting D-Bus") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);
int retry = 0; // Here we will try to bring our private session D-Bus
do { if (!hasUsableSessionBus) {
qDebug() << "Launching private session D-Bus.";
DBusHelper::launchDBusDaemon();
// Wait for dbus daemon env
QProcess getLaunchdDBusEnv;
m_splashScreen->showMessage(i18n("Waiting D-Bus") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);
int retry = 0;
getLaunchdDBusEnv.setProgram(QStringLiteral("launchctl")); getLaunchdDBusEnv.setProgram(QStringLiteral("launchctl"));
getLaunchdDBusEnv.setArguments({ getLaunchdDBusEnv.setArguments({
QStringLiteral("getenv"), QStringLiteral("getenv"),
@ -94,9 +99,10 @@ int IndicatorHelper::daemonHook(QProcess &kdeconnectd)
QString launchdDBusEnv = QString::fromLocal8Bit(getLaunchdDBusEnv.readAllStandardOutput()); QString launchdDBusEnv = QString::fromLocal8Bit(getLaunchdDBusEnv.readAllStandardOutput());
if (launchdDBusEnv.length() > 0) { if (launchdDBusEnv.length() > 0 && QDBusConnection::sessionBus().isConnected()) {
break; qDebug() << "Private D-Bus daemon launched and connected.";
} else if (retry >= 10) { hasUsableSessionBus = true;
} else {
// Show a warning and exit // Show a warning and exit
qCritical() << "Fail to get launchctl" << KDECONNECT_SESSION_DBUS_LAUNCHD_ENV << "env"; qCritical() << "Fail to get launchctl" << KDECONNECT_SESSION_DBUS_LAUNCHD_ENV << "env";
@ -106,11 +112,22 @@ int IndicatorHelper::daemonHook(QProcess &kdeconnectd)
QMessageBox::Abort, QMessageBox::Abort,
QMessageBox::Abort); QMessageBox::Abort);
return -2; return -2;
} else {
QThread::sleep(3); // Retry after 3s
retry++;
} }
} while(true); }
// Start kdeconnectd, the daemon will not duplicate when there is already one
if (QFile::exists(QCoreApplication::applicationDirPath() + QStringLiteral("/kdeconnectd"))) {
kdeconnectd.setProgram(QCoreApplication::applicationDirPath() + QStringLiteral("/kdeconnectd"));
} else if (QFile::exists(QString::fromLatin1(qgetenv("craftRoot")) + QStringLiteral("/../lib/libexec/kdeconnectd"))) {
kdeconnectd.setProgram(QString::fromLatin1(qgetenv("craftRoot")) + QStringLiteral("/../lib/libexec/kdeconnectd"));
} else {
QMessageBox::critical(nullptr, i18n("KDE Connect"),
i18n("Cannot find kdeconnectd"),
QMessageBox::Abort,
QMessageBox::Abort);
return -1;
}
kdeconnectd.startDetached();
m_splashScreen->showMessage(i18n("Loading modules") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white); m_splashScreen->showMessage(i18n("Loading modules") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);

View file

@ -116,12 +116,8 @@ int main(int argc, char** argv)
QStringLiteral("/MainApplication"), QStringLiteral("/MainApplication"),
QStringLiteral("org.qtproject.Qt.QCoreApplication"), QStringLiteral("org.qtproject.Qt.QCoreApplication"),
QStringLiteral("quit")); QStringLiteral("quit"));
DBusHelper::sessionBus().call(message, QDBus::NoBlock); // Close our daemon QDBusConnection::sessionBus().call(message, QDBus::NoBlock);
message = QDBusMessage::createMethodCall(qApp->applicationName(), qApp->quit();
QStringLiteral("/MainApplication"),
QStringLiteral("org.qtproject.Qt.QCoreApplication"),
QStringLiteral("quit"));
DBusHelper::sessionBus().call(message, QDBus::NoBlock); // Close our indicator
}); });
#elif defined Q_OS_WIN #elif defined Q_OS_WIN

View file

@ -11,7 +11,7 @@ QString DaemonDbusInterface::activatedService() {
static const QString service = QStringLiteral("org.kde.kdeconnect"); static const QString service = QStringLiteral("org.kde.kdeconnect");
#ifndef SAILFISHOS #ifndef SAILFISHOS
auto reply = DBusHelper::sessionBus().interface()->startService(service); auto reply = QDBusConnection::sessionBus().interface()->startService(service);
if (!reply.isValid()) { if (!reply.isValid()) {
qWarning() << "error activating kdeconnectd:" << reply.error(); qWarning() << "error activating kdeconnectd:" << reply.error();
} }
@ -21,7 +21,7 @@ QString DaemonDbusInterface::activatedService() {
} }
DaemonDbusInterface::DaemonDbusInterface(QObject* parent) DaemonDbusInterface::DaemonDbusInterface(QObject* parent)
: OrgKdeKdeconnectDaemonInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect"), DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDaemonInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect"), QDBusConnection::sessionBus(), parent)
{ {
connect(this, &OrgKdeKdeconnectDaemonInterface::pairingRequestsChanged, this, &DaemonDbusInterface::pairingRequestsChangedProxy); connect(this, &OrgKdeKdeconnectDaemonInterface::pairingRequestsChanged, this, &DaemonDbusInterface::pairingRequestsChangedProxy);
connect(this, &OrgKdeKdeconnectDaemonInterface::customDevicesChanged, this, &DaemonDbusInterface::customDevicesChangedProxy); connect(this, &OrgKdeKdeconnectDaemonInterface::customDevicesChanged, this, &DaemonDbusInterface::customDevicesChangedProxy);
@ -33,7 +33,7 @@ DaemonDbusInterface::~DaemonDbusInterface()
} }
DeviceDbusInterface::DeviceDbusInterface(const QString& id, QObject* parent) DeviceDbusInterface::DeviceDbusInterface(const QString& id, QObject* parent)
: OrgKdeKdeconnectDeviceInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") +id, DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") +id, QDBusConnection::sessionBus(), parent)
, m_id(id) , m_id(id)
{ {
connect(this, &OrgKdeKdeconnectDeviceInterface::trustedChanged, this, &DeviceDbusInterface::trustedChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::trustedChanged, this, &DeviceDbusInterface::trustedChangedProxy);
@ -55,11 +55,11 @@ QString DeviceDbusInterface::id() const
void DeviceDbusInterface::pluginCall(const QString& plugin, const QString& method) void DeviceDbusInterface::pluginCall(const QString& plugin, const QString& method)
{ {
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") +id() + QStringLiteral("/") + plugin, QStringLiteral("org.kde.kdeconnect.device.") + plugin, method); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") +id() + QStringLiteral("/") + plugin, QStringLiteral("org.kde.kdeconnect.device.") + plugin, method);
DBusHelper::sessionBus().asyncCall(msg); QDBusConnection::sessionBus().asyncCall(msg);
} }
BatteryDbusInterface::BatteryDbusInterface(const QString& id, QObject* parent) BatteryDbusInterface::BatteryDbusInterface(const QString& id, QObject* parent)
: OrgKdeKdeconnectDeviceBatteryInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/battery"), DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceBatteryInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/battery"), QDBusConnection::sessionBus(), parent)
{ {
connect(this, &OrgKdeKdeconnectDeviceBatteryInterface::refreshed, this, &BatteryDbusInterface::refreshedProxy); connect(this, &OrgKdeKdeconnectDeviceBatteryInterface::refreshed, this, &BatteryDbusInterface::refreshedProxy);
} }
@ -67,7 +67,7 @@ BatteryDbusInterface::BatteryDbusInterface(const QString& id, QObject* parent)
BatteryDbusInterface::~BatteryDbusInterface() = default; BatteryDbusInterface::~BatteryDbusInterface() = default;
ConnectivityReportDbusInterface::ConnectivityReportDbusInterface(const QString& id, QObject* parent) ConnectivityReportDbusInterface::ConnectivityReportDbusInterface(const QString& id, QObject* parent)
: OrgKdeKdeconnectDeviceConnectivity_reportInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/connectivity_report"), DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceConnectivity_reportInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/connectivity_report"), QDBusConnection::sessionBus(), parent)
{ {
connect(this, &OrgKdeKdeconnectDeviceConnectivity_reportInterface::refreshed, this, &ConnectivityReportDbusInterface::refreshedProxy); connect(this, &OrgKdeKdeconnectDeviceConnectivity_reportInterface::refreshed, this, &ConnectivityReportDbusInterface::refreshedProxy);
} }
@ -75,7 +75,7 @@ ConnectivityReportDbusInterface::ConnectivityReportDbusInterface(const QString&
ConnectivityReportDbusInterface::~ConnectivityReportDbusInterface() = default; ConnectivityReportDbusInterface::~ConnectivityReportDbusInterface() = default;
DeviceNotificationsDbusInterface::DeviceNotificationsDbusInterface(const QString& id, QObject* parent) DeviceNotificationsDbusInterface::DeviceNotificationsDbusInterface(const QString& id, QObject* parent)
: OrgKdeKdeconnectDeviceNotificationsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/notifications"), DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceNotificationsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/notifications"), QDBusConnection::sessionBus(), parent)
{ {
} }
@ -86,7 +86,7 @@ DeviceNotificationsDbusInterface::~DeviceNotificationsDbusInterface()
} }
NotificationDbusInterface::NotificationDbusInterface(const QString& deviceId, const QString& notificationId, QObject* parent) NotificationDbusInterface::NotificationDbusInterface(const QString& deviceId, const QString& notificationId, QObject* parent)
: OrgKdeKdeconnectDeviceNotificationsNotificationInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/notifications/") + notificationId, DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceNotificationsNotificationInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/notifications/") + notificationId, QDBusConnection::sessionBus(), parent)
, id(notificationId) , id(notificationId)
{ {
@ -98,7 +98,7 @@ NotificationDbusInterface::~NotificationDbusInterface()
} }
DeviceConversationsDbusInterface::DeviceConversationsDbusInterface(const QString& deviceId, QObject* parent) DeviceConversationsDbusInterface::DeviceConversationsDbusInterface(const QString& deviceId, QObject* parent)
: OrgKdeKdeconnectDeviceConversationsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId, DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceConversationsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId, QDBusConnection::sessionBus(), parent)
{ {
} }
@ -109,7 +109,7 @@ DeviceConversationsDbusInterface::~DeviceConversationsDbusInterface()
} }
SftpDbusInterface::SftpDbusInterface(const QString& id, QObject* parent) SftpDbusInterface::SftpDbusInterface(const QString& id, QObject* parent)
: OrgKdeKdeconnectDeviceSftpInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/sftp"), DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceSftpInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/sftp"), QDBusConnection::sessionBus(), parent)
{ {
} }
@ -120,7 +120,7 @@ SftpDbusInterface::~SftpDbusInterface()
} }
MprisDbusInterface::MprisDbusInterface(const QString& id, QObject* parent) MprisDbusInterface::MprisDbusInterface(const QString& id, QObject* parent)
: OrgKdeKdeconnectDeviceMprisremoteInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/mprisremote"), DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceMprisremoteInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/mprisremote"), QDBusConnection::sessionBus(), parent)
{ {
connect(this, &OrgKdeKdeconnectDeviceMprisremoteInterface::propertiesChanged, this, &MprisDbusInterface::propertiesChangedProxy); connect(this, &OrgKdeKdeconnectDeviceMprisremoteInterface::propertiesChanged, this, &MprisDbusInterface::propertiesChangedProxy);
} }
@ -130,7 +130,7 @@ MprisDbusInterface::~MprisDbusInterface()
} }
RemoteControlDbusInterface::RemoteControlDbusInterface(const QString& id, QObject* parent) RemoteControlDbusInterface::RemoteControlDbusInterface(const QString& id, QObject* parent)
: OrgKdeKdeconnectDeviceRemotecontrolInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/remotecontrol"), DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceRemotecontrolInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/remotecontrol"), QDBusConnection::sessionBus(), parent)
{ {
} }
@ -139,7 +139,7 @@ RemoteControlDbusInterface::~RemoteControlDbusInterface()
} }
LockDeviceDbusInterface::LockDeviceDbusInterface(const QString& id, QObject* parent) LockDeviceDbusInterface::LockDeviceDbusInterface(const QString& id, QObject* parent)
: OrgKdeKdeconnectDeviceLockdeviceInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/lockdevice"), DBusHelper::sessionBus(), parent) : OrgKdeKdeconnectDeviceLockdeviceInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + id + QStringLiteral("/lockdevice"), QDBusConnection::sessionBus(), parent)
{ {
connect(this, &OrgKdeKdeconnectDeviceLockdeviceInterface::lockedChanged, this, &LockDeviceDbusInterface::lockedChangedProxy); connect(this, &OrgKdeKdeconnectDeviceLockdeviceInterface::lockedChanged, this, &LockDeviceDbusInterface::lockedChangedProxy);
Q_ASSERT(isValid()); Q_ASSERT(isValid());
@ -150,7 +150,7 @@ LockDeviceDbusInterface::~LockDeviceDbusInterface()
} }
FindMyPhoneDeviceDbusInterface::FindMyPhoneDeviceDbusInterface(const QString& deviceId, QObject* parent): FindMyPhoneDeviceDbusInterface::FindMyPhoneDeviceDbusInterface(const QString& deviceId, QObject* parent):
OrgKdeKdeconnectDeviceFindmyphoneInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/findmyphone"), DBusHelper::sessionBus(), parent) OrgKdeKdeconnectDeviceFindmyphoneInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/findmyphone"), QDBusConnection::sessionBus(), parent)
{ {
} }
@ -159,14 +159,14 @@ FindMyPhoneDeviceDbusInterface::~FindMyPhoneDeviceDbusInterface()
} }
RemoteCommandsDbusInterface::RemoteCommandsDbusInterface(const QString& deviceId, QObject* parent): RemoteCommandsDbusInterface::RemoteCommandsDbusInterface(const QString& deviceId, QObject* parent):
OrgKdeKdeconnectDeviceRemotecommandsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotecommands"), DBusHelper::sessionBus(), parent) OrgKdeKdeconnectDeviceRemotecommandsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotecommands"), QDBusConnection::sessionBus(), parent)
{ {
} }
RemoteCommandsDbusInterface::~RemoteCommandsDbusInterface() = default; RemoteCommandsDbusInterface::~RemoteCommandsDbusInterface() = default;
RemoteKeyboardDbusInterface::RemoteKeyboardDbusInterface(const QString& deviceId, QObject* parent): RemoteKeyboardDbusInterface::RemoteKeyboardDbusInterface(const QString& deviceId, QObject* parent):
OrgKdeKdeconnectDeviceRemotekeyboardInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotekeyboard"), DBusHelper::sessionBus(), parent) OrgKdeKdeconnectDeviceRemotekeyboardInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotekeyboard"), QDBusConnection::sessionBus(), parent)
{ {
connect(this, &OrgKdeKdeconnectDeviceRemotekeyboardInterface::remoteStateChanged, this, &RemoteKeyboardDbusInterface::remoteStateChanged); connect(this, &OrgKdeKdeconnectDeviceRemotekeyboardInterface::remoteStateChanged, this, &RemoteKeyboardDbusInterface::remoteStateChanged);
} }
@ -174,26 +174,26 @@ RemoteKeyboardDbusInterface::RemoteKeyboardDbusInterface(const QString& deviceId
RemoteKeyboardDbusInterface::~RemoteKeyboardDbusInterface() = default; RemoteKeyboardDbusInterface::~RemoteKeyboardDbusInterface() = default;
SmsDbusInterface::SmsDbusInterface(const QString& deviceId, QObject* parent): SmsDbusInterface::SmsDbusInterface(const QString& deviceId, QObject* parent):
OrgKdeKdeconnectDeviceSmsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/sms"), DBusHelper::sessionBus(), parent) OrgKdeKdeconnectDeviceSmsInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/sms"), QDBusConnection::sessionBus(), parent)
{ {
} }
SmsDbusInterface::~SmsDbusInterface() = default; SmsDbusInterface::~SmsDbusInterface() = default;
ShareDbusInterface::ShareDbusInterface(const QString& deviceId, QObject* parent): ShareDbusInterface::ShareDbusInterface(const QString& deviceId, QObject* parent):
OrgKdeKdeconnectDeviceShareInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/share"), DBusHelper::sessionBus(), parent) OrgKdeKdeconnectDeviceShareInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/share"), QDBusConnection::sessionBus(), parent)
{ {
} }
ShareDbusInterface::~ShareDbusInterface() = default; ShareDbusInterface::~ShareDbusInterface() = default;
RemoteSystemVolumeDbusInterface::RemoteSystemVolumeDbusInterface(const QString& deviceId, QObject* parent): RemoteSystemVolumeDbusInterface::RemoteSystemVolumeDbusInterface(const QString& deviceId, QObject* parent):
OrgKdeKdeconnectDeviceRemotesystemvolumeInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotesystemvolume"), DBusHelper::sessionBus(), parent) OrgKdeKdeconnectDeviceRemotesystemvolumeInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/remotesystemvolume"), QDBusConnection::sessionBus(), parent)
{ {
} }
BigscreenDbusInterface::BigscreenDbusInterface(const QString& deviceId, QObject* parent): BigscreenDbusInterface::BigscreenDbusInterface(const QString& deviceId, QObject* parent):
OrgKdeKdeconnectDeviceBigscreenInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/bigscreen"), DBusHelper::sessionBus(), parent) OrgKdeKdeconnectDeviceBigscreenInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/bigscreen"), QDBusConnection::sessionBus(), parent)
{ {
} }

View file

@ -42,7 +42,7 @@ DevicesModel::DevicesModel(QObject* parent)
this, &DevicesModel::deviceRemoved); this, &DevicesModel::deviceRemoved);
QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(), QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(),
DBusHelper::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this);
connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &DevicesModel::refreshDeviceList); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &DevicesModel::refreshDeviceList);
connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &DevicesModel::clearDevices); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &DevicesModel::clearDevices);

View file

@ -31,7 +31,7 @@ NotificationsModel::NotificationsModel(QObject* parent)
this, &NotificationsModel::anyDismissableChanged); this, &NotificationsModel::anyDismissableChanged);
QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(), QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(),
DBusHelper::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this);
connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &NotificationsModel::refreshNotificationList); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &NotificationsModel::refreshNotificationList);
connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &NotificationsModel::clearNotifications); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &NotificationsModel::clearNotifications);
} }

View file

@ -22,7 +22,7 @@ RemoteCommandsModel::RemoteCommandsModel(QObject* parent)
this, &RemoteCommandsModel::rowsChanged); this, &RemoteCommandsModel::rowsChanged);
QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(), QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(),
DBusHelper::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this);
connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &RemoteCommandsModel::refreshCommandList); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &RemoteCommandsModel::refreshCommandList);
connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &RemoteCommandsModel::clearCommands); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &RemoteCommandsModel::clearCommands);
} }

View file

@ -23,7 +23,7 @@ RemoteSinksModel::RemoteSinksModel(QObject* parent)
this, &RemoteSinksModel::rowsChanged); this, &RemoteSinksModel::rowsChanged);
QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(), QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(),
DBusHelper::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this);
connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &RemoteSinksModel::refreshSinkList); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &RemoteSinksModel::refreshSinkList);
connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &RemoteSinksModel::refreshSinkList); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &RemoteSinksModel::refreshSinkList);
} }

View file

@ -37,13 +37,13 @@ MprisControlPlugin::MprisControlPlugin(QObject* parent, const QVariantList& args
: KdeConnectPlugin(parent, args) : KdeConnectPlugin(parent, args)
, prevVolume(-1) , prevVolume(-1)
{ {
m_watcher = new QDBusServiceWatcher(QString(), DBusHelper::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); m_watcher = new QDBusServiceWatcher(QString(), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this);
// TODO: QDBusConnectionInterface::serviceOwnerChanged is deprecated, maybe query org.freedesktop.DBus directly? // TODO: QDBusConnectionInterface::serviceOwnerChanged is deprecated, maybe query org.freedesktop.DBus directly?
connect(DBusHelper::sessionBus().interface(), &QDBusConnectionInterface::serviceOwnerChanged, this, &MprisControlPlugin::serviceOwnerChanged); connect(QDBusConnection::sessionBus().interface(), &QDBusConnectionInterface::serviceOwnerChanged, this, &MprisControlPlugin::serviceOwnerChanged);
//Add existing interfaces //Add existing interfaces
const QStringList services = DBusHelper::sessionBus().interface()->registeredServiceNames().value(); const QStringList services = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
for (const QString& service : services) { for (const QString& service : services) {
// The string doesn't matter, it just needs to be empty/non-empty // The string doesn't matter, it just needs to be empty/non-empty
serviceOwnerChanged(service, QLatin1String(""), QStringLiteral("1")); serviceOwnerChanged(service, QLatin1String(""), QStringLiteral("1"));
@ -74,7 +74,7 @@ void MprisControlPlugin::addPlayer(const QString& service)
{ {
const QString mediaPlayerObjectPath = QStringLiteral("/org/mpris/MediaPlayer2"); const QString mediaPlayerObjectPath = QStringLiteral("/org/mpris/MediaPlayer2");
OrgMprisMediaPlayer2Interface iface(service, mediaPlayerObjectPath, DBusHelper::sessionBus()); OrgMprisMediaPlayer2Interface iface(service, mediaPlayerObjectPath, QDBusConnection::sessionBus());
QString identity = iface.identity(); QString identity = iface.identity();
if (identity.isEmpty()) { if (identity.isEmpty()) {
@ -86,7 +86,7 @@ void MprisControlPlugin::addPlayer(const QString& service)
uniqueName = identity + QLatin1String(" [") + QString::number(i) + QLatin1Char(']'); uniqueName = identity + QLatin1String(" [") + QString::number(i) + QLatin1Char(']');
} }
MprisPlayer player(service, mediaPlayerObjectPath, DBusHelper::sessionBus()); MprisPlayer player(service, mediaPlayerObjectPath, QDBusConnection::sessionBus());
playerList.insert(uniqueName, player); playerList.insert(uniqueName, player);

View file

@ -109,7 +109,7 @@ void NotificationsPlugin::addNotification(Notification* noti)
m_notifications[publicId] = noti; m_notifications[publicId] = noti;
m_internalIdToPublicId[internalId] = publicId; m_internalIdToPublicId[internalId] = publicId;
DBusHelper::sessionBus().registerObject(device()->dbusPath() + QStringLiteral("/notifications/") + publicId, noti, QDBusConnection::ExportScriptableContents); QDBusConnection::sessionBus().registerObject(device()->dbusPath() + QStringLiteral("/notifications/") + publicId, noti, QDBusConnection::ExportScriptableContents);
Q_EMIT notificationPosted(publicId); Q_EMIT notificationPosted(publicId);
} }

View file

@ -60,10 +60,10 @@ bool PauseMusicPlugin::receivePacket(const NetworkPacket& np)
if (pause) { if (pause) {
//Search for interfaces currently playing //Search for interfaces currently playing
const QStringList interfaces = DBusHelper::sessionBus().interface()->registeredServiceNames().value(); const QStringList interfaces = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
for (const QString& iface : interfaces) { for (const QString& iface : interfaces) {
if (iface.startsWith(QLatin1String("org.mpris.MediaPlayer2"))) { if (iface.startsWith(QLatin1String("org.mpris.MediaPlayer2"))) {
OrgMprisMediaPlayer2PlayerInterface mprisInterface(iface, QStringLiteral("/org/mpris/MediaPlayer2"), DBusHelper::sessionBus()); OrgMprisMediaPlayer2PlayerInterface mprisInterface(iface, QStringLiteral("/org/mpris/MediaPlayer2"), QDBusConnection::sessionBus());
QString status = mprisInterface.playbackStatus(); QString status = mprisInterface.playbackStatus();
if (status == QLatin1String("Playing")) { if (status == QLatin1String("Playing")) {
if (!pausedSources.contains(iface)) { if (!pausedSources.contains(iface)) {
@ -99,7 +99,7 @@ bool PauseMusicPlugin::receivePacket(const NetworkPacket& np)
if (pause && !pausedSources.empty()) { if (pause && !pausedSources.empty()) {
if (autoResume) { if (autoResume) {
for (const QString& iface : qAsConst(pausedSources)) { for (const QString& iface : qAsConst(pausedSources)) {
OrgMprisMediaPlayer2PlayerInterface mprisInterface(iface, QStringLiteral("/org/mpris/MediaPlayer2"), DBusHelper::sessionBus()); OrgMprisMediaPlayer2PlayerInterface mprisInterface(iface, QStringLiteral("/org/mpris/MediaPlayer2"), QDBusConnection::sessionBus());
mprisInterface.Play(); mprisInterface.Play();
} }
} }

View file

@ -33,7 +33,7 @@ NotificationsListener::NotificationsListener(KdeConnectPlugin* aPlugin)
{ {
qRegisterMetaTypeStreamOperators<NotifyingApplication>("NotifyingApplication"); qRegisterMetaTypeStreamOperators<NotifyingApplication>("NotifyingApplication");
bool ret = DBusHelper::sessionBus() bool ret = QDBusConnection::sessionBus()
.registerObject(QStringLiteral("/org/freedesktop/Notifications"), .registerObject(QStringLiteral("/org/freedesktop/Notifications"),
this, this,
QDBusConnection::ExportScriptableContents); QDBusConnection::ExportScriptableContents);
@ -41,7 +41,7 @@ NotificationsListener::NotificationsListener(KdeConnectPlugin* aPlugin)
qCWarning(KDECONNECT_PLUGIN_SENDNOTIFICATION) qCWarning(KDECONNECT_PLUGIN_SENDNOTIFICATION)
<< "Error registering notifications listener for device" << "Error registering notifications listener for device"
<< m_plugin->device()->name() << ":" << m_plugin->device()->name() << ":"
<< DBusHelper::sessionBus().lastError(); << QDBusConnection::sessionBus().lastError();
else else
qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION)
<< "Registered notifications listener for device" << "Registered notifications listener for device"
@ -65,7 +65,7 @@ NotificationsListener::~NotificationsListener()
QStringLiteral("org.freedesktop.DBus")); QStringLiteral("org.freedesktop.DBus"));
QDBusMessage res = iface.call(QStringLiteral("RemoveMatch"), QDBusMessage res = iface.call(QStringLiteral("RemoveMatch"),
QStringLiteral("interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'")); QStringLiteral("interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'"));
DBusHelper::sessionBus().unregisterObject(QStringLiteral("/org/freedesktop/Notifications")); QDBusConnection::sessionBus().unregisterObject(QStringLiteral("/org/freedesktop/Notifications"));
} }
void NotificationsListener::setTranslatedAppName() void NotificationsListener::setTranslatedAppName()

View file

@ -16,7 +16,3 @@ endif()
ecm_add_test(pluginloadtest.cpp LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(pluginloadtest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
ecm_add_test(sendfiletest.cpp LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(sendfiletest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
ecm_add_test(testsocketlinereader.cpp TEST_NAME testsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries}) ecm_add_test(testsocketlinereader.cpp TEST_NAME testsocketlinereader LINK_LIBRARIES ${kdeconnect_libraries})
if(PRIVATE_DBUS_ENABLED)
ecm_add_test(testprivatedbus.cpp LINK_LIBRARIES ${kdeconnect_libraries})
endif()

View file

@ -1,95 +0,0 @@
/**
* SPDX-FileCopyrightText: 2019 Weixuan XIAO <veyx.shaw@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "dbushelper.h"
#include <QtTest>
#include <QDBusMessage>
#include <QDBusConnectionInterface>
/**
* This class tests the working of private dbus in kdeconnect
*/
class PrivateDBusTest : public QObject
{
Q_OBJECT
public:
PrivateDBusTest()
{
DBusHelper::launchDBusDaemon();
}
~PrivateDBusTest()
{
DBusHelper::closeDBusDaemon();
}
private Q_SLOTS:
void testConnectionWithPrivateDBus();
void testServiceRegistrationWithPrivateDBus();
void testMethodCallWithPrivateDBus();
};
/**
* Open private DBus normally and get connection info
*/
void PrivateDBusTest::testConnectionWithPrivateDBus()
{
QDBusConnection conn = DBusHelper::sessionBus();
QVERIFY2(conn.isConnected(), "Connection not established");
QVERIFY2(conn.name() == QStringLiteral(KDECONNECT_PRIVATE_DBUS_NAME),
"DBus Connection is not the right one");
}
/**
* Open private DBus connection normally and register a service
*/
void PrivateDBusTest::testServiceRegistrationWithPrivateDBus()
{
QDBusConnection conn = DBusHelper::sessionBus();
QVERIFY2(conn.isConnected(), "DBus not connected");
QDBusConnectionInterface *bus = conn.interface();
QVERIFY2(bus != nullptr, "Failed to get DBus interface");
QVERIFY2(bus->registerService(QStringLiteral("privatedbus.test")) == QDBusConnectionInterface::ServiceRegistered,
"Failed to register DBus Serice");
bus->unregisterService(QStringLiteral("privatedbus.test"));
}
/**
* Open private DBus connection normally, call a method and get its reply
*/
void PrivateDBusTest::testMethodCallWithPrivateDBus()
{
QDBusConnection conn = DBusHelper::sessionBus();
QVERIFY2(conn.isConnected(), "DBus not connected");
/*
dbus-send --session \
--dest=org.freedesktop.DBus \
--type=method_call \
--print-reply \
/org/freedesktop/DBus \
org.freedesktop.DBus.ListNames
*/
QDBusMessage msg = conn.call(
QDBusMessage::createMethodCall(
QStringLiteral("org.freedesktop.DBus"), // Service
QStringLiteral("/org/freedesktop/DBus"), // Path
QStringLiteral("org.freedesktop.DBus"), // Interface
QStringLiteral("ListNames") // Method
)
);
QVERIFY2(msg.type() == QDBusMessage::ReplyMessage, "Failed calling method on private DBus");
}
QTEST_MAIN(PrivateDBusTest);
#include "testprivatedbus.moc"

View file

@ -162,7 +162,7 @@ int main(int argc, char** argv)
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device + QStringLiteral("/share"), QStringLiteral("org.kde.kdeconnect.device.share"), action); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect/devices/") + device + QStringLiteral("/share"), QStringLiteral("org.kde.kdeconnect.device.share"), action);
msg.setArguments({ url.toString() }); msg.setArguments({ url.toString() });
blockOnReply(DBusHelper::sessionBus().asyncCall(msg)); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg));
return 0; return 0;
} else { } else {
QMessageBox::critical(nullptr, description, QMessageBox::critical(nullptr, description,