Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ Files: *.qrc
Copyright: None
License: CC0-1.0

# polkit policy
Files: polkit-1/actions/*.policy
Copyright: None
License: CC0-1.0

# translations
Files: translations/*.ts
Copyright: UnionTech Software Technology Co., Ltd.
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,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 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)
85 changes: 40 additions & 45 deletions dbus/launcher1compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,31 +92,26 @@ void Launcher1Compat::uninstallPackageKitPackage(const QString & pkgDisplayName,
});
}

void Launcher1Compat::onHandleLastoreUninstall(const QDBusMessage &message)
void Launcher1Compat::uninstallPackageByScript(const QString & pkgDisplayName, const QString & packageDesktopFilePath)
{
QList<QVariant> arguments = message.arguments();

if (3 != arguments.count())
return;
// call `/usr/libexec/dde-appwiz-uninstaller.sh <packageDesktopFilePath>` and check the return code.
qDebug() << "Calling dde-appwiz-uninstaller.sh to uninstall" << pkgDisplayName << packageDesktopFilePath << "via script";
QProcess process;
process.start("/usr/libexec/dde-appwiz-uninstaller.sh", QStringList{packageDesktopFilePath});
process.waitForFinished();

QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
const QStringList keys = changedProps.keys();
QString standardOutput = process.readAllStandardOutput();
QString standardError = process.readAllStandardError();
qDebug() << "stdout:" << standardOutput;
qDebug() << "stderr:" << standardError;

QString status;
if (keys.contains("Status")) {
status = changedProps["Status"].toString();
}

#ifdef QT_DEBUG
qInfo() << "changedProps: " << changedProps << ", status: " << status;
#endif
if (status == "succeed" || status == "end") {
if (process.exitCode() != 0) {
sendNotification(pkgDisplayName, false);
} else {
sendNotification(pkgDisplayName, true);
QFileInfo fi(m_desktopFilePath);
// FIXME: THIS IS NOT DESKTOP ID
postUninstallCleanUp(fi.fileName());
emit UninstallSuccess(m_desktopFilePath);
} else if (status == "failed") {
emit UninstallFailed(m_desktopFilePath, QString());
}
}

Expand All @@ -129,19 +124,13 @@ void Launcher1Compat::RequestUninstall(const QString & desktop, bool unused)
// Thus this checking will be no longer necessary. We still need this check since we are
// still using lastore to uninstall package if it exists.
QString servicePid = QString::number(QDBusConnection::sessionBus().interface()->servicePid(message().service()));
QString procfs = QLatin1String("/proc/%1/cmdline").arg(servicePid);
QFile procfile(procfs);
if (!procfile.exists() || !procfile.open(QFile::ReadOnly)) {
qDebug() << "Cannot verify caller";
return;
}
QString cmdline(procfile.readAll());
procfile.close();
qDebug() << cmdline;
QString procfs = QLatin1String("/proc/%1/exe").arg(servicePid);
QFileInfo procfile(procfs);
QString realPath = procfile.canonicalFilePath();
#ifndef QT_DEBUG
if (!QString(cmdline).endsWith(BINDIR_PREFIX + QStringLiteral("dde-shell")) &&
!QString(cmdline).endsWith(BINDIR_PREFIX + QStringLiteral("dde-launchpad"))) {
qWarning() << cmdline << " has no right to uninstall " << desktop;
if (!realPath.endsWith(BINDIR_PREFIX + QStringLiteral("dde-shell")) &&
!realPath.endsWith(BINDIR_PREFIX + QStringLiteral("dde-launchpad"))) {
qWarning() << realPath << " has no right to uninstall " << desktop;
return;
}
#endif // !QT_DEBUG
Expand Down Expand Up @@ -177,22 +166,28 @@ void Launcher1Compat::RequestUninstall(const QString & desktop, bool unused)
emit UninstallSuccess(desktopFilePath);
sendNotification(desktopEntry.name(), true);
}
// TODO: check if it's a flatpak or snap bundle and do the uninstallation?
} else {
m_packageDisplayName = desktopEntry.name();
// TODO: check if it's a flatpak or snap bundle and do the uninstallation?

// Uninstall regular package via PackageKit or deepin-store
PKUtils::searchFiles(desktopFilePath, PackageKit::Transaction::FilterInstalled).then([this](const PKUtils::PkPackages packages) {
if (packages.size() == 0) {
qDebug() << "No matching package found";
return;
}
for (const PKUtils::PkPackage & pkg : packages) {
QString pkgId;
std::tie(std::ignore, pkgId, std::ignore) = pkg;
uninstallPackageKitPackage(m_packageDisplayName, pkgId);
}
}, [](const std::exception & e){
PKUtils::PkError::printException(e);
});
if (QFile::exists("/run/ostree-booted")) {
uninstallPackageByScript(m_packageDisplayName, desktopFilePath);
} else {
// call PackageKit to uninstall
PKUtils::searchFiles(desktopFilePath, PackageKit::Transaction::FilterInstalled).then([this](const PKUtils::PkPackages packages) {
if (packages.size() == 0) {
qDebug() << "No matching package found";
return;
}
for (const PKUtils::PkPackage & pkg : packages) {
QString pkgId;
std::tie(std::ignore, pkgId, std::ignore) = pkg;
uninstallPackageKitPackage(m_packageDisplayName, pkgId);
}
}, [](const std::exception & e){
PKUtils::PkError::printException(e);
});
}
}
}
2 changes: 1 addition & 1 deletion dbus/launcher1compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Launcher1Compat : public QObject, protected QDBusContext
explicit Launcher1Compat(QObject *parent = nullptr);

void uninstallPackageKitPackage(const QString & pkgDisplayName, const QString & pkPackageId);
void onHandleLastoreUninstall(const QDBusMessage &message);
void uninstallPackageByScript(const QString & pkgDisplayName, const QString & packageDesktopFilePath);

Launcher1Adaptor * m_daemonLauncher1Adapter;

Expand Down
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
dde-application-wizard (0.1.11) unstable; urgency=medium

* Fix uninstall on ostree-booted environment

-- Wang Zichong <wangzichong@deepin.org> Tue, 14 Jan 2025 21:00:00 +0800

dde-application-wizard (0.1.10) unstable; urgency=medium

* Revert "feat: Adapt to uninstall of applications patched by deepin-deb-fix"
Expand Down
15 changes: 15 additions & 0 deletions polkit-1/actions/org.deepin.dde.appwiz.uninstall.policy
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<action id="org.deepin.dde.appwiz.uninstall">
<description>Uninstall a package associated with a .desktop file</description>
<message>Authentication is required to uninstall a package.</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-uninstaller.sh</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>
36 changes: 36 additions & 0 deletions scripts/dde-appwiz-uninstaller.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash

# SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: GPL-3.0-or-later

# Check if the path to the .desktop file is provided
if [ -z "$1" ]; then
echo "Usage: $0 <path_to_desktop_file>"
exit 1
fi

DESKTOP_FILE_PATH="$1"

# Check if the .desktop file exists
if [ ! -f "$DESKTOP_FILE_PATH" ]; then
echo "Error: File '$DESKTOP_FILE_PATH' does not exist."
exit 1
fi

# Use dpkg to find the associated package name
PACKAGE_NAME=$(dpkg -S "$DESKTOP_FILE_PATH" 2>/dev/null | awk -F: '{print $1}' | head -n 1)

# Check if a package was found
if [ -z "$PACKAGE_NAME" ]; then
echo "Error: No package found for the file '$DESKTOP_FILE_PATH'."
exit 1
fi

# Use pkexec to uninstall the package
if pkexec apt purge -y "$PACKAGE_NAME"; then
echo "Package '$PACKAGE_NAME' has been successfully uninstalled."
else
echo "Error: Failed to uninstall the package '$PACKAGE_NAME'."
exit 1
fi