Akonadi

agentinstancecreatejob.cpp
1 /*
2  SPDX-FileCopyrightText: 2008 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "agentinstancecreatejob.h"
8 
9 #include "agentinstance.h"
10 #include "agentmanager.h"
11 #include "agentmanager_p.h"
12 #include "controlinterface.h"
13 #include "kjobprivatebase_p.h"
14 #include "servermanager.h"
15 #include <QDBusConnection>
16 
17 #include <KLocalizedString>
18 
19 #include <QTimer>
20 
21 #ifdef Q_OS_UNIX
22 #include <signal.h>
23 #include <sys/types.h>
24 #endif
25 
26 using namespace Akonadi;
27 
28 static const int safetyTimeout = 10000; // ms
29 
30 namespace Akonadi
31 {
32 /**
33  * @internal
34  */
35 class AgentInstanceCreateJobPrivate : public KJobPrivateBase
36 {
37  Q_OBJECT
38 public:
39  explicit AgentInstanceCreateJobPrivate(AgentInstanceCreateJob *parent)
40  : q(parent)
41  , safetyTimer(new QTimer(parent))
42  {
43  connect(AgentManager::self(), &AgentManager::instanceAdded, this, &AgentInstanceCreateJobPrivate::agentInstanceAdded);
44  connect(safetyTimer, &QTimer::timeout, this, &AgentInstanceCreateJobPrivate::timeout);
45  }
46 
47  void agentInstanceAdded(const AgentInstance &instance) const
48  {
49  if (agentInstance == instance && !tooLate) {
50  safetyTimer->stop();
51  if (doConfig) {
52  // return from dbus call first before doing the next one
53  QTimer::singleShot(0, this, &AgentInstanceCreateJobPrivate::doConfigure);
54  } else {
55  q->emitResult();
56  }
57  }
58  }
59 
60  void doConfigure()
61  {
62  auto agentControlIface =
63  new org::freedesktop::Akonadi::Agent::Control(ServerManager::agentServiceName(ServerManager::Agent, agentInstance.identifier()),
64  QStringLiteral("/"),
66  q);
67  if (!agentControlIface || !agentControlIface->isValid()) {
68  delete agentControlIface;
69 
70  q->setError(KJob::UserDefinedError);
71  q->setErrorText(i18n("Unable to access D-Bus interface of created agent."));
72  q->emitResult();
73  return;
74  }
75 
76  connect(agentControlIface, &org::freedesktop::Akonadi::Agent::Control::configurationDialogAccepted, this, [agentControlIface, this]() {
77  agentControlIface->deleteLater();
78  q->emitResult();
79  });
80  connect(agentControlIface, &org::freedesktop::Akonadi::Agent::Control::configurationDialogRejected, this, [agentControlIface, this]() {
81  agentControlIface->deleteLater();
82  AgentManager::self()->removeInstance(agentInstance);
83  q->emitResult();
84  });
85 
86  agentInstance.configure(parentWidget);
87  }
88 
89  void timeout()
90  {
91  tooLate = true;
92  q->setError(KJob::UserDefinedError);
93  q->setErrorText(i18n("Agent instance creation timed out."));
94  q->emitResult();
95  }
96 
97  void doStart() override;
98 
99  AgentInstanceCreateJob *const q;
100  AgentType agentType;
101  QString agentTypeId;
102  AgentInstance agentInstance;
103  QWidget *parentWidget = nullptr;
104  QTimer *const safetyTimer;
105  bool doConfig = false;
106  bool tooLate = false;
107 };
108 
109 } // namespace Akonadi
110 
112  : KJob(parent)
113  , d(new AgentInstanceCreateJobPrivate(this))
114 {
115  d->agentType = agentType;
116 }
117 
119  : KJob(parent)
120  , d(new AgentInstanceCreateJobPrivate(this))
121 {
122  d->agentTypeId = typeId;
123 }
124 
126 
128 {
129  d->parentWidget = parent;
130  d->doConfig = true;
131 }
132 
134 {
135  return d->agentInstance;
136 }
137 
139 {
140  d->start();
141 }
142 
143 void AgentInstanceCreateJobPrivate::doStart()
144 {
145  if (!agentType.isValid() && !agentTypeId.isEmpty()) {
146  agentType = AgentManager::self()->type(agentTypeId);
147  }
148 
149  if (!agentType.isValid()) {
150  q->setError(KJob::UserDefinedError);
151  q->setErrorText(i18n("Unable to obtain agent type '%1'.", agentTypeId));
153  return;
154  }
155 
156  agentInstance = AgentManager::self()->d->createInstance(agentType);
157  if (!agentInstance.isValid()) {
158  q->setError(KJob::UserDefinedError);
159  q->setErrorText(i18n("Unable to create agent instance."));
161  } else {
162  int timeout = safetyTimeout;
163 #ifdef Q_OS_UNIX
164  // Increate the timeout when valgrinding the agent, because that slows down things a log.
165  const QString agentValgrind = QString::fromLocal8Bit(qgetenv("AKONADI_VALGRIND"));
166  if (!agentValgrind.isEmpty() && agentType.identifier().contains(agentValgrind)) {
167  timeout *= 15;
168  }
169 #endif
170  // change the timeout when debugging the agent, because we need time to start the debugger
171  const QString agentDebugging = QString::fromLocal8Bit(qgetenv("AKONADI_DEBUG_WAIT"));
172  if (!agentDebugging.isEmpty()) {
173  // we are debugging
174  const QString agentDebuggingTimeout = QString::fromLocal8Bit(qgetenv("AKONADI_DEBUG_TIMEOUT"));
175  if (agentDebuggingTimeout.isEmpty()) {
176  // use default value of 150 seconds (the same as "valgrinding", this has to be checked)
177  timeout = 15 * safetyTimeout;
178  } else {
179  // use own value
180  timeout = agentDebuggingTimeout.toInt();
181  }
182  }
183  safetyTimer->start(timeout);
184  }
185 }
186 
187 #include "agentinstancecreatejob.moc"
A representation of an agent type.
static QString agentServiceName(ServiceAgentType agentType, const QString &identifier)
Returns the namespaced D-Bus service name for an agent of type agentType with agent identifier identi...
void configure(QWidget *parent=nullptr)
Setup the job to show agent configuration dialog once the agent instance has been successfully starte...
AgentInstanceCreateJob(const AgentType &type, QObject *parent=nullptr)
Creates a new agent instance create job.
void removeInstance(const AgentInstance &instance)
Removes the given agent instance.
QString i18n(const char *text, const TYPE &arg...)
QDBusConnection sessionBus()
QString fromLocal8Bit(const char *str, int size)
void instanceAdded(const Akonadi::AgentInstance &instance)
This signal is emitted whenever a new agent instance was created.
void timeout()
bool isEmpty() const const
~AgentInstanceCreateJob() override
Destroys the agent instance create job.
AgentInstance instance() const
Returns the AgentInstance object of the newly created agent instance.
int toInt(bool *ok, int base) const const
AgentType type(const QString &identifier) const
Returns the agent type with the given identifier or an invalid agent type if the identifier does not ...
static AgentManager * self()
Returns the global instance of the agent manager.
void emitResult()
void start() override
Starts the instance creation.
A representation of an agent instance.
QObject * parent() const const
Job for creating new agent instances.
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jun 30 2022 03:51:45 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.