File indexing completed on 2024-05-12 15:44:15

0001 /*
0002     SPDX-FileCopyrightText: 2012 Sebastian Kügler <sebas@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "config-package.h"
0008 #include "packagejob_p.h"
0009 #include "packagejobthread_p.h"
0010 
0011 #include "package_p.h"
0012 #include "utils.h"
0013 
0014 #include "kpackage_debug.h"
0015 
0016 #include <QDBusConnection>
0017 #include <QDBusMessage>
0018 
0019 namespace KPackage
0020 {
0021 class PackageJobPrivate
0022 {
0023 public:
0024     PackageJobThread *thread = nullptr;
0025     Package *package = nullptr;
0026     QString installPath;
0027 };
0028 
0029 PackageJob::PackageJob(Package *package, QObject *parent)
0030     : KJob(parent)
0031     , d(new PackageJobPrivate)
0032 {
0033     d->thread = new PackageJobThread(this);
0034     d->package = package;
0035 
0036     connect(PackageDeletionNotifier::self(), &PackageDeletionNotifier::packageDeleted, this, [this](Package *package) {
0037         if (package == d->package) {
0038             d->package = nullptr;
0039         }
0040     });
0041 
0042     connect(
0043         d->thread,
0044         &PackageJobThread::installPathChanged,
0045         this,
0046         [this](const QString &installPath) {
0047             if (d->package) {
0048                 d->package->setPath(installPath);
0049             }
0050             Q_EMIT installPathChanged(installPath);
0051         },
0052         Qt::QueuedConnection);
0053 }
0054 
0055 PackageJob::~PackageJob()
0056 {
0057     delete d;
0058 }
0059 
0060 void PackageJob::slotFinished(bool ok, const QString &err)
0061 {
0062     if (ok) {
0063         setError(NoError);
0064     } else {
0065         setError(d->thread->errorCode());
0066         setErrorText(err);
0067     }
0068     d->thread->exit(0);
0069     emitResult();
0070 }
0071 
0072 void PackageJob::start()
0073 {
0074     d->thread->start();
0075 }
0076 
0077 void PackageJob::install(const QString &src, const QString &dest)
0078 {
0079     setupNotificationsOnJobFinished(QStringLiteral("packageInstalled"));
0080     d->thread->install(src, dest);
0081 }
0082 
0083 void PackageJob::update(const QString &src, const QString &dest)
0084 {
0085     setupNotificationsOnJobFinished(QStringLiteral("packageUpdated"));
0086     d->thread->update(src, dest);
0087 }
0088 
0089 void PackageJob::uninstall(const QString &installationPath)
0090 {
0091     setupNotificationsOnJobFinished(QStringLiteral("packageUninstalled"));
0092     d->thread->uninstall(installationPath);
0093 }
0094 
0095 void PackageJob::setupNotificationsOnJobFinished(const QString &messageName)
0096 {
0097     // capture first as uninstalling wipes d->package
0098     // or d-package can become dangling during the job if deleted externally
0099     const QString pluginId = d->package->metadata().pluginId();
0100     const QStringList serviceTypes = readKPackageTypes(d->package->metadata());
0101 
0102     auto onJobFinished = [=](bool ok, const QString &error) {
0103         if (ok) {
0104             for (auto &packageType : serviceTypes) {
0105                 auto msg = QDBusMessage::createSignal(QStringLiteral("/KPackage/") + packageType, QStringLiteral("org.kde.plasma.kpackage"), messageName);
0106                 msg.setArguments({pluginId});
0107                 QDBusConnection::sessionBus().send(msg);
0108             }
0109         }
0110         slotFinished(ok, error);
0111     };
0112     connect(d->thread, &PackageJobThread::jobThreadFinished, this, onJobFinished, Qt::QueuedConnection);
0113 }
0114 
0115 } // namespace KPackage
0116 
0117 #include "moc_packagejob_p.cpp"