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 APPLICATIONSERVICE_H
|
|
|
|
#define APPLICATIONSERVICE_H
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
#include <QDBusObjectPath>
|
2023-07-17 14:49:35 +08:00
|
|
|
#include <QMap>
|
|
|
|
#include <QString>
|
|
|
|
#include <QDBusUnixFileDescriptor>
|
|
|
|
#include <QSharedPointer>
|
2023-07-24 14:12:59 +08:00
|
|
|
#include <QUuid>
|
|
|
|
#include <QTextStream>
|
|
|
|
#include <QFile>
|
2023-08-07 14:25:22 +08:00
|
|
|
#include "dbus/instanceservice.h"
|
2023-07-17 14:49:35 +08:00
|
|
|
#include "global.h"
|
2023-07-24 14:12:59 +08:00
|
|
|
#include "desktopentry.h"
|
|
|
|
#include "desktopicons.h"
|
2023-08-07 14:25:22 +08:00
|
|
|
#include "dbus/jobmanager1service.h"
|
2023-07-10 10:18:33 +08:00
|
|
|
|
|
|
|
class ApplicationService : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2023-07-17 14:49:35 +08:00
|
|
|
~ApplicationService() override;
|
2023-07-21 14:47:40 +08:00
|
|
|
ApplicationService(const ApplicationService &) = delete;
|
2023-07-17 14:49:35 +08:00
|
|
|
ApplicationService(ApplicationService &&) = delete;
|
2023-07-21 14:47:40 +08:00
|
|
|
ApplicationService &operator=(const ApplicationService &) = delete;
|
2023-07-17 14:49:35 +08:00
|
|
|
ApplicationService &operator=(ApplicationService &&) = delete;
|
|
|
|
|
2023-08-11 17:46:46 +08:00
|
|
|
Q_PROPERTY(QStringList Actions READ actions)
|
2023-08-10 14:32:09 +08:00
|
|
|
[[nodiscard]] QStringList actions() const noexcept;
|
2023-07-17 14:49:35 +08:00
|
|
|
|
2023-07-24 14:12:59 +08:00
|
|
|
Q_PROPERTY(QString ID READ id CONSTANT)
|
2023-08-10 14:32:09 +08:00
|
|
|
[[nodiscard]] QString id() const noexcept;
|
2023-07-17 14:49:35 +08:00
|
|
|
|
|
|
|
Q_PROPERTY(IconMap Icons READ icons)
|
2023-08-10 14:32:09 +08:00
|
|
|
[[nodiscard]] IconMap icons() const;
|
2023-07-21 14:47:40 +08:00
|
|
|
IconMap &iconsRef();
|
2023-07-17 14:49:35 +08:00
|
|
|
|
|
|
|
Q_PROPERTY(bool AutoStart READ isAutoStart WRITE setAutoStart)
|
2023-08-10 14:32:09 +08:00
|
|
|
[[nodiscard]] bool isAutoStart() const noexcept;
|
2023-07-17 14:49:35 +08:00
|
|
|
void setAutoStart(bool autostart) noexcept;
|
|
|
|
|
|
|
|
Q_PROPERTY(QList<QDBusObjectPath> Instances READ instances)
|
2023-08-10 14:32:09 +08:00
|
|
|
[[nodiscard]] QList<QDBusObjectPath> instances() const noexcept;
|
2023-07-17 14:49:35 +08:00
|
|
|
|
2023-08-10 14:32:09 +08:00
|
|
|
[[nodiscard]] QDBusObjectPath findInstance(const QString &instanceId) const;
|
2023-07-24 14:12:59 +08:00
|
|
|
|
2023-08-10 14:32:09 +08:00
|
|
|
[[nodiscard]] const QString &getLauncher() const noexcept { return m_launcher; }
|
2023-07-24 14:12:59 +08:00
|
|
|
void setLauncher(const QString &launcher) noexcept { m_launcher = launcher; }
|
|
|
|
|
2023-08-08 15:10:32 +08:00
|
|
|
bool addOneInstance(const QString &instanceId, const QString &application, const QString &systemdUnitPath);
|
2023-07-17 14:49:35 +08:00
|
|
|
void recoverInstances(const QList<QDBusObjectPath>) noexcept;
|
2023-08-08 15:10:32 +08:00
|
|
|
void removeOneInstance(const QDBusObjectPath &instance);
|
2023-07-17 14:49:35 +08:00
|
|
|
void removeAllInstance();
|
2023-07-10 10:18:33 +08:00
|
|
|
|
|
|
|
public Q_SLOTS:
|
2023-07-17 14:49:35 +08:00
|
|
|
QString GetActionName(const QString &identifier, const QStringList &env);
|
2023-07-24 14:12:59 +08:00
|
|
|
QDBusObjectPath Launch(QString action, QStringList fields, QVariantMap options);
|
2023-07-17 14:49:35 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
friend class ApplicationManager1Service;
|
2023-07-24 14:12:59 +08:00
|
|
|
template <typename T>
|
|
|
|
ApplicationService(T &&source, ApplicationManager1Service *parent)
|
|
|
|
: m_parent(parent)
|
|
|
|
, m_desktopSource(std::forward<T>(source))
|
|
|
|
{
|
|
|
|
static_assert(std::is_same_v<T, DesktopFile> or std::is_same_v<T, QString>, "param type must be QString or DesktopFile.");
|
|
|
|
QString objectPath{DDEApplicationManager1ApplicationObjectPath};
|
|
|
|
QTextStream sourceStream;
|
|
|
|
QFile sourceFile;
|
|
|
|
auto dbusAppid = m_desktopSource.m_file.desktopId();
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, DesktopFile>) {
|
|
|
|
m_applicationPath = QDBusObjectPath{objectPath + escapeToObjectPath(dbusAppid)};
|
|
|
|
m_isPersistence = true;
|
|
|
|
sourceFile.setFileName(m_desktopSource.m_file.filePath());
|
|
|
|
if (!sourceFile.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text)) {
|
|
|
|
qCritical() << "desktop file can't open:" << m_desktopSource.m_file.filePath() << sourceFile.errorString();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sourceStream.setDevice(&sourceFile);
|
|
|
|
} else if (std::is_same_v<T, QString>) {
|
|
|
|
m_applicationPath = QDBusObjectPath{objectPath + QUuid::createUuid().toString(QUuid::Id128)};
|
|
|
|
m_isPersistence = false;
|
|
|
|
sourceStream.setString(&m_desktopSource.m_temp, QTextStream::ReadOnly | QTextStream::Text);
|
|
|
|
}
|
|
|
|
m_entry.reset(new DesktopEntry());
|
2023-08-11 17:46:46 +08:00
|
|
|
if (auto error = m_entry->parse(sourceStream); error != DesktopErrorCode::NoError) {
|
|
|
|
if (error != DesktopErrorCode::EntryKeyInvalid) {
|
2023-07-24 14:12:59 +08:00
|
|
|
m_entry.reset(nullptr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO: icon lookup
|
|
|
|
}
|
|
|
|
|
|
|
|
bool m_AutoStart{false};
|
|
|
|
bool m_isPersistence;
|
|
|
|
ApplicationManager1Service *m_parent{nullptr};
|
2023-07-17 14:49:35 +08:00
|
|
|
QDBusObjectPath m_applicationPath;
|
2023-08-07 14:25:22 +08:00
|
|
|
QString m_launcher{getApplicationLauncherBinary()};
|
2023-07-24 14:12:59 +08:00
|
|
|
union DesktopSource
|
|
|
|
{
|
|
|
|
template <typename T, std::enable_if_t<std::is_same_v<T, DesktopFile>, bool> = true>
|
|
|
|
DesktopSource(T &&source)
|
|
|
|
: m_file(std::forward<T>(source))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, std::enable_if_t<std::is_same_v<T, QString>, bool> = true>
|
|
|
|
DesktopSource(T &&source)
|
|
|
|
: m_temp(std::forward<T>(source))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void destruct(bool isPersistence)
|
|
|
|
{
|
|
|
|
if (isPersistence) {
|
|
|
|
m_file.~DesktopFile();
|
|
|
|
} else {
|
|
|
|
m_temp.~QString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
~DesktopSource(){};
|
|
|
|
QString m_temp;
|
|
|
|
DesktopFile m_file;
|
|
|
|
} m_desktopSource;
|
|
|
|
QSharedPointer<DesktopEntry> m_entry{nullptr};
|
|
|
|
QSharedPointer<DesktopIcons> m_Icons{nullptr};
|
2023-07-21 14:47:40 +08:00
|
|
|
QMap<QDBusObjectPath, QSharedPointer<InstanceService>> m_Instances;
|
2023-07-24 14:12:59 +08:00
|
|
|
QString userNameLookup(uid_t uid);
|
|
|
|
[[nodiscard]] LaunchTask unescapeExec(const QString &str, const QStringList &fields);
|
2023-07-10 10:18:33 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|