File indexing completed on 2024-12-22 05:13:39
0001 /* 0002 SPDX-FileCopyrightText: 2010-2016 Ivan Cukic <ivan.cukic(at)kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "manager_p.h" 0008 0009 #include <mutex> 0010 #include <optional> 0011 0012 #include <QCoreApplication> 0013 #include <QDBusConnection> 0014 #include <QFutureWatcher> 0015 #include <QFutureWatcherBase> 0016 0017 #include "debug_p.h" 0018 #include "mainthreadexecutor_p.h" 0019 0020 #include "common/dbus/common.h" 0021 #include "utils/continue_with.h" 0022 #include "utils/dbusfuture_p.h" 0023 #include "version.h" 0024 0025 namespace KActivities 0026 { 0027 Manager *Manager::s_instance = nullptr; 0028 0029 Manager::Manager() 0030 : QObject() 0031 , m_watcher(KAMD_DBUS_SERVICE, QDBusConnection::sessionBus()) 0032 , m_service(new KAMD_DBUS_CLASS_INTERFACE("/", Application, this)) 0033 , m_activities(new KAMD_DBUS_CLASS_INTERFACE("Activities", Activities, this)) 0034 , m_resources(new KAMD_DBUS_CLASS_INTERFACE("Resources", Resources, this)) 0035 , m_resourcesLinking(new KAMD_DBUS_CLASS_INTERFACE("Resources/Linking", ResourcesLinking, this)) 0036 , m_features(new KAMD_DBUS_CLASS_INTERFACE("Features", Features, this)) 0037 , m_serviceRunning(false) 0038 { 0039 connect(&m_watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &Manager::serviceOwnerChanged); 0040 0041 if (isServiceRunning()) { 0042 serviceOwnerChanged(KAMD_DBUS_SERVICE, QString(), KAMD_DBUS_SERVICE); 0043 } 0044 } 0045 0046 Manager *Manager::self() 0047 { 0048 static std::mutex singleton; 0049 std::lock_guard<std::mutex> singleton_lock(singleton); 0050 0051 if (!s_instance) { 0052 runInMainThread([]() { 0053 // check if the activity manager is already running 0054 if (!Manager::isServiceRunning()) { 0055 bool disableAutolaunch = QCoreApplication::instance()->property("org.kde.KActivities.core.disableAutostart").toBool(); 0056 0057 qCDebug(KAMD_CORELIB) << "Should we start the daemon?"; 0058 // start only if not disabled and we have a dbus connection at all 0059 if (!disableAutolaunch && QDBusConnection::sessionBus().interface()) { 0060 qCDebug(KAMD_CORELIB) << "Starting the activity manager daemon"; 0061 auto busInterface = QDBusConnection::sessionBus().interface(); 0062 busInterface->asyncCall(QStringLiteral("StartServiceByName"), KAMD_DBUS_SERVICE, uint(0)); 0063 } 0064 } 0065 0066 // creating a new instance of the class 0067 Manager::s_instance = new Manager(); 0068 }); 0069 } 0070 0071 return s_instance; 0072 } 0073 0074 bool Manager::isServiceRunning() 0075 { 0076 return (s_instance ? s_instance->m_serviceRunning : true) && QDBusConnection::sessionBus().interface() 0077 && QDBusConnection::sessionBus().interface()->isServiceRegistered(KAMD_DBUS_SERVICE); 0078 } 0079 0080 void Manager::serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner) 0081 { 0082 Q_UNUSED(oldOwner); 0083 0084 if (serviceName == KAMD_DBUS_SERVICE) { 0085 m_serviceRunning = !newOwner.isEmpty(); 0086 Q_EMIT serviceStatusChanged(m_serviceRunning); 0087 0088 if (m_serviceRunning) { 0089 using namespace kamd::utils; 0090 0091 continue_with(DBusFuture::fromReply(m_service->serviceVersion()), [this](const std::optional<QString> &serviceVersion) { 0092 // Test whether the service is older than the library. 0093 // If it is, we need to end this 0094 0095 if (!serviceVersion.has_value()) { 0096 qWarning() << "KActivities: FATAL ERROR: Failed to contact the activity manager daemon"; 0097 m_serviceRunning = false; 0098 return; 0099 } 0100 0101 auto split = serviceVersion->split(QLatin1Char('.')); 0102 QList<int> version; 0103 0104 // We require kactivitymanagerd version to be at least the 0105 // one before the repository split 0106 const int requiredVersion[] = {6, 2, 0}; 0107 0108 std::transform(split.cbegin(), split.cend(), std::back_inserter(version), [](const QString &component) { 0109 return component.toInt(); 0110 }); 0111 0112 // if required version is greater than the current version 0113 if (std::lexicographical_compare(version.cbegin(), version.cend(), std::begin(requiredVersion), std::end(requiredVersion))) { 0114 QString libraryVersion = QString::number(requiredVersion[0]) + QLatin1Char('.') + QString::number(requiredVersion[1]) + QLatin1Char('.') 0115 + QString::number(requiredVersion[2]); 0116 0117 qDebug() << "KActivities service version: " << serviceVersion.value(); 0118 qDebug() << "KActivities library version: " << libraryVersion; 0119 qFatal("KActivities: FATAL ERROR: The service is older than the library"); 0120 } 0121 }); 0122 } 0123 } 0124 } 0125 0126 Service::Activities *Manager::activities() 0127 { 0128 return self()->m_activities; 0129 } 0130 0131 Service::Resources *Manager::resources() 0132 { 0133 return self()->m_resources; 0134 } 0135 0136 Service::ResourcesLinking *Manager::resourcesLinking() 0137 { 0138 return self()->m_resourcesLinking; 0139 } 0140 0141 Service::Features *Manager::features() 0142 { 0143 return self()->m_features; 0144 } 0145 0146 } // namespace KActivities 0147 0148 #include "moc_manager_p.cpp"