File indexing completed on 2025-01-05 04:46:26
0001 /* 0002 SPDX-FileCopyrightText: 2008 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "agentinstance.h" 0008 #include "akonadicontrol_debug.h" 0009 0010 #include "agentmanager.h" 0011 0012 AgentInstance::AgentInstance(AgentManager &manager) 0013 : mManager(manager) 0014 { 0015 } 0016 0017 AgentInstance::~AgentInstance() = default; 0018 0019 void AgentInstance::quit() 0020 { 0021 if (mAgentControlInterface && mAgentControlInterface->isValid()) { 0022 mAgentControlInterface->quit(); 0023 } else { 0024 mPendingQuit = true; 0025 } 0026 } 0027 0028 void AgentInstance::cleanup() 0029 { 0030 if (mAgentControlInterface && mAgentControlInterface->isValid()) { 0031 mAgentControlInterface->cleanup(); 0032 } 0033 } 0034 0035 bool AgentInstance::obtainAgentInterface() 0036 { 0037 mAgentControlInterface = findInterface<org::freedesktop::Akonadi::Agent::Control>(Akonadi::DBus::Agent, "/"); 0038 mAgentStatusInterface = findInterface<org::freedesktop::Akonadi::Agent::Status>(Akonadi::DBus::Agent, "/"); 0039 0040 if (mPendingQuit && mAgentControlInterface && mAgentControlInterface->isValid()) { 0041 mAgentControlInterface->quit(); 0042 mPendingQuit = false; 0043 } 0044 0045 if (!mAgentControlInterface || !mAgentStatusInterface) { 0046 return false; 0047 } 0048 0049 mSearchInterface = findInterface<org::freedesktop::Akonadi::Agent::Search>(Akonadi::DBus::Agent, "/Search"); 0050 0051 connect(mAgentStatusInterface.get(), 0052 qOverload<int, const QString &>(&OrgFreedesktopAkonadiAgentStatusInterface::status), 0053 this, 0054 &AgentInstance::statusChanged); 0055 connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::advancedStatus, this, &AgentInstance::advancedStatusChanged); 0056 connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::percent, this, &AgentInstance::percentChanged); 0057 connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::warning, this, &AgentInstance::warning); 0058 connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::error, this, &AgentInstance::error); 0059 connect(mAgentStatusInterface.get(), &OrgFreedesktopAkonadiAgentStatusInterface::onlineChanged, this, &AgentInstance::onlineChanged); 0060 0061 refreshAgentStatus(); 0062 return true; 0063 } 0064 0065 bool AgentInstance::obtainResourceInterface() 0066 { 0067 mResourceInterface = findInterface<org::freedesktop::Akonadi::Resource>(Akonadi::DBus::Resource, "/"); 0068 0069 if (!mResourceInterface) { 0070 return false; 0071 } 0072 0073 connect(mResourceInterface.get(), &OrgFreedesktopAkonadiResourceInterface::nameChanged, this, &AgentInstance::resourceNameChanged); 0074 refreshResourceStatus(); 0075 return true; 0076 } 0077 0078 bool AgentInstance::obtainPreprocessorInterface() 0079 { 0080 mPreprocessorInterface = findInterface<org::freedesktop::Akonadi::Preprocessor>(Akonadi::DBus::Preprocessor, "/"); 0081 return mPreprocessorInterface != nullptr; 0082 } 0083 0084 void AgentInstance::statusChanged(int status, const QString &statusMsg) 0085 { 0086 if (mStatus == status && mStatusMessage == statusMsg) { 0087 return; 0088 } 0089 mStatus = status; 0090 mStatusMessage = statusMsg; 0091 Q_EMIT mManager.agentInstanceStatusChanged(mIdentifier, mStatus, mStatusMessage); 0092 } 0093 0094 void AgentInstance::advancedStatusChanged(const QVariantMap &status) 0095 { 0096 Q_EMIT mManager.agentInstanceAdvancedStatusChanged(mIdentifier, status); 0097 } 0098 0099 void AgentInstance::statusStateChanged(int status) 0100 { 0101 statusChanged(status, mStatusMessage); 0102 } 0103 0104 void AgentInstance::statusMessageChanged(const QString &msg) 0105 { 0106 statusChanged(mStatus, msg); 0107 } 0108 0109 void AgentInstance::percentChanged(int percent) 0110 { 0111 if (mPercent == percent) { 0112 return; 0113 } 0114 mPercent = percent; 0115 Q_EMIT mManager.agentInstanceProgressChanged(mIdentifier, mPercent, QString()); 0116 } 0117 0118 void AgentInstance::warning(const QString &msg) 0119 { 0120 Q_EMIT mManager.agentInstanceWarning(mIdentifier, msg); 0121 } 0122 0123 void AgentInstance::error(const QString &msg) 0124 { 0125 Q_EMIT mManager.agentInstanceError(mIdentifier, msg); 0126 } 0127 0128 void AgentInstance::onlineChanged(bool state) 0129 { 0130 if (mOnline == state) { 0131 return; 0132 } 0133 mOnline = state; 0134 Q_EMIT mManager.agentInstanceOnlineChanged(mIdentifier, state); 0135 } 0136 0137 void AgentInstance::resourceNameChanged(const QString &name) 0138 { 0139 if (name == mResourceName) { 0140 return; 0141 } 0142 mResourceName = name; 0143 Q_EMIT mManager.agentInstanceNameChanged(mIdentifier, name); 0144 } 0145 0146 void AgentInstance::refreshAgentStatus() 0147 { 0148 if (!hasAgentInterface()) { 0149 return; 0150 } 0151 0152 // async calls so we are not blocked by misbehaving agents 0153 mAgentStatusInterface->callWithCallback(QStringLiteral("status"), QList<QVariant>(), this, SLOT(statusStateChanged(int)), SLOT(errorHandler(QDBusError))); 0154 mAgentStatusInterface->callWithCallback(QStringLiteral("statusMessage"), 0155 QList<QVariant>(), 0156 this, 0157 SLOT(statusMessageChanged(QString)), 0158 SLOT(errorHandler(QDBusError))); 0159 mAgentStatusInterface->callWithCallback(QStringLiteral("progress"), QList<QVariant>(), this, SLOT(percentChanged(int)), SLOT(errorHandler(QDBusError))); 0160 mAgentStatusInterface->callWithCallback(QStringLiteral("isOnline"), QList<QVariant>(), this, SLOT(onlineChanged(bool)), SLOT(errorHandler(QDBusError))); 0161 } 0162 0163 void AgentInstance::refreshResourceStatus() 0164 { 0165 if (!hasResourceInterface()) { 0166 return; 0167 } 0168 0169 // async call so we are not blocked by misbehaving resources 0170 mResourceInterface->callWithCallback(QStringLiteral("name"), QList<QVariant>(), this, SLOT(resourceNameChanged(QString)), SLOT(errorHandler(QDBusError))); 0171 } 0172 0173 void AgentInstance::errorHandler(const QDBusError &error) 0174 { 0175 // avoid using the server tracer, can result in D-BUS lockups 0176 qCCritical(AKONADICONTROL_LOG) << QStringLiteral("D-Bus communication error '%1': '%2'").arg(error.name(), error.message()); 0177 // TODO try again after some time, esp. on timeout errors 0178 } 0179 0180 template<typename T> 0181 std::unique_ptr<T> AgentInstance::findInterface(Akonadi::DBus::AgentType agentType, const char *path) 0182 { 0183 auto iface = std::make_unique<T>(Akonadi::DBus::agentServiceName(mIdentifier, agentType), QLatin1StringView(path), QDBusConnection::sessionBus(), this); 0184 0185 if (!iface || !iface->isValid()) { 0186 qCCritical(AKONADICONTROL_LOG) << Q_FUNC_INFO << "Cannot connect to agent instance with identifier" << mIdentifier 0187 << ", error message:" << (iface ? iface->lastError().message() : QString()); 0188 return {}; 0189 } 0190 return iface; 0191 } 0192 0193 #include "moc_agentinstance.cpp"