feat: AM loader实现启动freedesktop类型应用
AM loader可以正常启动freedesktop类型应用了 Log: AM loader实现启动freedesktop类型应用 Task: https://pms.uniontech.com/task-view-108539.html Influence: AM loader Change-Id: If56835e638ca38ed53bcc7a0dddeca47e05cc8ba
This commit is contained in:
parent
5997b3a2a1
commit
38cf02a51f
@ -1,6 +1,6 @@
|
||||
set(SYSTEMD_FILES
|
||||
org.deskspec.application.instance@.service
|
||||
org.deskspec.application.manager.service
|
||||
org.desktopspec.application.instance@.service
|
||||
org.desktopspec.application.manager.service
|
||||
)
|
||||
|
||||
install(FILES ${SYSTEMD_FILES} DESTINATION lib/systemd/user/)
|
||||
|
@ -3,6 +3,6 @@ Description=Deepin Application Manager service
|
||||
|
||||
[Service]
|
||||
Type=DBus
|
||||
BusName=org.deskspec.ApplicationManager
|
||||
ExecStart=/usr/bin/deepin-application-service
|
||||
BusName=org.desktopspec.ApplicationManager
|
||||
ExecStart=/usr/bin/deepin-application-manager
|
||||
Slice=services.slice
|
@ -18,6 +18,10 @@
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <QString>
|
||||
#include <QProcess>
|
||||
#include <QDir>
|
||||
|
||||
#include "../modules/methods/basic.h"
|
||||
#include "../modules/methods/instance.hpp"
|
||||
#include "../modules/methods/quit.hpp"
|
||||
@ -40,25 +44,16 @@ struct App {
|
||||
std::string id;
|
||||
};
|
||||
|
||||
static App parseApp(const std::string& app)
|
||||
static App parseApp(const QString& app)
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
std::istringstream stream(app);
|
||||
std::string s;
|
||||
while (getline(stream, s, '/')) {
|
||||
if (s.empty()) {
|
||||
continue;
|
||||
}
|
||||
strings.push_back(s);
|
||||
}
|
||||
|
||||
QStringList values = app.split('/', QString::SkipEmptyParts);
|
||||
qInfo() << "app:" << app << ", values size:" << values.size();
|
||||
App result;
|
||||
if (strings.size() == 3) {
|
||||
result.prefix = strings[0];
|
||||
result.type = strings[1];
|
||||
result.id = strings[2];
|
||||
if (values.size() == 3) {
|
||||
result.prefix = values.at(0).toStdString();
|
||||
result.type = values.at(1).toStdString();
|
||||
result.id = values.at(2).toStdString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -77,12 +72,51 @@ void sig_handler(int num)
|
||||
}
|
||||
}
|
||||
|
||||
int runLinglong(void* _arg)
|
||||
// TODO: startManager合并流程?
|
||||
int childFreedesktop(Methods::Task* task, std::string path)
|
||||
{
|
||||
return 0;
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL);
|
||||
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||
prctl(PR_SET_PDEATHSIG, SIGHUP);
|
||||
|
||||
DesktopDeconstruction dd(path);
|
||||
dd.beginGroup("Desktop Entry");
|
||||
std::cout << dd.value<std::string>("Exec") << std::endl;
|
||||
|
||||
QStringList envs;
|
||||
for (auto it = task->environments.begin(); it != task->environments.end(); ++it) {
|
||||
envs.append(it.key() + "=" + it.value());
|
||||
}
|
||||
|
||||
int child(Methods::Task* task, std::string path)
|
||||
QStringList exeArgs;
|
||||
exeArgs << QString::fromStdString(dd.value<std::string>("Exec")).split(" ");
|
||||
|
||||
QString exec = exeArgs[0];
|
||||
exeArgs.removeAt(0);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
// 子进程
|
||||
QProcess process;
|
||||
qInfo() << "exec:" << exec;
|
||||
qInfo() << "exeArgs:" << exeArgs;
|
||||
process.setWorkingDirectory(QDir::homePath());
|
||||
process.setEnvironment(envs);
|
||||
process.start(exec, exeArgs);
|
||||
process.waitForFinished(-1);
|
||||
process.close();
|
||||
qInfo() << "process finish";
|
||||
exit(0);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
int childLinglong(Methods::Task* task, std::string path)
|
||||
{
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL);
|
||||
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||
@ -179,6 +213,12 @@ int child(Methods::Task* task, std::string path)
|
||||
return pid;
|
||||
}
|
||||
|
||||
int childAndroid(Methods::Task* task, std::string path)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DAM_TASK_HASH "DAM_TASK_HASH"
|
||||
#define DAM_TASK_TYPE "DAM_TASK_TYPE"
|
||||
|
||||
@ -228,19 +268,23 @@ int main(int argc, char* argv[])
|
||||
result = client.get(instanceArray);
|
||||
Methods::Task task;
|
||||
Methods::fromJson(result, task); // fromJson TODO 数据解析异常
|
||||
qWarning() << "[result] " << result;
|
||||
qInfo() << "[Task] " << result;
|
||||
|
||||
// 校验task内容
|
||||
App app = parseApp(task.runId.toStdString());
|
||||
App app = parseApp(task.runId);
|
||||
qInfo() << "[App] "
|
||||
<< "prefix:" << QString::fromStdString(app.prefix)
|
||||
<< "type:" << QString::fromStdString(app.type)
|
||||
<< "id:" << QString::fromStdString(app.id);
|
||||
if (task.id.isEmpty() || app.id.empty() || app.type.empty() || app.prefix.empty()) {
|
||||
std::cout << "get task error" << std::endl;
|
||||
return -4;
|
||||
}
|
||||
|
||||
std::string path{ "/usr/share/applications/" + app.id + ".desktop" };
|
||||
if (app.type == "user") {
|
||||
struct passwd* user = getpwuid(getuid());
|
||||
path = std::string(user->pw_dir) + "/.local/share/applications/" + app.id + ".desktop";
|
||||
if (app.prefix != "freedesktop"
|
||||
&& app.prefix != "linglong"
|
||||
&& app.prefix != "android") {
|
||||
qWarning() << "error app prefix :" << QString::fromStdString(app.type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_attr_t attr;
|
||||
@ -251,27 +295,39 @@ int main(int argc, char* argv[])
|
||||
|
||||
/* 先将SIGCHLD信号阻塞 保证在子进程结束前设置父进程的捕捉函数 */
|
||||
sigset_t nmask, omask;
|
||||
sigemptyset(&nmask);
|
||||
sigaddset(&nmask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
||||
// sigemptyset(&nmask);
|
||||
// sigaddset(&nmask, SIGCHLD);
|
||||
// sigprocmask(SIG_BLOCK, &nmask, &omask);
|
||||
|
||||
//char* stack = (char*) malloc(stack_size);
|
||||
//pid_t pid = clone(child, stack + stack_size, CLONE_NEWPID | SIGCHLD, static_cast<void*>(&task));
|
||||
pid_t pid = child(&task, path);
|
||||
pid_t pid = -1;
|
||||
if (app.prefix == "freedesktop") {
|
||||
pid = childFreedesktop(&task, task.filePath.toStdString());
|
||||
} else if (app.prefix == "linglong") {
|
||||
pid = childLinglong(&task, task.filePath.toStdString());
|
||||
} else if (app.prefix == "android") {
|
||||
pid = childAndroid(&task, task.filePath.toStdString());
|
||||
} else {
|
||||
qWarning() << "error app prefix:" << QString::fromStdString(app.prefix);
|
||||
}
|
||||
|
||||
// TODO: 启动线程,创建新的连接去接受服务器的消息
|
||||
|
||||
// TODO:信号处理有问题
|
||||
/* 设置捕捉函数 */
|
||||
struct sigaction sig;
|
||||
sig.sa_handler = sig_handler;
|
||||
sigemptyset(&sig.sa_mask);
|
||||
sig.sa_flags = 0;
|
||||
sigaction(SIGCHLD, &sig, NULL);
|
||||
// struct sigaction sig;
|
||||
// sig.sa_handler = sig_handler;
|
||||
// sigemptyset(&sig.sa_mask);
|
||||
// sig.sa_flags = 0;
|
||||
// sigaction(SIGCHLD, &sig, NULL);
|
||||
/* 然后再unblock */
|
||||
sigdelset(&omask, SIGCHLD);
|
||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
// sigdelset(&omask, SIGCHLD);
|
||||
// sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
|
||||
int exitCode;
|
||||
waitpid(pid, &exitCode, 0);
|
||||
qInfo() << "app exitCode:" << exitCode;
|
||||
|
||||
Methods::Quit quit;
|
||||
quit.code = exitCode;
|
||||
|
@ -18,6 +18,7 @@ namespace Methods
|
||||
QString runId;
|
||||
QString type{"task"};
|
||||
QString date;
|
||||
QString filePath;
|
||||
QList<QString> arguments;
|
||||
QMap<QString, QString> environments;
|
||||
};
|
||||
@ -36,7 +37,8 @@ namespace Methods
|
||||
QJsonObject obj = {
|
||||
{"type", task.type},
|
||||
{"id", task.id},
|
||||
{"run_id", task.runId},
|
||||
{"runId", task.runId},
|
||||
{"filePath", task.filePath},
|
||||
{"date", task.date},
|
||||
{"arguments", argArray},
|
||||
{"environments", QJsonObject::fromVariantMap(envsMap)}
|
||||
@ -51,26 +53,32 @@ namespace Methods
|
||||
qWarning() << "fromJson task failed";
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject obj = doc.object();
|
||||
if (!obj.contains("id") || !obj.contains("runId") || !obj.contains("date") \
|
||||
|| !obj.contains("arguments") || !obj.contains("environments")) {
|
||||
qWarning() << "id runId date arguments environments not exist in task array";
|
||||
return;
|
||||
if (obj.contains("id")) {
|
||||
task.id = obj.value("id").toString();
|
||||
}
|
||||
if (obj.contains("runId")) {
|
||||
task.runId = obj.value("runId").toString();
|
||||
}
|
||||
if (obj.contains("filePath")) {
|
||||
task.filePath = obj.value("filePath").toString();
|
||||
}
|
||||
if (obj.contains("date")) {
|
||||
task.date = obj.value("date").toString();
|
||||
}
|
||||
|
||||
task.id = obj.value("id").toString();
|
||||
task.runId = obj.value("runId").toString();
|
||||
task.date = obj.value("date").toString();
|
||||
if (obj.contains("arguments")) {
|
||||
for (auto arg : obj.value("arguments").toArray()) {
|
||||
task.arguments.append(arg.toString());
|
||||
}
|
||||
|
||||
}
|
||||
if (obj.contains("environments")) {
|
||||
QVariantMap envsMap = obj.value("environments").toObject().toVariantMap();
|
||||
for (auto it = envsMap.constBegin(); it != envsMap.constEnd(); ++it) {
|
||||
task.environments.insert(it.key(), it.value().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Methods
|
||||
|
||||
#endif /* B0B88BD6_CF1E_4E87_926A_E6DBE6B9B19C */
|
||||
|
@ -68,8 +68,9 @@ public:
|
||||
emit q_ptr->taskFinished(p->exitCode());
|
||||
}
|
||||
#else
|
||||
qInfo() << "app manager load service:" << QString("org.desktopspec.application.instance@%1.service").arg(m_id);
|
||||
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");
|
||||
QDBusReply<void> reply = systemd.call("StartUnit", QString("org.desktopspec.application.instance@%1.service").arg(m_id), "replace-irreversibly");
|
||||
if (!reply.isValid()) {
|
||||
qInfo() << reply.error();
|
||||
q_ptr->deleteLater();
|
||||
@ -82,7 +83,7 @@ public:
|
||||
#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");
|
||||
qInfo() << systemd.call("StopUnit", QString("org.desktopspec.application.instance@%1.service").arg(m_id), "replace-irreversibly");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -146,6 +147,7 @@ Methods::Task ApplicationInstance::taskInfo() const
|
||||
Methods::Task task;
|
||||
task.id = d->m_id;
|
||||
task.runId = d->application->id();
|
||||
task.filePath = d->application->filePath();
|
||||
task.date = QString::number(startuptime());
|
||||
task.arguments = m_files;
|
||||
|
||||
|
@ -90,8 +90,11 @@ void ApplicationManagerPrivate::recvClientData(int socket, const std::vector<cha
|
||||
result.state = false;
|
||||
// std::lock_guard<std::mutex> lock(task_mutex);
|
||||
for (auto it = tasks.begin(); it != tasks.end(); ++it) {
|
||||
if (registe.hash == QString::fromStdString(it->first)) {
|
||||
result.state = true;
|
||||
result.hash = QString::fromStdString(it->first);
|
||||
result.hash = registe.hash;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Methods::toJson(tmpArray, result);
|
||||
write(socket, tmpArray.toStdString());
|
||||
@ -199,6 +202,7 @@ QList<QDBusObjectPath> ApplicationManager::GetInstances(const QString &id)
|
||||
*/
|
||||
QDBusObjectPath ApplicationManager::Launch(const QString &id, QStringList files)
|
||||
{
|
||||
qInfo() << "Launch " << id;
|
||||
Q_D(ApplicationManager);
|
||||
if (!d->checkDMsgUid())
|
||||
return {};
|
||||
|
@ -90,6 +90,11 @@ int main(int argc, char *argv[])
|
||||
QDBusConnection::sessionBus().registerObject(app->path().path(), "org.desktopspec.Application", app.get());
|
||||
}
|
||||
|
||||
for (const QSharedPointer<Application> &app : apps) {
|
||||
qInfo() << "appId - " << app->id();
|
||||
qInfo() << "appFilePath - " << app->filePath();
|
||||
}
|
||||
|
||||
ApplicationManager::instance()->addApplication(apps);
|
||||
|
||||
ApplicationManager::instance()->launchAutostartApps();
|
||||
|
Loading…
Reference in New Issue
Block a user