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 <QDBusConnection>
15 
16 #include <KLocalizedString>
17 
18 #include <QTimer>
19 
20 #ifdef Q_OS_UNIX
21 #include <signal.h>
22 #include <sys/types.h>
23 #endif
24 
25 using namespace Akonadi;
26 
27 static const int safetyTimeout = 10000; // ms
28 
29 namespace Akonadi
30 {
31 /**
32  * @internal
33  */
34 class AgentInstanceCreateJobPrivate : public KJobPrivateBase
35 {
36  Q_OBJECT
37 public:
38  explicit AgentInstanceCreateJobPrivate(AgentInstanceCreateJob *parent)
39  : q(parent)
40  , safetyTimer(new QTimer(parent))
41  {
42  connect(AgentManager::self(), &AgentManager::instanceAdded, this, &AgentInstanceCreateJobPrivate::agentInstanceAdded);
43  connect(safetyTimer, &QTimer::timeout, this, &AgentInstanceCreateJobPrivate::timeout);
44  }
45 
46  void agentInstanceAdded(const AgentInstance &instance) const
47  {
48  if (agentInstance == instance && !tooLate) {
49  safetyTimer->stop();
50  if (doConfig) {
51  // return from dbus call first before doing the next one
52  QTimer::singleShot(0, this, &AgentInstanceCreateJobPrivate::doConfigure);
53  } else {
54  q->emitResult();
55  }
56  }
57  }
58 
59  void doConfigure()
60  {
61  auto agentControlIface =
62  new org::freedesktop::Akonadi::Agent::Control(ServerManager::agentServiceName(ServerManager::Agent, agentInstance.identifier()),
63  QStringLiteral("/"),
65  q);
66  if (!agentControlIface || !agentControlIface->isValid()) {
67  delete agentControlIface;
68 
69  q->setError(KJob::UserDefinedError);
70  q->setErrorText(i18n("Unable to access D-Bus interface of created agent."));
71  q->emitResult();
72  return;
73  }
74 
75  connect(agentControlIface, &org::freedesktop::Akonadi::Agent::Control::configurationDialogAccepted, this, [agentControlIface, this]() {
76  agentControlIface->deleteLater();
77  q->emitResult();
78  });
79  connect(agentControlIface, &org::freedesktop::Akonadi::Agent::Control::configurationDialogRejected, this, [agentControlIface, this]() {
80  agentControlIface->deleteLater();
81  AgentManager::self()->removeInstance(agentInstance);
82  q->emitResult();
83  });
84 
85  agentInstance.configure(parentWidget);
86  }
87 
88  void timeout()
89  {
90  tooLate = true;
91  q->setError(KJob::UserDefinedError);
92  q->setErrorText(i18n("Agent instance creation timed out."));
93  q->emitResult();
94  }
95 
96  void doStart() override;
97 
98  AgentInstanceCreateJob *const q;
99  AgentType agentType;
100  QString agentTypeId;
101  AgentInstance agentInstance;
102  QWidget *parentWidget = nullptr;
103  QTimer *const safetyTimer;
104  bool doConfig = false;
105  bool tooLate = false;
106 };
107 
108 } // namespace Akonadi
109 
111  : KJob(parent)
112  , d(new AgentInstanceCreateJobPrivate(this))
113 {
114  d->agentType = agentType;
115 }
116 
118  : KJob(parent)
119  , d(new AgentInstanceCreateJobPrivate(this))
120 {
121  d->agentTypeId = typeId;
122 }
123 
125 
127 {
128  d->parentWidget = parent;
129  d->doConfig = true;
130 }
131 
133 {
134  return d->agentInstance;
135 }
136 
138 {
139  d->start();
140 }
141 
142 void AgentInstanceCreateJobPrivate::doStart()
143 {
144  if (!agentType.isValid() && !agentTypeId.isEmpty()) {
145  agentType = AgentManager::self()->type(agentTypeId);
146  }
147 
148  if (!agentType.isValid()) {
149  q->setError(KJob::UserDefinedError);
150  q->setErrorText(i18n("Unable to obtain agent type '%1'.", agentTypeId));
152  return;
153  }
154 
155  agentInstance = AgentManager::self()->d->createInstance(agentType);
156  if (!agentInstance.isValid()) {
157  q->setError(KJob::UserDefinedError);
158  q->setErrorText(i18n("Unable to create agent instance."));
160  } else {
161  int timeout = safetyTimeout;
162 #ifdef Q_OS_UNIX
163  // Increate the timeout when valgrinding the agent, because that slows down things a log.
164  const QString agentValgrind = QString::fromLocal8Bit(qgetenv("AKONADI_VALGRIND"));
165  if (!agentValgrind.isEmpty() && agentType.identifier().contains(agentValgrind)) {
166  timeout *= 15;
167  }
168 #endif
169  // change the timeout when debugging the agent, because we need time to start the debugger
170  const QString agentDebugging = QString::fromLocal8Bit(qgetenv("AKONADI_DEBUG_WAIT"));
171  if (!agentDebugging.isEmpty()) {
172  // we are debugging
173  const QString agentDebuggingTimeout = QString::fromLocal8Bit(qgetenv("AKONADI_DEBUG_TIMEOUT"));
174  if (agentDebuggingTimeout.isEmpty()) {
175  // use default value of 150 seconds (the same as "valgrinding", this has to be checked)
176  timeout = 15 * safetyTimeout;
177  } else {
178  // use own value
179  timeout = agentDebuggingTimeout.toInt();
180  }
181  }
182  safetyTimer->start(timeout);
183  }
184 }
185 
186 #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-2023 The KDE developers.
Generated on Mon May 8 2023 03:52:15 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.