Akonadi

akonadicontrol/agentinstance.cpp
1 /*
2  Copyright (c) 2008 Volker Krause <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "agentinstance.h"
21 #include "akonadicontrol_debug.h"
22 
23 #include "agenttype.h"
24 #include "agentmanager.h"
25 
26 AgentInstance::AgentInstance(AgentManager &manager)
27  : mManager(manager)
28 {
29 }
30 
32 
33 void AgentInstance::quit()
34 {
35  if (mAgentControlInterface && mAgentControlInterface->isValid()) {
36  mAgentControlInterface->quit();
37  } else {
38  mPendingQuit = true;
39  }
40 }
41 
42 void AgentInstance::cleanup()
43 {
44  if (mAgentControlInterface && mAgentControlInterface->isValid()) {
45  mAgentControlInterface->cleanup();
46  }
47 }
48 
49 bool AgentInstance::obtainAgentInterface()
50 {
51  mAgentControlInterface = findInterface<org::freedesktop::Akonadi::Agent::Control>(Akonadi::DBus::Agent, "/");
52  mAgentStatusInterface = findInterface<org::freedesktop::Akonadi::Agent::Status>(Akonadi::DBus::Agent, "/");
53 
54  if (mPendingQuit && mAgentControlInterface && mAgentControlInterface->isValid()) {
55  mAgentControlInterface->quit();
56  mPendingQuit = false;
57  }
58 
59  if (!mAgentControlInterface || !mAgentStatusInterface) {
60  return false;
61  }
62 
63  mSearchInterface =
64  findInterface<org::freedesktop::Akonadi::Agent::Search>(Akonadi::DBus::Agent, "/Search");
65 
66  connect(mAgentStatusInterface.get(), qOverload<int, const QString &>(&OrgFreedesktopAkonadiAgentStatusInterface::status),
67  this, &AgentInstance::statusChanged);
68  connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::advancedStatus, this, &AgentInstance::advancedStatusChanged);
69  connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::percent, this, &AgentInstance::percentChanged);
70  connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::warning, this, &AgentInstance::warning);
71  connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::error, this, &AgentInstance::error);
72  connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::onlineChanged, this, &AgentInstance::onlineChanged);
73 
74  refreshAgentStatus();
75  return true;
76 }
77 
78 bool AgentInstance::obtainResourceInterface()
79 {
80  mResourceInterface = findInterface<org::freedesktop::Akonadi::Resource>(Akonadi::DBus::Resource, "/");
81 
82  if (!mResourceInterface) {
83  return false;
84  }
85 
86  connect(mResourceInterface.get(), &OrgFreedesktopAkonadiResourceInterface::nameChanged, this, &AgentInstance::resourceNameChanged);
87  refreshResourceStatus();
88  return true;
89 }
90 
91 bool AgentInstance::obtainPreprocessorInterface()
92 {
93  mPreprocessorInterface = findInterface<org::freedesktop::Akonadi::Preprocessor>(Akonadi::DBus::Preprocessor, "/");
94  return mPreprocessorInterface != nullptr;
95 }
96 
97 void AgentInstance::statusChanged(int status, const QString &statusMsg)
98 {
99  if (mStatus == status && mStatusMessage == statusMsg) {
100  return;
101  }
102  mStatus = status;
103  mStatusMessage = statusMsg;
104  Q_EMIT mManager.agentInstanceStatusChanged(mIdentifier, mStatus, mStatusMessage);
105 }
106 
107 void AgentInstance::advancedStatusChanged(const QVariantMap &status)
108 {
109  Q_EMIT mManager.agentInstanceAdvancedStatusChanged(mIdentifier, status);
110 }
111 
112 void AgentInstance::statusStateChanged(int status)
113 {
114  statusChanged(status, mStatusMessage);
115 }
116 
117 void AgentInstance::statusMessageChanged(const QString &msg)
118 {
119  statusChanged(mStatus, msg);
120 }
121 
122 void AgentInstance::percentChanged(int percent)
123 {
124  if (mPercent == percent) {
125  return;
126  }
127  mPercent = percent;
128  Q_EMIT mManager.agentInstanceProgressChanged(mIdentifier, mPercent, QString());
129 }
130 
131 void AgentInstance::warning(const QString &msg)
132 {
133  Q_EMIT mManager.agentInstanceWarning(mIdentifier, msg);
134 }
135 
136 void AgentInstance::error(const QString &msg)
137 {
138  Q_EMIT mManager.agentInstanceError(mIdentifier, msg);
139 }
140 
141 void AgentInstance::onlineChanged(bool state)
142 {
143  if (mOnline == state) {
144  return;
145  }
146  mOnline = state;
147  Q_EMIT mManager.agentInstanceOnlineChanged(mIdentifier, state);
148 }
149 
150 void AgentInstance::resourceNameChanged(const QString &name)
151 {
152  if (name == mResourceName) {
153  return;
154  }
155  mResourceName = name;
156  Q_EMIT mManager.agentInstanceNameChanged(mIdentifier, name);
157 }
158 
159 void AgentInstance::refreshAgentStatus()
160 {
161  if (!hasAgentInterface()) {
162  return;
163  }
164 
165  // async calls so we are not blocked by misbehaving agents
166  mAgentStatusInterface->callWithCallback(QStringLiteral("status"), QList<QVariant>(),
167  this, SLOT(statusStateChanged(int)),
168  SLOT(errorHandler(QDBusError)));
169  mAgentStatusInterface->callWithCallback(QStringLiteral("statusMessage"), QList<QVariant>(),
170  this, SLOT(statusMessageChanged(QString)),
171  SLOT(errorHandler(QDBusError)));
172  mAgentStatusInterface->callWithCallback(QStringLiteral("progress"), QList<QVariant>(),
173  this, SLOT(percentChanged(int)),
174  SLOT(errorHandler(QDBusError)));
175  mAgentStatusInterface->callWithCallback(QStringLiteral("isOnline"), QList<QVariant>(),
176  this, SLOT(onlineChanged(bool)),
177  SLOT(errorHandler(QDBusError)));
178 }
179 
180 void AgentInstance::refreshResourceStatus()
181 {
182  if (!hasResourceInterface()) {
183  return;
184  }
185 
186  // async call so we are not blocked by misbehaving resources
187  mResourceInterface->callWithCallback(QStringLiteral("name"), QList<QVariant>(),
188  this, SLOT(resourceNameChanged(QString)),
189  SLOT(errorHandler(QDBusError)));
190 }
191 
192 void AgentInstance::errorHandler(const QDBusError &error)
193 {
194  //avoid using the server tracer, can result in D-BUS lockups
195  qCCritical(AKONADICONTROL_LOG) << QStringLiteral("D-Bus communication error '%1': '%2'").arg(error.name(), error.message());
196  // TODO try again after some time, esp. on timeout errors
197 }
198 
199 template <typename T>
200 std::unique_ptr<T> AgentInstance::findInterface(Akonadi::DBus::AgentType agentType, const char *path)
201 {
202  auto iface = std::make_unique<T>(Akonadi::DBus::agentServiceName(mIdentifier, agentType),
204 
205  if (!iface || !iface->isValid()) {
206  qCCritical(AKONADICONTROL_LOG) << Q_FUNC_INFO << "Cannot connect to agent instance with identifier"
207  << mIdentifier << ", error message:"
208  << (iface ? iface->lastError().message() : QString());
209  iface.release();
210  }
211  return iface;
212 }
QString name() const const
QString message() const const
QDBusConnection sessionBus()
~AgentInstance()
Destroys the agent instance object.
The agent manager has knowledge about all available agents (it scans for .desktop files in the agent ...
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Q_EMITQ_EMIT
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon May 25 2020 22:46:07 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.