Akonadi

collectionattributessynchronizationjob.cpp
1 /*
2  * Copyright (c) 2009 Volker Krause <[email protected]>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "collectionattributessynchronizationjob.h"
19 #include <QDBusConnection>
20 #include "kjobprivatebase_p.h"
21 #include "servermanager.h"
22 #include "akonadicore_debug.h"
23 
24 #include "agentinstance.h"
25 #include "agentmanager.h"
26 #include "collection.h"
27 
28 #include <KLocalizedString>
29 
30 #include <QDBusInterface>
31 #include <QTimer>
32 
33 namespace Akonadi
34 {
35 
36 class CollectionAttributesSynchronizationJobPrivate : public KJobPrivateBase
37 {
38  Q_OBJECT
39 
40 public:
41  CollectionAttributesSynchronizationJobPrivate(CollectionAttributesSynchronizationJob *parent)
42  : q(parent)
43  {
44  connect(&safetyTimer, &QTimer::timeout, this, &CollectionAttributesSynchronizationJobPrivate::slotTimeout);
45  safetyTimer.setInterval(std::chrono::seconds{5});
46  safetyTimer.setSingleShot(false);
47  }
48 
49  void doStart() override;
50 
51  CollectionAttributesSynchronizationJob *q;
52  AgentInstance instance;
53  Collection collection;
54  QDBusInterface *interface = nullptr;
55  QTimer safetyTimer;
56  int timeoutCount = 0;
57  static const int timeoutCountLimit;
58 
59 private Q_SLOTS:
60  void slotSynchronized(qlonglong);
61  void slotTimeout();
62 };
63 
64 const int CollectionAttributesSynchronizationJobPrivate::timeoutCountLimit = 2;
65 
67  : KJob(parent)
68  , d(new CollectionAttributesSynchronizationJobPrivate(this))
69 {
70  d->instance = AgentManager::self()->instance(collection.resource());
71  d->collection = collection;
72 }
73 
75 {
76  delete d;
77 }
78 
79 void CollectionAttributesSynchronizationJob::start()
80 {
81  d->start();
82 }
83 
84 void CollectionAttributesSynchronizationJobPrivate::doStart()
85 {
86  if (!collection.isValid()) {
87  q->setError(KJob::UserDefinedError);
88  q->setErrorText(i18n("Invalid collection instance."));
89  q->emitResult();
90  return;
91  }
92 
93  if (!instance.isValid()) {
94  q->setError(KJob::UserDefinedError);
95  q->setErrorText(i18n("Invalid resource instance."));
96  q->emitResult();
97  return;
98  }
99 
100  interface = new QDBusInterface(ServerManager::agentServiceName(ServerManager::Resource, instance.identifier()),
101  QStringLiteral("/"),
102  QStringLiteral("org.freedesktop.Akonadi.Resource"),
104  connect(interface, SIGNAL(attributesSynchronized(qlonglong)), this, SLOT(slotSynchronized(qlonglong))); // clazy:exclude=old-style-connect
105 
106  if (interface->isValid()) {
107  const QDBusMessage reply = interface->call(QStringLiteral("synchronizeCollectionAttributes"), collection.id());
108  if (reply.type() == QDBusMessage::ErrorMessage) {
109  // This means that the resource doesn't provide a synchronizeCollectionAttributes method, so we just finish the job
110  q->emitResult();
111  return;
112  }
113  safetyTimer.start();
114  } else {
115  q->setError(KJob::UserDefinedError);
116  q->setErrorText(i18n("Unable to obtain D-Bus interface for resource '%1'", instance.identifier()));
117  q->emitResult();
118  return;
119  }
120 }
121 
122 void CollectionAttributesSynchronizationJobPrivate::slotSynchronized(qlonglong id)
123 {
124  if (id == collection.id()) {
125  disconnect(interface, SIGNAL(attributesSynchronized(qlonglong)), this, SLOT(slotSynchronized(qlonglong))); // clazy:exclude=old-style-connect
126  safetyTimer.stop();
127  q->emitResult();
128  }
129 }
130 
131 void CollectionAttributesSynchronizationJobPrivate::slotTimeout()
132 {
133  instance = AgentManager::self()->instance(instance.identifier());
134  timeoutCount++;
135 
136  if (timeoutCount > timeoutCountLimit) {
137  safetyTimer.stop();
138  q->setError(KJob::UserDefinedError);
139  q->setErrorText(i18n("Collection attributes synchronization timed out."));
140  q->emitResult();
141  return;
142  }
143 
144  if (instance.status() == AgentInstance::Idle) {
145  // try again, we might have lost the synchronized() signal
146  qCDebug(AKONADICORE_LOG) << "collection attributes" << collection.id() << instance.identifier();
147  interface->call(QStringLiteral("synchronizeCollectionAttributes"), collection.id());
148  }
149 }
150 
151 }
152 
153 #include "collectionattributessynchronizationjob.moc"
The agent instance does currently nothing.
Represents a collection of PIM items.
Definition: collection.h:76
QString identifier() const
Returns the unique identifier of the agent instance.
QDBusConnection sessionBus()
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
CollectionAttributesSynchronizationJob(const Collection &collection, QObject *parent=nullptr)
Creates a new synchronization job for the given collection.
Represents one agent instance and takes care of communication with it.
void timeout()
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
QString i18n(const char *text, const TYPE &arg...)
if(recurs()&&!first)
Helper integration between Akonadi and Qt.
static AgentManager * self()
Returns the global instance of the agent manager.
QString resource() const
Returns the identifier of the resource owning the collection.
Definition: collection.cpp:318
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
~CollectionAttributesSynchronizationJob() override
Destroys the synchronization job.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jun 5 2020 23:08:54 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.