feat: 初始代码
AM初始代码,迁移自gitlabwh Log: Task: https://pms.uniontech.com/task-view-108539.html Influence: Change-Id: I6096f97e5d68d13796ff5dc51d9858c0f40264a0
This commit is contained in:
55
src/service/CMakeLists.txt
Normal file
55
src/service/CMakeLists.txt
Normal file
@ -0,0 +1,55 @@
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
find_package(Qt5 REQUIRED COMPONENTS Core DBus Concurrent)
|
||||
|
||||
qt5_add_dbus_adaptor(ADAPTER_SOURCES
|
||||
../../DBus/org.desktopspec.ApplicationManager.xml
|
||||
impl/application_manager.h
|
||||
ApplicationManager)
|
||||
|
||||
qt5_add_dbus_adaptor(ADAPTER_SOURCES
|
||||
../../DBus/org.desktopspec.Application.xml
|
||||
impl/application.h
|
||||
Application)
|
||||
|
||||
qt5_add_dbus_adaptor(ADAPTER_SOURCES
|
||||
../../DBus/org.desktopspec.ApplicationInstance.xml
|
||||
impl/application_instance.h
|
||||
ApplicationInstance)
|
||||
add_definitions(-DUSE_QT)
|
||||
|
||||
set(SRCS ${PROJECT_BINARY_DIR}/src/define.h)
|
||||
|
||||
set(SRCS
|
||||
./main.cpp
|
||||
./impl/application_manager.h
|
||||
./impl/application_manager.cpp
|
||||
./impl/application.h
|
||||
./impl/application.cpp
|
||||
./impl/application_instance.h
|
||||
./impl/application_instance.cpp
|
||||
../modules/applicationhelper/helper.h
|
||||
../modules/tools/desktop_deconstruction.hpp
|
||||
../modules/socket/server.h
|
||||
../modules/socket/server.cpp
|
||||
../modules/methods/basic.h
|
||||
../modules/methods/task.hpp
|
||||
../modules/methods/instance.hpp
|
||||
../modules/methods/quit.hpp
|
||||
../modules/methods/registe.hpp
|
||||
)
|
||||
|
||||
add_executable(deepin-application-manager
|
||||
${SRCS}
|
||||
${ADAPTER_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(deepin-application-manager
|
||||
Qt5::Core
|
||||
Qt5::DBus
|
||||
Qt5::Concurrent
|
||||
)
|
||||
|
||||
install(TARGETS deepin-application-manager DESTINATION bin)
|
168
src/service/impl/application.cpp
Normal file
168
src/service/impl/application.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
#include "application.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
#include <QThread>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../modules/applicationhelper/helper.h"
|
||||
#include "../modules/tools/desktop_deconstruction.hpp"
|
||||
#include "application_instance.h"
|
||||
|
||||
class ApplicationPrivate {
|
||||
Application *q_ptr = nullptr;
|
||||
Q_DECLARE_PUBLIC(Application);
|
||||
|
||||
QList<QSharedPointer<ApplicationInstance>> instances;
|
||||
QSharedPointer<modules::ApplicationHelper::Helper> helper;
|
||||
QString m_prefix;
|
||||
Application::Type m_type;
|
||||
|
||||
public:
|
||||
ApplicationPrivate(Application *parent) : q_ptr(parent) {}
|
||||
|
||||
~ApplicationPrivate() {}
|
||||
|
||||
QStringList categories() const
|
||||
{
|
||||
return helper->categories();
|
||||
}
|
||||
|
||||
QString icon() const
|
||||
{
|
||||
return helper->icon();
|
||||
}
|
||||
|
||||
QString id() const
|
||||
{
|
||||
return helper->id();
|
||||
}
|
||||
|
||||
QStringList mimetypes() const
|
||||
{
|
||||
return helper->mimetypes();
|
||||
}
|
||||
|
||||
QString comment(const QString &locale) const
|
||||
{
|
||||
return helper->comment(locale);
|
||||
}
|
||||
|
||||
QString name(const QString &name) const
|
||||
{
|
||||
return helper->name(name);
|
||||
}
|
||||
};
|
||||
|
||||
Application::Application(const QString &prefix, Type type, QSharedPointer<modules::ApplicationHelper::Helper> helper) : QObject(nullptr), dd_ptr(new ApplicationPrivate(this))
|
||||
{
|
||||
Q_D(Application);
|
||||
|
||||
d->helper = helper;
|
||||
d->m_type = type;
|
||||
d->m_prefix = prefix;
|
||||
}
|
||||
|
||||
Application::~Application() {}
|
||||
|
||||
QStringList Application::categories() const
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
return d->categories();
|
||||
}
|
||||
|
||||
QString Application::icon() const
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
return d->icon();
|
||||
}
|
||||
|
||||
QString Application::id() const
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
const QString id{ d->id() };
|
||||
return QString("/%1/%2/%3").arg(d->m_prefix).arg(d->m_type == Application::Type::System ? "system" : "user").arg(id);
|
||||
}
|
||||
|
||||
QList<QDBusObjectPath> Application::instances() const
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
QList<QDBusObjectPath> result;
|
||||
|
||||
for (const auto &ins : d->instances) {
|
||||
result << ins->path();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList Application::mimetypes() const
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
return d->mimetypes();
|
||||
}
|
||||
|
||||
QString Application::Comment(const QString &locale)
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
return d->comment(locale);
|
||||
}
|
||||
|
||||
QString Application::Name(const QString &locale)
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
return d->name(locale);
|
||||
}
|
||||
|
||||
QDBusObjectPath Application::path() const
|
||||
{
|
||||
return QDBusObjectPath(QString("/org/desktopspec/Application/%1").arg(QString(QCryptographicHash::hash(id().toUtf8(), QCryptographicHash::Md5).toHex())));
|
||||
}
|
||||
|
||||
Application::Type Application::type() const
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
return d->m_type;
|
||||
}
|
||||
|
||||
QString Application::filePath() const
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
return d->helper->desktop();
|
||||
}
|
||||
|
||||
QSharedPointer<ApplicationInstance> Application::createInstance()
|
||||
{
|
||||
Q_D(Application);
|
||||
|
||||
d->instances << QSharedPointer<ApplicationInstance>(new ApplicationInstance(this, d->helper));
|
||||
|
||||
connect(d->instances.last().get(), &ApplicationInstance::taskFinished, this, [=] {
|
||||
for (auto it = d->instances.begin(); it != d->instances.end(); ++it) {
|
||||
if ((*it).data() == sender()) {
|
||||
d->instances.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
qWarning() << "The instance should not be found!";
|
||||
});
|
||||
|
||||
return d->instances.last();
|
||||
}
|
||||
|
||||
QString Application::prefix() const
|
||||
{
|
||||
Q_D(const Application);
|
||||
|
||||
return d->m_prefix;
|
||||
}
|
60
src/service/impl/application.h
Normal file
60
src/service/impl/application.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef A216803F_06DD_4F40_8FD1_5BAED85905BE
|
||||
#define A216803F_06DD_4F40_8FD1_5BAED85905BE
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QObject>
|
||||
#include <QDBusObjectPath>
|
||||
|
||||
namespace modules {
|
||||
namespace ApplicationHelper {
|
||||
class Helper;
|
||||
}
|
||||
}
|
||||
|
||||
class ApplicationPrivate;
|
||||
class ApplicationInstance;
|
||||
class Application : public QObject {
|
||||
Q_OBJECT
|
||||
QScopedPointer<ApplicationPrivate> dd_ptr;
|
||||
Q_DECLARE_PRIVATE_D(qGetPtrHelper(dd_ptr), Application)
|
||||
public:
|
||||
enum class Type {
|
||||
System,
|
||||
User,
|
||||
};
|
||||
|
||||
Application(const QString& prefix, Type type, QSharedPointer<modules::ApplicationHelper::Helper> helper);
|
||||
~Application() override;
|
||||
|
||||
public: // PROPERTIES
|
||||
Q_PROPERTY(QStringList categories READ categories)
|
||||
QStringList categories() const;
|
||||
|
||||
Q_PROPERTY(QString icon READ icon)
|
||||
QString icon() const;
|
||||
|
||||
Q_PROPERTY(QString id READ id)
|
||||
QString id() const;
|
||||
|
||||
Q_PROPERTY(QList<QDBusObjectPath> instances READ instances)
|
||||
QList<QDBusObjectPath> instances() const;
|
||||
|
||||
Q_PROPERTY(QStringList mimetypes READ mimetypes)
|
||||
QStringList mimetypes() const;
|
||||
|
||||
QDBusObjectPath path() const;
|
||||
|
||||
QString prefix() const;
|
||||
|
||||
Type type() const;
|
||||
|
||||
QString filePath() const;
|
||||
|
||||
QSharedPointer<ApplicationInstance> createInstance();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
QString Comment(const QString &locale);
|
||||
QString Name(const QString &locale);
|
||||
};
|
||||
|
||||
#endif /* A216803F_06DD_4F40_8FD1_5BAED85905BE */
|
169
src/service/impl/application_instance.cpp
Normal file
169
src/service/impl/application_instance.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include "application_instance.h"
|
||||
|
||||
#include <qdatetime.h>
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDateTime>
|
||||
#include <QProcess>
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include "../../modules/applicationhelper/helper.h"
|
||||
#include "application.h"
|
||||
#include "applicationinstanceadaptor.h"
|
||||
|
||||
#ifdef DEFINE_LOADER_PATH
|
||||
#include "../../src/define.h"
|
||||
#endif
|
||||
|
||||
class ApplicationInstancePrivate {
|
||||
ApplicationInstance* q_ptr = nullptr;
|
||||
Q_DECLARE_PUBLIC(ApplicationInstance);
|
||||
|
||||
Application* application;
|
||||
ApplicationInstanceAdaptor* adapter;
|
||||
QString m_path;
|
||||
QSharedPointer<modules::ApplicationHelper::Helper> helper;
|
||||
QDateTime startupTime;
|
||||
QString m_id;
|
||||
|
||||
public:
|
||||
ApplicationInstancePrivate(ApplicationInstance* parent) : q_ptr(parent)
|
||||
{
|
||||
startupTime = QDateTime::currentDateTime();
|
||||
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);
|
||||
}
|
||||
|
||||
~ApplicationInstancePrivate()
|
||||
{
|
||||
// disconnect dbus
|
||||
QDBusConnection::sessionBus().unregisterObject(m_path);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
#ifdef DEFINE_LOADER_PATH
|
||||
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, [=] {
|
||||
qInfo().noquote() << p->readAllStandardOutput();
|
||||
qWarning().noquote() << p->readAllStandardError();
|
||||
});
|
||||
p->connect(p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), q_ptr, &ApplicationInstance::taskFinished);
|
||||
p->connect(p, &QProcess::readyReadStandardOutput, p, [=] { qInfo() << p->readAllStandardOutput(); });
|
||||
p->connect(p, &QProcess::readyReadStandardError, p, [=] { qWarning() << p->readAllStandardError(); });
|
||||
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) {
|
||||
emit q_ptr->taskFinished(p->exitCode());
|
||||
}
|
||||
#else
|
||||
QDBusInterface systemd("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager");
|
||||
QDBusReply<void> reply = systemd.call("StartUnit", QString("org.deskspec.application.instance@%1.service").arg(m_id), "replace-irreversibly");
|
||||
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");
|
||||
qInfo() << systemd.call("StopUnit", QString("org.deskspec.application.instance@%1.service").arg(m_id), "replace-irreversibly");
|
||||
#endif
|
||||
}
|
||||
|
||||
void _kill() {}
|
||||
};
|
||||
|
||||
ApplicationInstance::ApplicationInstance(Application* parent, QSharedPointer<modules::ApplicationHelper::Helper> helper) : QObject(nullptr), dd_ptr(new ApplicationInstancePrivate(this))
|
||||
{
|
||||
Q_D(ApplicationInstance);
|
||||
|
||||
d->application = parent;
|
||||
d->helper = helper;
|
||||
|
||||
QTimer::singleShot(0, this, [=] {
|
||||
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;
|
||||
task.id = d->m_id.toStdString();
|
||||
task.runId = d->application->id().toStdString();
|
||||
task.date = QString::number(startuptime()).toStdString();
|
||||
|
||||
// TODO: debug to display environment
|
||||
task.environments.insert({ "DISPLAY", ":0" });
|
||||
auto sysEnv = QProcessEnvironment::systemEnvironment();
|
||||
for (const auto& key : sysEnv.keys()) {
|
||||
task.environments.insert({ key.toStdString(), sysEnv.value(key).toStdString() });
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
void ApplicationInstance::Exit()
|
||||
{
|
||||
Q_D(ApplicationInstance);
|
||||
|
||||
return d->_exit();
|
||||
}
|
||||
|
||||
void ApplicationInstance::Kill()
|
||||
{
|
||||
Q_D(ApplicationInstance);
|
||||
|
||||
return d->_kill();
|
||||
}
|
44
src/service/impl/application_instance.h
Normal file
44
src/service/impl/application_instance.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef D6D05668_8A58_43AA_91C5_C6278643A1AF
|
||||
#define D6D05668_8A58_43AA_91C5_C6278643A1AF
|
||||
|
||||
#include <QDBusObjectPath>
|
||||
#include <QObject>
|
||||
|
||||
#include "../../modules/methods/task.hpp"
|
||||
|
||||
namespace modules {
|
||||
namespace ApplicationHelper {
|
||||
class Helper;
|
||||
}
|
||||
} // namespace modules
|
||||
|
||||
class Application;
|
||||
class ApplicationInstancePrivate;
|
||||
class ApplicationInstance : public QObject {
|
||||
Q_OBJECT
|
||||
QScopedPointer<ApplicationInstancePrivate> dd_ptr;
|
||||
Q_DECLARE_PRIVATE_D(qGetPtrHelper(dd_ptr), ApplicationInstance)
|
||||
public:
|
||||
ApplicationInstance(Application* parent, QSharedPointer<modules::ApplicationHelper::Helper> helper);
|
||||
~ApplicationInstance() override;
|
||||
|
||||
public: // PROPERTIES
|
||||
Q_PROPERTY(QDBusObjectPath id READ id)
|
||||
QDBusObjectPath id() const;
|
||||
|
||||
Q_PROPERTY(quint64 startuptime READ startuptime)
|
||||
quint64 startuptime() const;
|
||||
|
||||
QDBusObjectPath path() const;
|
||||
QString hash() const;
|
||||
Methods::Task taskInfo() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void taskFinished(int exitCode) const;
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
void Exit();
|
||||
void Kill();
|
||||
};
|
||||
|
||||
#endif /* D6D05668_8A58_43AA_91C5_C6278643A1AF */
|
195
src/service/impl/application_manager.cpp
Normal file
195
src/service/impl/application_manager.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
#include "application_manager.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <thread>
|
||||
|
||||
#include "../../modules/methods/basic.h"
|
||||
#include "../../modules/methods/instance.hpp"
|
||||
#include "../../modules/methods/quit.hpp"
|
||||
#include "../../modules/methods/registe.hpp"
|
||||
#include "../../modules/methods/task.hpp"
|
||||
#include "../../modules/socket/server.h"
|
||||
#include "application.h"
|
||||
#include "application_instance.h"
|
||||
#include "applicationinstanceadaptor.h"
|
||||
|
||||
class ApplicationManagerPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
ApplicationManager *q_ptr = nullptr;
|
||||
Q_DECLARE_PUBLIC(ApplicationManager);
|
||||
|
||||
QList<QSharedPointer<Application>> applications;
|
||||
Socket::Server server;
|
||||
std::multimap<std::string, QSharedPointer<ApplicationInstance>> tasks;
|
||||
|
||||
public:
|
||||
ApplicationManagerPrivate(ApplicationManager *parent) : QObject(parent), q_ptr(parent)
|
||||
{
|
||||
const QString socketPath{ QString("/run/user/%1/deepin-application-manager.socket").arg(getuid()) };
|
||||
connect(&server, &Socket::Server::onReadyRead, this, &ApplicationManagerPrivate::recvClientData, Qt::QueuedConnection);
|
||||
server.listen(socketPath.toStdString());
|
||||
}
|
||||
~ApplicationManagerPrivate() {}
|
||||
|
||||
private:
|
||||
void recvClientData(int socket, const std::vector<char> &data)
|
||||
{
|
||||
std::string tmp;
|
||||
for (char c : data) {
|
||||
tmp += c;
|
||||
}
|
||||
using namespace nlohmann;
|
||||
if (json::parse(tmp).is_null()) {
|
||||
server.close(socket);
|
||||
return;
|
||||
}
|
||||
Methods::Basic basic = json::parse(tmp);
|
||||
do {
|
||||
if (basic.type == "instance") {
|
||||
Methods::Instance instance = nlohmann::json::parse(tmp);
|
||||
auto find = tasks.find(instance.hash);
|
||||
if (find != tasks.end()) {
|
||||
nlohmann::json result = find->second->taskInfo();
|
||||
write(socket, result.dump());
|
||||
tasks.erase(find);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (basic.type == "quit") {
|
||||
Methods::Quit quit = json::parse(tmp);
|
||||
server.close(socket);
|
||||
std::cout << "client quit" << std::endl;
|
||||
break;
|
||||
}
|
||||
if (basic.type == "registe") {
|
||||
Methods::Registe registe = nlohmann::json::parse(tmp);
|
||||
Methods::Registe result;
|
||||
result.state = false;
|
||||
//std::lock_guard<std::mutex> lock(task_mutex);
|
||||
for (auto it = tasks.begin(); it != tasks.end(); ++it) {
|
||||
result.state = true;
|
||||
result.hash = it->first;
|
||||
}
|
||||
write(socket, json(result).dump());
|
||||
std::cout << "registe a new client" << std::endl;
|
||||
break;
|
||||
}
|
||||
write(socket, json().dump());
|
||||
} while (false);
|
||||
}
|
||||
|
||||
void write(int socket, const std::vector<char> &data)
|
||||
{
|
||||
std::vector<char> tmp = data;
|
||||
tmp.push_back('\0');
|
||||
server.write(socket, tmp);
|
||||
}
|
||||
void write(int socket, const std::string &data)
|
||||
{
|
||||
std::vector<char> result;
|
||||
std::copy(data.cbegin(), data.cend(), std::back_inserter(result));
|
||||
return write(socket, result);
|
||||
}
|
||||
void write(int socket, const char c)
|
||||
{
|
||||
return write(socket, std::vector<char>(c));
|
||||
}
|
||||
};
|
||||
|
||||
ApplicationManager::ApplicationManager(QObject *parent) : QObject(parent), dd_ptr(new ApplicationManagerPrivate(this)) {}
|
||||
|
||||
ApplicationManager::~ApplicationManager() {}
|
||||
|
||||
void ApplicationManager::addApplication(const QList<QSharedPointer<Application>> &list)
|
||||
{
|
||||
Q_D(ApplicationManager);
|
||||
|
||||
d->applications = list;
|
||||
}
|
||||
|
||||
QDBusObjectPath ApplicationManager::GetId(int pid)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
QDBusObjectPath ApplicationManager::GetInformation(const QString &id)
|
||||
{
|
||||
Q_D(ApplicationManager);
|
||||
|
||||
for (const QSharedPointer<Application> &app : d->applications) {
|
||||
if (app->id() == id) {
|
||||
return app->path();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<QDBusObjectPath> ApplicationManager::GetInstances(const QString &id)
|
||||
{
|
||||
Q_D(const ApplicationManager);
|
||||
|
||||
for (const auto &app : d->applications) {
|
||||
if (app->id() == id) {
|
||||
return app->instances();
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QDBusObjectPath ApplicationManager::Run(const QString &id)
|
||||
{
|
||||
Q_D(ApplicationManager);
|
||||
|
||||
// 创建一个实例
|
||||
for (const QSharedPointer<Application> &app : d->applications) {
|
||||
if (app->id() == id) {
|
||||
// 创建任务所需的数据,并记录到任务队列,等待 loader 消耗
|
||||
QSharedPointer<ApplicationInstance> instance{ app->createInstance() };
|
||||
const std::string hash{ instance->hash().toStdString() };
|
||||
connect(instance.get(), &ApplicationInstance::taskFinished, this, [=] {
|
||||
for (auto it = d->tasks.begin(); it != d->tasks.end(); ++it) {
|
||||
if (it->first == hash) {
|
||||
d->tasks.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
d->tasks.insert(std::make_pair(hash, instance));
|
||||
return instance->path();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<QDBusObjectPath> ApplicationManager::instances() const
|
||||
{
|
||||
Q_D(const ApplicationManager);
|
||||
|
||||
QList<QDBusObjectPath> result;
|
||||
|
||||
for (const auto &app : d->applications) {
|
||||
result += app->instances();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<QDBusObjectPath> ApplicationManager::list() const
|
||||
{
|
||||
Q_D(const ApplicationManager);
|
||||
|
||||
QList<QDBusObjectPath> result;
|
||||
for (const QSharedPointer<Application> &app : d->applications) {
|
||||
result << app->path();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#include "application_manager.moc"
|
43
src/service/impl/application_manager.h
Normal file
43
src/service/impl/application_manager.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef A2862DC7_5DA3_4129_9796_671D88015BED
|
||||
#define A2862DC7_5DA3_4129_9796_671D88015BED
|
||||
|
||||
#include <QObject>
|
||||
#include <QDBusObjectPath>
|
||||
#include <QList>
|
||||
|
||||
class Application;
|
||||
class ApplicationInstance;
|
||||
class ApplicationManagerPrivate;
|
||||
class ApplicationManager : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QList<QDBusObjectPath> instances READ instances)
|
||||
Q_PROPERTY(QList<QDBusObjectPath> list READ list)
|
||||
QScopedPointer<ApplicationManagerPrivate> dd_ptr;
|
||||
Q_DECLARE_PRIVATE_D(qGetPtrHelper(dd_ptr), ApplicationManager)
|
||||
|
||||
ApplicationManager(QObject *parent = nullptr);
|
||||
|
||||
public:
|
||||
~ApplicationManager() override;
|
||||
static ApplicationManager* Instance() {
|
||||
static ApplicationManager manager;
|
||||
return &manager;
|
||||
}
|
||||
|
||||
void addApplication(const QList<QSharedPointer<Application>> &list);
|
||||
|
||||
signals:
|
||||
void requestCreateInstance(const QSharedPointer<ApplicationInstance> instance);
|
||||
|
||||
public: // PROPERTIES
|
||||
QList<QDBusObjectPath> instances() const;
|
||||
QList<QDBusObjectPath> list() const;
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
QDBusObjectPath GetId(int pid);
|
||||
QDBusObjectPath GetInformation(const QString &id);
|
||||
QList<QDBusObjectPath> GetInstances(const QString &id);
|
||||
QDBusObjectPath Run(const QString &id);
|
||||
};
|
||||
|
||||
#endif /* A2862DC7_5DA3_4129_9796_671D88015BED */
|
81
src/service/main.cpp
Normal file
81
src/service/main.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "impl/application_manager.h"
|
||||
#include "impl/application.h"
|
||||
#include "applicationmanageradaptor.h"
|
||||
#include "applicationadaptor.h"
|
||||
#include "../modules/applicationhelper/helper.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <pwd.h>
|
||||
|
||||
QFileInfoList scan(const QString &path)
|
||||
{
|
||||
QDir dir(path);
|
||||
dir.setFilter(QDir::Files);
|
||||
dir.setNameFilters({ "*.desktop" });
|
||||
return dir.entryInfoList();
|
||||
}
|
||||
|
||||
// 扫描系统目录
|
||||
// 扫描用户目录
|
||||
QList<QSharedPointer<Application>> scanFiles()
|
||||
{
|
||||
QList<QSharedPointer<Application>> applications;
|
||||
auto apps = scan("/usr/share/applications/");
|
||||
for (const QFileInfo &info : apps) {
|
||||
applications << QSharedPointer<Application>(new Application(
|
||||
"freedesktop",
|
||||
Application::Type::System,
|
||||
QSharedPointer<modules::ApplicationHelper::Helper>(new modules::ApplicationHelper::Helper(info.filePath()))
|
||||
));
|
||||
}
|
||||
|
||||
struct passwd *user = getpwent();
|
||||
while (user) {
|
||||
auto userApps = scan(QString("%1/.local/share/applications/").arg(user->pw_dir));
|
||||
for (const QFileInfo &info : userApps) {
|
||||
applications << QSharedPointer<Application>(new Application(
|
||||
"freedesktop",
|
||||
Application::Type::System,
|
||||
QSharedPointer<modules::ApplicationHelper::Helper>(new modules::ApplicationHelper::Helper(info.filePath()))
|
||||
));
|
||||
}
|
||||
user = getpwent();
|
||||
}
|
||||
endpwent();
|
||||
auto linglong = scan("/deepin/linglong/entries/share/applications/");
|
||||
for (const QFileInfo &info : linglong) {
|
||||
applications << QSharedPointer<Application>(new Application(
|
||||
"linglong",
|
||||
Application::Type::System,
|
||||
QSharedPointer<modules::ApplicationHelper::Helper>(new modules::ApplicationHelper::Helper(info.filePath()))
|
||||
));
|
||||
}
|
||||
|
||||
return applications;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
new ApplicationManagerAdaptor(ApplicationManager::Instance());
|
||||
|
||||
QDBusConnection::sessionBus().registerService("org.desktopspec.Application");
|
||||
QDBusConnection::sessionBus().registerService("org.desktopspec.ApplicationManager");
|
||||
QDBusConnection::sessionBus().registerObject("/org/desktopspec/ApplicationManager", "org.desktopspec.ApplicationManager", ApplicationManager::Instance());
|
||||
|
||||
QList<QSharedPointer<Application>> apps{ scanFiles() };
|
||||
QList<QSharedPointer<ApplicationAdaptor>> appAdapters;
|
||||
for (const QSharedPointer<Application> app : apps) {
|
||||
QSharedPointer<ApplicationAdaptor> adapter = QSharedPointer<ApplicationAdaptor>(new ApplicationAdaptor(app.get()));
|
||||
appAdapters << adapter;
|
||||
QDBusConnection::sessionBus().registerObject(app->path().path(), "org.desktopspec.Application", app.get());
|
||||
}
|
||||
|
||||
ApplicationManager::Instance()->addApplication(apps);
|
||||
|
||||
return app.exec();
|
||||
}
|
Reference in New Issue
Block a user