2023-07-10 10:18:33 +08:00
|
|
|
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
|
|
|
|
#ifndef JOBMANAGER1SERVICE_H
|
|
|
|
#define JOBMANAGER1SERVICE_H
|
|
|
|
|
|
|
|
#include <QObject>
|
2023-07-17 14:49:35 +08:00
|
|
|
#include <QMap>
|
2023-07-10 10:18:33 +08:00
|
|
|
#include <QDBusObjectPath>
|
2023-07-17 14:49:35 +08:00
|
|
|
#include <QSharedPointer>
|
2023-07-18 15:55:29 +08:00
|
|
|
#include <QMutex>
|
|
|
|
#include <QMutexLocker>
|
|
|
|
#include <QtConcurrent>
|
2023-08-08 15:10:32 +08:00
|
|
|
#include <QDBusError>
|
2023-07-18 15:55:29 +08:00
|
|
|
#include <QFuture>
|
|
|
|
#include <QUuid>
|
|
|
|
#include "global.h"
|
2023-08-07 14:25:22 +08:00
|
|
|
#include "dbus/jobadaptor.h"
|
2023-07-24 14:12:59 +08:00
|
|
|
|
|
|
|
class ApplicationManager1Service;
|
|
|
|
|
|
|
|
struct LaunchTask
|
|
|
|
{
|
2023-08-11 10:12:46 +08:00
|
|
|
LaunchTask() = default;
|
2023-07-24 14:12:59 +08:00
|
|
|
~LaunchTask() = default;
|
|
|
|
LaunchTask(const LaunchTask &) = default;
|
|
|
|
LaunchTask(LaunchTask &&) = default;
|
|
|
|
LaunchTask &operator=(const LaunchTask &) = default;
|
|
|
|
LaunchTask &operator=(LaunchTask &&) = default;
|
2023-11-06 11:30:54 +08:00
|
|
|
explicit operator bool() const { return !LaunchBin.isEmpty() and !command.isEmpty(); }
|
2023-07-24 14:12:59 +08:00
|
|
|
QString LaunchBin;
|
|
|
|
QStringList command;
|
|
|
|
QVariantList Resources;
|
|
|
|
};
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(LaunchTask)
|
2023-07-18 15:55:29 +08:00
|
|
|
|
2023-07-17 14:49:35 +08:00
|
|
|
class JobManager1Service final : public QObject
|
2023-07-10 10:18:33 +08:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2023-07-17 14:49:35 +08:00
|
|
|
JobManager1Service(const JobManager1Service &) = delete;
|
2023-07-21 14:47:40 +08:00
|
|
|
JobManager1Service(JobManager1Service &&) = delete;
|
2023-07-17 14:49:35 +08:00
|
|
|
JobManager1Service &operator=(const JobManager1Service &) = delete;
|
|
|
|
JobManager1Service &operator=(JobManager1Service &&) = delete;
|
|
|
|
|
|
|
|
~JobManager1Service() override;
|
2023-07-18 15:55:29 +08:00
|
|
|
template <typename F>
|
2023-08-10 14:32:09 +08:00
|
|
|
QDBusObjectPath addJob(const QString &source, F func, QVariantList args)
|
2023-07-18 15:55:29 +08:00
|
|
|
{
|
|
|
|
static_assert(std::is_invocable_v<F, QVariant>, "param type must be QVariant.");
|
|
|
|
|
2023-08-16 17:44:56 +08:00
|
|
|
QString objectPath =
|
2023-09-20 18:29:42 +08:00
|
|
|
QString{"%1/%2"}.arg(DDEApplicationManager1JobManager1ObjectPath).arg(QUuid::createUuid().toString(QUuid::Id128));
|
2023-07-24 14:12:59 +08:00
|
|
|
QFuture<QVariantList> future = QtConcurrent::mappedReduced(std::move(args),
|
|
|
|
func,
|
|
|
|
qOverload<QVariantList::parameter_type>(&QVariantList::append),
|
|
|
|
QVariantList{},
|
|
|
|
QtConcurrent::ReduceOption::OrderedReduce);
|
2023-07-18 15:55:29 +08:00
|
|
|
QSharedPointer<JobService> job{new JobService{future}};
|
2023-08-11 10:12:46 +08:00
|
|
|
|
|
|
|
auto *ptr = job.data();
|
|
|
|
new JobAdaptor(ptr);
|
2023-08-28 11:11:50 +08:00
|
|
|
if (!registerObjectToDBus(ptr, objectPath, JobInterface)) {
|
2023-07-24 14:12:59 +08:00
|
|
|
qCritical() << "can't register job to dbus.";
|
|
|
|
future.cancel();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2023-07-18 15:55:29 +08:00
|
|
|
auto path = QDBusObjectPath{objectPath};
|
|
|
|
{
|
|
|
|
QMutexLocker locker{&m_mutex};
|
2023-08-10 14:32:09 +08:00
|
|
|
m_jobs.insert(path, job); // Insertion is always successful
|
2023-07-18 15:55:29 +08:00
|
|
|
}
|
2023-07-24 14:12:59 +08:00
|
|
|
emit JobNew(path, QDBusObjectPath{source});
|
|
|
|
|
2023-07-21 14:47:40 +08:00
|
|
|
auto emitRemove = [this, job, path, future](QVariantList value) {
|
2023-07-24 14:12:59 +08:00
|
|
|
if (!removeOneJob(path)) {
|
2023-07-19 17:56:45 +08:00
|
|
|
return value;
|
2023-07-18 15:55:29 +08:00
|
|
|
}
|
2023-07-24 14:12:59 +08:00
|
|
|
|
2023-07-18 15:55:29 +08:00
|
|
|
QString result{job->status()};
|
|
|
|
for (const auto &val : future.result()) {
|
2023-08-08 15:10:32 +08:00
|
|
|
if (val.metaType().id() == QMetaType::fromType<QDBusError>().id()) {
|
2023-07-18 15:55:29 +08:00
|
|
|
result = "failed";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2023-07-24 14:12:59 +08:00
|
|
|
emit JobRemoved(path, result, future.result());
|
2023-07-19 17:56:45 +08:00
|
|
|
return value;
|
2023-07-18 15:55:29 +08:00
|
|
|
};
|
2023-07-24 14:12:59 +08:00
|
|
|
|
|
|
|
future.then(this, emitRemove);
|
|
|
|
return path;
|
2023-07-18 15:55:29 +08:00
|
|
|
}
|
2023-07-10 10:18:33 +08:00
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
void JobNew(const QDBusObjectPath &job, const QDBusObjectPath &source);
|
2023-07-18 15:55:29 +08:00
|
|
|
void JobRemoved(const QDBusObjectPath &job, const QString &status, const QVariantList &result);
|
2023-07-17 14:49:35 +08:00
|
|
|
|
|
|
|
private:
|
2023-07-24 14:12:59 +08:00
|
|
|
bool removeOneJob(const QDBusObjectPath &path);
|
|
|
|
friend class ApplicationManager1Service;
|
2023-08-10 14:32:09 +08:00
|
|
|
explicit JobManager1Service(ApplicationManager1Service *parent);
|
2023-07-18 15:55:29 +08:00
|
|
|
QMutex m_mutex;
|
2023-07-17 14:49:35 +08:00
|
|
|
QMap<QDBusObjectPath, QSharedPointer<JobService>> m_jobs;
|
2023-07-24 14:12:59 +08:00
|
|
|
ApplicationManager1Service *m_parent{nullptr};
|
2023-07-10 10:18:33 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|