waydroid: Use KAuth progressStep

This commit is contained in:
Florian RICHER 2025-07-26 19:32:26 +02:00
parent 4450031dee
commit a2b9e98801
5 changed files with 119 additions and 3 deletions

View file

@ -15,11 +15,16 @@
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QObject> #include <QObject>
#include <QProcess> #include <QProcess>
#include <QRegularExpression>
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
#define WAYDROID_COMMAND "waydroid" #define WAYDROID_COMMAND "waydroid"
// Extract current downloaded size, total_size and speed.
// Example of log: "[Downloading] 62.19 MB/1197.24 MB 96740.75 kbps(approx.)"
static const QRegularExpression downloadingStatusRegExp(R"(\[Downloading]\s*(\d+\.\d+)\s*MB/(\d+\.\d+)\s*MB\s*(\d+\.\d+)\s*kbps\(approx\.\))");
class WaydroidHelper : public QObject class WaydroidHelper : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -41,7 +46,42 @@ KAuth::ActionReply WaydroidHelper::initialize(const QVariantMap &args)
QProcess *process = new QProcess(this); QProcess *process = new QProcess(this);
process->start(WAYDROID_COMMAND, arguments); process->start(WAYDROID_COMMAND, arguments);
process->waitForFinished();
connect(process, &QProcess::readyReadStandardOutput, this, [process]() {
const QByteArray output = process->readAllStandardOutput();
const QByteArray lastLine = output.split('\r').last();
QVariantMap informations = {{u"log"_s, lastLine.constData()}};
QRegularExpressionMatch match = downloadingStatusRegExp.match(lastLine);
if (!match.hasMatch()) {
KAuth::HelperSupport::progressStep(informations);
return;
}
const QString downloadMatch = match.captured(1);
const QString totalMatch = match.captured(2);
const QString speedMatch = match.captured(3);
if (downloadMatch.isEmpty() || totalMatch.isEmpty() || speedMatch.isEmpty()) {
KAuth::HelperSupport::progressStep(informations);
return;
}
bool downloadCastOk, totalCastOk, speedCastOk;
float downloadedMB = downloadMatch.toFloat(&downloadCastOk);
float totalMB = totalMatch.toFloat(&totalCastOk);
float speedKbps = speedMatch.toFloat(&speedCastOk);
if (downloadCastOk && totalCastOk && speedCastOk) {
informations.insert(u"downloaded"_s, downloadedMB);
informations.insert(u"total"_s, totalMB);
informations.insert(u"speed"_s, speedKbps);
}
KAuth::HelperSupport::progressStep(informations);
});
process->waitForFinished(-1);
if (process->exitCode() == 0) { if (process->exitCode() == 0) {
return KAuth::ActionReply::SuccessReply(); return KAuth::ActionReply::SuccessReply();

View file

@ -220,6 +220,16 @@ void WaydroidState::initialize(const SystemType systemType, const RomType romTyp
KAuth::ExecuteJob *job = writeAction.execute(); KAuth::ExecuteJob *job = writeAction.execute();
job->start(); job->start();
connect(job, &KAuth::ExecuteJob::newData, this, [this](const QVariantMap &data) {
QString log = data.value("log", "").toString();
float downloaded = data.value("downloaded", 0.0).toFloat();
float total = data.value("total", 0.0).toFloat();
float speed = data.value("speed", 0.0).toFloat();
qCDebug(WAYDROIDINTEGRATIONPLUGIN) << "log: " << log;
Q_EMIT downloadStatusChanged(downloaded, total, speed);
});
connect(job, &KAuth::ExecuteJob::finished, this, [this](KJob *job, auto) { connect(job, &KAuth::ExecuteJob::finished, this, [this](KJob *job, auto) {
if (job->error() == 0) { if (job->error() == 0) {
m_status = Initialized; m_status = Initialized;

View file

@ -118,6 +118,8 @@ public:
Q_SIGNALS: Q_SIGNALS:
void statusChanged(); void statusChanged();
// download and total is in MB and speed in Kbps
void downloadStatusChanged(float downloaded, float total, float speed);
void sessionStatusChanged(); void sessionStatusChanged();
void systemTypeChanged(); void systemTypeChanged();
void ipAddressChanged(); void ipAddressChanged();

View file

@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2025 Florian RICHER <florian.richer@protonmail.com>
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.19 as Kirigami
import org.kde.plasma.components 3.0 as PC3
ColumnLayout {
id: root
property string text
property real downloaded: 0.0
property real total: 0.0
property real speed: 0.0
anchors.centerIn: parent
spacing: Kirigami.Units.largeSpacing
QQC2.Label {
text: root.text
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignHCenter
}
QQC2.ProgressBar {
from: 0
value: downloaded
to: total
indeterminate: total <= 0.0
Layout.alignment: Qt.AlignHCenter
}
QQC2.Label {
visible: total > 0.0
text: i18n("Downloading %1MB/%2MB Speed %3", downloaded.toFixed(2), total.toFixed(2), formatSpeed())
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignHCenter
font.pixelSize: Kirigami.Theme.smallFont.pixelSize
}
function formatSpeed(): string {
if (speed > 1024) {
return i18n("%1Mb/s", (speed / 1024).toFixed(0))
} else {
return i18n("%1Kb/s", speed.toFixed(0))
}
}
}

View file

@ -46,9 +46,20 @@ KCM.SimpleKCM {
visible: AIP.WaydroidState.errorTitle === "" && AIP.WaydroidState.status == AIP.WaydroidState.NotInitialized visible: AIP.WaydroidState.errorTitle === "" && AIP.WaydroidState.status == AIP.WaydroidState.NotInitialized
} }
WaydroidLoader { WaydroidDownloadStatus {
id: downloadStatus
visible: AIP.WaydroidState.errorTitle === "" && AIP.WaydroidState.status == AIP.WaydroidState.Initializing visible: AIP.WaydroidState.errorTitle === "" && AIP.WaydroidState.status == AIP.WaydroidState.Initializing
text: i18n("Waydroid is initializing.\nIt can take a few minutes.") text: i18n("Downloading Android and vendor images.\nIt can take a few minutes.")
Connections {
target: AIP.WaydroidState
function onDownloadStatusChanged(downloaded, total, speed) {
downloadStatus.downloaded = downloaded
downloadStatus.total = total
downloadStatus.speed = speed
}
}
} }
ColumnLayout { ColumnLayout {