2022-03-30 17:56:27 +08:00
|
|
|
#include "application_manager.h"
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2022-05-15 12:10:42 +08:00
|
|
|
#include <QDBusMessage>
|
|
|
|
#include <QDBusConnectionInterface>
|
|
|
|
#include <QDBusConnection>
|
|
|
|
#include <QDebug>
|
|
|
|
|
2022-03-30 17:56:27 +08:00
|
|
|
#include <iostream>
|
|
|
|
#include <map>
|
|
|
|
#include <mutex>
|
|
|
|
#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"
|
|
|
|
|
2022-04-24 14:52:13 +08:00
|
|
|
class ApplicationManagerPrivate : public QObject
|
|
|
|
{
|
2022-03-30 17:56:27 +08:00
|
|
|
Q_OBJECT
|
|
|
|
ApplicationManager *q_ptr = nullptr;
|
|
|
|
Q_DECLARE_PUBLIC(ApplicationManager);
|
|
|
|
|
2022-04-24 14:52:13 +08:00
|
|
|
QList<QSharedPointer<Application>> applications;
|
|
|
|
Socket::Server server;
|
2022-03-30 17:56:27 +08:00
|
|
|
std::multimap<std::string, QSharedPointer<ApplicationInstance>> tasks;
|
|
|
|
|
|
|
|
public:
|
|
|
|
ApplicationManagerPrivate(ApplicationManager *parent) : QObject(parent), q_ptr(parent)
|
|
|
|
{
|
2022-04-24 14:52:13 +08:00
|
|
|
const QString socketPath{QString("/run/user/%1/deepin-application-manager.socket").arg(getuid())};
|
2022-03-30 17:56:27 +08:00
|
|
|
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;
|
|
|
|
}
|
2022-04-24 14:52:13 +08:00
|
|
|
|
|
|
|
QByteArray jsonArray = data.data();
|
|
|
|
Methods::Basic basic;
|
|
|
|
Methods::fromJson(jsonArray, basic);
|
|
|
|
QByteArray tmpArray;
|
2022-03-30 17:56:27 +08:00
|
|
|
do {
|
|
|
|
if (basic.type == "instance") {
|
2022-04-24 14:52:13 +08:00
|
|
|
Methods::Instance instance;
|
|
|
|
Methods::fromJson(jsonArray, instance);
|
|
|
|
auto find = tasks.find(instance.hash.toStdString());
|
|
|
|
if (find != tasks.end())
|
|
|
|
{
|
|
|
|
Methods::Task task = find->second->taskInfo();
|
|
|
|
Methods::toJson(tmpArray, task);
|
|
|
|
write(socket, tmpArray.toStdString());
|
2022-03-30 17:56:27 +08:00
|
|
|
tasks.erase(find);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (basic.type == "quit") {
|
2022-04-24 14:52:13 +08:00
|
|
|
Methods::Quit quit;
|
|
|
|
Methods::fromJson(jsonArray, quit);
|
2022-03-30 17:56:27 +08:00
|
|
|
server.close(socket);
|
|
|
|
std::cout << "client quit" << std::endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (basic.type == "registe") {
|
2022-04-24 14:52:13 +08:00
|
|
|
Methods::Registe registe;
|
|
|
|
Methods::fromJson(jsonArray, registe);
|
2022-03-30 17:56:27 +08:00
|
|
|
Methods::Registe result;
|
|
|
|
result.state = false;
|
2022-04-24 14:52:13 +08:00
|
|
|
// std::lock_guard<std::mutex> lock(task_mutex);
|
2022-03-30 17:56:27 +08:00
|
|
|
for (auto it = tasks.begin(); it != tasks.end(); ++it) {
|
|
|
|
result.state = true;
|
2022-04-24 14:52:13 +08:00
|
|
|
result.hash = QString::fromStdString(it->first);
|
2022-03-30 17:56:27 +08:00
|
|
|
}
|
2022-04-24 14:52:13 +08:00
|
|
|
Methods::toJson(tmpArray, result);
|
|
|
|
write(socket, tmpArray.toStdString());
|
2022-03-30 17:56:27 +08:00
|
|
|
break;
|
|
|
|
}
|
2022-04-24 14:52:13 +08:00
|
|
|
write(socket, jsonArray.toStdString());
|
2022-03-30 17:56:27 +08:00
|
|
|
} 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));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-05-15 12:10:42 +08:00
|
|
|
ApplicationManager::ApplicationManager(QObject *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, dd_ptr(new ApplicationManagerPrivate(this))
|
|
|
|
, startManager(new StartManager(this))
|
|
|
|
{
|
|
|
|
connect(startManager, &StartManager::autostartChanged, this, &ApplicationManager::AutostartChanged);
|
|
|
|
}
|
2022-03-30 17:56:27 +08:00
|
|
|
|
|
|
|
ApplicationManager::~ApplicationManager() {}
|
|
|
|
|
|
|
|
void ApplicationManager::addApplication(const QList<QSharedPointer<Application>> &list)
|
|
|
|
{
|
|
|
|
Q_D(ApplicationManager);
|
|
|
|
|
|
|
|
d->applications = list;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDBusObjectPath ApplicationManager::GetInformation(const QString &id)
|
|
|
|
{
|
|
|
|
Q_D(ApplicationManager);
|
|
|
|
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!checkDMsgUid())
|
|
|
|
return {};
|
|
|
|
|
2022-03-30 17:56:27 +08:00
|
|
|
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);
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!checkDMsgUid())
|
|
|
|
return {};
|
2022-03-30 17:56:27 +08:00
|
|
|
|
|
|
|
for (const auto &app : d->applications) {
|
|
|
|
if (app->id() == id) {
|
|
|
|
return app->instances();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
QDBusObjectPath ApplicationManager::Run(const QString &id)
|
|
|
|
{
|
|
|
|
Q_D(ApplicationManager);
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!checkDMsgUid())
|
|
|
|
return {};
|
2022-03-30 17:56:27 +08:00
|
|
|
|
|
|
|
// 创建一个实例
|
|
|
|
for (const QSharedPointer<Application> &app : d->applications) {
|
|
|
|
if (app->id() == id) {
|
|
|
|
// 创建任务所需的数据,并记录到任务队列,等待 loader 消耗
|
2022-04-24 14:52:13 +08:00
|
|
|
QSharedPointer<ApplicationInstance> instance{app->createInstance()};
|
|
|
|
const std::string hash{instance->hash().toStdString()};
|
2022-03-30 17:56:27 +08:00
|
|
|
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 {};
|
|
|
|
}
|
|
|
|
|
2022-05-15 12:10:42 +08:00
|
|
|
bool ApplicationManager::AddAutostart(QString fileName)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return startManager->addAutostart(fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ApplicationManager::RemoveAutostart(QString fileName)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return startManager->removeAutostart(fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList ApplicationManager::AutostartList()
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return {};
|
|
|
|
|
|
|
|
return startManager->autostartList();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString ApplicationManager::DumpMemRecord()
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return {};
|
|
|
|
|
|
|
|
return startManager->dumpMemRecord();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ApplicationManager::IsAutostart(QString fileName)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return startManager->isAutostart(fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ApplicationManager::IsMemSufficient()
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return startManager->isMemSufficient();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationManager::LaunchApp(QString desktopFile, uint32_t timestamp, QStringList files)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
startManager->launchApp(desktopFile, timestamp, files);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationManager::LaunchAppAction(QString desktopFile, QString action, uint32_t timestamp)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
startManager->launchAppAction(desktopFile, action, timestamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationManager::LaunchAppWithOptions(QString desktopFile, uint32_t timestamp, QStringList files, QMap<QString, QString> options)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
startManager->launchAppWithOptions(desktopFile, timestamp, files, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationManager::RunCommand(QString exe, QStringList args)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
startManager->runCommand(exe, args);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationManager::RunCommandWithOptions(QString exe, QStringList args, QMap<QString, QString> options)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
startManager->runCommandWithOptions(exe, args, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApplicationManager::TryAgain(bool launch)
|
|
|
|
{
|
|
|
|
if (!checkDMsgUid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
startManager->tryAgain(launch);
|
|
|
|
}
|
|
|
|
|
2022-03-30 17:56:27 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-05-15 12:10:42 +08:00
|
|
|
bool ApplicationManager::checkDMsgUid()
|
|
|
|
{
|
|
|
|
QDBusReply<uint> reply = connection().interface()->serviceUid(message().service());
|
|
|
|
return reply.isValid() && (reply.value() == getuid());
|
|
|
|
}
|
|
|
|
|
2022-03-30 17:56:27 +08:00
|
|
|
#include "application_manager.moc"
|