Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
# SPDX-FileCopyrightText: 2023-2026 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: CC0-1.0

Expand Down Expand Up @@ -77,6 +77,7 @@ target_link_libraries(${BIN_NAME} PRIVATE
install(TARGETS ${BIN_NAME} DESTINATION ${CMAKE_INSTALL_LIBEXECDIR})
install(FILES scripts/dde-appwiz-uninstaller.sh DESTINATION ${CMAKE_INSTALL_LIBEXECDIR})
install(FILES scripts/dde-appwiz-linglong-uninstaller.sh DESTINATION ${CMAKE_INSTALL_LIBEXECDIR})
install(FILES scripts/dde-appwiz-apm-uninstaller.sh DESTINATION ${CMAKE_INSTALL_LIBEXECDIR})
install(FILES polkit-1/actions/org.deepin.dde.appwiz.uninstall.policy DESTINATION ${CMAKE_INSTALL_DATADIR}/polkit-1/actions)
install(FILES polkit-1/rules.d/org.deepin.dde.application-wizard.rules DESTINATION ${CMAKE_INSTALL_DATADIR}/polkit-1/rules.d)
install(FILES ${TRANSLATED_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/dde-application-wizard/translations)
68 changes: 61 additions & 7 deletions dbus/launcher1compat.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2023-2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -88,7 +88,13 @@ bool uninstallLinglongBundle(const DDesktopEntry & entry)
QProcess process;
qDebug() << "Uninstalling Linglong bundle" << appId << "via script";
process.start("pkexec", QStringList{"/usr/libexec/dde-appwiz-linglong-uninstaller.sh", appId});
process.waitForFinished();

bool finished = process.waitForFinished(300000); // 5 minutes timeout
if (!finished) {
qDebug() << "Process timed out or failed to finish";
process.kill();
return false;
}

return process.exitCode() == 0;
}
Expand Down Expand Up @@ -146,7 +152,15 @@ void Launcher1Compat::uninstallDCMPackage(const QString & pkgDisplayName, const
args.prepend("env");

process.start("pkexec", args);
process.waitForFinished();

bool finished = process.waitForFinished(300000); // 5 minutes timeout
if (!finished) {
qDebug() << "Process timed out or failed to finish";
process.kill();
sendNotification(pkgDisplayName, false, m_base64Icon);
return;
}

if (process.exitCode() != 0) {
sendNotification(pkgDisplayName, false, m_base64Icon);
} else {
Expand All @@ -163,7 +177,14 @@ void Launcher1Compat::uninstallPackageByScript(const QString & pkgDisplayName, c
qDebug() << "Calling dde-appwiz-uninstaller.sh to uninstall" << pkgDisplayName << packageDesktopFilePath << "via script";
QProcess process;
process.start("pkexec", QStringList{"/usr/libexec/dde-appwiz-uninstaller.sh", packageDesktopFilePath});
process.waitForFinished();

bool finished = process.waitForFinished(300000); // 5 minutes timeout
if (!finished) {
qDebug() << "Process timed out or failed to finish";
process.kill();
sendNotification(pkgDisplayName, false, m_base64Icon);
return;
}

QString standardOutput = process.readAllStandardOutput();
QString standardError = process.readAllStandardError();
Expand All @@ -174,12 +195,42 @@ void Launcher1Compat::uninstallPackageByScript(const QString & pkgDisplayName, c
sendNotification(pkgDisplayName, false, m_base64Icon);
} else {
sendNotification(pkgDisplayName, true, m_base64Icon);
QFileInfo fi(m_desktopFilePath);
QFileInfo fi(packageDesktopFilePath);
// FIXME: THIS IS NOT DESKTOP ID
postUninstallCleanUp(fi.fileName(), PackageType::Deb);
}
}

void Launcher1Compat::uninstallAPMPackage(const QString & pkgDisplayName, const QString & packageDesktopFilePath)
{
// call `/usr/libexec/dde-appwiz-apm-uninstaller.sh <packageDesktopFilePath>` and check the return code.
qDebug() << "Calling dde-appwiz-apm-uninstaller.sh to uninstall" << pkgDisplayName << packageDesktopFilePath << "via script";
QProcess process;
process.start("pkexec", QStringList{"/usr/libexec/dde-appwiz-apm-uninstaller.sh", packageDesktopFilePath});

bool finished = process.waitForFinished(300000); // 5 minutes timeout
if (!finished) {
qDebug() << "Process timed out or failed to finish";
process.kill();
sendNotification(pkgDisplayName, false, m_base64Icon);
return;
}

QString standardOutput = process.readAllStandardOutput();
QString standardError = process.readAllStandardError();
qDebug() << "stdout:" << standardOutput;
qDebug() << "stderr:" << standardError;

if (process.exitCode() != 0) {
sendNotification(pkgDisplayName, false, m_base64Icon);
} else {
sendNotification(pkgDisplayName, true, m_base64Icon);
QFileInfo fi(packageDesktopFilePath);
// FIXME: THIS IS NOT DESKTOP ID
postUninstallCleanUp(fi.fileName(), PackageType::APM);
}
}

// the 1st argument is the full path of a desktop file.
void Launcher1Compat::RequestUninstall(const QString & desktop, bool skipPreinstallHook)
{
Expand Down Expand Up @@ -259,6 +310,8 @@ void Launcher1Compat::RequestUninstall(const QString & desktop, bool skipPreinst
}
}

m_packageDisplayName = desktopEntry.ddeDisplayName();

// Check and do uninstallation
if (desktopFilePath.contains("/persistent/linglong") || desktopFilePath.contains("/var/lib/linglong")) {
// Uninstall Linglong Bundle
Expand All @@ -274,10 +327,11 @@ void Launcher1Compat::RequestUninstall(const QString & desktop, bool skipPreinst
emit UninstallSuccess(desktopFilePath);
sendNotification(desktopEntry.ddeDisplayName(), true, m_base64Icon);
}
} else if (!desktopEntry.stringValue("X-APM-APPID").isEmpty()) {
// Uninstall APM Package
uninstallAPMPackage(m_packageDisplayName, desktopFilePath);
// TODO: check if it's a flatpak or snap bundle and do the uninstallation?
} else {
m_packageDisplayName = desktopEntry.ddeDisplayName();

const QString compatibleDesktopJsonPath("/var/lib/deepin-compatible/compatibleDesktop.json");
if (QFile::exists(compatibleDesktopJsonPath)) {
qDebug() << "Found compatibleDesktop.json, checking if" << m_packageDisplayName << "is a compatible-mode application.";
Expand Down
6 changes: 4 additions & 2 deletions dbus/launcher1compat.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2023-2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand All @@ -12,7 +12,8 @@ enum class PackageType {
Linglong, // 玲珑包
Flatpak, // Flatpak包
Deb, // deb包/PackageKit包
DCM // DCM兼容模式包
DCM, // DCM兼容模式包
APM // APM包
};

class Launcher1Adaptor;
Expand Down Expand Up @@ -41,6 +42,7 @@ class Launcher1Compat : public QObject, protected QDBusContext
void uninstallPackageKitPackage(const QString & pkgDisplayName, const QString & pkPackageId);
void uninstallDCMPackage(const QString & pkgDisplayName, const QString & uninstallCmd);
void uninstallPackageByScript(const QString & pkgDisplayName, const QString & packageDesktopFilePath);
void uninstallAPMPackage(const QString & pkgDisplayName, const QString & packageDesktopFilePath);

Launcher1Adaptor * m_daemonLauncher1Adapter;

Expand Down
11 changes: 11 additions & 0 deletions polkit-1/actions/org.deepin.dde.appwiz.uninstall.policy
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,15 @@
<annotate key="org.freedesktop.policykit.exec.path">/usr/libexec/dde-appwiz-linglong-uninstaller.sh</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
<action id="org.deepin.dde.appwiz.uninstall.apm">
<description>Uninstall a APM application</description>
<message>Authentication is required to uninstall a APM bundle application.</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/libexec/dde-appwiz-apm-uninstaller.sh</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>
1 change: 1 addition & 0 deletions polkit-1/rules.d/org.deepin.dde.application-wizard.rules
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

polkit.addRule(function(action, subject) {
if ((action.id == "org.deepin.dde.appwiz.uninstall" ||
action.id == "org.deepin.dde.appwiz.uninstall.apm" ||
action.id == "org.deepin.dde.appwiz.uninstall.linglong") &&
subject.active == true && subject.local == true &&
subject.isInGroup("sudo")) {
Expand Down
45 changes: 45 additions & 0 deletions scripts/dde-appwiz-apm-uninstaller.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

# SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: GPL-3.0-or-later
# 检查是否提供了文件参数
if [ $# -eq 0 ]; then
echo "错误: 请提供一个文件作为参数"
echo "用法: $0 <文件路径>"
exit 1
fi

FILE="$1"

# 检查文件是否存在
if [ ! -f "$FILE" ]; then
echo "错误: 文件 '$FILE' 不存在"
exit 1
fi

# 检查文件中是否包含 X-APM-APPID=
if ! grep -q "X-APM-APPID=" "$FILE"; then
echo "错误: 文件中未找到 'X-APM-APPID=' 内容"
exit 1
fi

# 提取 X-APM-APPID= 的值
APPID=$(grep -o "X-APM-APPID=[^ ]*" "$FILE" | head -1 | cut -d'=' -f2)

# 检查是否成功提取到值
if [ -z "$APPID" ]; then
echo "错误: 无法提取 X-APM-APPID 的值"
exit 1
fi

echo "找到 APM ID: $APPID"

# 如果不是root用户,则使用pkexec
if [ "$EUID" -ne 0 ]; then
echo "当前不是root用户,使用 pkexec 提升权限..."
exec pkexec apm autoremove "$APPID" -y
else
echo "以root用户身份执行命令..."
exec apm autoremove "$APPID" -y
fi
Loading