Verified Commit 9b4df73f authored by Daniel Vrátil's avatar Daniel Vrátil 🤖
Browse files

AgentManager: ignore DBus services belonging to other Akonadi instances

parent ade84d0b
......@@ -93,6 +93,43 @@ private Q_SLOTS:
akTestSetInstanceIdentifier(QStringLiteral("foo"));
QCOMPARE(DBus::agentServiceName(QLatin1String("akonadi_maildir_resource_0"), DBus::Agent), QLatin1String("org.freedesktop.Akonadi.Agent.akonadi_maildir_resource_0.foo"));
}
void testParseInstanceIdentifier_data()
{
QTest::addColumn<QString>("serviceName");
QTest::addColumn<bool>("hasInstance");
QTest::newRow("server") << QStringLiteral("org.freedesktop.Akonadi") << false;
QTest::newRow("server instance") << QStringLiteral("org.freedesktop.Akonadi.instance") << true;
QTest::newRow("control") << QStringLiteral("org.freedesktop.Akonadi.Control") << false;
QTest::newRow("control instance") << QStringLiteral("org.freedesktop.Akonadi.Control.instance") << true;
QTest::newRow("control lock") << QStringLiteral("org.freedesktop.Akonadi.Control.lock") << false;
QTest::newRow("control lock instance") << QStringLiteral("org.freedesktop.Akonadi.Control.lock.instance") << true;
QTest::newRow("janitor") << QStringLiteral("org.freedesktop.Akonadi.Janitor") << false;
QTest::newRow("janitor instance") << QStringLiteral("org.freedesktop.Akonadi.Janitor.instance") << true;
QTest::newRow("agentserver") << QStringLiteral("org.freedesktop.Akonadi.AgentServer") << false;
QTest::newRow("agentserver instance") << QStringLiteral("org.freedesktop.Akonadi.AgentServer.instance") << true;
QTest::newRow("upgrading") << QStringLiteral("org.freedesktop.Akonadi.upgrading") << false;
QTest::newRow("upgrading instance") << QStringLiteral("org.freedesktop.Akonadi.upgrading.instance") << true;
QTest::newRow("agent") << QStringLiteral("org.freedesktop.Akonadi.Agent.akonadi_agent_identifier") << false;
QTest::newRow("agent instance") << QStringLiteral("org.freedesktop.Akonadi.Agent.akonadi_agent_identifier.instance") << true;
QTest::newRow("resource") << QStringLiteral("org.freedesktop.Akonadi.Resource.akonadi_resource_identifier") << false;
QTest::newRow("resource instance") << QStringLiteral("org.freedesktop.Akonadi.Resource.akonadi_resource_identifier.instance") << true;
QTest::newRow("preprocessor") << QStringLiteral("org.freedesktop.Akonadi.Preprocessor.akonadi_preprocessor_identifier") << false;
QTest::newRow("preprocessor instance") << QStringLiteral("org.freedesktop.Akonadi.Preprocessor.akonadi_preprocessor_identifier.instance") << true;
}
void testParseInstanceIdentifier()
{
QFETCH(QString, serviceName);
QFETCH(bool, hasInstance);
const auto identifier = DBus::parseInstanceIdentifier(serviceName);
QCOMPARE(identifier.has_value(), hasInstance);
if (hasInstance) {
QCOMPARE(identifier.value(), QStringLiteral("instance"));
}
}
};
AKTEST_MAIN(DBusTest)
......
......@@ -643,6 +643,18 @@ void AgentManager::serviceOwnerChanged(const QString &name, const QString &oldOw
// This is called by the D-Bus server when a service comes up, goes down or changes ownership for some reason
// and this is where we "hook up" our different Agent interfaces.
// Ignore DBus address name (e.g. :1.310)
if (name.startsWith(QLatin1Char(':'))) {
return;
}
// Ignore services belonging to another Akonadi instance
const auto parsedInstance = Akonadi::DBus::parseInstanceIdentifier(name);
const auto currentInstance = Akonadi::Instance::hasIdentifier() ? Akonadi::akOptional<QString>(Akonadi::Instance::identifier()) : Akonadi::nullopt;
if (parsedInstance != currentInstance) {
return;
}
qCDebug(AKONADICONTROL_LOG) << "Service" << name << "owner changed from" << oldOwner << "to" << newOwner;
if ((name == Akonadi::DBus::serviceName(Akonadi::DBus::Server) || name == Akonadi::DBus::serviceName(Akonadi::DBus::AgentServer)) && !newOwner.isEmpty()) {
......
......@@ -110,3 +110,39 @@ QString DBus::agentServiceName(const QString &agentIdentifier, DBus::AgentType a
}
return serviceName;
}
akOptional<QString> DBus::parseInstanceIdentifier(const QString &serviceName)
{
constexpr std::array<QStringView, 4> services = {QStringView{AKONADI_DBUS_STORAGEJANITOR_SERVICE},
QStringView{AKONADI_DBUS_AGENTSERVER_SERVICE},
QStringView{AKONADI_DBUS_CONTROL_SERVICE_LOCK},
QStringView{AKONADI_DBUS_CONTROL_SERVICE}};
for (const auto &service : services) {
if (serviceName.startsWith(service)) {
if (serviceName != service) {
return serviceName.mid(service.length() + 1); // +1 for the separator "."
}
return nullopt;
}
}
if (serviceName.startsWith(QStringView{AKONADI_DBUS_SERVER_SERVICE})) {
const auto split = serviceName.splitRef(QLatin1Char('.'));
if (split.size() <= 3) {
return nullopt;
}
// [0]org.[1]freedesktop.[2]Akonadi.[3]type.[4]identifier.[5]instance
if (split[3] == QStringView{u"Agent"} || split[3] == QStringView{u"Resource"} || split[3] == QStringView{u"Preprocessor"}) {
if (split.size() == 6) {
return split[5].toString();
} else {
return nullopt;
}
} else {
return split[3].toString();
}
}
return nullopt;
}
......@@ -82,6 +82,11 @@ AKONADIPRIVATE_EXPORT akOptional<AgentService> parseAgentServiceName(const QStri
*/
AKONADIPRIVATE_EXPORT QString agentServiceName(const QString &agentIdentifier, DBus::AgentType agentType);
/**
* Returns the Akonadi instance name encoded in the service name.
*/
AKONADIPRIVATE_EXPORT akOptional<QString> parseInstanceIdentifier(const QString &serviceName);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment