2022-03-30 17:56:27 +08:00
|
|
|
#include "application_instance.h"
|
2022-06-15 14:14:43 +08:00
|
|
|
#include "../applicationhelper.h"
|
|
|
|
#include "application.h"
|
|
|
|
#include "applicationinstanceadaptor.h"
|
2022-03-30 17:56:27 +08:00
|
|
|
|
|
|
|
#include <qdatetime.h>
|
|
|
|
#include <QCryptographicHash>
|
|
|
|
#include <QDateTime>
|
|
|
|
#include <QProcess>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QUuid>
|
|
|
|
#include <QtConcurrent/QtConcurrent>
|
|
|
|
|
|
|
|
#ifdef DEFINE_LOADER_PATH
|
|
|
|
#include "../../src/define.h"
|
|
|
|
#endif
|
|
|
|
|
2022-06-15 14:14:43 +08:00
|
|
|
class ApplicationInstancePrivate
|
|
|
|
{
|
2022-03-30 17:56:27 +08:00
|
|
|
ApplicationInstance* q_ptr = nullptr;
|
|
|
|
Q_DECLARE_PUBLIC(ApplicationInstance);
|
|
|
|
|
2022-06-15 14:14:43 +08:00
|
|
|
Application* application;
|
|
|
|
ApplicationInstanceAdaptor* adapter;
|
|
|
|
QString m_path;
|
2022-03-30 17:56:27 +08:00
|
|
|
QSharedPointer<modules::ApplicationHelper::Helper> helper;
|
2022-06-15 14:14:43 +08:00
|
|
|
QDateTime startupTime;
|
|
|
|
QString m_id;
|
|
|
|
uint32_t pid;
|
2022-03-30 17:56:27 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
ApplicationInstancePrivate(ApplicationInstance* parent) : q_ptr(parent)
|
|
|
|
{
|
|
|
|
startupTime = QDateTime::currentDateTime();
|
2022-06-15 14:14:43 +08:00
|
|
|
m_id = QString(QCryptographicHash::hash(QUuid::createUuid().toByteArray(), QCryptographicHash::Md5).toHex());
|
|
|
|
m_path = QString("/org/desktopspec/ApplicationInstance/%1").arg(m_id);
|
|
|
|
adapter = new ApplicationInstanceAdaptor(q_ptr);
|
2022-03-30 17:56:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
~ApplicationInstancePrivate()
|
|
|
|
{
|
|
|
|
// disconnect dbus
|
|
|
|
QDBusConnection::sessionBus().unregisterObject(m_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
void run()
|
|
|
|
{
|
|
|
|
#ifdef DEFINE_LOADER_PATH
|
2022-05-19 13:13:55 +08:00
|
|
|
|
2022-06-15 14:14:43 +08:00
|
|
|
const QString task_hash{QString("DAM_TASK_HASH=%1").arg(m_id)};
|
|
|
|
const QString task_type{"DAM_TASK_TYPE=freedesktop "};
|
|
|
|
QProcess* p = new QProcess(q_ptr);
|
|
|
|
p->connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), p, [ = ] {
|
2022-03-30 17:56:27 +08:00
|
|
|
qInfo().noquote() << p->readAllStandardOutput();
|
|
|
|
qWarning().noquote() << p->readAllStandardError();
|
|
|
|
});
|
|
|
|
p->connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), q_ptr, &ApplicationInstance::taskFinished);
|
2022-06-15 14:14:43 +08:00
|
|
|
p->connect(p, &QProcess::readyReadStandardOutput, p, [ = ]
|
|
|
|
{ qInfo() << p->readAllStandardOutput(); });
|
|
|
|
p->connect(p, &QProcess::readyReadStandardError, p, [ = ]
|
|
|
|
{ qWarning() << p->readAllStandardError(); });
|
2022-03-30 17:56:27 +08:00
|
|
|
p->setProgram(LOADER_PATH);
|
|
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
|
|
env.insert("DAM_TASK_HASH", m_id);
|
|
|
|
env.insert("DAM_TASK_TYPE", "freedesktop");
|
|
|
|
p->setEnvironment(env.toStringList());
|
|
|
|
p->start();
|
|
|
|
p->waitForStarted();
|
|
|
|
if (p->state() == QProcess::ProcessState::NotRunning) {
|
2022-06-15 14:14:43 +08:00
|
|
|
Q_EMIT q_ptr->taskFinished(p->exitCode());
|
2022-03-30 17:56:27 +08:00
|
|
|
}
|
|
|
|
#else
|
2022-05-25 11:46:28 +08:00
|
|
|
qInfo() << "app manager load service:" << QString("org.desktopspec.application.instance@%1.service").arg(m_id);
|
2022-06-15 14:14:43 +08:00
|
|
|
QDBusInterface systemd("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager");
|
2022-05-25 11:46:28 +08:00
|
|
|
QDBusReply<void> reply = systemd.call("StartUnit", QString("org.desktopspec.application.instance@%1.service").arg(m_id), "replace-irreversibly");
|
2022-03-30 17:56:27 +08:00
|
|
|
if (!reply.isValid()) {
|
|
|
|
qInfo() << reply.error();
|
|
|
|
q_ptr->deleteLater();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void _exit()
|
|
|
|
{
|
|
|
|
#ifdef LOADER_PATH
|
|
|
|
#else
|
|
|
|
QDBusInterface systemd("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager");
|
2022-05-25 11:46:28 +08:00
|
|
|
qInfo() << systemd.call("StopUnit", QString("org.desktopspec.application.instance@%1.service").arg(m_id), "replace-irreversibly");
|
2022-03-30 17:56:27 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void _kill() {}
|
2022-06-15 14:14:43 +08:00
|
|
|
uint32_t _getPid()
|
|
|
|
{
|
|
|
|
return pid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void _success(const QString& data)
|
|
|
|
{
|
|
|
|
pid = data.toUInt();
|
|
|
|
}
|
2022-03-30 17:56:27 +08:00
|
|
|
};
|
|
|
|
|
2022-05-19 13:13:55 +08:00
|
|
|
ApplicationInstance::ApplicationInstance(Application* parent, QSharedPointer<modules::ApplicationHelper::Helper> helper, QStringList files)
|
2022-06-15 14:14:43 +08:00
|
|
|
: QObject(nullptr)
|
|
|
|
, dd_ptr(new ApplicationInstancePrivate(this))
|
|
|
|
, m_files(files)
|
2022-03-30 17:56:27 +08:00
|
|
|
{
|
|
|
|
Q_D(ApplicationInstance);
|
|
|
|
|
|
|
|
d->application = parent;
|
2022-06-15 14:14:43 +08:00
|
|
|
d->helper = helper;
|
2022-03-30 17:56:27 +08:00
|
|
|
|
2022-06-15 14:14:43 +08:00
|
|
|
QTimer::singleShot(0, this, [ = ] {
|
2022-03-30 17:56:27 +08:00
|
|
|
QDBusConnection::sessionBus().registerObject(d->m_path, "org.desktopspec.ApplicationInstance", this);
|
|
|
|
d->run();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
ApplicationInstance::~ApplicationInstance()
|
|
|
|
{
|
|
|
|
Q_D(ApplicationInstance);
|
|
|
|
qDebug() << "instance quit " << d->helper->desktop();
|
|
|
|
}
|
|
|
|
|
|
|
|
QDBusObjectPath ApplicationInstance::id() const
|
|
|
|
{
|
|
|
|
Q_D(const ApplicationInstance);
|
|
|
|
|
|
|
|
return d->application->path();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString ApplicationInstance::hash() const
|
|
|
|
{
|
|
|
|
Q_D(const ApplicationInstance);
|
|
|
|
|
|
|
|
return d->m_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
quint64 ApplicationInstance::startuptime() const
|
|
|
|
{
|
|
|
|
Q_D(const ApplicationInstance);
|
|
|
|
|
|
|
|
return d->startupTime.toSecsSinceEpoch();
|
|
|
|
}
|
|
|
|
|
|
|
|
QDBusObjectPath ApplicationInstance::path() const
|
|
|
|
{
|
|
|
|
Q_D(const ApplicationInstance);
|
|
|
|
|
|
|
|
return QDBusObjectPath(d->m_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
Methods::Task ApplicationInstance::taskInfo() const
|
|
|
|
{
|
|
|
|
Q_D(const ApplicationInstance);
|
|
|
|
|
|
|
|
Methods::Task task;
|
2022-06-15 14:14:43 +08:00
|
|
|
task.id = d->m_id;
|
2022-04-24 14:52:13 +08:00
|
|
|
task.runId = d->application->id();
|
2022-05-25 11:46:28 +08:00
|
|
|
task.filePath = d->application->filePath();
|
2022-06-15 14:14:43 +08:00
|
|
|
task.date = QString::number(startuptime());
|
2022-05-19 13:13:55 +08:00
|
|
|
task.arguments = m_files;
|
2022-03-30 17:56:27 +08:00
|
|
|
|
|
|
|
// TODO: debug to display environment
|
2022-06-15 14:14:43 +08:00
|
|
|
task.environments.insert("DISPLAY", ":0");
|
2022-03-30 17:56:27 +08:00
|
|
|
auto sysEnv = QProcessEnvironment::systemEnvironment();
|
|
|
|
for (const auto& key : sysEnv.keys()) {
|
2022-06-15 14:14:43 +08:00
|
|
|
task.environments.insert(key, sysEnv.value(key));
|
2022-03-30 17:56:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return task;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationInstance::Exit()
|
|
|
|
{
|
|
|
|
Q_D(ApplicationInstance);
|
|
|
|
|
|
|
|
return d->_exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationInstance::Kill()
|
|
|
|
{
|
|
|
|
Q_D(ApplicationInstance);
|
|
|
|
|
|
|
|
return d->_kill();
|
|
|
|
}
|
2022-06-15 14:14:43 +08:00
|
|
|
|
|
|
|
uint32_t ApplicationInstance::getPid()
|
|
|
|
{
|
|
|
|
Q_D(ApplicationInstance);
|
|
|
|
|
|
|
|
return d->_getPid();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationInstance::Success(const QString& data)
|
|
|
|
{
|
|
|
|
Q_D(ApplicationInstance);
|
|
|
|
QDBusConnection::sessionBus().registerObject(d->m_path, "org.desktopspec.ApplicationInstance", this);
|
|
|
|
return d->_success(data);
|
|
|
|
}
|