mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
waydroid: Implement reset action
This commit is contained in:
parent
b5f1cb2eea
commit
8210205780
7 changed files with 169 additions and 3 deletions
|
|
@ -9,6 +9,7 @@ target_link_libraries(waydroidintegrationplugin PRIVATE
|
|||
Qt::Qml
|
||||
Qt::Quick
|
||||
KF6::AuthCore
|
||||
KF6::ConfigCore
|
||||
KF6::I18n
|
||||
QCoro::Core
|
||||
QCoro::Qml
|
||||
|
|
|
|||
|
|
@ -104,3 +104,10 @@ Description[zh_CN]=允许获取 Waydroid 容器的 Android ID 以激活谷歌服
|
|||
Policy=yes
|
||||
PolicyInactive=yes
|
||||
Persistence=session
|
||||
|
||||
[org.kde.plasma.mobileshell.waydroidhelper.reset]
|
||||
Name=Reset Waydroid
|
||||
Description=Allow delete waydroid folder
|
||||
Policy=yes
|
||||
PolicyInactive=yes
|
||||
Persistence=session
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <KAuth/HelperSupport>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QLoggingCategory>
|
||||
|
|
@ -20,6 +21,8 @@
|
|||
using namespace Qt::StringLiterals;
|
||||
|
||||
#define WAYDROID_COMMAND "waydroid"
|
||||
#define WAYDROID_FOLDER "/var/lib/waydroid"
|
||||
#define WAYDROID_USER_FOLDER "/.local/share/waydroid/"
|
||||
|
||||
// Extract current downloaded size, total_size and speed.
|
||||
// Example of log: "[Downloading] 62.19 MB/1197.24 MB 96740.75 kbps(approx.)"
|
||||
|
|
@ -31,6 +34,10 @@ class WaydroidHelper : public QObject
|
|||
public Q_SLOTS:
|
||||
KAuth::ActionReply initialize(const QVariantMap &args);
|
||||
KAuth::ActionReply getandroidid(const QVariantMap &args);
|
||||
KAuth::ActionReply reset(const QVariantMap &args);
|
||||
|
||||
private:
|
||||
bool removeDir(const QString dirPath);
|
||||
};
|
||||
|
||||
KAuth::ActionReply WaydroidHelper::initialize(const QVariantMap &args)
|
||||
|
|
@ -121,6 +128,34 @@ KAuth::ActionReply WaydroidHelper::getandroidid(const QVariantMap &args)
|
|||
}
|
||||
}
|
||||
|
||||
KAuth::ActionReply WaydroidHelper::reset(const QVariantMap &args)
|
||||
{
|
||||
const QString homeDir = args.value("homeDir"_L1).toString();
|
||||
|
||||
if (!removeDir(WAYDROID_FOLDER)) {
|
||||
qCWarning(WAYDROIDHELPER) << "Failed to remove Waydroid directory";
|
||||
return KAuth::ActionReply::HelperErrorReply();
|
||||
}
|
||||
|
||||
if (!removeDir(homeDir % WAYDROID_USER_FOLDER)) {
|
||||
qCWarning(WAYDROIDHELPER) << "Failed to remove user Waydroid directory";
|
||||
return KAuth::ActionReply::HelperErrorReply();
|
||||
}
|
||||
|
||||
return KAuth::ActionReply::SuccessReply();
|
||||
}
|
||||
|
||||
bool WaydroidHelper::removeDir(const QString dirPath)
|
||||
{
|
||||
qCWarning(WAYDROIDHELPER) << "Removing " << dirPath;
|
||||
QDir qDir(dirPath);
|
||||
if (!qDir.exists()) {
|
||||
return true; // Ignore if directory not exists
|
||||
}
|
||||
|
||||
return qDir.removeRecursively();
|
||||
}
|
||||
|
||||
KAUTH_HELPER_MAIN("org.kde.plasma.mobileshell.waydroidhelper", WaydroidHelper)
|
||||
|
||||
#include "waydroidhelper.moc"
|
||||
#include "waydroidhelper.moc"
|
||||
|
|
|
|||
|
|
@ -15,12 +15,16 @@
|
|||
#include <QGuiApplication>
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QStandardPaths>
|
||||
#include <QTimer>
|
||||
#include <QtLogging>
|
||||
|
||||
#include <KAuth/Action>
|
||||
#include <KAuth/ExecuteJob>
|
||||
#include <KConfigGroup>
|
||||
#include <KDesktopFile>
|
||||
#include <KLocalizedString>
|
||||
#include <KSandbox>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
|
|
@ -328,6 +332,50 @@ void WaydroidState::copyToClipboard(const QString text)
|
|||
qGuiApp->clipboard()->setText(text);
|
||||
}
|
||||
|
||||
QCoro::QmlTask WaydroidState::resetWaydroidQml()
|
||||
{
|
||||
return resetWaydroid();
|
||||
}
|
||||
|
||||
QCoro::Task<void> WaydroidState::resetWaydroid()
|
||||
{
|
||||
if (m_status != Initialized || m_sessionStatus == SessionStarting) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
m_status = Resetting;
|
||||
Q_EMIT statusChanged();
|
||||
|
||||
if (m_sessionStatus == SessionRunning) {
|
||||
co_await stopSession();
|
||||
}
|
||||
|
||||
const QVariantMap args = {{u"homeDir"_s, QDir::homePath()}};
|
||||
|
||||
KAuth::Action writeAction(u"org.kde.plasma.mobileshell.waydroidhelper.reset"_s);
|
||||
writeAction.setHelperId(u"org.kde.plasma.mobileshell.waydroidhelper"_s);
|
||||
writeAction.setArguments(args);
|
||||
|
||||
KAuth::ExecuteJob *job = writeAction.execute();
|
||||
job->start();
|
||||
|
||||
co_await qCoro(job, &KAuth::ExecuteJob::finished);
|
||||
|
||||
removeWaydroidApplications();
|
||||
|
||||
if (job->error() == 0) {
|
||||
m_status = NotInitialized;
|
||||
} else {
|
||||
m_errorTitle = i18n("Failed to reset Waydroid.");
|
||||
Q_EMIT errorTitleChanged();
|
||||
|
||||
m_status = Initialized;
|
||||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "KAuth returned an error code:" << job->error() << " message: " << job->errorString();
|
||||
}
|
||||
|
||||
Q_EMIT statusChanged();
|
||||
}
|
||||
|
||||
WaydroidState::Status WaydroidState::status() const
|
||||
{
|
||||
return m_status;
|
||||
|
|
@ -498,3 +546,52 @@ void WaydroidState::checkSessionStarting(const int limit, const int tried)
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
QString WaydroidState::desktopFileDirectory()
|
||||
{
|
||||
auto dir = []() -> QString {
|
||||
if (KSandbox::isFlatpak()) {
|
||||
return qEnvironmentVariable("HOME") % u"/.local/share/applications/";
|
||||
}
|
||||
return QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
|
||||
}();
|
||||
|
||||
QDir(dir).mkpath(QStringLiteral("."));
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
bool WaydroidState::removeWaydroidApplications()
|
||||
{
|
||||
const QDir appsDir(desktopFileDirectory());
|
||||
const auto fileInfos = appsDir.entryInfoList(QDir::Files);
|
||||
if (fileInfos.length() < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool allFileRemoved = true;
|
||||
|
||||
for (const auto &fileInfo : fileInfos) {
|
||||
if (fileInfo.fileName().contains(QStringView(u".desktop"))) {
|
||||
const KDesktopFile desktopFile(fileInfo.filePath());
|
||||
const KConfigGroup configGroup = desktopFile.desktopGroup();
|
||||
|
||||
if (!configGroup.hasKey(u"Categories"_s)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto categories = configGroup.readEntry(u"Categories"_s);
|
||||
if (!categories.contains(u"X-WayDroid-App"_s)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QFile file(fileInfo.filePath());
|
||||
if (!file.remove()) {
|
||||
allFileRemoved &= false;
|
||||
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "Failed to remove: " << desktopFile.name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allFileRemoved;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ public:
|
|||
NotSupported = 0,
|
||||
NotInitialized,
|
||||
Initializing,
|
||||
Initialized
|
||||
Initialized,
|
||||
Resetting
|
||||
};
|
||||
Q_ENUM(Status)
|
||||
|
||||
|
|
@ -103,7 +104,9 @@ public:
|
|||
QCoro::Task<void> startSession();
|
||||
Q_INVOKABLE QCoro::QmlTask stopSessionQml();
|
||||
QCoro::Task<void> stopSession();
|
||||
|
||||
Q_INVOKABLE QCoro::QmlTask resetWaydroidQml();
|
||||
QCoro::Task<void> resetWaydroid();
|
||||
|
||||
Q_INVOKABLE void copyToClipboard(const QString text);
|
||||
|
||||
Status status() const;
|
||||
|
|
@ -202,4 +205,7 @@ private:
|
|||
* https://github.com/waydroid/waydroid/blob/2c41162d8bfef5bf83333a6ce4834af0c3c2b535/tools/actions/session_manager.py#L31
|
||||
*/
|
||||
void checkSessionStarting(const int limit, const int tried = 0);
|
||||
|
||||
QString desktopFileDirectory();
|
||||
bool removeWaydroidApplications();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,6 +51,21 @@ ColumnLayout {
|
|||
text: i18n("Installed applications")
|
||||
onClicked: kcm.push("WaydroidApplicationsPage.qml")
|
||||
}
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
text: i18n("Reset waydroid")
|
||||
onClicked: confirmDialog.open()
|
||||
}
|
||||
|
||||
Kirigami.PromptDialog {
|
||||
id: confirmDialog
|
||||
title: i18nc("@title:window", "Confirm Waydroid Reset")
|
||||
subtitle: i18n("Are you sure you want to reset Waydroid ? This is a destructive action, and will wipe all user data.")
|
||||
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
|
||||
|
||||
onAccepted: AIP.WaydroidState.resetWaydroidQml()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Some informations as IP address can take time to be set by Waydroid
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ KCM.SimpleKCM {
|
|||
}
|
||||
}
|
||||
|
||||
WaydroidLoader {
|
||||
visible: AIP.WaydroidState.errorTitle === "" && AIP.WaydroidState.status == AIP.WaydroidState.Resetting
|
||||
text: i18n("Waydroid is resetting.\nIt can take a few seconds.")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: AIP.WaydroidState.errorTitle === "" && AIP.WaydroidState.status == AIP.WaydroidState.Initialized && AIP.WaydroidState.sessionStatus == AIP.WaydroidState.SessionStopped
|
||||
anchors.centerIn: parent
|
||||
|
|
|
|||
Loading…
Reference in a new issue