File indexing completed on 2023-10-01 08:41:45
0001 /* 0002 Copyright (C) 2011 Collabora Ltd. <info@collabora.com> 0003 @author George Kiagiadakis <george.kiagiadakis@collabora.com> 0004 0005 This library is free software; you can redistribute it and/or modify 0006 it under the terms of the GNU Lesser General Public License as published 0007 by the Free Software Foundation; either version 2.1 of the License, or 0008 (at your option) any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU General Public License for more details. 0014 0015 You should have received a copy of the GNU Lesser General Public License 0016 along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 #include "service-availability-checker.h" 0019 0020 #include <QtDBus/QDBusConnectionInterface> 0021 #include <QtDBus/QDBusServiceWatcher> 0022 #include <QtDBus/QDBusPendingCall> 0023 #include <QtDBus/QDBusReply> 0024 0025 #include "ktp-debug.h" 0026 0027 namespace KTp 0028 { 0029 0030 struct ServiceAvailabilityChecker::Private 0031 { 0032 QString serviceName; 0033 bool serviceAvailable; 0034 bool serviceActivatable; 0035 }; 0036 0037 ServiceAvailabilityChecker::ServiceAvailabilityChecker(const QString & serviceName, QObject *parent) 0038 : QObject(parent), d(new Private) 0039 { 0040 d->serviceName = serviceName; 0041 d->serviceAvailable = false; 0042 d->serviceActivatable = false; 0043 0044 QDBusServiceWatcher *serviceWatcher = new QDBusServiceWatcher(serviceName, 0045 QDBusConnection::sessionBus(), 0046 QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, 0047 this); 0048 connect(serviceWatcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), 0049 this, SLOT(onServiceOwnerChanged(QString,QString,QString))); 0050 0051 introspect(); 0052 } 0053 0054 ServiceAvailabilityChecker::~ServiceAvailabilityChecker() 0055 { 0056 delete d; 0057 } 0058 0059 bool ServiceAvailabilityChecker::isAvailable() const 0060 { 0061 return d->serviceAvailable || d->serviceActivatable; 0062 } 0063 0064 void ServiceAvailabilityChecker::introspect() 0065 { 0066 QDBusConnectionInterface *dbusIface = QDBusConnection::sessionBus().interface(); 0067 0068 QDBusPendingCall call = dbusIface->asyncCall(QLatin1String("ListActivatableNames")); 0069 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); 0070 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), 0071 this, SLOT(onCallFinished(QDBusPendingCallWatcher*))); 0072 watcher->setObjectName(QLatin1String("ListActivatableNamesWatcher")); 0073 0074 call = dbusIface->asyncCall(QLatin1String("ListNames")); 0075 watcher = new QDBusPendingCallWatcher(call, this); 0076 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), 0077 this, SLOT(onCallFinished(QDBusPendingCallWatcher*))); 0078 } 0079 0080 void ServiceAvailabilityChecker::onCallFinished(QDBusPendingCallWatcher *watcher) 0081 { 0082 QDBusReply<QStringList> reply = *watcher; 0083 if (!reply.isValid()) { 0084 qCDebug(KTP_COMMONINTERNALS) << "Got error while introspecting service availability:" << reply.error(); 0085 } else { 0086 if (watcher->objectName() == QLatin1String("ListActivatableNamesWatcher")) { 0087 d->serviceActivatable = reply.value().contains(d->serviceName); 0088 } else { 0089 if (!d->serviceAvailable) { 0090 d->serviceAvailable = reply.value().contains(d->serviceName); 0091 } 0092 //else onServiceOwnerChanged() has been emitted before the introspection finished 0093 //so the reply we got here may be incorrect, claiming that the service is not available 0094 } 0095 } 0096 0097 watcher->deleteLater(); 0098 } 0099 0100 void ServiceAvailabilityChecker::onServiceOwnerChanged(const QString & service, 0101 const QString & oldOwner, const QString & newOwner) 0102 { 0103 Q_UNUSED(oldOwner); 0104 0105 if (service == d->serviceName) { 0106 d->serviceAvailable = !newOwner.isEmpty(); 0107 } 0108 } 0109 0110 }