File indexing completed on 2024-11-10 04:40:28
0001 /* 0002 * SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "collectionattributessynchronizationjob.h" 0008 #include "akonadicore_debug.h" 0009 #include "kjobprivatebase_p.h" 0010 #include "servermanager.h" 0011 #include <QDBusConnection> 0012 0013 #include "agentinstance.h" 0014 #include "agentmanager.h" 0015 #include "collection.h" 0016 0017 #include <KLocalizedString> 0018 0019 #include <QDBusInterface> 0020 #include <QTimer> 0021 0022 namespace Akonadi 0023 { 0024 class CollectionAttributesSynchronizationJobPrivate : public KJobPrivateBase 0025 { 0026 Q_OBJECT 0027 0028 public: 0029 explicit CollectionAttributesSynchronizationJobPrivate(CollectionAttributesSynchronizationJob *parent) 0030 : q(parent) 0031 { 0032 connect(&safetyTimer, &QTimer::timeout, this, &CollectionAttributesSynchronizationJobPrivate::slotTimeout); 0033 safetyTimer.setInterval(std::chrono::seconds{5}); 0034 safetyTimer.setSingleShot(false); 0035 } 0036 0037 void doStart() override; 0038 0039 CollectionAttributesSynchronizationJob *const q; 0040 AgentInstance instance; 0041 Collection collection; 0042 QDBusInterface *interface = nullptr; 0043 QTimer safetyTimer; 0044 int timeoutCount = 0; 0045 static const int timeoutCountLimit; 0046 0047 private Q_SLOTS: 0048 void slotSynchronized(qlonglong /*id*/); 0049 void slotTimeout(); 0050 }; 0051 0052 const int CollectionAttributesSynchronizationJobPrivate::timeoutCountLimit = 2; 0053 0054 CollectionAttributesSynchronizationJob::CollectionAttributesSynchronizationJob(const Collection &collection, QObject *parent) 0055 : KJob(parent) 0056 , d(new CollectionAttributesSynchronizationJobPrivate(this)) 0057 { 0058 d->instance = AgentManager::self()->instance(collection.resource()); 0059 d->collection = collection; 0060 } 0061 0062 CollectionAttributesSynchronizationJob::~CollectionAttributesSynchronizationJob() = default; 0063 0064 void CollectionAttributesSynchronizationJob::start() 0065 { 0066 d->start(); 0067 } 0068 0069 void CollectionAttributesSynchronizationJobPrivate::doStart() 0070 { 0071 if (!collection.isValid()) { 0072 q->setError(KJob::UserDefinedError); 0073 q->setErrorText(i18n("Invalid collection instance.")); 0074 q->emitResult(); 0075 return; 0076 } 0077 0078 if (!instance.isValid()) { 0079 q->setError(KJob::UserDefinedError); 0080 q->setErrorText(i18n("Invalid resource instance.")); 0081 q->emitResult(); 0082 return; 0083 } 0084 0085 interface = new QDBusInterface(ServerManager::agentServiceName(ServerManager::Resource, instance.identifier()), 0086 QStringLiteral("/"), 0087 QStringLiteral("org.freedesktop.Akonadi.Resource"), 0088 QDBusConnection::sessionBus(), 0089 this); 0090 connect(interface, SIGNAL(attributesSynchronized(qlonglong)), this, SLOT(slotSynchronized(qlonglong))); // clazy:exclude=old-style-connect 0091 0092 if (interface->isValid()) { 0093 const QDBusMessage reply = interface->call(QStringLiteral("synchronizeCollectionAttributes"), collection.id()); 0094 if (reply.type() == QDBusMessage::ErrorMessage) { 0095 // This means that the resource doesn't provide a synchronizeCollectionAttributes method, so we just finish the job 0096 q->emitResult(); 0097 return; 0098 } 0099 safetyTimer.start(); 0100 } else { 0101 q->setError(KJob::UserDefinedError); 0102 q->setErrorText(i18n("Unable to obtain D-Bus interface for resource '%1'", instance.identifier())); 0103 q->emitResult(); 0104 return; 0105 } 0106 } 0107 0108 void CollectionAttributesSynchronizationJobPrivate::slotSynchronized(qlonglong id) 0109 { 0110 if (id == collection.id()) { 0111 disconnect(interface, SIGNAL(attributesSynchronized(qlonglong)), this, SLOT(slotSynchronized(qlonglong))); // clazy:exclude=old-style-connect 0112 safetyTimer.stop(); 0113 q->emitResult(); 0114 } 0115 } 0116 0117 void CollectionAttributesSynchronizationJobPrivate::slotTimeout() 0118 { 0119 instance = AgentManager::self()->instance(instance.identifier()); 0120 timeoutCount++; 0121 0122 if (timeoutCount > timeoutCountLimit) { 0123 safetyTimer.stop(); 0124 q->setError(KJob::UserDefinedError); 0125 q->setErrorText(i18n("Collection attributes synchronization timed out.")); 0126 q->emitResult(); 0127 return; 0128 } 0129 0130 if (instance.status() == AgentInstance::Idle) { 0131 // try again, we might have lost the synchronized() signal 0132 qCDebug(AKONADICORE_LOG) << "collection attributes" << collection.id() << instance.identifier(); 0133 interface->call(QStringLiteral("synchronizeCollectionAttributes"), collection.id()); 0134 } 0135 } 0136 0137 } // namespace Akonadi 0138 0139 #include "collectionattributessynchronizationjob.moc" 0140 0141 #include "moc_collectionattributessynchronizationjob.cpp"